From 04466033af595a7b4575805a7fc127bb4c9169a5 Mon Sep 17 00:00:00 2001 From: essemi-yuzr Date: Thu, 21 Nov 2019 11:12:51 +0800 Subject: [PATCH 001/110] Add es32f0271 drivers --- bsp/essemi/es32f0271/.config | 439 + bsp/essemi/es32f0271/Kconfig | 27 + bsp/essemi/es32f0271/README.md | 95 + bsp/essemi/es32f0271/SConscript | 14 + bsp/essemi/es32f0271/SConstruct | 39 + bsp/essemi/es32f0271/applications/SConscript | 11 + bsp/essemi/es32f0271/applications/main.c | 28 + bsp/essemi/es32f0271/drivers/Kconfig | 102 + bsp/essemi/es32f0271/drivers/SConscript | 45 + bsp/essemi/es32f0271/drivers/board.c | 136 + bsp/essemi/es32f0271/drivers/board.h | 35 + bsp/essemi/es32f0271/drivers/drv_gpio.c | 532 ++ bsp/essemi/es32f0271/drivers/drv_gpio.h | 16 + bsp/essemi/es32f0271/drivers/drv_hwtimer.c | 174 + bsp/essemi/es32f0271/drivers/drv_hwtimer.h | 16 + bsp/essemi/es32f0271/drivers/drv_i2c.c | 275 + bsp/essemi/es32f0271/drivers/drv_i2c.h | 16 + bsp/essemi/es32f0271/drivers/drv_pwm.c | 208 + bsp/essemi/es32f0271/drivers/drv_pwm.h | 16 + bsp/essemi/es32f0271/drivers/drv_rtc.c | 252 + bsp/essemi/es32f0271/drivers/drv_rtc.h | 16 + bsp/essemi/es32f0271/drivers/drv_spi.c | 439 + bsp/essemi/es32f0271/drivers/drv_spi.h | 22 + bsp/essemi/es32f0271/drivers/drv_uart.c | 296 + bsp/essemi/es32f0271/drivers/drv_uart.h | 16 + .../es32f0271/drivers/linker_scripts/link.sct | 14 + .../CMSIS_END_USER_LICENCE_AGREEMENT.pdf | Bin 0 -> 172641 bytes .../CMSIS_END_USER_LICENCE_AGREEMENT.rtf | 793 ++ .../ES32F0271/Include/ES32F0271/reg_ad16c4t.h | 683 ++ .../ES32F0271/Include/ES32F0271/reg_adc.h | 795 ++ .../ES32F0271/Include/ES32F0271/reg_aes.h | 193 + .../ES32F0271/Include/ES32F0271/reg_cmp.h | 95 + .../ES32F0271/Include/ES32F0271/reg_crc.h | 125 + .../ES32F0271/Include/ES32F0271/reg_dac.h | 97 + .../ES32F0271/Include/ES32F0271/reg_dma.h | 825 ++ .../ES32F0271/Include/ES32F0271/reg_exti.h | 809 ++ .../ES32F0271/Include/ES32F0271/reg_fc.h | 181 + .../ES32F0271/Include/ES32F0271/reg_gpio.h | 710 ++ .../ES32F0271/Include/ES32F0271/reg_hdiv.h | 75 + .../ES32F0271/Include/ES32F0271/reg_i2c.h | 623 ++ .../ES32F0271/Include/ES32F0271/reg_iwdg.h | 73 + .../ES32F0271/Include/ES32F0271/reg_mcm.h | 211 + .../ES32F0271/Include/ES32F0271/reg_mswd.h | 58 + .../ES32F0271/Include/ES32F0271/reg_rcu.h | 585 ++ .../ES32F0271/Include/ES32F0271/reg_rtc.h | 613 ++ .../ES32F0271/Include/ES32F0271/reg_spi.h | 444 + .../ES32F0271/Include/ES32F0271/reg_syscfg.h | 215 + .../ES32F0271/Include/ES32F0271/reg_tick.h | 113 + .../ES32F0271/Include/ES32F0271/reg_uart.h | 606 ++ .../ES32F0271/Include/ES32F0271/reg_usb.h | 873 ++ .../ES32F0271/Include/ES32F0271/reg_wwdg.h | 88 + .../ES32F0271/Include/ES32F0271/reg_wwdt.h | 92 + .../EastSoft/ES32F0271/Include/es32f0271.h | 389 + .../EastSoft/ES32F0271/Include/rt_misc.h | 183 + .../EastSoft/ES32F0271/ReleaseNote.html | 16 + .../ES32F0271/Startup/iar/startup_es32f027x.s | 256 + .../EastSoft/ES32F0271/Startup/keil/boot.c | 321 + .../Startup/keil/startup_es32f027x.s | 244 + .../EastSoft/ES32F0271/System/core_cm0.c | 472 ++ .../EastSoft/ES32F0271/System/retarget.c | 55 + .../ES32F0271/System/system_es32f027x.c | 79 + .../ES32F0271/System/system_es32f027x.h | 83 + .../CMSIS/Include/arm_common_tables.h | 121 + .../CMSIS/Include/arm_const_structs.h | 66 + .../libraries/CMSIS/Include/arm_math.h | 7157 +++++++++++++++++ .../libraries/CMSIS/Include/cmsis_armcc.h | 870 ++ .../libraries/CMSIS/Include/cmsis_armclang.h | 1877 +++++ .../libraries/CMSIS/Include/cmsis_compiler.h | 266 + .../libraries/CMSIS/Include/cmsis_gcc.h | 2088 +++++ .../libraries/CMSIS/Include/cmsis_iccarm.h | 913 +++ .../libraries/CMSIS/Include/cmsis_version.h | 39 + .../libraries/CMSIS/Include/core_armv8mbl.h | 1896 +++++ .../libraries/CMSIS/Include/core_armv8mml.h | 2960 +++++++ .../libraries/CMSIS/Include/core_cm0.h | 888 ++ .../libraries/CMSIS/Include/core_cm0plus.h | 1023 +++ .../libraries/CMSIS/Include/core_cm23.h | 1899 +++++ .../libraries/CMSIS/Include/core_cm3.h | 1933 +++++ .../libraries/CMSIS/Include/core_cm33.h | 2963 +++++++ .../libraries/CMSIS/Include/core_cm4.h | 2118 +++++ .../libraries/CMSIS/Include/core_cm7.h | 2660 ++++++ .../libraries/CMSIS/Include/core_sc000.h | 1016 +++ .../libraries/CMSIS/Include/core_sc300.h | 1903 +++++ .../libraries/CMSIS/Include/mpu_armv7.h | 197 + .../libraries/CMSIS/Include/mpu_armv8.h | 333 + .../libraries/CMSIS/Include/tz_context.h | 70 + .../libraries/CMSIS/RTOS/Template/cmsis_os.h | 707 ++ .../es32f0271/libraries/CMSIS/index.html | 14 + .../Include/md_ad16c4t.h | 4484 +++++++++++ .../Include/md_adc.h | 6109 ++++++++++++++ .../Include/md_aes.h | 941 +++ .../Include/md_cmp.h | 573 ++ .../Include/md_crc.h | 519 ++ .../Include/md_dac.h | 290 + .../Include/md_dma.h | 5561 +++++++++++++ .../Include/md_exti.h | 5167 ++++++++++++ .../Include/md_fc.h | 832 ++ .../Include/md_gpio.h | 2873 +++++++ .../Include/md_hdiv.h | 292 + .../Include/md_i2c.h | 3273 ++++++++ .../Include/md_rcu.h | 5804 +++++++++++++ .../Include/md_rtc.h | 2785 +++++++ .../Include/md_spi.h | 2523 ++++++ .../Include/md_syscfg.h | 1249 +++ .../Include/md_tick.h | 433 + .../Include/md_uart.h | 2874 +++++++ .../Include/md_wwdt.h | 382 + .../Include/usb_lowlayer_api.h | 728 ++ .../ReleaseNote.html | 17 + .../Source/md_adc.c | 298 + .../Source/md_fc.c | 300 + .../Source/md_gpio.c | 215 + .../Source/md_i2c.c | 245 + .../Source/md_rcu.c | 378 + .../Source/md_spi.c | 108 + .../Source/md_tick.c | 207 + .../Source/md_uart.c | 127 + .../Source/md_usb.c | 3804 +++++++++ .../Source/md_wwdt.c | 86 + bsp/essemi/es32f0271/libraries/SConscript | 32 + .../es32f0271/libraries/usblib/drivers/type.h | 41 + .../usblib/drivers/usb_lowlayer_api.h | 728 ++ bsp/essemi/es32f0271/project.uvoptx | 797 ++ bsp/essemi/es32f0271/project.uvprojx | 662 ++ bsp/essemi/es32f0271/rtconfig.h | 183 + bsp/essemi/es32f0271/rtconfig.py | 135 + bsp/essemi/es32f0271/template.uvoptx | 177 + bsp/essemi/es32f0271/template.uvprojx | 389 + 127 files changed, 107950 insertions(+) create mode 100644 bsp/essemi/es32f0271/.config create mode 100644 bsp/essemi/es32f0271/Kconfig create mode 100644 bsp/essemi/es32f0271/README.md create mode 100644 bsp/essemi/es32f0271/SConscript create mode 100644 bsp/essemi/es32f0271/SConstruct create mode 100644 bsp/essemi/es32f0271/applications/SConscript create mode 100644 bsp/essemi/es32f0271/applications/main.c create mode 100644 bsp/essemi/es32f0271/drivers/Kconfig create mode 100644 bsp/essemi/es32f0271/drivers/SConscript create mode 100644 bsp/essemi/es32f0271/drivers/board.c create mode 100644 bsp/essemi/es32f0271/drivers/board.h create mode 100644 bsp/essemi/es32f0271/drivers/drv_gpio.c create mode 100644 bsp/essemi/es32f0271/drivers/drv_gpio.h create mode 100644 bsp/essemi/es32f0271/drivers/drv_hwtimer.c create mode 100644 bsp/essemi/es32f0271/drivers/drv_hwtimer.h create mode 100644 bsp/essemi/es32f0271/drivers/drv_i2c.c create mode 100644 bsp/essemi/es32f0271/drivers/drv_i2c.h create mode 100644 bsp/essemi/es32f0271/drivers/drv_pwm.c create mode 100644 bsp/essemi/es32f0271/drivers/drv_pwm.h create mode 100644 bsp/essemi/es32f0271/drivers/drv_rtc.c create mode 100644 bsp/essemi/es32f0271/drivers/drv_rtc.h create mode 100644 bsp/essemi/es32f0271/drivers/drv_spi.c create mode 100644 bsp/essemi/es32f0271/drivers/drv_spi.h create mode 100644 bsp/essemi/es32f0271/drivers/drv_uart.c create mode 100644 bsp/essemi/es32f0271/drivers/drv_uart.h create mode 100644 bsp/essemi/es32f0271/drivers/linker_scripts/link.sct create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.rtf create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_ad16c4t.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_adc.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_aes.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_cmp.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_crc.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_dac.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_dma.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_exti.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_fc.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_gpio.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_hdiv.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_i2c.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_iwdg.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_mcm.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_mswd.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_rcu.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_rtc.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_spi.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_syscfg.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_tick.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_uart.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_usb.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_wwdg.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271/reg_wwdt.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/es32f0271.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/rt_misc.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/ReleaseNote.html create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/iar/startup_es32f027x.s create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/keil/boot.c create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/keil/startup_es32f027x.s create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/core_cm0.c create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/retarget.c create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.c create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_common_tables.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_const_structs.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_math.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_armcc.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_armclang.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_compiler.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_gcc.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_iccarm.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_version.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_armv8mbl.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_armv8mml.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm0.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm0plus.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm23.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm3.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm33.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm4.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm7.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_sc000.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/core_sc300.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/mpu_armv7.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/mpu_armv8.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/Include/tz_context.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/RTOS/Template/cmsis_os.h create mode 100644 bsp/essemi/es32f0271/libraries/CMSIS/index.html create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_ad16c4t.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_adc.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_aes.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_cmp.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_crc.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_dac.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_dma.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_exti.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_fc.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_gpio.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_hdiv.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_i2c.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_rcu.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_rtc.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_spi.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_syscfg.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_tick.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_uart.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_wwdt.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/usb_lowlayer_api.h create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/ReleaseNote.html create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_adc.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_fc.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_gpio.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_i2c.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_rcu.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_spi.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_tick.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_uart.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_usb.c create mode 100644 bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_wwdt.c create mode 100644 bsp/essemi/es32f0271/libraries/SConscript create mode 100644 bsp/essemi/es32f0271/libraries/usblib/drivers/type.h create mode 100644 bsp/essemi/es32f0271/libraries/usblib/drivers/usb_lowlayer_api.h create mode 100644 bsp/essemi/es32f0271/project.uvoptx create mode 100644 bsp/essemi/es32f0271/project.uvprojx create mode 100644 bsp/essemi/es32f0271/rtconfig.h create mode 100644 bsp/essemi/es32f0271/rtconfig.py create mode 100644 bsp/essemi/es32f0271/template.uvoptx create mode 100644 bsp/essemi/es32f0271/template.uvprojx diff --git a/bsp/essemi/es32f0271/.config b/bsp/essemi/es32f0271/.config new file mode 100644 index 0000000000..15ed9fadcd --- /dev/null +++ b/bsp/essemi/es32f0271/.config @@ -0,0 +1,439 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +# CONFIG_RT_USING_MEMHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMTRACE is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x40002 +# CONFIG_RT_USING_CPU_FFS is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=1024 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# C++ features +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Command shell +# +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=2048 +CONFIG_FINSH_CMD_SIZE=80 +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_USING_MSH_DEFAULT=y +CONFIG_FINSH_USING_MSH_ONLY=y +CONFIG_FINSH_ARG_MAX=10 + +# +# Device virtual file system +# +# CONFIG_RT_USING_DFS is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_PIPE_BUFSZ=512 +# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SERIAL=y +# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_WIFI is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# POSIX layer and C standard library +# +# CONFIG_RT_USING_LIBC is not set +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_LIBC_USING_TIME is not set + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# Network interface device +# +# CONFIG_RT_USING_NETDEV is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT is not set + +# +# VBUS(Virtual Software BUS) +# +# CONFIG_RT_USING_VBUS is not set + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOTHUB is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_CMSIS is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_LCD_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_UKAL is not set +CONFIG_SOC_ES32F0271LT=y + +# +# Hardware Drivers Config +# + +# +# On-chip Peripheral Drivers +# + +# +# PIN Drivers +# +CONFIG_BSP_USING_GPIO=y + +# +# UART Drivers +# +CONFIG_BSP_USING_UART1=y +# CONFIG_BSP_USING_UART2 is not set +# CONFIG_BSP_USING_UART3 is not set + +# +# SPI Drivers +# +# CONFIG_BSP_USING_SPI1 is not set +# CONFIG_BSP_USING_SPI2 is not set + +# +# I2C Drivers +# +# CONFIG_BSP_USING_I2C1 is not set +# CONFIG_BSP_USING_I2C2 is not set + +# +# HWtimer Drivers +# +# CONFIG_BSP_USING_HWTIMER1 is not set + +# +# PWM Drivers +# +# CONFIG_BSP_USING_PWM_GP16C2T1 is not set +# CONFIG_BSP_USING_PWM_GP16C2T4 is not set + +# +# RTC Drivers +# +# CONFIG_BSP_USING_RTC is not set + +# +# ADC Drivers +# +# CONFIG_BSP_USING_ADC is not set + +# +# Onboard Peripheral Drivers +# + +# +# Offboard Peripheral Drivers +# diff --git a/bsp/essemi/es32f0271/Kconfig b/bsp/essemi/es32f0271/Kconfig new file mode 100644 index 0000000000..2065783042 --- /dev/null +++ b/bsp/essemi/es32f0271/Kconfig @@ -0,0 +1,27 @@ +mainmenu "RT-Thread Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" + +config SOC_ES32F0271LT + bool + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +source "drivers/Kconfig" diff --git a/bsp/essemi/es32f0271/README.md b/bsp/essemi/es32f0271/README.md new file mode 100644 index 0000000000..c50443466b --- /dev/null +++ b/bsp/essemi/es32f0271/README.md @@ -0,0 +1,95 @@ +# ES-PDS-ES32F0271 开发板 BSP 说明 +标签: EastSoft、国产MCU、Cortex-M0、ES32F0271LT + +## 1. 简介 + +本文档为上海东软载波微电子开发团队为 ES-PDS-ES32F0271 开发板提供的 BSP (板级支持包) 说明。 +通过阅读本文档,开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。 + +### 1.1 开发板介绍 + +主要内容如下: +ES-PDS-ES32F0271 是东软载波微电子官方推出的一款基于 ARM Cortex-M0 内核的开发板,最高主频为 48MHz,可满足基础功能测试及高端功能扩展等开发需求。 + +ES-PDS-ES32F0271-V1.1 + +该开发板常用 **板载资源** 如下: + +- MCU:ES32F0271LT,主频 48MHz,8KB SRAM,64KB FLASH +- 外部模块:SPI FLASH (MX25L64,8MB)、I2C EEPROM (M24C04,512B) +- 常用外设 + - 可调电阻:1个,(PC03) + - LED:2个,(PD03/PB08) + - 五轴按键: +- 常用接口:GPIO、UART、SPI、I2C +- 调试接口,ESLinkⅡ(EastSoft 官方推出的开发工具,有标准版和mini版两种版本,均自带 CDC 串口功能) SWD 下载 + +外设支持: + +本 BSP 目前对外设的支持情况如下: + +| **板载外设** | **支持情况** | **备注** | +| :---------------- | :----------: | :------------------------------------| +| **片上外设** | **支持情况** | **备注** | +| GPIO | 支持 | GPIOs | +| UART | 支持 | UART1/2/3 | +| SPI | 支持 | SPI1/2 | +| I2C | 支持 | I2C1/2 | +| PWM | 支持 | PWM1/2 | +| TIMER | 支持 | TIMER1 | +| RTC | 支持 | RTC | +| ADC | 支持 | ADC | + +### 1.2 注意事项 + +- 本BSP中,SPI2和PWM2不能同时使用 + +更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/) + +## 2. 快速上手 + +本 BSP 为开发者提供 MDK5 工程。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。 + +### 硬件连接 + +使用 ESLinkⅡ (自带 CDC 串口)或 Jlink 等调试工具连接开发板到 PC端,拨动开关选择使用调试工具供电或使用外部电源供电。若使用 Jlink 等调试工具,还需要将 UART1_TX(PB06)、UART1_RX(PB07)、GND 接到串口工具上。 + +ESLinkⅡ(mini) + ES-PDS-ES32F0271-V1.1 + +### 编译下载 + +双击 project.uvprojx 文件,打开 MDK5 工程,工程默认配置使用 JLink 下载程序,在通过 JLink 连接开发板的基础上,点击下载按钮即可下载程序到开发板,如果使用 ESLinkⅡ,则选择 "CMSIS-DAP Debugger",连接正常后即可编译并下载程序到开发板。 + +### 运行结果 + +下载程序成功之后,系统会自动运行,观察串口输出的信息,同时开发板LED闪烁。 + +```bash + \ | / +- RT - Thread Operating System + / | \ 4.0.2 build Oct 31 2019 + 2006 - 2019 Copyright by rt-thread team +msh > +``` +## 3. 进阶使用 + +此 BSP 默认只开启了 GPIO 和 uart1 的功能,如果需使用 Flash 等更多高级功能,需要利用 ENV 工具对 BSP 进行配置,步骤如下: + +1. 在 bsp 下打开 env 工具。 + +2. 输入`menuconfig`命令配置工程,配置好之后保存退出。 + +3. 输入`pkgs --update`命令更新软件包。 + +4. 输入`scons --target=mdk5/iar` 命令重新生成工程。 + +更多 Env 工具的详细介绍请参考 [RT-Thread 文档中心](https://www.rt-thread.org/document/site/) + +## 4. 联系人信息 + +- [yuzr](https://github.com/essemi-yuzr) + +## 5. 参考 + +- [ EastSoft 官网](http://www.essemi.com) + diff --git a/bsp/essemi/es32f0271/SConscript b/bsp/essemi/es32f0271/SConscript new file mode 100644 index 0000000000..468297b6a9 --- /dev/null +++ b/bsp/essemi/es32f0271/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +Import('RTT_ROOT') + +objs = [] +cwd = str(Dir('#')) +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/essemi/es32f0271/SConstruct b/bsp/essemi/es32f0271/SConstruct new file mode 100644 index 0000000000..164265293d --- /dev/null +++ b/bsp/essemi/es32f0271/SConstruct @@ -0,0 +1,39 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = env["LINKCOM"] + ' --map project.map') + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/essemi/es32f0271/applications/SConscript b/bsp/essemi/es32f0271/applications/SConscript new file mode 100644 index 0000000000..e0c84e8f14 --- /dev/null +++ b/bsp/essemi/es32f0271/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') + +CPPPATH = [cwd, str(Dir('#'))] +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/essemi/es32f0271/applications/main.c b/bsp/essemi/es32f0271/applications/main.c new file mode 100644 index 0000000000..31e31d355d --- /dev/null +++ b/bsp/essemi/es32f0271/applications/main.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include + +#define LED_PIN 61 + +int main(void) +{ + /* LED pin configuration */ + rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); + + while (1) + { + rt_pin_write(LED_PIN, PIN_HIGH); + rt_thread_mdelay(1000); + rt_pin_write(LED_PIN, PIN_LOW); + rt_thread_mdelay(1000); + } +} diff --git a/bsp/essemi/es32f0271/drivers/Kconfig b/bsp/essemi/es32f0271/drivers/Kconfig new file mode 100644 index 0000000000..37265a5ba8 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/Kconfig @@ -0,0 +1,102 @@ +menu "Hardware Drivers Config" + + menu "On-chip Peripheral Drivers" + menu "PIN Drivers" + config BSP_USING_GPIO + bool "Enable GPIO" + select RT_USING_PIN + default y + endmenu + + menu "UART Drivers" + config BSP_USING_UART1 + bool "Enable UART1 PB06/PB07(T/R)" + select RT_USING_SERIAL + default y + + config BSP_USING_UART2 + bool "Enable UART2 PA02/PA03(T/R)" + select RT_USING_SERIAL + default n + + config BSP_USING_UART3 + bool "Enable UART3 PC06/PC07(T/R)" + select RT_USING_SERIAL + default n + endmenu + + menu "SPI Drivers" + config BSP_USING_SPI1 + bool "Enable SPI1 BUS PB03/PB04/PB05(CLK/MISO/MOSI)" + select RT_USING_SPI + select RT_USING_PIN + default n + + config BSP_USING_SPI2 + bool "Enable SPI2 BUS PB13/PB14/PB15(CLK/MISO/MOSI)" + select RT_USING_SPI + select RT_USING_PIN + default n + depends on !BSP_USING_PWM_GP16C2T4 + endmenu + + menu "I2C Drivers" + config BSP_USING_I2C1 + bool "Enable I2C1 BUS PC12/PD02(SCL/SDA)" + select RT_USING_I2C + default n + + config BSP_USING_I2C2 + bool "Enable I2C2 BUS PB10/PB11(SCL/SDA)" + select RT_USING_I2C + default n + endmenu + + menu "HWtimer Drivers" + + config BSP_USING_HWTIMER1 + bool "Using timer1" + select RT_USING_HWTIMER + default n + endmenu + + menu "PWM Drivers" + + config BSP_USING_PWM_GP16C2T1 + bool "Using PWM_1(GP16C2T1) PB01/PB02" + select RT_USING_PWM + default n + + config BSP_USING_PWM_GP16C2T4 + bool "Using PWM2(GP16C2T4) PB12/PB14" + select RT_USING_PWM + default n + depends on !BSP_USING_SPI2 + + endmenu + + menu "RTC Drivers" + config BSP_USING_RTC + bool "Using RTC" + select RT_USING_RTC + default n + endmenu + + menu "ADC Drivers" + config BSP_USING_ADC + bool "Using ADC" + select RT_USING_ADC + default n + endmenu + + endmenu + + menu "Onboard Peripheral Drivers" + + endmenu + + menu "Offboard Peripheral Drivers" + + endmenu + +endmenu diff --git a/bsp/essemi/es32f0271/drivers/SConscript b/bsp/essemi/es32f0271/drivers/SConscript new file mode 100644 index 0000000000..3be3df80c5 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/SConscript @@ -0,0 +1,45 @@ +from building import * + +cwd = GetCurrentDir() + +# add the general drivers. +src = Split(''' +board.c +''') + +# add gpio code +if GetDepend('RT_USING_PIN'): + src += ['drv_gpio.c'] + +# add serial driver code +if GetDepend('BSP_USING_UART1') or GetDepend('BSP_USING_UART2') or GetDepend('BSP_USING_UART3'): + src += ['drv_uart.c'] + +# add spi driver code +if GetDepend('BSP_USING_SPI1') or GetDepend('BSP_USING_SPI2'): + src += ['drv_spi.c'] + +# add i2c driver code +if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2'): + src += ['drv_i2c.c'] + +# add pwm driver code +if GetDepend('BSP_USING_PWM1') or GetDepend('BSP_USING_PWM2') or GetDepend('BSP_USING_PWM3') or GetDepend('BSP_USING_PWM4') or GetDepend('BSP_USING_PWM_GP16C2T1') or GetDepend('BSP_USING_PWM_GP16C2T4'): + src += ['drv_pwm.c'] + +# add hwtimer driver code +if GetDepend('BSP_USING_HWTIMER1'): + src += ['drv_hwtimer.c'] + +# add rtc driver code +if GetDepend(['BSP_USING_RTC']): + src += ['drv_rtc.c'] + +# add adc driver code +if GetDepend(['BSP_USING_ADC']): + src += ['drv_adc.c'] + +CPPPATH = [cwd] +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/essemi/es32f0271/drivers/board.c b/bsp/essemi/es32f0271/drivers/board.c new file mode 100644 index 0000000000..8ebc351ff1 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/board.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include +#include "board.h" +#include "drv_uart.h" +#include "drv_gpio.h" +#include "md_gpio.h" + +/** + * @addtogroup es32f0 + */ + +/*@{*/ + +/******************************************************************************* +* Function Name : NVIC_Configuration +* Description : Configures Vector Table base location. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void NVIC_Configuration(void) +{ +} + +/******************************************************************************* + * Function Name : SystemClock_Configuration + * Description : Configures the System Clock. + * Input : None + * Output : None + * Return : None + *******************************************************************************/ +void SystemClock_Config(void) +{ + /*-------------------------Clock Config-------------------------/ + * Config system clock to 48MHz of which the clock source + * is PLL0. + */ + + // + // Open PLL0/HRC then wait it ready. + // + SET_BIT(RCU->CON, RCU_CON_PLL0ON_MSK); + SET_BIT(RCU->CON, RCU_CON_HRCON_MSK); + + /* Wait HRC clock steady. */ + while (!READ_BIT(RCU->CON, RCU_CON_HRCRDY_MSK)); + + // + // Change system clock source,PLL0,48MHz. + // + /* Chose PLL0 as system clock. */ + MODIFY_REG(RCU->CFG, RCU_CFG_SW_MSK, (0x4 << RCU_CFG_SW_POSS)); + /* Config mul of PLL0. */ + MODIFY_REG(RCU->CFG, RCU_CFG_PLLMUL_MSK, (11 << RCU_CFG_PLLMUL_POSS)); + + // + // Start to change system clock and wait it ready. + // + /* Config flash read wait time. */ + MODIFY_REG(FC->CON, FC_CON_WAIT_MSK, (0X2 << FC_CON_WAIT_POSS)); + /* Start to change. */ + SET_BIT(RCU->CFG, RCU_CFG_CKCFG_MSK); + + /* Wait system clock ready. */ + while (!READ_BIT(RCU->CON, RCU_CON_SWRDY_MSK)); + + // + // Remember the system clock. + // + SystemCoreClock = 48000000; +} + +/******************************************************************************* + * Function Name : SysTick_Configuration + * Description : Configures the SysTick for OS tick. + * Input : None + * Output : None + * Return : None + *******************************************************************************/ +void SysTick_Configuration(void) +{ + /* ticks = sysclk / RT_TICK_PER_SECOND */ + SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); +} + +/** + * This is the timer interrupt service routine. + * + */ +void SysTick_Handler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +/*@}*/ +/** + * This function will initial ES32F0 board. + */ +void rt_hw_board_init(void) +{ + /* NVIC Configuration */ + NVIC_Configuration(); + + /*System Clock Configuration */ + SystemClock_Config(); + + /* Configure the SysTick */ + SysTick_Configuration(); + +#ifdef RT_USING_HEAP + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); +#endif +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif +} + diff --git a/bsp/essemi/es32f0271/drivers/board.h b/bsp/essemi/es32f0271/drivers/board.h new file mode 100644 index 0000000000..b1cb44890d --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/board.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +// <<< Use Configuration Wizard in Context Menu >>> +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include "es32f0271.h" + +#define ES32F0_SRAM_SIZE 0x2000 +#define ES32F0_SRAM_END (0x20000000 + ES32F0_SRAM_SIZE) + +#if defined(__CC_ARM) || defined(__CLANG_ARM) + extern int Image$$RW_IRAM1$$ZI$$Limit; + #define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ + #pragma section="HEAP" + #define HEAP_BEGIN (__segment_end("HEAP")) +#else + extern int __bss_end; + #define HEAP_BEGIN ((void *)&__bss_end) +#endif + +#define HEAP_END ES32F0_SRAM_END + +void rt_hw_board_init(void); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_gpio.c b/bsp/essemi/es32f0271/drivers/drv_gpio.c new file mode 100644 index 0000000000..293febc728 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_gpio.c @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include +#include "board.h" +#include "drv_gpio.h" + +#ifdef RT_USING_PIN + +#define __ES32F0_PIN(index, gpio, gpio_index) {index, GPIO##gpio, gpio_index} +#define __ES32F0_PIN_DEFAULT {-1, 0, 0} + +/* ES32F0 GPIO driver */ +struct pin_index +{ + int index; + GPIO_TypeDef *gpio; + uint32_t pin; +}; + +static const struct pin_index pins[] = +{ + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN(2, C, 13), + __ES32F0_PIN(3, C, 14), + __ES32F0_PIN(4, C, 15), + __ES32F0_PIN(5, D, 14), + __ES32F0_PIN(6, D, 15), + __ES32F0_PIN(7, D, 13), + __ES32F0_PIN(8, C, 0), + __ES32F0_PIN(9, C, 1), + __ES32F0_PIN(10, C, 2), + __ES32F0_PIN(11, C, 3), + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN(14, A, 0), + __ES32F0_PIN(15, A, 1), + __ES32F0_PIN(16, A, 2), + __ES32F0_PIN(17, A, 3), + __ES32F0_PIN(18, D, 0), + __ES32F0_PIN(19, D, 1), + __ES32F0_PIN(20, A, 4), + __ES32F0_PIN(21, A, 5), + __ES32F0_PIN(22, A, 6), + __ES32F0_PIN(23, A, 7), + __ES32F0_PIN(24, C, 4), + __ES32F0_PIN(25, C, 5), + __ES32F0_PIN(26, B, 0), + __ES32F0_PIN(27, B, 1), + __ES32F0_PIN(28, B, 2), + __ES32F0_PIN(29, B, 10), + __ES32F0_PIN(30, B, 11), + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN(33, B, 12), + __ES32F0_PIN(34, B, 13), + __ES32F0_PIN(35, B, 14), + __ES32F0_PIN(36, B, 15), + __ES32F0_PIN(37, C, 6), + __ES32F0_PIN(38, C, 7), + __ES32F0_PIN(39, C, 8), + __ES32F0_PIN(40, C, 9), + __ES32F0_PIN(41, A, 8), + __ES32F0_PIN(42, A, 9), + __ES32F0_PIN(43, A, 10), + __ES32F0_PIN(44, A, 11), + __ES32F0_PIN(45, A, 12), + __ES32F0_PIN(46, A, 13), + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN(49, A, 14), + __ES32F0_PIN(50, A, 15), + __ES32F0_PIN(51, C, 10), + __ES32F0_PIN(52, C, 11), + __ES32F0_PIN(53, C, 12), + __ES32F0_PIN(54, D, 2), + __ES32F0_PIN(55, B, 3), + __ES32F0_PIN(56, B, 4), + __ES32F0_PIN(57, B, 5), + __ES32F0_PIN(58, B, 6), + __ES32F0_PIN(59, B, 7), + __ES32F0_PIN(60, D, 3), + __ES32F0_PIN(61, B, 8), + __ES32F0_PIN(62, B, 9), + __ES32F0_PIN_DEFAULT, + __ES32F0_PIN_DEFAULT, +}; + +struct pin_irq_map +{ + rt_uint16_t pinbit; + IRQn_Type irqno; +}; +static const struct pin_irq_map pin_irq_map[] = +{ + {0, EXTI_0to1_IRQn}, + {1, EXTI_0to1_IRQn}, + {2, EXTI_2to3_IRQn}, + {3, EXTI_2to3_IRQn}, + {4, EXTI_4to15_IRQn}, + {5, EXTI_4to15_IRQn}, + {6, EXTI_4to15_IRQn}, + {7, EXTI_4to15_IRQn}, + {8, EXTI_4to15_IRQn}, + {9, EXTI_4to15_IRQn}, + {10, EXTI_4to15_IRQn}, + {11, EXTI_4to15_IRQn}, + {12, EXTI_4to15_IRQn}, + {13, EXTI_4to15_IRQn}, + {14, EXTI_4to15_IRQn}, + {15, EXTI_4to15_IRQn}, +}; + +struct rt_pin_irq_hdr pin_irq_hdr_tab[] = +{ + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, + { -1, 0, RT_NULL, RT_NULL}, +}; + +#define ITEM_NUM(items) sizeof(items) / sizeof(items[0]) +const struct pin_index *get_pin(uint8_t pin) +{ + const struct pin_index *index; + if (pin < ITEM_NUM(pins)) + { + index = &pins[pin]; + if (index->index == -1) + index = RT_NULL; + } + else + { + index = RT_NULL; + } + return index; +}; + +void es32f0_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) +{ + const struct pin_index *index; + index = get_pin(pin); + if (index == RT_NULL) + { + return; + } + + /* Write GPIO */ + if (value == 0) + SET_BIT(index->gpio->BSBR, 0x1<<(index->pin+16)); + else + SET_BIT(index->gpio->BSBR, 0x1<pin); +} + +int es32f0_pin_read(rt_device_t dev, rt_base_t pin) +{ + int value; + const struct pin_index *index; + value = PIN_LOW; + index = get_pin(pin); + if (index == RT_NULL) + { + return value; + } + + /* Read the GPIO value with the spcified index */ + value = (index->gpio->IDATA & (0x1<pin)) != 0; + + return value; +} + +void es32f0_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) +{ + const struct pin_index *index; + GPIO_TypeDef *gpiox; + index = get_pin(pin); + if (index == RT_NULL) + { + return; + } + + /* Get the IO port */ + gpiox = index->gpio; + + /* Config GPIO */ + switch(mode) + { + case PIN_MODE_OUTPUT: + { + /* pushpull & output & 16mA */ + MODIFY_REG(gpiox->MOD, (0x3<<(index->pin*2)), (0x1<<(index->pin*2))); + CLEAR_BIT(gpiox->OT, (0x1<pin)); + CLEAR_BIT(gpiox->DS, (0x1<pin)); + break; + } + case PIN_MODE_OUTPUT_OD: + { + /* opendrain & output & 16mA */ + MODIFY_REG(gpiox->MOD, (0x3<pin), (0x1<pin)); + SET_BIT(gpiox->OT, (0x1<pin)); + CLEAR_BIT(gpiox->DS, (0x1<pin)); + break; + } + case PIN_MODE_INPUT: + { + /* input & no pull & CMOS & filter */ + MODIFY_REG(gpiox->MOD, (0x3<pin), (0x0<pin)); + MODIFY_REG(gpiox->PUD, (0x3<pin), (0x0<pin)); + SET_BIT(gpiox->IST, (0x1<pin)); + SET_BIT(gpiox->FIR, (0x1<pin)); + break; + } + case PIN_MODE_INPUT_PULLUP: + { + /* input & pull up & CMOS & filter */ + MODIFY_REG(gpiox->MOD, (0x3<pin), (0x0<pin)); + MODIFY_REG(gpiox->PUD, (0x3<pin), (0x1<pin)); + SET_BIT(gpiox->IST, (0x1<pin)); + SET_BIT(gpiox->FIR, (0x1<pin)); + break; + } + case PIN_MODE_INPUT_PULLDOWN: + { + /* input & pull down & CMOS & filter */ + MODIFY_REG(gpiox->MOD, (0x3<pin), (0x0<pin)); + MODIFY_REG(gpiox->PUD, (0x3<pin), (0x2<pin)); + SET_BIT(gpiox->IST, (0x1<pin)); + SET_BIT(gpiox->FIR, (0x1<pin)); + break; + } + default: + { + /* output */ + MODIFY_REG(gpiox->MOD, (0x3<pin), (0x1<pin)); + } + } +} + +rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint16_t gpio_pin) +{ + rt_int32_t mapindex = gpio_pin & 0x00FF; + if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map)) + { + return RT_NULL; + } + return &pin_irq_map[mapindex]; +}; + +rt_err_t es32f0_pin_attach_irq(struct rt_device *device, rt_int32_t pin, + rt_uint32_t mode, void (*hdr)(void *args), void *args) +{ + const struct pin_index *index; + rt_base_t level; + rt_int32_t irqindex; + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_ENOSYS; + } + /* pin no. convert to dec no. */ + for (irqindex = 0; irqindex < 16; irqindex++) + { + if ((0x01 << irqindex) == index->pin) + { + break; + } + } + if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) + { + return RT_ENOSYS; + } + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[irqindex].pin == pin && + pin_irq_hdr_tab[irqindex].hdr == hdr && + pin_irq_hdr_tab[irqindex].mode == mode && + pin_irq_hdr_tab[irqindex].args == args) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + if (pin_irq_hdr_tab[irqindex].pin != -1) + { + rt_hw_interrupt_enable(level); + return RT_EBUSY; + } + pin_irq_hdr_tab[irqindex].pin = pin; + pin_irq_hdr_tab[irqindex].hdr = hdr; + pin_irq_hdr_tab[irqindex].mode = mode; + pin_irq_hdr_tab[irqindex].args = args; + rt_hw_interrupt_enable(level); + return RT_EOK; +} + +rt_err_t es32f0_pin_detach_irq(struct rt_device *device, rt_int32_t pin) +{ + const struct pin_index *index; + rt_base_t level; + rt_int32_t irqindex = -1; + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_ENOSYS; + } + irqindex = index->pin & 0x00FF; + if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) + { + return RT_ENOSYS; + } + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[irqindex].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + pin_irq_hdr_tab[irqindex].pin = -1; + pin_irq_hdr_tab[irqindex].hdr = RT_NULL; + pin_irq_hdr_tab[irqindex].mode = 0; + pin_irq_hdr_tab[irqindex].args = RT_NULL; + rt_hw_interrupt_enable(level); + return RT_EOK; +} + +rt_err_t es32f0_pin_irq_enable(struct rt_device *device, rt_base_t pin, + rt_uint32_t enabled) +{ + const struct pin_index *index; + const struct pin_irq_map *irqmap; + GPIO_TypeDef *gpiox; + rt_base_t level; + rt_int32_t irqindex = -1; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_ENOSYS; + } + + /* Get the IO port */ + gpiox = index->gpio; + + if (enabled == PIN_IRQ_ENABLE) + { + /* pin no. convert to dec no. */ + for (irqindex = 0; irqindex < 16; irqindex++) + { + if ((0x01 << irqindex) == index->pin) + { + break; + } + } + if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) + { + return RT_ENOSYS; + } + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[irqindex].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_ENOSYS; + } + irqmap = &pin_irq_map[irqindex]; + + /* Config EXTI */ + MODIFY_REG(gpiox->MOD, (0x3<pin), (0x0<pin)); + SET_BIT(gpiox->FIR, index->pin); + SET_BIT(gpiox->IST, index->pin); + MODIFY_REG(((uint32_t *)(&EXTI->ICFG1))[index->pin/8], + 0xF<<(index->pin%8), + (((uint32_t)(index->gpio) - AHB2_BASE)/0x400)<<(index->pin%8)); + SET_BIT(EXTI->DB, 0x1<pin); + + switch (pin_irq_hdr_tab[irqindex].mode) + { + case PIN_IRQ_MODE_RISING: + { + /* pull down the pin */ + MODIFY_REG(gpiox->PUD, (0x3<pin), (0x2<pin)); + /* Enable EXTI rising interrupt and disable falling interrupt */ + SET_BIT(EXTI->RTS, (0x1<pin)); + CLEAR_BIT(EXTI->FTS, (0x1<pin)); + break; + } + case PIN_IRQ_MODE_FALLING: + { + /* pull up the pin */ + MODIFY_REG(gpiox->PUD, (0x3<pin), (0x1<pin)); + /* Enable EXTI falling interrupt and disable rising interrupt */ + CLEAR_BIT(EXTI->RTS, (0x1<pin)); + SET_BIT(EXTI->FTS, (0x1<pin)); + break; + } + case PIN_IRQ_MODE_RISING_FALLING: + { + /* pull up the pin */ + MODIFY_REG(gpiox->PUD, (0x3<pin), (0x1<pin)); + /* Enable EXTI falling interrupt and enable rising interrupt */ + SET_BIT(EXTI->RTS, (0x1<pin)); + SET_BIT(EXTI->FTS, (0x1<pin)); + break; + } + } + + /* Enable EXTI interrupt */ + SET_BIT(EXTI->IER, (0x1<pin)); + NVIC_EnableIRQ(irqmap->irqno); + rt_hw_interrupt_enable(level); + } + else if (enabled == PIN_IRQ_DISABLE) + { + irqmap = get_pin_irq_map(index->pin); + if (irqmap == RT_NULL) + { + return RT_ENOSYS; + } + NVIC_DisableIRQ(irqmap->irqno); + } + else + { + return RT_ENOSYS; + } + return RT_EOK; +} + +const static struct rt_pin_ops _es32f0_pin_ops = +{ + es32f0_pin_mode, + es32f0_pin_write, + es32f0_pin_read, + es32f0_pin_attach_irq, + es32f0_pin_detach_irq, + es32f0_pin_irq_enable, +}; + +int rt_hw_pin_init(void) +{ + int result; + + /* Open IO clock */ + SET_BIT(RCU->AHBEN, RCU_AHBEN_GPDEN_MSK|RCU_AHBEN_GPCEN_MSK \ + |RCU_AHBEN_GPBEN_MSK|RCU_AHBEN_GPAEN_MSK); + + /* register IO device */ + result = rt_device_pin_register("pin", &_es32f0_pin_ops, RT_NULL); + return result; +} +INIT_BOARD_EXPORT(rt_hw_pin_init); + +rt_inline void pin_irq_hdr(uint16_t GPIO_Pin) +{ + uint16_t irqno; + /* pin no. convert to dec no. */ + for (irqno = 0; irqno < 16; irqno++) + { + if ((0x01 << irqno) == GPIO_Pin) + { + break; + } + } + if (irqno == 16) + return; + if (pin_irq_hdr_tab[irqno].hdr) + { + pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args); + } +} + +void GPIO_EXTI_Callback(uint16_t GPIO_Pin) +{ + /* Read the exti interrupt then clear the flag */ + if ((EXTI->RIF & (0x1<ICR, 0x1< +#include +#include +#include +#include +#include "md_ad16c4t.h" +#include "md_rcu.h" + +#ifdef RT_USING_HWTIMER + +/* Defien the hardware timer control struct */ +struct es32f0_hwtimer_dev +{ + rt_hwtimer_t parent; + AD16C4T_TypeDef *hwtimer_periph; + IRQn_Type IRQn; +}; + +#ifdef BSP_USING_HWTIMER1 +static struct es32f0_hwtimer_dev hwtimer1; + +void BS16T1_IRQHandler(void) +{ + /* if BS16T1 IT */ + if (BS16T1->IFM & AD16C4T_RIF_UI_MSK) + { + SET_BIT(BS16T1->ICR, AD16C4T_ICR_UI_MSK); + rt_device_hwtimer_isr(&hwtimer1.parent); + + if (HWTIMER_MODE_ONESHOT == hwtimer1.parent.mode) + { + CLEAR_BIT(BS16T1->CON1, AD16C4T_CON1_CNTEN_MSK); + } + } +} +#endif + +static struct rt_hwtimer_info es32f0_hwtimer_info = +{ + 48000000, /* maximum count frequency */ + 1, /* minimum count frequency */ + 65535, /* counter maximum value */ + HWTIMER_CNTMODE_UP +}; + +static void es32f0_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state) +{ + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + + RT_ASSERT(hwtimer != RT_NULL); + + if (1 == state) + { + /* Set frequency */ + WRITE_REG(hwtimer->hwtimer_periph->PRES, (SystemCoreClock/hwtimer->parent.freq - 1)); + /* Enable timer IT */ + SET_BIT(hwtimer->hwtimer_periph->IER, AD16C4T_IER_UI_MSK); + NVIC_EnableIRQ(hwtimer->IRQn); + } + else + { + /* Dsiable timer IT */ + SET_BIT(hwtimer->hwtimer_periph->IDR, AD16C4T_IER_UI_MSK); + } +} + +static rt_err_t es32f0_hwtimer_start(rt_hwtimer_t *timer, + rt_uint32_t cnt, + rt_hwtimer_mode_t mode) +{ + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + + RT_ASSERT(hwtimer != RT_NULL); + + WRITE_REG(hwtimer->hwtimer_periph->AR, cnt); + SET_BIT(hwtimer->hwtimer_periph->CON1, AD16C4T_CON1_CNTEN_MSK); + + return RT_EOK; +} + +static void es32f0_hwtimer_stop(rt_hwtimer_t *timer) +{ + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + + RT_ASSERT(hwtimer != RT_NULL); + + CLEAR_BIT(hwtimer->hwtimer_periph->CON1, AD16C4T_CON1_CNTEN_MSK); +} + +static rt_uint32_t es32f0_hwtimer_count_get(rt_hwtimer_t *timer) +{ + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + uint32_t hwtimer_count = 0; + + RT_ASSERT(hwtimer != RT_NULL); + + hwtimer_count = READ_REG(hwtimer->hwtimer_periph->COUNT); + + return hwtimer_count; +} + +static rt_err_t es32f0_hwtimer_control(rt_hwtimer_t *timer, + rt_uint32_t cmd, + void *args) +{ + rt_err_t ret = RT_EOK; + rt_uint32_t freq = 0; + struct es32f0_hwtimer_dev *hwtimer = (struct es32f0_hwtimer_dev *)timer->parent.user_data; + + RT_ASSERT(hwtimer != RT_NULL); + + switch (cmd) + { + case HWTIMER_CTRL_FREQ_SET: + freq = *(rt_uint32_t *)args; + if ((freq < hwtimer->parent.info->minfreq) || (freq > hwtimer->parent.info->maxfreq)) + { + ret = RT_EINVAL; + } + /* Set frequency */ + WRITE_REG(hwtimer->hwtimer_periph->PRES, (SystemCoreClock/freq - 1)); + break; + + case HWTIMER_CTRL_STOP: + CLEAR_BIT(hwtimer->hwtimer_periph->CON1, AD16C4T_CON1_CNTEN_MSK); + break; + + default: + ret = RT_EINVAL; + break; + } + + return ret; +} + +static struct rt_hwtimer_ops es32f0_hwtimer_ops = +{ + es32f0_hwtimer_init, + es32f0_hwtimer_start, + es32f0_hwtimer_stop, + es32f0_hwtimer_count_get, + es32f0_hwtimer_control +}; + +int rt_hw_hwtimer_init(void) +{ + rt_err_t ret = RT_EOK; + +#ifdef BSP_USING_HWTIMER1 + /*Open clock*/ + SET_BIT(RCU->APB1EN, RCU_APB1EN_BS16T1EN_MSK); + + hwtimer1.hwtimer_periph = BS16T1; + hwtimer1.IRQn = BS16T1_IRQn; + hwtimer1.parent.info = &es32f0_hwtimer_info; + hwtimer1.parent.ops = &es32f0_hwtimer_ops; + ret = rt_device_hwtimer_register(&hwtimer1.parent, "timer1", &hwtimer1); +#endif + + return ret; +} +INIT_BOARD_EXPORT(rt_hw_hwtimer_init); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_hwtimer.h b/bsp/essemi/es32f0271/drivers/drv_hwtimer.h new file mode 100644 index 0000000000..576671e735 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_hwtimer.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#ifndef DRV_HWTIMER_H__ +#define DRV_HWTIMER_H__ + +int rt_hw_hwtimer_init(void); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_i2c.c b/bsp/essemi/es32f0271/drivers/drv_i2c.c new file mode 100644 index 0000000000..5d863fc447 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_i2c.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include +#include +#include "board.h" +#include "drv_i2c.h" +#include "md_i2c.h" +#include "md_gpio.h" + +#ifdef RT_USING_I2C + +#define TIMEOUT 0xF +/* Define I2C hardware SCL timeout */ +#define I2C_TIMING_48MHZ_CLK100KHZ ((0xBU<<28)|(4<<20)|(2<<16)|(0xF<<8)|(0x13)) + +/** + * @brief: I2C receive. + * @param: i2cx, pointer to the I2Cx + * @param: addr, address + * @param: buf, send data buffer + * @param: len, the length of buf + * @param: timout, timeout + * @retval: rt_err_t + */ +static rt_err_t __i2c_master_recv(I2C_TypeDef *i2cx, rt_uint16_t addr, + rt_uint8_t *buf, rt_uint16_t len, rt_uint32_t timout) +{ + rt_uint32_t rt_timout; + + // + // Config I2C transfer mode + // + md_i2c_set_con2_add10(i2cx, MD_I2C_ADDRESSINGMODE_7BIT); + /* Config slaver address */ + md_i2c_set_con2_sadd(i2cx, addr); + /* Config data size */ + md_i2c_set_con2_nbytes(i2cx, len); + /* Reset TX FIFO */ + md_i2c_set_fcon_txfrst(i2cx, MD_I2C_TXFIFO_RESET); + /* Config mode */ + md_i2c_set_con2_rd_wrn(i2cx, MD_I2C_MASTER_READ); + /* Config auto-reload */ + md_i2c_set_con2_reload(i2cx, MD_I2C_NORELOAD_MODE); + /* When NBYTES is matched, the communication will be automatically stop */ + md_i2c_set_con2_autoend(i2cx, MD_I2C_AUTOEND_MODE); + /* Start the I2C communication */ + md_i2c_set_con2_start(i2cx, MD_I2C_START_GENERATION); + + while (len > 0) + { + /* Wait Rx FIFO non-empty */ + rt_timout = timout; + while (md_i2c_is_active_stat_rxe(i2cx) && (--rt_timout)); + if (rt_timout == 0) + return RT_ETIMEOUT; + + *buf++ = md_i2c_recv(i2cx); + len--; + } + + return RT_EOK; +} + +/** + * @brief: I2C send. + * @param: i2cx, pointer to the I2Cx + * @param: addr, address + * @param: buf, send data buffer + * @param: len, the length of buf + * @param: timout, timeout + * @retval: rt_err_t + */ +static rt_err_t __i2c_master_send(I2C_TypeDef *i2cx, rt_uint16_t addr, + rt_uint8_t *buf, rt_uint16_t len, rt_uint32_t timout) +{ + rt_uint32_t rt_timout; + rt_uint8_t index; + + // + // Config I2C transfer mode + // + md_i2c_set_con2_add10(i2cx, MD_I2C_ADDRESSINGMODE_7BIT); + /* Config slaver address */ + md_i2c_set_con2_sadd(i2cx, addr); + /* Config data size */ + md_i2c_set_con2_nbytes(i2cx, len); + /* Reset TX FIFO */ + md_i2c_set_fcon_txfrst(i2cx, MD_I2C_TXFIFO_RESET); + /* Config mode */ + md_i2c_set_con2_rd_wrn(i2cx, MD_I2C_MASTER_WRITE); + /* Enable auto-end */ + md_i2c_set_con2_autoend(i2cx, MD_I2C_AUTOEND_MODE); + + // + // Check if the bus is busy + // + /* Wait bus to be ready */ + rt_timout = timout; + while ((READ_BIT(i2cx->STAT, I2C_STAT_BUSY_MSK) == I2C_STAT_BUSY_MSK) && (--rt_timout)); + if (rt_timout == 0) + return RT_EBUSY; + + // + // Start to send + // + if (len <= 8) + { + for (index = 0; index < len; index++) + md_i2c_send(i2cx, *buf++); + + len = 0; + } + else + { + for (index = 0; index < 8; index++) + md_i2c_send(i2cx, *buf++); + + len -= 8; + } + + /* Start the I2C communication */ + md_i2c_set_con2_start(i2cx, MD_I2C_START_GENERATION); + + while (len > 0) + { + rt_timout = timout; + while (md_i2c_is_active_stat_txf(i2cx) && (--rt_timout)); + if (rt_timout == 0) + return RT_ETIMEOUT; + + md_i2c_send(i2cx, *buf++); + len--; + } + + return RT_EOK; +} + +static rt_size_t es32f0_master_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + struct rt_i2c_msg *msg; + rt_uint32_t i; + rt_err_t ret = RT_ERROR; + + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + if (msg->flags & RT_I2C_RD) + { + if (__i2c_master_recv(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0) + { + i2c_dbg("i2c bus write failed,i2c bus stop!\n"); + goto out; + } + } + else + { + if (__i2c_master_send(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0) + { + i2c_dbg("i2c bus write failed,i2c bus stop!\n"); + goto out; + } + } + } + + ret = i; + +out: + i2c_dbg("send stop condition\n"); + + return ret; +} + +const struct rt_i2c_bus_device_ops es32f0_i2c_ops = +{ + es32f0_master_xfer, + RT_NULL, + RT_NULL, +}; + +static void _i2c_init(void) +{ + md_i2c_inittypedef I2C_Init = + { + .Timing = CLK100kHz48M, + .Address1 = 0x55 << 1, + .AddrSize = MD_I2C_ADDRESSINGMODE_7BIT, + .DualAddressMode = MD_I2C_DUALADDRESS_DISABLE, + .Address2 = 0xAA, + .Address2Masks = MD_I2C_ADDR2_NOMASK + }; + +#ifdef BSP_USING_I2C1 + /* Open I2C clock */ + SET_BIT(RCU->APB1EN, RCU_APB1EN_I2C1EN_MSK); + + /* GPIO configuration */ + md_gpio_set_pull (GPIOC, MD_GPIO_PIN_12, MD_GPIO_PULL_UP); + md_gpio_set_pull (GPIOD, MD_GPIO_PIN_2, MD_GPIO_PULL_UP); + md_gpio_set_output_type (GPIOC, MD_GPIO_PIN_12, MD_GPIO_OUTPUT_OPENDRAIN); + md_gpio_set_output_type (GPIOD, MD_GPIO_PIN_2, MD_GPIO_OUTPUT_OPENDRAIN); + md_gpio_set_mode (GPIOC, MD_GPIO_PIN_12, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOD, MD_GPIO_PIN_2, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function8_15(GPIOC, MD_GPIO_PIN_12, MD_GPIO_AF1); + md_gpio_set_function0_7 (GPIOD, MD_GPIO_PIN_2, MD_GPIO_AF1); + + // + // Config I2C + // + md_i2c_init(I2C1, &I2C_Init); +#endif + +#ifdef BSP_USING_I2C2 + /* Open I2C clock */ + SET_BIT(RCU->APB1EN, RCU_APB1EN_I2C2EN_MSK); + + /* GPIO configuration */ + md_gpio_set_pull (GPIOB, MD_GPIO_PIN_10, MD_GPIO_PULL_UP); + md_gpio_set_pull (GPIOB, MD_GPIO_PIN_11, MD_GPIO_PULL_UP); + md_gpio_set_output_type (GPIOB, MD_GPIO_PIN_10, MD_GPIO_OUTPUT_OPENDRAIN); + md_gpio_set_output_type (GPIOB, MD_GPIO_PIN_11, MD_GPIO_OUTPUT_OPENDRAIN); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_10, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_11, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function8_15(GPIOB, MD_GPIO_PIN_10, MD_GPIO_AF1); + md_gpio_set_function8_15(GPIOB, MD_GPIO_PIN_11, MD_GPIO_AF1); + + // + // Config I2C + // + md_i2c_init(I2C2, &I2C_Init); +#endif +} + +#ifdef BSP_USING_I2C2 +static struct rt_i2c_bus_device i2c_device2; +#endif + +#ifdef BSP_USING_I2C1 +static struct rt_i2c_bus_device i2c_device1; +#endif +int rt_hw_i2c_init(void) +{ + _i2c_init(); + +#ifdef BSP_USING_I2C2 + /* define i2c Instance */ + rt_memset((void *)&i2c_device2, 0, sizeof(struct rt_i2c_bus_device)); + i2c_device2.ops = &es32f0_i2c_ops; + i2c_device2.priv = I2C2; + rt_i2c_bus_device_register(&i2c_device2, "i2c2"); +#endif + +#ifdef BSP_USING_I2C1 + /* define i2c Instance */ + rt_memset((void *)&i2c_device1, 0, sizeof(struct rt_i2c_bus_device)); + i2c_device1.ops = &es32f0_i2c_ops; + i2c_device1.priv = I2C1; + rt_i2c_bus_device_register(&i2c_device1, "i2c1"); +#endif + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_i2c_init); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_i2c.h b/bsp/essemi/es32f0271/drivers/drv_i2c.h new file mode 100644 index 0000000000..7af06805f7 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_i2c.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#ifndef DRV_I2C_H__ +#define DRV_I2C_H__ + +int rt_hw_i2c_init(void); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_pwm.c b/bsp/essemi/es32f0271/drivers/drv_pwm.c new file mode 100644 index 0000000000..768fcd04cd --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_pwm.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include +#include +#include +#include "md_gpio.h" + +/* PWM device control struct */ +struct pwm_dev_ctrl { + AD16C4T_TypeDef *timx; + rt_uint8_t chnm; /* Cannel number */ + struct rt_pwm_configuration *cfg; +}; + +#ifdef BSP_USING_PWM_GP16C2T1 + +/* Remember channel configuration */ +static struct rt_pwm_configuration pwm_ch_cfg_gp16c2t1[2] = { + [0] = { + .channel = 1, + .period = 0, + .pulse = 0 + }, + [1] = { + .channel = 2, + .period = 0, + .pulse = 0 + } +}; + +/* Define static device */ +static struct rt_device_pwm pwm_dev_gp16c2t1; +static struct pwm_dev_ctrl pwm_dev_gp16c2t1_ctrl; +#endif +#ifdef BSP_USING_PWM_GP16C2T4 + +/* Remember channel configuration */ +static struct rt_pwm_configuration pwm_ch_cfg_gp16c2t4[2] = { + [0] = { + .channel = 1, + .period = 0, + .pulse = 0 + }, + [1] = { + .channel = 2, + .period = 0, + .pulse = 0 + } +}; + +/* Define static device */ +static struct rt_device_pwm pwm_dev_gp16c2t4; +static struct pwm_dev_ctrl pwm_dev_gp16c2t4_ctrl; +#endif + +static void pwm_auto_config_freq(AD16C4T_TypeDef *timerx, uint32_t ns) +{ + uint32_t temp_ar; + uint32_t temp_pres = timerx->PRES & 0xFFFF; + uint32_t err_cnt = 0; + + /* Automatic setting frequency division ratio */ + while (err_cnt++ < 65536) + { + temp_ar = (uint64_t)SystemCoreClock * ns / 1000000000 / (temp_pres + 1); + if (temp_ar <= 0xFFFF) + break; + temp_pres++; + } + + /* Write back to PRES */ + timerx->PRES = (uint16_t)(temp_pres & 0xFFFF); + timerx->AR = temp_ar; +} + +static void pwm_set_duty(AD16C4T_TypeDef *timerx, uint8_t ch, uint32_t ns) +{ + uint32_t temp_pres = timerx->PRES & 0xFFFF; + uint64_t tmp = (uint64_t)SystemCoreClock * ns / 1000000000 / (temp_pres + 1); + + if (ch == 1) + WRITE_REG(timerx->CCVAL1, (uint32_t)tmp); + else if (ch == 2) + WRITE_REG(timerx->CCVAL2, (uint32_t)tmp); +} + +static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void *arg) +{ + rt_err_t ret = RT_EOK; + struct pwm_dev_ctrl *dev_ctrl + = (struct pwm_dev_ctrl *)device->parent.user_data; + struct rt_pwm_configuration *cfg = (struct rt_pwm_configuration *)arg; + AD16C4T_TypeDef *timerx = (AD16C4T_TypeDef *)dev_ctrl->timx; + + switch (cmd) + { + case PWM_CMD_ENABLE: + { + if (cfg->channel == 1) + SET_BIT(timerx->CCEP, AD16C4T_CCEP_CC1EN_MSK); + else if (cfg->channel == 2) + SET_BIT(timerx->CCEP, AD16C4T_CCEP_CC2EN_MSK); + break; + } + case PWM_CMD_DISABLE: + { + if (cfg->channel == 1) + CLEAR_BIT(timerx->CCEP, AD16C4T_CCEP_CC1EN_MSK); + else if (cfg->channel == 2) + CLEAR_BIT(timerx->CCEP, AD16C4T_CCEP_CC2EN_MSK); + break; + } + case PWM_CMD_SET: + { + /* count registers max 0xFFFF, auto adjust prescaler */ + pwm_auto_config_freq(timerx, cfg->period); + pwm_set_duty(timerx, cfg->channel, cfg->pulse); + /* Remember configuration */ + dev_ctrl->cfg[cfg->channel-1].period = cfg->period; + dev_ctrl->cfg[cfg->channel-1].pulse = cfg->pulse; + break; + } + case PWM_CMD_GET: + { + cfg->period = dev_ctrl->cfg[cfg->channel-1].period; + cfg->pulse = dev_ctrl->cfg[cfg->channel-1].pulse; + break; + } + + default: + break; + } + return ret; +} + +const static struct rt_pwm_ops es32f0_pwm_ops = +{ + es32f0_pwm_control +}; + +int rt_hw_pwm_init(void) +{ + rt_err_t ret = RT_EOK; + +#ifdef BSP_USING_PWM_GP16C2T1 /* 2 channels */ + /* Open clock */ + SET_BIT(RCU->APB2EN, RCU_APB2EN_GP16C2T1EN_MSK); + + /* GPIO configuration */ + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_1, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_2, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_1, MD_GPIO_AF5); + md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_2, MD_GPIO_AF5); + + /* Timer configuration */ + MODIFY_REG(GP16C2T1->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1MOD_MSK, + (6 << AD16C4T_CHMR1_OUTPUT_CH1MOD_POSS)); + MODIFY_REG(GP16C2T1->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2MOD_MSK, + (6 << AD16C4T_CHMR1_OUTPUT_CH2MOD_POSS)); + SET_BIT(GP16C2T1->BDCFG, AD16C4T_BDCFG_GOEN_MSK); + SET_BIT(GP16C2T1->CON1, AD16C4T_CON1_CNTEN_MSK); + + pwm_dev_gp16c2t1_ctrl.chnm = 2; + pwm_dev_gp16c2t1_ctrl.timx = GP16C2T1; + pwm_dev_gp16c2t1_ctrl.cfg = pwm_ch_cfg_gp16c2t1; + /* Register PWM device */ + ret = rt_device_pwm_register(&pwm_dev_gp16c2t1, + "pwm1", &es32f0_pwm_ops, &pwm_dev_gp16c2t1_ctrl); +#endif + +#ifdef BSP_USING_PWM_GP16C2T4 /* 2 channels */ + /* Open clock */ + SET_BIT(RCU->APB2EN, RCU_APB2EN_GP16C2T4EN_MSK); + + /* GPIO configuration */ + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_12, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_14, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function8_15(GPIOB, MD_GPIO_PIN_12, MD_GPIO_AF5); + md_gpio_set_function8_15(GPIOB, MD_GPIO_PIN_14, MD_GPIO_AF5); + + /* Timer configuration */ + MODIFY_REG(GP16C2T4->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1MOD_MSK, + (6 << AD16C4T_CHMR1_OUTPUT_CH1MOD_POSS)); + MODIFY_REG(GP16C2T4->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2MOD_MSK, + (6 << AD16C4T_CHMR1_OUTPUT_CH2MOD_POSS)); + SET_BIT(GP16C2T4->BDCFG, AD16C4T_BDCFG_GOEN_MSK); + SET_BIT(GP16C2T4->CON1, AD16C4T_CON1_CNTEN_MSK); + + pwm_dev_gp16c2t4_ctrl.chnm = 2; + pwm_dev_gp16c2t4_ctrl.timx = GP16C2T4; + pwm_dev_gp16c2t4_ctrl.cfg = pwm_ch_cfg_gp16c2t4; + /* Register PWM device */ + ret = rt_device_pwm_register(&pwm_dev_gp16c2t4, + "pwm2", &es32f0_pwm_ops, &pwm_dev_gp16c2t4_ctrl); +#endif + + return ret; +} +INIT_DEVICE_EXPORT(rt_hw_pwm_init); diff --git a/bsp/essemi/es32f0271/drivers/drv_pwm.h b/bsp/essemi/es32f0271/drivers/drv_pwm.h new file mode 100644 index 0000000000..12c0364563 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_pwm.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#ifndef DRV_PWM_H__ +#define DRV_PWM_H__ + +int rt_hw_pwm_init(void); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_rtc.c b/bsp/essemi/es32f0271/drivers/drv_rtc.c new file mode 100644 index 0000000000..23bab4dc16 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_rtc.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include +#include +#include +#include "board.h" +#include "drv_rtc.h" + +#ifdef RT_USING_RTC + +/** + * @brief Time structure + */ +typedef struct +{ + uint8_t hour; /**< Hours */ + uint8_t minute; /**< Minutes */ + uint8_t second; /**< Seconds */ + uint16_t sub_sec; /**< Sub-seconds */ +} rtc_time_t; + +/** + * @brief Date structure + */ +typedef struct +{ + uint8_t week; /**< Weeks */ + uint8_t day; /**< days */ + uint8_t month; /**< months */ + uint8_t year; /**< years */ +} rtc_date_t; + +static rt_uint32_t bcd_to_dec(rt_uint32_t bcd) +{ + return ((bcd & 0xF) + ((bcd >> 4) & 0xF) * 10); +} + +static void rtc_get_time(rtc_time_t *time) +{ + rt_uint32_t tmp = RTC->TIME; + + time->second = bcd_to_dec(tmp & 0x7F); + time->minute = bcd_to_dec((tmp >> 8) & 0x7F); + time->hour = bcd_to_dec((tmp >> 16) & 0x7F); + + return; +} + +static void rtc_get_date(rtc_date_t *date) +{ + uint32_t tmp = RTC->CAL; + + date->day = bcd_to_dec(tmp & 0x3F); + date->month = bcd_to_dec((tmp >> 8) & 0x1F); + date->year = bcd_to_dec((tmp >> 16) & 0xFF); + date->week = bcd_to_dec((RTC->TIME >> 24) & 0x7); + + return; +} + +static rt_err_t es32f0_rtc_control(rt_device_t dev, int cmd, void *args) +{ + rt_err_t result = RT_EOK; + + struct tm time_temp; + struct tm *pNow; + rt_uint16_t timout = 0xFFF; + rtc_time_t *time = rt_malloc(sizeof(rtc_time_t)); + rtc_date_t *date = rt_malloc(sizeof(rtc_date_t)); + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + { + /* Wait RTC data ready then read */ + while ((--timout)&&((RTC->STAT & RTC_STAT_SYNDONE_MSK) != RTC_STAT_SYNDONE_MSK)); + if (timout == 0) + result = RT_ERROR; + /* Read */ + rtc_get_time(time); + rtc_get_date(date); + + time_temp.tm_sec = time->second; + time_temp.tm_min = time->minute; + time_temp.tm_hour = time->hour; + time_temp.tm_wday = date->week - 1; + time_temp.tm_mday = date->day; + time_temp.tm_mon = date->month - 1; + time_temp.tm_year = date->year - 1900 + 2000; + *((time_t *)args) = mktime(&time_temp); + break; + } + case RT_DEVICE_CTRL_RTC_SET_TIME: + { + rt_enter_critical(); + /* converts calendar time time into local time. */ + pNow = localtime((const time_t *)args); + /* copy the statically located variable */ + memcpy(&time_temp, pNow, sizeof(struct tm)); + /* unlock scheduler. */ + rt_exit_critical(); + + time->hour = time_temp.tm_hour; + time->minute = time_temp.tm_min; + time->second = time_temp.tm_sec; + date->year = time_temp.tm_year + 1900 - 2000; + date->month = time_temp.tm_mon + 1; + date->day = time_temp.tm_mday; + /* Stop RTC */ + CLEAR_BIT(RTC->CON, RTC_CON_RTCEN_MSK); + WRITE_REG(RTC->TIME, ((time->hour/10)<hour%10)<minute/10)<minute%10)<second/10)<second%10)<CAL, ((date->year/10)<year%10)<month/10)<month%10)<day/10)<day%10)<CON, RTC_CON_RTCEN_MSK); + break; + } + case RT_DEVICE_CTRL_RTC_GET_ALARM: + break; + + case RT_DEVICE_CTRL_RTC_SET_ALARM: + break; + + default: + break; + } + + rt_free(time); + rt_free(date); + + return result; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops es32f0_rtc_ops = +{ + RT_NULL, + RT_NULL, + RT_NULL, + RT_NULL, + RT_NULL, + es32f0_rtc_control +}; +#endif + +static struct rt_device rtc_dev; +#define RTC_SOURCE_LOSC 0x1 +#define RTC_SOURCE_LRC 0x2 +int rt_hw_rtc_init(void) +{ + rt_err_t ret = RT_EOK; + rt_uint16_t timout = 0xFFFF; + rt_uint32_t rtc_clk = 32768-1; + rt_uint8_t rtc_src = RTC_SOURCE_LOSC; + + /* + * Config RTC clock + * We config the external 32.768K crystal as RTC clock source for the first + * choice. If external 32.768K crystal is not ready, we will choose LRC. + */ + /* Enable LOSC then wait it ready */ + if ((RCU->CON & RCU_CON_LOSCON_MSK) != RCU_CON_LOSCON_MSK) + SET_BIT(RCU->CON, RCU_CON_LOSCON_MSK); + + /* Wait external 32.768K crystal ready */ + while (((RCU->CON & RCU_CON_LOSCRDY_MSK) != RCU_CON_LOSCRDY_MSK)&&(--timout)); + if (timout == 0) + { + /* We use LRC if external 32.768K crystal is not ready */ + if ((RCU->CON & RCU_CON_LRCON_MSK) != RCU_CON_LRCON_MSK) + SET_BIT(RCU->CON, RCU_CON_LRCON_MSK); + /* Wait LRC ready */ + timout = 0xFF; + while (((RCU->CON & RCU_CON_LRCRDY_MSK) != RCU_CON_LRCRDY_MSK)&&(--timout)); + rtc_clk = 32000-1; + rtc_src = RTC_SOURCE_LRC; + } + + /* Open RTC clock */ + SET_BIT(RCU->AHBEN, RCU_AHBEN_RTCEN_MSK); + + /* Reset RTC */ + SET_BIT(RCU->AHBRST, RCU_AHBRST_RTCEN_MSK); + CLEAR_BIT(RCU->AHBRST, RCU_AHBRST_RTCEN_MSK); + CLEAR_BIT(RTC->CON, RTC_CON_RTCEN_MSK); + + /* Config RTC clock source */ + MODIFY_REG(RTC->CON, RTC_CON_CKSEL_MSK, rtc_src<CON, RTC_CON_PSCALE_MSK|RTC_CON_SCALE_MSK, + ((rtc_clk&0x7F)<>7)&0xFF)<TIME, (0x3<CAL, (0x1<CON, RTC_CON_RTCEN_MSK); + + rtc_dev.type = RT_Device_Class_RTC; + rtc_dev.rx_indicate = RT_NULL; + rtc_dev.tx_complete = RT_NULL; + +#ifdef RT_USING_DEVICE_OPS + rtc_dev.ops = &es32f0_rtc_ops; +#else + rtc_dev.init = RT_NULL; + rtc_dev.open = RT_NULL; + rtc_dev.close = RT_NULL; + rtc_dev.read = RT_NULL; + rtc_dev.write = RT_NULL; + rtc_dev.control = es32f0_rtc_control; +#endif + + rtc_dev.user_data = RTC; + + ret = rt_device_register(&rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR); + + return ret; +} +INIT_DEVICE_EXPORT(rt_hw_rtc_init); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_rtc.h b/bsp/essemi/es32f0271/drivers/drv_rtc.h new file mode 100644 index 0000000000..0fd0661026 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_rtc.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#ifndef DRV_RTC_H__ +#define DRV_RTC_H__ + +int rt_hw_rtc_init(void); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_spi.c b/bsp/essemi/es32f0271/drivers/drv_spi.c new file mode 100644 index 0000000000..9a7fc3ab70 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_spi.c @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include +#include +#include +#include "board.h" +#include "drv_spi.h" +#include "md_spi.h" +#include "md_gpio.h" + +#ifdef RT_USING_SPI + +#define SPITIMEOUT 0x0FFF + +static rt_err_t __spi_send(struct rt_spi_device *device, rt_uint8_t *buf, + rt_int32_t len, rt_uint32_t tmout); +static rt_err_t __spi_recv(struct rt_spi_device *device, rt_uint8_t *buf, + rt_int32_t len, rt_uint32_t tmout); +static rt_err_t __spi_send_recv(struct rt_spi_device *device, rt_uint8_t *tbuf, + rt_uint8_t *rbuf, rt_int32_t len, rt_uint32_t tmout); + +/** + * @brief: SPI single line send. + * @param: device, pointer to the SPI device + * @param: buf, send data buffer + * @param: len, the length of buf + * @param: tmout, timeout + * @retval: rt_err_t + */ +static rt_err_t __spi_send(struct rt_spi_device *device, rt_uint8_t *buf, + rt_int32_t len, rt_uint32_t tmout) +{ + SPI_TypeDef *hspi; + rt_uint32_t rt_timout; + rt_uint8_t temp_data; + + /* Get the SPI port */ + hspi = (SPI_TypeDef *)device->bus->parent.user_data; + + /* Open SPI if it is disabled */ + if (READ_BIT(hspi->CON1, SPI_CON1_SPIEN_MSK) != SPI_CON1_SPIEN_MSK) + SET_BIT(hspi->CON1, SPI_CON1_SPIEN_MSK); + + while (len > 0) + { + /* Confirm that no data is being transmitted */ + rt_timout = tmout; + while (((hspi->STAT & SPI_STAT_TXE_MSK) == 0) && (--rt_timout)); + if (rt_timout == 0) + return RT_ETIMEOUT; + + /* Send data */ + if (device->config.data_width == 8) + { + hspi->DATA = *(rt_uint8_t *)buf; + buf++; + len--; + } + else if (device->config.data_width == 16) + { + hspi->DATA = *(rt_uint16_t *)buf; + buf += 2; + len -= 2; + } + else + return RT_EINVAL; + } + + /* At here, we have transmitted all the data. + * The next step is to clear the IT flag. + */ + for (rt_uint8_t i = 0; i < md_spi_get_stat_rxflv(hspi); i++) + temp_data = hspi->DATA; + UNUSED(temp_data); + hspi->ICR = hspi->RIF; + + return RT_EOK; +} + +/** + * @brief: SPI single line receive. + * @param: device, pointer to the SPI device + * @param: buf, receive data buffer + * @param: len, the length of buf + * @param: tmout, timeout + * @retval: rt_err_t + */ +static rt_err_t __spi_recv(struct rt_spi_device *device, rt_uint8_t *buf, + rt_int32_t len, rt_uint32_t tmout) +{ + SPI_TypeDef *hspi; + rt_uint32_t rt_timout; + + /* Get the SPI port */ + hspi = (SPI_TypeDef *)device->bus->parent.user_data; + + /* Open SPI if it is disabled */ + if (READ_BIT(hspi->CON1, SPI_CON1_SPIEN_MSK) != SPI_CON1_SPIEN_MSK) + SET_BIT(hspi->CON1, SPI_CON1_SPIEN_MSK); + + /* Handle data in __spi_send_recv() function */ + if (((device->config.mode & RT_SPI_SLAVE) == 0) + && ((device->config.mode & RT_SPI_3WIRE) == 0)) + __spi_send_recv(device, buf, buf, len, tmout); + + while (len > 0) + { + /* Waiting for data */ + rt_timout = tmout; + while (((hspi->STAT & SPI_STAT_RXTH_MSK) == 0) && (--rt_timout)); + if (rt_timout == 0) + return RT_ETIMEOUT; + + /* Send data */ + if (device->config.data_width == 8) + { + *(rt_uint8_t *)buf = hspi->DATA; + buf++; + len--; + } + else if (device->config.data_width == 16) + { + *(rt_uint16_t *)buf = hspi->DATA; + buf += 2; + len -= 2; + } + else + return RT_EINVAL; + } + + /* At here, we have transmitted all the data. + * The next step is to clear the IT flag. + */ + hspi->ICR = hspi->RIF; + + return RT_EOK; +} + +/** + * @brief: SPI two line transmission. + * @param: device, pointer to the SPI device + * @param: tbuf, send data buffer + * @param: rbuf, receive data buffer + * @param: len, the length of buf + * @param: tmout, timeout + * @retval: rt_err_t + */ +static rt_err_t __spi_send_recv(struct rt_spi_device *device, rt_uint8_t *tbuf, + rt_uint8_t *rbuf, rt_int32_t len, rt_uint32_t tmout) +{ + SPI_TypeDef *hspi; + rt_uint32_t rt_timout; + + /* Get the SPI port */ + hspi = (SPI_TypeDef *)device->bus->parent.user_data; + + /* Open SPI if it is disabled */ + if (READ_BIT(hspi->CON1, SPI_CON1_SPIEN_MSK) != SPI_CON1_SPIEN_MSK) + SET_BIT(hspi->CON1, SPI_CON1_SPIEN_MSK); + + /* return error if SPI is in 1-line mode */ + if ((device->config.mode & RT_SPI_3WIRE) == RT_SPI_3WIRE) + return RT_ERROR; + + while (len > 0) + { + /* Confirm that no data is being transmitted */ + rt_timout = tmout; + while (((hspi->STAT & SPI_STAT_TXE_MSK) == 0) && (--rt_timout)); + if (rt_timout == 0) + return RT_ETIMEOUT; + + /* Send data */ + if (device->config.data_width == 8) + { + hspi->DATA = *(rt_uint8_t *)tbuf; + tbuf++; + len--; + } + else if (device->config.data_width == 16) + { + hspi->DATA = *(rt_uint16_t *)tbuf; + tbuf += 2; + len -= 2; + } + else + return RT_EINVAL; + + /* Waiting for data */ + rt_timout = tmout; + while (((hspi->STAT & SPI_STAT_RXTH_MSK) == 0) && (--rt_timout)); + if (rt_timout == 0) + return RT_ETIMEOUT; + + /* Send data */ + if (device->config.data_width == 8) + { + *(rt_uint8_t *)rbuf = hspi->DATA; + rbuf++; + } + else if (device->config.data_width == 16) + { + *(rt_uint16_t *)rbuf = hspi->DATA; + rbuf += 2; + } + } + + /* At here, we have transmitted all the data. + * The next step is to clear the IT flag. + */ + hspi->ICR = hspi->RIF; + + return RT_EOK; +} + +rt_err_t spi_configure(struct rt_spi_device *device, + struct rt_spi_configuration *cfg) +{ + SPI_TypeDef *hspi; + hspi = (SPI_TypeDef *)device->bus->parent.user_data; + + /* Close SPI temporarily */ + md_spi_disable_con1_spien(hspi); + + /* config spi mode */ + if (cfg->mode & RT_SPI_SLAVE) + md_spi_set_con1_mstren(hspi, MD_SPI_MODE_SLAVE); + else + md_spi_set_con1_mstren(hspi, MD_SPI_MODE_MASTER); + + /* Config data mode */ + if (cfg->mode & RT_SPI_3WIRE) + md_spi_set_con1_bidimode(hspi, MD_SPI_HALF_DUPLEX); + else + md_spi_set_con1_bidimode(hspi, MD_SPI_FULL_DUPLEX); + + /* Config data width */ + if (cfg->data_width == 8) + md_spi_set_con1_flen(hspi, MD_SPI_FRAME_FORMAT_8BIT); + else if (cfg->data_width == 16) + md_spi_set_con1_flen(hspi, SPI_CON1_FLEN_MSK); + + /* Config phase */ + if (cfg->mode & RT_SPI_CPHA) + md_spi_set_con1_cpha(hspi, MD_SPI_PHASE_2EDGE); + else + md_spi_set_con1_cpha(hspi, MD_SPI_PHASE_1EDGE); + + /* Config polarity */ + if (cfg->mode & RT_SPI_CPOL) + md_spi_set_con1_cpol(hspi, MD_SPI_POLARITY_HIGH); + else + md_spi_set_con1_cpol(hspi, MD_SPI_POLARITY_LOW); + + /* Config if NSS pin is managed by software */ + md_spi_disable_con1_ssen(hspi); + + /* config spi clock */ + if (cfg->max_hz >= SystemCoreClock / 2) + { + /* pclk1 max speed 48MHz, spi master max speed 10MHz */ + if (SystemCoreClock / 2 <= 10000000) + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV2); + else if (SystemCoreClock / 4 <= 10000000) + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV4); + else + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV8); + } + else if (cfg->max_hz >= SystemCoreClock / 4) + { + /* pclk1 max speed 48MHz, spi master max speed 10MHz */ + if (SystemCoreClock / 4 <= 10000000) + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV4); + else + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV8); + } + else if (cfg->max_hz >= SystemCoreClock / 8) + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV8); + else if (cfg->max_hz >= SystemCoreClock / 16) + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV16); + else if (cfg->max_hz >= SystemCoreClock / 32) + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV32); + else if (cfg->max_hz >= SystemCoreClock / 64) + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV64); + else if (cfg->max_hz >= SystemCoreClock / 128) + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV128); + else + md_spi_set_con1_baud(hspi, MD_SPI_BAUDRATEPRESCALER_DIV256); + + /* Enable SPI */ + md_spi_enable_con1_spien(hspi); + + return RT_EOK; +} + +static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + rt_err_t res; + rt_uint32_t *cs; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->bus != RT_NULL); + RT_ASSERT(device->bus->parent.user_data != RT_NULL); + RT_ASSERT(message->send_buf != RT_NULL || message->recv_buf != RT_NULL); + + cs = (rt_uint32_t *)device->parent.user_data; + + /* only send data */ + if (message->recv_buf == RT_NULL) + { + if (message->cs_take) + { + rt_pin_write(*cs, 0); + } + res = __spi_send(device, (rt_uint8_t *)message->send_buf, (rt_int32_t)message->length, SPITIMEOUT); + if (message->cs_release) + { + rt_pin_write(*cs, 1); + } + if (res != RT_EOK) + return RT_ERROR; + } + + /* only receive data */ + if (message->send_buf == RT_NULL) + { + if (message->cs_take) + { + rt_pin_write(*cs, 0); + } + res = __spi_recv(device, (rt_uint8_t *)message->recv_buf, (rt_int32_t)message->length, SPITIMEOUT); + if (message->cs_release) + { + rt_pin_write(*cs, 1); + } + if (res != RT_EOK) + return RT_ERROR; + } + + /* send & receive */ + else + { + if (message->cs_take) + { + rt_pin_write(*cs, 0); + } + res = __spi_send_recv(device, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, + (rt_int32_t)message->length, SPITIMEOUT); + if (message->cs_release) + { + rt_pin_write(*cs, 1); + } + if (res != RT_EOK) + return RT_ERROR; + } + + return message->length; +} + +const struct rt_spi_ops es32f0_spi_ops = +{ + spi_configure, + spixfer, +}; + +static struct rt_spi_bus _spi_bus1, _spi_bus2; +int es32f0_spi_register_bus(SPI_TypeDef *SPIx, const char *name) +{ + struct rt_spi_bus *spi_bus; + + if (SPIx == SPI2) + { + /* Open GPIO and SPI clock */ + SET_BIT(RCU->APB1EN, RCU_APB1EN_SPI2EN_MSK); + SET_BIT(RCU->AHBEN, RCU_AHBEN_GPBEN_MSK); + + /* Config SPI2 GPIO */ + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_13, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_14, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_15, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function8_15 (GPIOB, MD_GPIO_PIN_13, MD_GPIO_AF0); + md_gpio_set_function8_15 (GPIOB, MD_GPIO_PIN_14, MD_GPIO_AF0); + md_gpio_set_function8_15 (GPIOB, MD_GPIO_PIN_15, MD_GPIO_AF0); + + /* Remember SPI bus2 */ + spi_bus = &_spi_bus2; + } + else if (SPIx == SPI1) + { + /* Open GPIO and SPI clock */ + SET_BIT(RCU->APB2EN, RCU_APB2EN_SPI1EN_MSK); + SET_BIT(RCU->AHBEN, RCU_AHBEN_GPBEN_MSK); + + /* Config SPI1 GPIO */ + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_3, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_4, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_5, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_3, MD_GPIO_AF0); + md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_4, MD_GPIO_AF0); + md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_5, MD_GPIO_AF0); + + /* Remember SPI bus1 */ + spi_bus = &_spi_bus1; + } + else + { + return -1; + } + spi_bus->parent.user_data = SPIx; + + return rt_spi_bus_register(spi_bus, name, &es32f0_spi_ops); +} + +int rt_hw_spi_init(void) +{ + int result = 0; + +#ifdef BSP_USING_SPI2 + result = es32f0_spi_register_bus(SPI2, "spi2"); +#endif + +#ifdef BSP_USING_SPI1 + result = es32f0_spi_register_bus(SPI1, "spi1"); +#endif + + return result; +} +INIT_BOARD_EXPORT(rt_hw_spi_init); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_spi.h b/bsp/essemi/es32f0271/drivers/drv_spi.h new file mode 100644 index 0000000000..c7c8a13b4a --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_spi.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#ifndef DRV_SPI_H__ +#define DRV_SPI_H__ + +#include +#include +#include + +///* cannot be used before completion init */ +//rt_err_t es32f0_spi_device_attach(rt_uint32_t pin, const char *bus_name, const char *device_name); +int rt_hw_spi_init(void); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_uart.c b/bsp/essemi/es32f0271/drivers/drv_uart.c new file mode 100644 index 0000000000..f860c2df91 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_uart.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include +#include +#include "board.h" +#include "drv_uart.h" +#include "md_gpio.h" +#include "md_uart.h" + +#ifdef RT_USING_SERIAL + +/* es32 uart driver */ +struct es32_uart +{ + UART_TypeDef *huart; + IRQn_Type irq; +}; + +static rt_err_t es32f0x_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct es32_uart *uart; + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + uart = (struct es32_uart *)serial->parent.user_data; + + /* Close TX/RX temporarily */ + md_uart_disable_lcon_txen(uart->huart); + md_uart_disable_lcon_rxen(uart->huart); + +#ifdef BSP_USING_UART1 + /* Open UART1 clock */ + SET_BIT(RCU->APB2EN, RCU_APB2EN_UART1EN_MSK); + + /* Config UART1 GPIO pin */ + md_gpio_set_pull (GPIOB, MD_GPIO_PIN_7, MD_GPIO_PULL_UP); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_6, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOB, MD_GPIO_PIN_7, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_6, MD_GPIO_AF2); + md_gpio_set_function0_7 (GPIOB, MD_GPIO_PIN_7, MD_GPIO_AF2); +#endif /* uart2 gpio init */ + +#ifdef BSP_USING_UART2 + /* Open UART2 clock */ + SET_BIT(RCU->APB1EN, RCU_APB1EN_UART2EN_MSK); + + /* Config UART2 GPIO pin */ + md_gpio_set_pull (GPIOA, MD_GPIO_PIN_3, MD_GPIO_PULL_UP); + md_gpio_set_mode (GPIOA, MD_GPIO_PIN_2, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOA, MD_GPIO_PIN_3, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function0_7 (GPIOA, MD_GPIO_PIN_2, MD_GPIO_AF2); + md_gpio_set_function0_7 (GPIOA, MD_GPIO_PIN_3, MD_GPIO_AF2); +#endif /* uart1 gpio init */ + +#ifdef BSP_USING_UART3 + /* Open UART3 clock */ + SET_BIT(RCU->APB1EN, RCU_APB1EN_UART3EN_MSK); + + /* Config UART3 GPIO pin */ + md_gpio_set_pull (GPIOC, MD_GPIO_PIN_7, MD_GPIO_PULL_UP); + md_gpio_set_mode (GPIOC, MD_GPIO_PIN_6, MD_GPIO_MODE_FUNCTION); + md_gpio_set_mode (GPIOC, MD_GPIO_PIN_7, MD_GPIO_MODE_FUNCTION); + md_gpio_set_function0_7 (GPIOC, MD_GPIO_PIN_6, MD_GPIO_AF2); + md_gpio_set_function0_7 (GPIOC, MD_GPIO_PIN_7, MD_GPIO_AF2); +#endif /* uart3 gpio init */ + + if (cfg->bit_order == BIT_ORDER_MSB) + { + md_uart_set_lcon_msb(uart->huart, MD_UART_LCON_MSB_FIRST); + } + else + { + md_uart_set_lcon_msb(uart->huart, MD_UART_LCON_LSB_FIRST); + } + + if (cfg->invert == NRZ_INVERTED) + { + md_uart_enable_lcon_datainv(uart->huart); + } + else + { + md_uart_disable_lcon_datainv(uart->huart); + } + + /* Config buadrate */ + md_uart_set_brr(uart->huart, SystemCoreClock/cfg->baud_rate); + /* Config data width */ + md_uart_set_lcon_dls(uart->huart, 8-cfg->data_bits); + /* Config stop bits */ + md_uart_set_lcon_stop(uart->huart, cfg->stop_bits); + /* Config parity */ + if (cfg->parity > PARITY_NONE) + { + md_uart_set_lcon_ps(uart->huart, cfg->parity-1); + md_uart_enable_lcon_pe(uart->huart); + } + else + md_uart_disable_lcon_pe(uart->huart); + + /* enable rx int */ + md_uart_set_fcon_rxth(uart->huart, MD_UART_FCON_RXTH_1); + md_uart_enable_ier_rfth(uart->huart); + md_uart_enable_lcon_txen(uart->huart); + md_uart_enable_lcon_rxen(uart->huart); + + return RT_EOK; +} + +static rt_err_t es32f0x_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct es32_uart *uart; + RT_ASSERT(serial != RT_NULL); + + uart = (struct es32_uart *)serial->parent.user_data; + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + NVIC_DisableIRQ(uart->irq); + /* disable interrupt */ + md_uart_disable_idr_rfth(uart->huart); + break; + + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + NVIC_EnableIRQ(uart->irq); + /* enable interrupt */ + md_uart_enable_ier_rfth(uart->huart); + break; + } + + return RT_EOK; +} + +static int es32f0x_putc(struct rt_serial_device *serial, char c) +{ + struct es32_uart *uart; + RT_ASSERT(serial != RT_NULL); + uart = (struct es32_uart *)serial->parent.user_data; + + while (uart->huart->STAT & UART_STAT_TSBUSY_MSK); + WRITE_REG(uart->huart->TXBUF, c); + + return 1; +} + +static int es32f0x_getc(struct rt_serial_device *serial) +{ + int ch = -1; + struct es32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct es32_uart *)serial->parent.user_data; + + if (uart->huart->STAT & UART_STAT_RFTH_MSK) + { + ch = (uint8_t)(uart->huart->RXBUF & 0xFF); + } + + return ch; +} + +static const struct rt_uart_ops es32f0x_uart_ops = +{ + es32f0x_configure, + es32f0x_control, + es32f0x_putc, + es32f0x_getc, +}; + +#ifdef BSP_USING_UART1 +/* UART1 device driver structure */ +struct es32_uart uart1 = +{ + UART1, + UART1_IRQn +}; + +struct rt_serial_device serial1; + +void UART1_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + if (md_uart_is_active_flag_rif_rfth(UART1) == 1) + { + rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND); + md_uart_clear_flag_rfth(UART1); + } + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* BSP_USING_UART1 */ + +#ifdef BSP_USING_UART2 +/* UART2 device driver structure */ +struct es32_uart uart2 = +{ + UART2, + UART2_IRQn +}; + +struct rt_serial_device serial2; + +void UART2_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + if (md_uart_is_active_flag_rif_rfth(UART2) == 1) + { + rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND); + md_uart_clear_flag_rfth(UART2); + } + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* BSP_USING_UART2 */ + +#ifdef BSP_USING_UART3 +/* UART3 device driver structure */ +struct es32_uart uart3 = +{ + UART3, + UART3_IRQn +}; + +struct rt_serial_device serial3; + +void UART3_AES_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + if (md_uart_is_active_flag_rif_rfth(UART3) == 1) + { + rt_hw_serial_isr(&serial3, RT_SERIAL_EVENT_RX_IND); + md_uart_clear_flag_rfth(UART3); + } + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* BSP_USING_UART3 */ + +int rt_hw_uart_init(void) +{ + struct es32_uart *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + +#ifdef BSP_USING_UART1 + uart = &uart1; + serial1.ops = &es32f0x_uart_ops; + serial1.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&serial1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); +#endif /* BSP_USING_UART1 */ + +#ifdef BSP_USING_UART2 + uart = &uart2; + serial2.ops = &es32f0x_uart_ops; + serial2.config = config; + + /* register UART2 device */ + rt_hw_serial_register(&serial2, "uart2", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); +#endif /* BSP_USING_UART2 */ + +#ifdef BSP_USING_UART3 + uart = &uart3; + serial3.ops = &es32f0x_uart_ops; + serial3.config = config; + + /* register UART3 device */ + rt_hw_serial_register(&serial3, "uart3", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); +#endif /* BSP_USING_UART3 */ + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_uart_init); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/drv_uart.h b/bsp/essemi/es32f0271/drivers/drv_uart.h new file mode 100644 index 0000000000..7d3755d0a6 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_uart.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#ifndef DRV_UART_H__ +#define DRV_UART_H__ + +int rt_hw_uart_init(void); + +#endif diff --git a/bsp/essemi/es32f0271/drivers/linker_scripts/link.sct b/bsp/essemi/es32f0271/drivers/linker_scripts/link.sct new file mode 100644 index 0000000000..4ee8d1e3fc --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/linker_scripts/link.sct @@ -0,0 +1,14 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x00000000 0x10000 { ; load region size_region + ER_IROM1 0x00000000 0x10000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x20000000 0x2000{ ; RW data + .ANY (+RW +ZI) + } +} diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf b/bsp/essemi/es32f0271/libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b374366930b2d1b5689ff5044caba49eace6aa68 GIT binary patch literal 172641 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 z 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 +#include +#include "system_es32f027x.h" +/** + * @brief these files declare Peripheral register bit_definition. + */ +#include "reg_rcu.h" +#include "reg_syscfg.h" +#include "reg_fc.h" +#include "reg_dma.h" +#include "reg_gpio.h" +#include "reg_i2c.h" +#include "reg_uart.h" +#include "reg_adc.h" +#include "reg_cmp.h" +#include "reg_dac.h" +#include "reg_spi.h" +#include "reg_crc.h" +#include "reg_ad16c4t.h" +#include "reg_hdiv.h" +#include "reg_aes.h" +#include "reg_wwdt.h" +#include "reg_rtc.h" +#include "reg_mswd.h" +#include "reg_mcm.h" +#include "reg_exti.h" +#include "reg_usb.h" + +/******************************************************************************/ +/* Peripheral register */ +/******************************************************************************/ + +/* allow anonymous structures and anonymous enumeration */ +/* #pragma anon_unions */ + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ + +/********************* Base addresses *************************/ +#define FLASH_BASE (0x08000000UL) +#define FLASH_INFO_BASE (0x1FFFE000UL) /* EFLASH Info ( 6K Bytes) - Boot Loader Memory */ +#define SRAM_BASE (0x20000000UL) +#define APB1_BASE (0x40000000UL) +#define APB2_BASE (0x40010000UL) +#define AHB1_BASE (0x40020000UL) +#define AHB2_BASE (0x48000000UL) +#define CM0IN_BASE (0xE0000000UL) + +/* Cortex簧-M0 internal Peripherals - CM0IN_BASE: 0xE0000000*/ +#define TICK_BASE (CM0IN_BASE + 0xE010) + +#define SRAM1_BASE (SRAM_BASE + 0x0000) // SRAM1 Memory ( 4K Bytes) +#define SRAM2_BASE (SRAM_BASE + 0x1000) // SRAM2 Memory ( 4K Bytes) for Rev.B +#define STACK_SIZE 0x00000400>>2 // Stack size (in Words) +#define SRAMTOP 0x1000//0x2000 // Jackey 2018.9.5 + +/***************** peripherals base addresses ********************/ +/* APB1 */ +#define GP32C4T1_BASE (APB1_BASE + 0x0000) +#define GP16C4T1_BASE (APB1_BASE + 0x0400) +#define GP16C4T2_BASE (APB1_BASE + 0x0800) +#define GP16C4T3_BASE (APB1_BASE + 0x0C00) +#define BS16T1_BASE (APB1_BASE + 0x1000) +#define WWDT_BASE (APB1_BASE + 0x2C00) +#define IWDT_BASE (APB1_BASE + 0x3000) +#define SPI2_BASE (APB1_BASE + 0x3800) +#define UART2_BASE (APB1_BASE + 0x4400) +#define UART3_BASE (APB1_BASE + 0x4800) +#define SUART1_BASE (APB1_BASE + 0x4C00) +#define SUART2_BASE (APB1_BASE + 0x5000) +#define I2C1_BASE (APB1_BASE + 0x5400) +#define I2C2_BASE (APB1_BASE + 0x5800) +#define DAC_BASE (APB1_BASE + 0x5C00) +#define PWR_BASE (APB1_BASE + 0x7000) +/* APB2 */ +#define EXTI_BASE (APB2_BASE + 0x0400) +#define ADC_BASE (APB2_BASE + 0x2400) +#define AD16C4T1_BASE (APB2_BASE + 0x2C00) +#define SPI1_BASE (APB2_BASE + 0x3000) +#define UART1_BASE (APB2_BASE + 0x3800) +#define GP16C2T1_BASE (APB2_BASE + 0x4000) +#define GP16C2T2_BASE (APB2_BASE + 0x4400) +#define GP16C2T3_BASE (APB2_BASE + 0x4800) +#define GP16C2T4_BASE (APB2_BASE + 0x4C00) +#define MCM_BASE (APB2_BASE + 0x5400) +#define DBGMCU_BASE (APB2_BASE + 0x5800) +#define COMP_BASE (APB2_BASE + 0x5C00) +/* AHB1 */ +#define DMA1_BASE (AHB1_BASE + 0x0000) +#define RCU_BASE (AHB1_BASE + 0x1000) +#define SYSCFG_BASE (AHB1_BASE + 0x1400) +#define RTC_BASE (AHB1_BASE + 0x1800) +#define EFLASH_BASE (AHB1_BASE + 0x2000) +#define MSWD_BASE (AHB1_BASE + 0x2C00) +#define CRC_BASE (AHB1_BASE + 0x3000) +#define AES_BASE (AHB1_BASE + 0x3400) +#define USB_BASE (AHB1_BASE + 0x3800) +#define HDIV_BASE (AHB1_BASE + 0x3C00) +/* AHB2 */ +#define GPIOA_BASE (AHB2_BASE + 0x0000) +#define GPIOB_BASE (AHB2_BASE + 0x0400) +#define GPIOC_BASE (AHB2_BASE + 0x0800) +#define GPIOD_BASE (AHB2_BASE + 0x0C00) +#define GPIOE_BASE (AHB2_BASE + 0x1000) +#define GPIOF_BASE (AHB2_BASE + 0x1400) + +/********************* Peripheral declaration *************************/ +#define TICK (( TICK_TypeDef *) TICK_BASE) +#define GPIOA (( GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB (( GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC (( GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD (( GPIO_TypeDef *) GPIOD_BASE) +#define DMA1 (( DMA_TypeDef *) DMA1_BASE) +#define RCU (( RCU_TypeDef *) RCU_BASE) +#define SYSCFG (( SYSCFG_TypeDef *) SYSCFG_BASE) +#define FC (( FC_TypeDef *) EFLASH_BASE) +#define CRC (( CRC_TypeDef *) CRC_BASE) +#define AES (( AES_TypeDef *) AES_BASE) +#define HDIV (( HDIV_TypeDef *) HDIV_BASE) +#define MSWD (( MSWD_TypeDef *) MSWD_BASE) +#define USB (( USBCTRL_TypeDef *) USB_BASE) +#define USBH (( USBCTRL_TypeDef *) USB_BASE) +#define USBD (( USBCTRL_TypeDef *) USB_BASE) +#define IWDT (( IWDT_TypeDef *) IWDT_BASE) +#define WWDT (( WWDT_TypeDef *) WWDT_BASE) +#define ADC (( ADC_TypeDef *) ADC_BASE) +#define AD16C4T1 (( AD16C4T_TypeDef *) AD16C4T1_BASE) +#define GP32C4T1 (( AD16C4T_TypeDef *) GP32C4T1_BASE) +#define GP16C4T1 (( AD16C4T_TypeDef *) GP16C4T1_BASE) +#define GP16C4T2 (( AD16C4T_TypeDef *) GP16C4T2_BASE) +#define GP16C4T3 (( AD16C4T_TypeDef *) GP16C4T3_BASE) +#define GP16C2T1 (( AD16C4T_TypeDef *) GP16C2T1_BASE) +#define GP16C2T2 (( AD16C4T_TypeDef *) GP16C2T2_BASE) +#define GP16C2T3 (( AD16C4T_TypeDef *) GP16C2T3_BASE) +#define GP16C2T4 (( AD16C4T_TypeDef *) GP16C2T4_BASE) +#define BS16T1 (( AD16C4T_TypeDef *) BS16T1_BASE) +#define SPI1 (( SPI_TypeDef *) SPI1_BASE) +#define SPI2 (( SPI_TypeDef *) SPI2_BASE) +#define I2C1 (( I2C_TypeDef *) I2C1_BASE) +#define I2C2 (( I2C_TypeDef *) I2C2_BASE) +#define DAC (( DAC_TypeDef *) DAC_BASE) +#define CMP (( CMP_TypeDef *) COMP_BASE) +#define UART1 (( UART_TypeDef *) UART1_BASE) +#define UART2 (( UART_TypeDef *) UART2_BASE) +#define UART3 (( UART_TypeDef *) UART3_BASE) +#define SUART1 (( UART_TypeDef *) SUART1_BASE) +#define SUART2 (( UART_TypeDef *) SUART2_BASE) +#define EXTI (( EXTI_TypeDef *) EXTI_BASE) +#define RTC (( RTC_TypeDef *) RTC_BASE) +#define MCM (( MCM_TypeDef *) MCM_BASE) +/* Special stuff */ +#define MSG_INCR ( __IO uint8_t *) (DBGMCU_BASE + 0x50) +#define MSG_WR ( __IO uint32_t *) (DBGMCU_BASE + 0x54) +#define MSG_END ( __IO uint32_t *) (DBGMCU_BASE + 0x58) +#define MSG_INCR_S ( __IO uint32_t *) (DBGMCU_BASE + 0x5C) +#define MSG_INCR_X ( __IO uint32_t *) (DBGMCU_BASE + 0x60) +#define MSG_INCR_B ( __IO uint32_t *) (DBGMCU_BASE + 0x64) +#define MSG_PTR ( __IO uint8_t **) (DBGMCU_BASE + 0x68) +#define MSG_INCR_D ( __IO uint32_t *) (DBGMCU_BASE + 0x78) +#define INCR_ERR_CNT ( __IO uint32_t *) (DBGMCU_BASE + 0x6C) + +#define END_SIM *MSG_END +#define SIM_FAIL 0xFFFFAAAA +#define SIM_PASS 0xFFFF5555 +/******************************************************************************/ +/* macros */ +/******************************************************************************/ + +/** @addtogroup Public_macros + * @{ + */ +#if defined (__CC_ARM) +#define __INLINE__ __inline +#else +#define __INLINE__ inline +#endif + +#define __isr__ + +#define UNUSED(x) ((void)(x)) + +#ifdef USE_ASSERT +#define assert_param(x) \ +do \ +{ \ + if (!(x)) \ + { \ + __disable_irq(); \ + while (1) \ + ; \ + } \ +} while (0) +#else +#define assert_param(x) +#endif + +#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x))) + +#define BITS(start, end) ((0xFFFFFFFFUL << (start)) &\ + (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) + +#define SET_BIT(REG, SETMASK) ((REG) |= (SETMASK)) + +#define CLEAR_BIT(REG, SETMASK) ((REG) &= ~(SETMASK)) + +#define READ_BIT(REG, SETMASK) ((REG) & (SETMASK)) + +#define CLEAR_REG(REG) ((REG) = (0x0)) + +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) + +#define READ_REG(REG) ((REG)) + +#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) + +#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL))) + +/** + * @} + */ + +/******************************************************************************/ +/* types */ +/******************************************************************************/ +/** @addtogroup Public_types + * @{ + */ +typedef enum +{ + DISABLE = 0, + ENABLE = !DISABLE +} TypeFunc,FuncState; +#define IS_FUNC_STATE(x) (((x) == DISABLE) || ((x) == ENABLE)) + +typedef enum +{ + RESET = 0, + SET = !RESET +} FlagStatus, ITStatus, PinStatus; + +typedef enum +{ + ERROR = 0, + SUCCESS = !ERROR +} ErrorStatus; + +typedef enum +{ + BIT_RESET = 0x0, + BIT_SET = 0x1, +} BitStatus; + +typedef enum +{ + FALSE = 0x0, + TRUE = 0x1, +} TypeBool; + +typedef enum +{ + UNLOCK = 0x0, + LOCK = 0x1, +} LockState; +#define IS_LOCK_STATE(x) (((x) == UNLOCK) || ((x) == LOCK)) + +/** + * @} Public_types + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/** + * @} ES32F0271_SUB + */ + +/** + * @} CMSIS + */ + +/************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/rt_misc.h b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/rt_misc.h new file mode 100644 index 0000000000..71a3270c6e --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Include/rt_misc.h @@ -0,0 +1,183 @@ +/* rt_misc.h: definitions for miscellaneous retargetable functions + * + * Copyright 1999,2013-2014 ARM Limited. All rights reserved. + * + * RCS $Revision$ + * Checkin $Date$ + * Revising $Author$ + */ + +#ifndef __RT_MISC_H +#define __RT_MISC_H +#define __ARMCLIB_VERSION 5060019 + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * This will be called during startup if it's defined, in order to + * allow a user reimplementation of getenv() to initialise itself. + */ +extern void _getenv_init(void); + +/* + * This will be called during startup if it's defined, in order to + * allow a user reimplementation of clock() to initialise itself. + */ +extern void _clock_init(void); + +/* + * This must return a pointer to __USER_LIBSPACE_SIZE bytes of + * zero-initialised space, used to store vital static data such as + * errno, the heap state, and the FP status word. + */ +#define __USER_LIBSPACE_SIZE 96 +extern void *__user_libspace(void); + +/* + * This is the library init function itself, provided just in case + * a user needs to call it directly. It is called just after + * __rt_stackheap_init(), and passed an initial chunk of memory to + * use as a heap. It returns argc and argv ready to be passed to + * main(). (The __argc_argv structure contains four words rather + * than just two, in case you need to pass anything else to main() + * such as the Unix envp. For AArch64 struct __argc_argv is 8 words + * (4 registers) and explicit padding is used to ensure argc is in w0.) + */ +struct __argc_argv { +#if (defined(__ARM_64BIT_STATE) || defined(__TARGET_ARCH_AARCH64)) && \ + (defined(__ARM_BIG_ENDIAN) || defined(__BIG_ENDIAN)) + int padding; +#endif + int argc; +#if (defined(__ARM_64BIT_STATE) || defined(__TARGET_ARCH_AARCH64)) && \ + !(defined(__ARM_BIG_ENDIAN) || defined(__BIG_ENDIAN)) + int padding; +#endif + char **argv; + void *r2; + void *r3; +}; +extern __value_in_regs struct __argc_argv +__rt_lib_init(unsigned /*heapbase*/, unsigned /*heaptop*/); + +/* + * This function is responsible for constructing argc and argv to + * be passed to main(). Normally it works by calling + * _sys_command_string() and then splitting up the returned command + * line. If you define main() without arguments, the compiler also + * defines an empty version of this function to save time. In + * special circumstances, you might need to redefine this function + * explicitly yourself. + */ +__value_in_regs struct __argc_argv __ARM_get_argv(void */*internal use only*/); + +/* + * This is the library shutdown function, analogous to + * __rt_lib_init(). + */ +extern void __rt_lib_shutdown(void); + +/* + * The medium-level exit function. exit() calls atexit()-registered + * functions and shuts down the library; _sys_exit() does neither + * of those things; __rt_exit() shuts down the library but doesn't + * call atexit() functions. + */ +extern void __rt_exit(int /*returncode*/); /* never returns */ + +/* + * This can be defined to override the standard memory models' way + * of determining where to put the initial stack and heap. + * + * The input parameters R0 and R2 contain nothing useful. The input + * parameters SP and SL are the values that were in SP and SL when + * the program began execution (so you can return them if you want + * to keep that stack). + * + * The two `limit' fields in the return structure are ignored if + * you are using the one-region memory model: the memory region is + * taken to be all the space between heap_base and stack_base. + */ +struct __initial_stackheap { + unsigned heap_base; /* low-address end of initial heap */ + unsigned stack_base; /* high-address end of initial stack */ + unsigned heap_limit; /* high-address end of initial heap */ + unsigned stack_limit; /* low-address end of initial stack */ +}; +extern __value_in_regs struct __initial_stackheap +__user_initial_stackheap(unsigned /*R0*/, unsigned /*SP*/, + unsigned /*R2*/, unsigned /*SL*/); + +/* + * This can be defined to give bounds on the address space the heap + * will ever use. + */ +struct __heap_extent { + uintptr_t base; + size_t range; +}; +extern __value_in_regs struct __heap_extent +__user_heap_extent(uintptr_t /*ignore*/, size_t /*ignore*/); + +/* + * This can be defined to specify how much spare stack is needed + * below SL in addition to the 256 bytes required by ATPCS: + * `always' gives the number of bytes of extra stack required at + * all instants (so that an interrupt handler has space to run in, + * for example), while `cleanup' gives the number of bytes of extra + * stack required to be available after a stack overflow has + * occurred, so that the stack overflow routine (e.g. SIGSTAK + * handler) has room to tidy up. + */ +struct __stack_slop { + unsigned always, cleanup; +}; +extern __value_in_regs struct __stack_slop +__user_stack_slop(unsigned /*ignore*/, unsigned /*ignore*/); + +/* + * This can be defined to return extra blocks of memory, separate + * from the initial one, to be used by the heap. It should place a + * pointer to a block of at least the requested size in `*base', + * and return the size of the block. It should return 0 if no such + * block can be returned, in which case the value stored at `*base' + * is never used. + */ +extern size_t __user_heap_extend(int /*ignore*/, + void ** /*base*/, + size_t /*requestedsize*/); + +/* + * Redefine this to completely override the C handling of signals + * (bypassing the signal() mechanism). Return values are 0 to + * continue execution, or a non-zero value to cause an exit with + * that return code. + */ +int __raise(int /*sig*/, intptr_t /*type*/); + +/* + * Redefine this to change the default handling of signals. The + * interface is the same as __raise(), but this function will only + * get called after the C signal handling mechanism has declined to + * process the signal. + */ +int __default_signal_handler(int /*sig*/, intptr_t /*type*/); + +/* + * Redefine this to replace the library's entire signal handling + * mechanism in the most efficient possible way. The default + * implementation of this is what calls __raise (above). + */ +void __rt_raise(int /*sig*/, intptr_t /*type*/); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/ReleaseNote.html b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/ReleaseNote.html new file mode 100644 index 0000000000..dce80ba62c --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/ReleaseNote.html @@ -0,0 +1,16 @@ + + + + +ReleaseNote +

ES32F0271 Device Release Note

+

V1.00 2019-1-4

+

初版发布

+

V1.03 2019-09-23

+
    +
  1. Drivers\CMSIS\Device\EastSoft\ES32F0271\Startup\iar\ : 增加startup_es32f027x.s
  2. + +
+

 

+ + \ No newline at end of file diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/iar/startup_es32f027x.s b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/iar/startup_es32f027x.s new file mode 100644 index 0000000000..bda1ad6ecd --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/iar/startup_es32f027x.s @@ -0,0 +1,256 @@ +;******************************************************************************* +; file : startup_ES32f027x.s +; description: ES32F027x Device Startup File +; author : Eastsoft MCU Software Team +; data : 10 Dec 2018 +; Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. +;******************************************************************************* + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) ;0, load top of stack + DCD Reset_Handler ;1, reset handler + DCD NMI_Handler ;2, nmi handler + DCD HardFault_Handler ;3, hard fault handler + DCD 0 ;4, MPU Fault Handler + DCD 0 ;5, Bus Fault Handler + DCD 0 ;6, Usage Fault Handler + DCD 0 ;7, Reserved + DCD 0 ;8, Reserved + DCD 0 ;9, Reserved + DCD 0 ;10, Reserved + DCD SVC_Handler ;11, svcall handler + DCD 0 ;12, Reserved + DCD 0 ;13, Reserved + DCD PENDSV_Handler ;14, PENDSV Handler + DCD SYSTICK_Handler ;15, SYSTICK Handler + DCD WWDT_IRQHandler ;16, WWDT IRQHandler + DCD PVD_IRQHandler ;17, PVD IRQHandler + DCD RTC_IRQHandler ;18, RTC IRQHandler + DCD LowPowerWakeup_IRQHandler ;19, LowPowerWakeup IRQHandler + DCD 0 ;20, Reserved + DCD EXTI0_1_IRQHandler ;21, EXTI01_1 IRQHandler + DCD EXTI2_3_IRQHandler ;22, EXTI2_3 IRQHandler + DCD EXTI4_15_IRQHandler ;23, EXTI4_15 IRQHandler + DCD 0 ;24, Reserved + DCD DMA1_CH0_IRQHandler ;25, DMA1_CH1 IRQHandler + DCD DMA1_CH1_2_IRQHandler ;26, DMA1_CH2_3 IRQHandler + DCD DMA1_CH3_5_IRQHandler ;27, DMA1_CH4_7 IRQHandler + DCD ADC_CMP_IRQHandler ;28, ADC_CMP IRQHandler + DCD AD16C4T1_IRQHandler ;29, AD16C4T1 IRQHandler + DCD BS16T1_IRQHandler ;30, BS16T1 IRQHandler + DCD GP32C4T1_IRQHandler ;31, GP32C4T1 IRQHandler + DCD GP16C4T1_IRQHandler ;32, GP16C4T1 IRQHandler + DCD GP16C4T2_IRQHandler ;33, GP16C4T2 IRQHandler + DCD GP16C4T3_IRQHandler ;34, GP16C4T3 IRQHandler + DCD GP16C2T1_IRQHandler ;35, GP16C2T1 IRQHandler + DCD GP16C2T2_IRQHandler ;36, GP16C2T2 IRQHandler + DCD GP16C2T3_IRQHandler ;37, GP16C2T3 IRQHandler + DCD GP16C2T4_IRQHandler ;38, GP16C2T4 IRQHandler + DCD I2C1_IRQHandler ;39, I2C1 IRQHandler + DCD I2C2_IRQHandler ;40, I2C2 IRQHandler + DCD SPI1_IRQHandler ;41, SPI1 IRQHandler + DCD SPI2_IRQHandler ;42, SPI2 IRQHandler + DCD UART1_IRQHandler ;43, UART1 IRQHandler + DCD UART2_IRQHandler ;44, UART2 IRQHandler + DCD UART3_AES_IRQHandler ;45, UART3_AES IRQHandler + DCD SUART1_SUART2_IRQHandler ;46, SUART1_SUART2 IRQHandler + DCD USB_IRQHandler ;47, USB IRQHandler + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK PENDSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PENDSV_Handler + B PENDSV_Handler + + PUBWEAK SYSTICK_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SYSTICK_Handler + B SYSTICK_Handler + + PUBWEAK WWDT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDT_IRQHandler + B WWDT_IRQHandler + + PUBWEAK PVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_IRQHandler + B PVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK LowPowerWakeup_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LowPowerWakeup_IRQHandler + B LowPowerWakeup_IRQHandler + + PUBWEAK EXTI0_1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_1_IRQHandler + B EXTI0_1_IRQHandler + + PUBWEAK EXTI2_3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_3_IRQHandler + B EXTI2_3_IRQHandler + + PUBWEAK EXTI4_15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_15_IRQHandler + B EXTI4_15_IRQHandler + + PUBWEAK DMA1_CH0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH0_IRQHandler + B DMA1_CH0_IRQHandler + + PUBWEAK DMA1_CH1_2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH1_2_IRQHandler + B DMA1_CH1_2_IRQHandler + + PUBWEAK DMA1_CH3_5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_CH3_5_IRQHandler + B DMA1_CH3_5_IRQHandler + + PUBWEAK ADC_CMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_CMP_IRQHandler + B ADC_CMP_IRQHandler + + PUBWEAK AD16C4T1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +AD16C4T1_IRQHandler + B AD16C4T1_IRQHandler + + PUBWEAK BS16T1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +BS16T1_IRQHandler + B BS16T1_IRQHandler + + PUBWEAK GP32C4T1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GP32C4T1_IRQHandler + B GP32C4T1_IRQHandler + + PUBWEAK GP16C4T1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GP16C4T1_IRQHandler + B GP16C4T1_IRQHandler + + PUBWEAK GP16C4T2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GP16C4T2_IRQHandler + B GP16C4T2_IRQHandler + + PUBWEAK GP16C4T3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GP16C4T3_IRQHandler + B GP16C4T3_IRQHandler + + PUBWEAK GP16C2T1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GP16C2T1_IRQHandler + B GP16C2T1_IRQHandler + + PUBWEAK GP16C2T2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GP16C2T2_IRQHandler + B GP16C2T2_IRQHandler + + PUBWEAK GP16C2T3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GP16C2T3_IRQHandler + B GP16C2T3_IRQHandler + + PUBWEAK GP16C2T4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GP16C2T4_IRQHandler + B GP16C2T4_IRQHandler + + PUBWEAK I2C1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_IRQHandler + B I2C1_IRQHandler + + PUBWEAK I2C2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_IRQHandler + B I2C2_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK UART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART1_IRQHandler + B UART1_IRQHandler + + PUBWEAK UART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART2_IRQHandler + B UART2_IRQHandler + + PUBWEAK UART3_AES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART3_AES_IRQHandler + B UART3_AES_IRQHandler + + PUBWEAK SUART1_SUART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SUART1_SUART2_IRQHandler + B SUART1_SUART2_IRQHandler + + PUBWEAK USB_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USB_IRQHandler + B USB_IRQHandler + + END diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/keil/boot.c b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/keil/boot.c new file mode 100644 index 0000000000..4c4e15ee4c --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/keil/boot.c @@ -0,0 +1,321 @@ + +// +// Boot (vectors) file for Cortex-M0 Integration Kit +// + +#include +#include +#include +#include "es32F0271_sub.h" + +// +// Build a stand-alone image +// + +#pragma import(__use_no_semihosting) + + +/*----------------------------------------------------------------------*/ +/*-------------- Interrupt Handlers --------------*/ +/*----------------------------------------------------------------------*/ +// The following functions are defined weakly to allow the user +// to override them at link time simply by declaring their own +// function of the same name. +// +// If no user function is provided, the weak function is used. +// +//------------------------------------ IRQ NMI Handler +__weak void NMI_Handler(void) +{ + while(1); +} +//------------------------------------ IRQ Hard Fault Handler +__weak void HardFault_Handler(void) +{ + //printf("Hard Fault\r\n"); + while(1); +} +//------------------------------------ IRQ SVCall Handler +__weak void SVC_Handler(void) +{ + while(1); +} +//------------------------------------ IRQ PendSV Handler +__weak void PendSV_Handler(void) +{ + while(1); +} +//------------------------------------ IRQ SysTick Handler +__weak void SysTick_Handler(void) +{ + while(1); +} +//------------------------------------ IRQ 31 +__weak void USB_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 30 +__weak void SUART12_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 29 +__weak void UART3_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 28 +__weak void UART2_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 27 +__weak void UART1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 26 +__weak void SPI2_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 25 +__weak void SPI1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 24 +__weak void I2C2_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 23 +__weak void I2C1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 22 +__weak void GPTIMC4_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 21 +__weak void GPTIMC3_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 20 +__weak void GPTIMC2_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 19 +__weak void GPTIMC1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 18 +__weak void GPTIMB3_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 17 +__weak void GPTIMB2_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 16 +__weak void GPTIMB1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 15 +__weak void GPTIMA1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 14 +__weak void BSTIM1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 13 +__weak void ADTIM1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 12 +__weak void ADC_COMP_IRQHandler(void) +{ + // while(1); +} +//------------------------------------ IRQ 11 +__weak void DMA1_CH345_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 10 +__weak void DMA1_CH12_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 9 +__weak void DMA1_CH0_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 8 +//------------------------------------ IRQ 7 +__weak void EXTI_4to15_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 6 +__weak void EXTI_2to3_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 5 +__weak void EXTI_0to1_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 4 +//------------------------------------ IRQ 3 +__weak void WAKEUP_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 2 +__weak void RTC_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 1 +__weak void PVD_IRQHandler(void) +{ + while(1); +} +//------------------------------------ IRQ 0 +__weak void WWDT_IRQHandler(void) +{ + while(1); +} + + +/*----------------------------------------------------------------------*/ +/*-------------- Defined Handler --------------*/ +/*----------------------------------------------------------------------*/ +__weak void Default_IRQHandler(void) +{ + while(1); +} + +/*----------------------------------------------------------------------*/ +/*-------------- Symbols defined in linker script ---------*/ +/*----------------------------------------------------------------------*/ + +extern void __main(void); + +/*----------------------------------------------------------------------*/ +/*-------------- Reset Handler --------------*/ +/*----------------------------------------------------------------------*/ +void Reset_Handler(void) +{ + __main(); + while(1) {;} // In case main() fails +} + +/*----------------------------------------------------------------------*/ +/*-------------- Set up Vector Table --------------*/ +/*----------------------------------------------------------------------*/ +typedef void (*const vect_t)(void) __irq; + +vect_t __Vectors[] +__attribute__ ((section("vectors"))) = { + (vect_t)(SRAM1_BASE+SRAMTOP),//(vect_t)(0x20000F80), // Top of Stack - Allowing 4 words for DEBUGDRIVERDATA + (vect_t)Reset_Handler, // Reset Handler + (vect_t)NMI_Handler, // NMI Handler + (vect_t)HardFault_Handler,// Hard Fault Handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + (vect_t)SVC_Handler, // SVCall Handler + 0, // Reserved + 0, // Reserved + (vect_t)PendSV_Handler, // PendSV Handler + (vect_t)SysTick_Handler, // SysTick Handler + /*----------External Exceptions---------------------------------------------*/ + // External Interrupts 0 - 31 + // These are essentially unused, so will all + // take the same default handler if invoked. + // External Interrupts + //|=========================================| + //| IRQ NO. | M621 | + //|-----------------------------------------| + (vect_t)WWDT_IRQHandler, //| 0 | WWDG | | + (vect_t)PVD_IRQHandler, //| 1 | PVD | EXTI[20] | + (vect_t)RTC_IRQHandler, //| 2 | RTC | | + (vect_t)WAKEUP_IRQHandler, //| 3 | WAKEUP | EXTI[21] | + (vect_t)Default_IRQHandler, //| 4 | | | + (vect_t)EXTI_0to1_IRQHandler, //| 5 | EXTI[1:0] | GPIOx[1:0] | + (vect_t)EXTI_2to3_IRQHandler, //| 6 | EXTI[3:2] | GPIOx[3:2] | + (vect_t)EXTI_4to15_IRQHandler, //| 7 | EXTI[15:4] | GPIOx[15:4] | + (vect_t)Default_IRQHandler, //| 8 | | | + (vect_t)DMA1_CH0_IRQHandler, //| 9 | DMA1_CH0 | | + (vect_t)DMA1_CH12_IRQHandler, //| 10 | DMA1_CH12 | | + (vect_t)DMA1_CH345_IRQHandler, //| 11 | DMA1_CH345 | | + (vect_t)ADC_COMP_IRQHandler, //| 12 | ADC/COMP0-3 | EXTI[19:16] | + (vect_t)ADTIM1_IRQHandler, //| 13 | ADTIM1 | | + (vect_t)BSTIM1_IRQHandler, //| 14 | BSTIM1 | | + (vect_t)GPTIMA1_IRQHandler, //| 15 | GPTIMA1 | | + (vect_t)GPTIMB1_IRQHandler, //| 16 | GPTIMB1 | | + (vect_t)GPTIMB2_IRQHandler, //| 17 | GPTIMB2 | | + (vect_t)GPTIMB3_IRQHandler, //| 18 | GPTIMB3 | | + (vect_t)GPTIMC1_IRQHandler, //| 19 | GPTIMC1 | | + (vect_t)GPTIMC2_IRQHandler, //| 20 | GPTIMC2 | | + (vect_t)GPTIMC3_IRQHandler, //| 21 | GPTIMC3 | | + (vect_t)GPTIMC4_IRQHandler, //| 22 | GPTIMC4 | | + (vect_t)I2C1_IRQHandler, //| 23 | I2C1 | | + (vect_t)I2C2_IRQHandler, //| 24 | I2C2 | | + (vect_t)SPI1_IRQHandler, //| 25 | SPI1 | | + (vect_t)SPI2_IRQHandler, //| 26 | SPI2 | | + (vect_t)UART1_IRQHandler, //| 27 | UART1 | | + (vect_t)UART2_IRQHandler, //| 28 | UART2 | | + (vect_t)UART3_IRQHandler, //| 29 | UART3 | | + (vect_t)SUART12_IRQHandler, //| 30 | SUART1/2 | | + (vect_t)USB_IRQHandler //| 31 | USB | | + //==========================================| +}; + + +/*----------------------------------------------------------------------*/ +/*-------------- Set up initial stack and heap --------------*/ +/*----------------------------------------------------------------------*/ +__value_in_regs struct __initial_stackheap +__user_initial_stackheap(unsigned hb, unsigned sb, unsigned hl, unsigned sl) +{ + struct __initial_stackheap s; + + s.heap_base = hb; + s.stack_base = sb; + s.heap_limit = s.stack_base; + s.stack_limit = s.heap_base; + return s; +} + +/*----------------------------------------------------------------------*/ +/*------ Set test status bits in testbench when main() exits -------*/ +/*----------------------------------------------------------------------*/ +void _sys_exit(int return_code) +{ + while(1); +} + + + diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/keil/startup_es32f027x.s b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/keil/startup_es32f027x.s new file mode 100644 index 0000000000..78c14566c3 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/Startup/keil/startup_es32f027x.s @@ -0,0 +1,244 @@ +;******************************************************************************* +; *file : startup_ES32F027x.s +; *description: ES32F027x Device Startup File +; *author : Eastsoft MCU Software Team +; *version : V0.01 +; *data : 12/10/2018 +; +; *Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. +; * +; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED +; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. +; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR +; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. +;******************************************************************************* + + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000000 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + +__Vectors DCD __initial_sp ; Top of Stack + ; External Interrupts + DCD Reset_Handler ;1, Reset Handler + DCD NMI_Handler ;2, NMI Handler + DCD HardFault_Handler ;3, HARDFAULT Handler + DCD 0 ;4, Reserved + DCD 0 ;5, Reserved + DCD 0 ;6, Reserved + DCD 0 ;7, Reserved + DCD 0 ;8, Reserved + DCD 0 ;9, Reserved + DCD 0 ;10, Reserved + DCD SVC_Handler ;11, SVC Handler + DCD 0 ;12, Reserved + DCD 0 ;13, Reserved + DCD PendSV_Handler ;14, PENDSV Handler + DCD SysTick_Handler ;15, SYSTICK Handler + DCD WWDT_IRQHandler ;16, WWDT IRQHandler + DCD PVD_IRQHandler ;17, PVD IRQHandler + DCD RTC_IRQHandler ;18, RTC IRQHandler + DCD LowPowerWakeup_IRQHandler ;19, LowPowerWakeup IRQHandler + DCD 0 ;20, Reserved + DCD EXTI0_1_IRQHandler ;21, EXTI01_1 IRQHandler + DCD EXTI2_3_IRQHandler ;22, EXTI2_3 IRQHandler + DCD EXTI4_15_IRQHandler ;23, EXTI4_15 IRQHandler + DCD 0 ;24, Reserved + DCD DMA1_CH0_IRQHandler ;25, DMA1_CH0 IRQHandler + DCD DMA1_CH1_2_IRQHandler ;26, DMA1_CH1_2 IRQHandler + DCD DMA1_CH3_5_IRQHandler ;27, DMA1_CH3_5 IRQHandler + DCD ADC_CMP_IRQHandler ;28, ADC_CMP IRQHandler + DCD AD16C4T1_IRQHandler ;29, AD16C4T1 IRQHandler + DCD BS16T1_IRQHandler ;30, BS16T1 IRQHandler + DCD GP32C4T1_IRQHandler ;31, GP32C4T1 IRQHandler + DCD GP16C4T1_IRQHandler ;32, GP16C4T1 IRQHandler + DCD GP16C4T2_IRQHandler ;33, GP16C4T2 IRQHandler + DCD GP16C4T3_IRQHandler ;34, GP16C4T3 IRQHandler + DCD GP16C2T1_IRQHandler ;35, GP16C2T1 IRQHandler + DCD GP16C2T2_IRQHandler ;36, GP16C2T2 IRQHandler + DCD GP16C2T3_IRQHandler ;37, GP16C2T3 IRQHandler + DCD GP16C2T4_IRQHandler ;38, GP16C2T4 IRQHandler + DCD I2C1_IRQHandler ;39, I2C1 IRQHandler + DCD I2C2_IRQHandler ;40, I2C2 IRQHandler + DCD SPI1_IRQHandler ;41, SPI1 IRQHandler + DCD SPI2_IRQHandler ;42, SPI2 IRQHandler + DCD UART1_IRQHandler ;43, UART1 IRQHandler + DCD UART2_IRQHandler ;44, UART2 IRQHandler + DCD UART3_AES_IRQHandler ;45, UART3_AES IRQHandler + DCD SUART1_SUART2_IRQHandler ;46, SUART1_SUART2 IRQHandler + DCD USB_IRQHandler ;47, USB IRQHandler + + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception IRQHandlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP + + +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP + +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + + + EXPORT WWDT_IRQHandler [WEAK] + EXPORT PVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT LowPowerWakeup_IRQHandler [WEAK] + EXPORT EXTI0_1_IRQHandler [WEAK] + EXPORT EXTI2_3_IRQHandler [WEAK] + EXPORT EXTI4_15_IRQHandler [WEAK] + EXPORT DMA1_CH0_IRQHandler [WEAK] + EXPORT DMA1_CH1_2_IRQHandler [WEAK] + EXPORT DMA1_CH3_5_IRQHandler [WEAK] + EXPORT ADC_CMP_IRQHandler [WEAK] + EXPORT AD16C4T1_IRQHandler [WEAK] + EXPORT BS16T1_IRQHandler [WEAK] + EXPORT GP32C4T1_IRQHandler [WEAK] + EXPORT GP16C4T1_IRQHandler [WEAK] + EXPORT GP16C4T2_IRQHandler [WEAK] + EXPORT GP16C4T3_IRQHandler [WEAK] + EXPORT GP16C2T1_IRQHandler [WEAK] + EXPORT GP16C2T2_IRQHandler [WEAK] + EXPORT GP16C2T3_IRQHandler [WEAK] + EXPORT GP16C2T4_IRQHandler [WEAK] + EXPORT I2C1_IRQHandler [WEAK] + EXPORT I2C2_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT UART1_IRQHandler [WEAK] + EXPORT UART2_IRQHandler [WEAK] + EXPORT UART3_AES_IRQHandler [WEAK] + EXPORT SUART1_SUART2_IRQHandler [WEAK] + EXPORT USB_IRQHandler [WEAK] + + + +WWDT_IRQHandler +PVD_IRQHandler +RTC_IRQHandler +LowPowerWakeup_IRQHandler +EXTI0_1_IRQHandler +EXTI2_3_IRQHandler +EXTI4_15_IRQHandler +DMA1_CH0_IRQHandler +DMA1_CH1_2_IRQHandler +DMA1_CH3_5_IRQHandler +ADC_CMP_IRQHandler +AD16C4T1_IRQHandler +BS16T1_IRQHandler +GP32C4T1_IRQHandler +GP16C4T1_IRQHandler +GP16C4T2_IRQHandler +GP16C4T3_IRQHandler +GP16C2T1_IRQHandler +GP16C2T2_IRQHandler +GP16C2T3_IRQHandler +GP16C2T4_IRQHandler +I2C1_IRQHandler +I2C2_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +UART1_IRQHandler +UART2_IRQHandler +UART3_AES_IRQHandler +SUART1_SUART2_IRQHandler +USB_IRQHandler + + + B . + + ENDP + + ALIGN + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END + + diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/core_cm0.c b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/core_cm0.c new file mode 100644 index 0000000000..e8a1ed21c0 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/core_cm0.c @@ -0,0 +1,472 @@ +/* + *----------------------------------------------------------------------------- + * The confidential and proprietary information contained in this file may + * only be used by a person authorised under and to the extent permitted + * by a subsisting licensing agreement from ARM Limited. + * + * (C) COPYRIGHT 2009-2010 ARM Limited. + * ALL RIGHTS RESERVED + * + * This entire notice must be reproduced on all copies of this file + * and copies of this file may only be made by a person if such person is + * permitted to do so under the terms of a subsisting license agreement + * from ARM Limited. + * + * SVN Information + * + * Checked In : $Date: 2008-12-31 10:59:44 +0000 (Wed, 31 Dec 2008) $ + * + * Revision : $Revision: 97564 $ + * + * Release Information : Cortex-M0-AT510-r0p0-03rel0 + *----------------------------------------------------------------------------- + */ + + +#include + + +/* define compiler specific symbols */ +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for armcc */ + #define __INLINE __inline /*!< inline keyword for armcc */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for iarcc */ + #define __INLINE inline /*!< inline keyword for iarcc. Only avaiable in High optimization mode! */ + #define __nop __no_operation /*!< no operation intrinsic in iarcc */ + +#elif defined ( __GNUC__ ) + #define __ASM asm /*!< asm keyword for gcc */ + #define __INLINE inline /*!< inline keyword for gcc */ +#endif + + + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ + +/** + * @brief Return the Process Stack Pointer + * + * @param none + * @return uint32_t ProcessStackPointer + * + * Return the actual process stack pointer + */ +__ASM uint32_t __get_PSP(void) +{ + mrs r0, psp + bx lr +} + +/** + * @brief Set the Process Stack Pointer + * + * @param uint32_t Process Stack Pointer + * @return none + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +__ASM void __set_PSP(uint32_t topOfProcStack) +{ + msr psp, r0 + bx lr +} + +/** + * @brief Return the Main Stack Pointer + * + * @param none + * @return uint32_t Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +__ASM uint32_t __get_MSP(void) +{ + mrs r0, msp + bx lr +} + +/** + * @brief Set the Main Stack Pointer + * + * @param uint32_t Main Stack Pointer + * @return none + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +__ASM void __set_MSP(uint32_t mainStackPointer) +{ + msr msp, r0 + bx lr +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param uint16_t value to reverse + * @return uint32_t reversed value + * + * Reverse byte order in unsigned short value + */ +__ASM uint32_t __REV16(uint16_t value) +{ + rev16 r0, r0 + bx lr +} + +/** + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param int16_t value to reverse + * @return int32_t reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ +__ASM int32_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} + + +#if (__ARMCC_VERSION < 400000) + + +/** + * @brief Return the Priority Mask value + * + * @param none + * @return uint32_t PriMask + * + * Return the state of the priority mask bit from the priority mask + * register + */ +__ASM uint32_t __get_PRIMASK(void) +{ + mrs r0, primask + bx lr +} + +/** + * @brief Set the Priority Mask value + * + * @param uint32_t PriMask + * @return none + * + * Set the priority mask bit in the priority mask register + */ +__ASM void __set_PRIMASK(uint32_t priMask) +{ + msr primask, r0 + bx lr +} + + +/** + * @brief Return the Control Register value + * + * @param none + * @return uint32_t Control value + * + * Return the content of the control register + */ +__ASM uint32_t __get_CONTROL(void) +{ + mrs r0, control + bx lr +} + +/** + * @brief Set the Control Register value + * + * @param uint32_t Control value + * @return none + * + * Set the control register + */ +__ASM void __set_CONTROL(uint32_t control) +{ + msr control, r0 + bx lr +} + +#endif /* __ARMCC_VERSION */ + + +#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/ +#pragma diag_suppress=Pe940 + +/** + * @brief Return the Process Stack Pointer + * + * @param none + * @return uint32_t ProcessStackPointer + * + * Return the actual process stack pointer + */ +uint32_t __get_PSP(void) +{ + __ASM("mrs r0, psp"); + __ASM("bx lr"); +} + +/** + * @brief Set the Process Stack Pointer + * + * @param uint32_t Process Stack Pointer + * @return none + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +void __set_PSP(uint32_t topOfProcStack) +{ + __ASM("msr psp, r0"); + __ASM("bx lr"); +} + +/** + * @brief Return the Main Stack Pointer + * + * @param none + * @return uint32_t Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +uint32_t __get_MSP(void) +{ + __ASM("mrs r0, msp"); + __ASM("bx lr"); +} + +/** + * @brief Set the Main Stack Pointer + * + * @param uint32_t Main Stack Pointer + * @return none + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +void __set_MSP(uint32_t topOfMainStack) +{ + __ASM("msr msp, r0"); + __ASM("bx lr"); +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param uint16_t value to reverse + * @return uint32_t reversed value + * + * Reverse byte order in unsigned short value + */ +uint32_t __REV16(uint16_t value) +{ + __ASM("rev16 r0, r0"); + __ASM("bx lr"); +} + + +#pragma diag_default=Pe940 + + + + +#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ + +/** + * @brief Return the Process Stack Pointer + * + * @param none + * @return uint32_t ProcessStackPointer + * + * Return the actual process stack pointer + */ +uint32_t __get_PSP(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Process Stack Pointer + * + * @param uint32_t Process Stack Pointer + * @return none + * + * Assign the value ProcessStackPointer to the MSP + * (process stack pointer) Cortex processor register + */ +void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) ); +} + +/** + * @brief Return the Main Stack Pointer + * + * @param none + * @return uint32_t Main Stack Pointer + * + * Return the current value of the MSP (main stack pointer) + * Cortex processor register + */ +uint32_t __get_MSP(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Main Stack Pointer + * + * @param uint32_t Main Stack Pointer + * @return none + * + * Assign the value mainStackPointer to the MSP + * (main stack pointer) Cortex processor register + */ +void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) ); +} + + +/** + * @brief Return the Priority Mask value + * + * @param none + * @return uint32_t PriMask + * + * Return the state of the priority mask bit from the priority mask + * register + */ +uint32_t __get_PRIMASK(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Priority Mask value + * + * @param uint32_t PriMask + * @return none + * + * Set the priority mask bit in the priority mask register + */ +void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); +} + + +/** + * @brief Reverse byte order in integer value + * + * @param uint32_t value to reverse + * @return uint32_t reversed value + * + * Reverse byte order in integer value + */ +uint32_t __REV(uint32_t value) +{ + uint32_t result=0; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief Reverse byte order in unsigned short value + * + * @param uint16_t value to reverse + * @return uint32_t reversed value + * + * Reverse byte order in unsigned short value + */ +uint32_t __REV16(uint16_t value) +{ + uint32_t result=0; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +/** + * @brief Reverse byte order in signed short value with sign extension to integer + * + * @param int32_t value to reverse + * @return int32_t reversed value + * + * Reverse byte order in signed short value with sign extension to integer + */ +int32_t __REVSH(int16_t value) +{ + uint32_t result=0; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** + * @brief Return the Control Register value + * + * @param none + * @return uint32_t Control value + * + * Return the content of the control register + */ +uint32_t __get_CONTROL(void) +{ + uint32_t result=0; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + +/** + * @brief Set the Control Register value + * + * @param uint32_t Control value + * @return none + * + * Set the control register + */ +void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) ); +} + +#endif + + + + + + + + + + + + + + + + + diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/retarget.c b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/retarget.c new file mode 100644 index 0000000000..1303e0765e --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/retarget.c @@ -0,0 +1,55 @@ +/******************************************************************************/ +/* RETARGET.C: 'Retarget' layer for target-dependent low level functions */ +/******************************************************************************/ +/* This file is part of the uVision/ARM development tools. */ +/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */ +/* This software may only be used under the terms of a valid, current, */ +/* end user licence from KEIL for a compatible version of KEIL software */ +/* development tools. Nothing else gives you the right to use this software. */ +/******************************************************************************/ + +#include +#include + +//#pragma import(__use_no_semihosting_swi) + +__weak uint8_t sendchar(uint8_t ui8char) +{ + (void) ui8char; + return 0; +} + + +int ITM_fputc(int ch); /* ITM debug */ + +struct __FILE +{ +int handle; /* Add whatever you need here */ +}; +FILE __stdout; + + +int fputc(int ch, FILE *f) +{ + return (sendchar(ch)); +} + + +int ferror(FILE *f) +{ + /* Your implementation of ferror */ + return EOF; +} + + +void _ttywrch(int ch) +{ + sendchar(ch); +} + + +void _sys_exit(int return_code) +{ +label: + goto label; /* endless loop */ +} diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.c b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.c new file mode 100644 index 0000000000..6112c52bb4 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.c @@ -0,0 +1,79 @@ +/** + ************************************************************************************** + * @file system_es32f027x.c + * @brief System File. + * + * @version V0.01 + * @data 5/17/2018 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ************************************************************************************** + */ + +/* Incudes--------------------------------------------------------*/ +#include "system_es32f027x.h" + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup System_ES32F027X + * @{ + */ + +/* Public Functions -----------------------------------------------------------*/ +/* Public Init Structure ------------------------------------------------------*/ +/* Public Macros --------------------------------------------------------------*/ +/* Public Constants -----------------------------------------------------------*/ +/* Private Macros -------------------------------------------------------------*/ +/* Private Constants-----------------------------------------------------------*/ + +/* Private Variables ----------------------------------------------------------*/ +/** @addtogroup Private_Variables + * @{ + */ + +/** + * @brief update the value of SystemCoreClock after changing the system clock. + */ +unsigned int SystemCoreClock = 4000000; +unsigned int SystemFrequency_SysClk = 4000000; +unsigned int SystemFrequency_AHBClk = 4000000; +unsigned int SystemFrequency_APBClk = 4000000; +unsigned int PLL1Frequency = 48000000; +unsigned int PLL0Frequency = 4000000; + +/** + * @} Private_Variables + */ + +/* Private Functions ----------------------------------------------------------*/ +/** @addtogroup Private_Functions + * @{ + */ + +/** + * @brief:SystemInit. + * @param:none + * @retval:none + */ +void SystemInit (void) +{ +} + +/** + * @} Private_Functions + */ + +/** + * @} System_ES32F072X + */ + +/** + * @} CMSIS + */ +/********** (C) COPYRIGHT Eastsoft Microelectronics END OF FILE SYSTEM_ES32F027X.H **********/ + diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.h b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.h new file mode 100644 index 0000000000..d2cee80354 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.h @@ -0,0 +1,83 @@ +/** + ************************************************************************************** + * @file SYSTEM_ES32F027x.H + * @brief es32f0271 system head file. + * + * @version V0.01 + * @data 5/17/2018 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ************************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __SYSTEM_ES32F027x_H__ +#define __SYSTEM_ES32F027x_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes -------------------------------------------------------*/ +#include + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup System_ES32F027x + * @{ + */ + +/* Public Functions -----------------------------------------------------------*/ +/* Public Init Structure ------------------------------------------------------*/ +/* Public Macros --------------------------------------------------------------*/ +/* Public Constants -----------------------------------------------------------*/ +/* Private Variables ----------------------------------------------------------*/ +/* Private Macros -------------------------------------------------------------*/ +/* Private Constants-----------------------------------------------------------*/ + +/* Public Types ---------------------------------------------------------------*/ +/** @addtogroup Public_Types + * @{ + */ +extern unsigned int SystemCoreClock; +extern unsigned int SystemFrequency_SysClk; +extern unsigned int SystemFrequency_AHBClk; +extern unsigned int SystemFrequency_APBClk; +extern unsigned int PLL1Frequency; +extern unsigned int PLL0Frequency; + +/* Exported function -------------------------------------------------*/ +/** @addtogroup Public_Functions + * @{ + */ + +extern void SystemInit (void); + +#ifdef __cplusplus +} +#endif + +#endif + +/** + * @} Public_Functions + */ + +/** + * @} Public_Types + */ + +/** + * @} System_ES32F027x + */ + +/** + * @} CMSIS + */ +/********** (C) COPYRIGHT Eastsoft Microelectronics END OF FILE SYSTEM_ES32F027x.H **********/ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_common_tables.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_common_tables.h new file mode 100644 index 0000000000..dfea7460e9 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_common_tables.h @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_common_tables.h + * Description: Extern declaration for common tables + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. 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 _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + +/* floating-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) +#define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) +#define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) +#define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) +#define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) +#define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) +#define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) +#define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) +#define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) +#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) +#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_const_structs.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_const_structs.h new file mode 100644 index 0000000000..80a3e8bbe7 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_const_structs.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_const_structs.h + * Description: Constant structs that are initialized for user convenience. + * For example, some can be given as arguments to the arm_cfft_f32() function. + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. 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 _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_math.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_math.h new file mode 100644 index 0000000000..ea9dd26aa8 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/arm_math.h @@ -0,0 +1,7157 @@ +/****************************************************************************** + * @file arm_math.h + * @brief Public header file for CMSIS DSP LibraryU + * @version V1.5.3 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2010-2018 Arm Limited or its affiliates. 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. + */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) + * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) + * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) + * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) + * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) + * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) + * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) + * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) + * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) + * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) + * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) + * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) + * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) + * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) + * - arm_ARMv8MBLl_math.lib (Armv8-M Baseline, Little endian) + * - arm_ARMv8MMLl_math.lib (Armv8-M Mainline, Little endian) + * - arm_ARMv8MMLlfsp_math.lib (Armv8-M Mainline, Little endian, Single Precision Floating Point Unit) + * - arm_ARMv8MMLld_math.lib (Armv8-M Mainline, Little endian, DSP instructions) + * - arm_ARMv8MMLldfsp_math.lib (Armv8-M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate preprocessor macro ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * For Armv8-M cores define preprocessor macro ARM_MATH_ARMV8MBL or ARM_MATH_ARMV8MML. + * Set preprocessor macro __DSP_PRESENT if Armv8-M Mainline core supports DSP instructions. + * + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to rebuild libraries on MDK toolchain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional preprocessor macros detailed above. + * + * Preprocessor Macros + * ------------ + * + * Each library project have different preprocessor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and + * ARM_MATH_CM7 for building the library on cortex-M7. + * + * - ARM_MATH_ARMV8MxL: + * + * Define macro ARM_MATH_ARMV8MBL for building the library on Armv8-M Baseline target, ARM_MATH_ARMV8MML for building library + * on Armv8-M Mainline target. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for floating point libraries. + * + * - __DSP_PRESENT: + * + * Initialize macro __DSP_PRESENT = 1 when Armv8-M Mainline core supports DSP instructions. + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | + * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2015 Arm Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#else + #error Unknown compiler +#endif + + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) + #include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_ARMV8MBL) + #include "core_armv8mbl.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_ARMV8MML) + #include "core_armv8mml.h" + #if (defined (__DSP_PRESENT) && (__DSP_PRESENT == 1)) + #define ARM_MATH_DSP + #endif +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI + #define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined ( __CC_ARM ) + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __GNUC__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __ICCARM__ ) + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#elif defined ( __TI_ARM__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE + +#elif defined ( __CSMC__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#elif defined ( __TASKING__ ) + #define __SIMD32_TYPE __unaligned int32_t + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if !defined (ARM_MATH_DSP) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif /* !defined (ARM_MATH_DSP) */ + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + CMSIS_INLINE __STATIC_INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + CMSIS_INLINE __STATIC_INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + CMSIS_INLINE __STATIC_INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + CMSIS_INLINE __STATIC_INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + CMSIS_INLINE __STATIC_INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if (in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1U); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if (in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + + +/* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if !defined (ARM_MATH_DSP) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + + /* + * @brief C custom defined SMMLA for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) + { + return (sum + (int32_t) (((int64_t) x * y) >> 32)); + } + +#endif /* !defined (ARM_MATH_DSP) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#if !defined (ARM_MATH_DSP) + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] S points to an instance of the floating-point FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31U); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#if defined (ARM_MATH_DSP) + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + */ + CMSIS_INLINE __STATIC_INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * The function implements the forward Park transform. + * + */ + CMSIS_INLINE __STATIC_INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if ((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1U); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + CMSIS_INLINE __STATIC_INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + CMSIS_INLINE __STATIC_INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if (in >= 0.0f) + { + +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined(__GNUC__) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4U); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4U); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __GNUC__ ) + #define LOW_OPTIMIZATION_ENTER \ + __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __ICCARM__ ) + /* Enter low optimization region - place directly above function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TI_ARM__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __CSMC__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TASKING__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic pop + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#else + #error Unknown compiler +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_armcc.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_armcc.h new file mode 100644 index 0000000000..093d35b9e5 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_armcc.h @@ -0,0 +1,870 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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 __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \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 + */ +#define __REV __rev + + +/** + \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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \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 + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \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. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \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 (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE 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 + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \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 + */ +#define __SSAT __ssat + + +/** + \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 + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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; +} + +/** + \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 + */ +__attribute__((always_inline)) __STATIC_INLINE 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 /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_armclang.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_armclang.h new file mode 100644 index 0000000000..5c4c20e877 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_armclang.h @@ -0,0 +1,1877 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + +#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \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 + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \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 + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \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 + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \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 + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \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. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \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 + */ +#define __SSAT __builtin_arm_ssat + + +/** + \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 + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \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 + */ +__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; +} + +/** + \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 + */ +__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 /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_compiler.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_compiler.h new file mode 100644 index 0000000000..94212eb87a --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_compiler.h @@ -0,0 +1,266 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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 __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_gcc.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_gcc.h new file mode 100644 index 0000000000..5d0f07e8ac --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_gcc.h @@ -0,0 +1,2088 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.3 + * @date 16. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM 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 __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #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" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #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" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #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" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + +#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \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) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \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; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + 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) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \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 + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \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. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + 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 */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \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 + */ +__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; +} + +/** + \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 + */ +__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 /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_iccarm.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_iccarm.h new file mode 100644 index 0000000000..edcaee3d4a --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_iccarm.h @@ -0,0 +1,913 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.5 + * @date 10. January 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT restrict +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE 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; + } + + __STATIC_INLINE 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 + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_version.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_version.h new file mode 100644 index 0000000000..660f612aa3 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_armv8mbl.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_armv8mbl.h new file mode 100644 index 0000000000..47a39893ac --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_armv8mbl.h @@ -0,0 +1,1896 @@ +/**************************************************************************//** + * @file core_armv8mbl.h + * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MBL_H_GENERIC +#define __CORE_ARMV8MBL_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MBL + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M ( 2U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MBL_H_DEPENDANT +#define __CORE_ARMV8MBL_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MBL_REV + #define __ARMv8MBL_REV 0x0000U + #warning "__ARMv8MBL_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MBL */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Armv8-M Baseline */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Armv8-M Baseline */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_armv8mml.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_armv8mml.h new file mode 100644 index 0000000000..0951a1f781 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_armv8mml.h @@ -0,0 +1,2960 @@ +/**************************************************************************//** + * @file core_armv8mml.h + * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MML_H_GENERIC +#define __CORE_ARMV8MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS Armv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MML_H_DEPENDANT +#define __CORE_ARMV8MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MML_REV + #define __ARMv8MML_REV 0x0000U + #warning "__ARMv8MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm0.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm0.h new file mode 100644 index 0000000000..a3f1b9ac33 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm0.h @@ -0,0 +1,888 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.3 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M0 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M0 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm0plus.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm0plus.h new file mode 100644 index 0000000000..f8f30c3496 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm0plus.h @@ -0,0 +1,1023 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M0+ */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M0+ */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; + +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm23.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm23.h new file mode 100644 index 0000000000..7d1d478af2 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm23.h @@ -0,0 +1,1899 @@ +/**************************************************************************//** + * @file core_cm23.h + * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM23_H_GENERIC +#define __CORE_CM23_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M23 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ + __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (23U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM23_H_DEPENDANT +#define __CORE_CM23_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM23_REV + #define __CM23_REV 0x0000U + #warning "__CM23_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M23 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< @Deprecated TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< @Deprecated TPI ACPR: PRESCALER Mask */ + +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M23 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm3.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm3.h new file mode 100644 index 0000000000..a2c0d08057 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm3.h @@ -0,0 +1,1933 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V5.0.5 + * @date 08. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (3U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< @Deprecated TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< @Deprecated TPI ACPR: PRESCALER Mask */ + +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm33.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm33.h new file mode 100644 index 0000000000..b1efbcae7c --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm33.h @@ -0,0 +1,2963 @@ +/**************************************************************************//** + * @file core_cm33.h + * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File + * @version V5.0.5 + * @date 08. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM33_H_GENERIC +#define __CORE_CM33_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M33 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM33 definitions */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (33U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_PCS_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM33_H_DEPENDANT +#define __CORE_CM33_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM33_REV + #define __CM33_REV 0x0000U + #warning "__CM33_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M33 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< @Deprecated TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< @Deprecated TPI ACPR: PRESCALER Mask */ + +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm4.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000000..a11a3817a2 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm4.h @@ -0,0 +1,2118 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.0.5 + * @date 08. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< @Deprecated TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< @Deprecated TPI ACPR: PRESCALER Mask */ + +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm7.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm7.h new file mode 100644 index 0000000000..1fe53bf012 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_cm7.h @@ -0,0 +1,2660 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.0.5 + * @date 08. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< @Deprecated TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< @Deprecated TPI ACPR: PRESCALER Mask */ + +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_INLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + register uint32_t ccsidr; + register uint32_t sets; + register uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_INLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_INLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_INLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_sc000.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_sc000.h new file mode 100644 index 0000000000..9aab5e5b3e --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_sc000.h @@ -0,0 +1,1016 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V5.0.3 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for SC000 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for SC000 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_sc300.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_sc300.h new file mode 100644 index 0000000000..a569ef2ace --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/core_sc300.h @@ -0,0 +1,1903 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V5.0.3 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC3000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + uint32_t RESERVED1[1U]; +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \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. + \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 CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/mpu_armv7.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/mpu_armv7.h new file mode 100644 index 0000000000..aa180c9e59 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/mpu_armv7.h @@ -0,0 +1,197 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) + +#define ARM_MPU_AP_NONE 0U +#define ARM_MPU_AP_PRIV 1U +#define ARM_MPU_AP_URO 2U +#define ARM_MPU_AP_FULL 3U +#define ARM_MPU_AP_PRO 5U +#define ARM_MPU_AP_RO 6U + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size ) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (MPU_RASR_ENABLE_Msk)) + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/mpu_armv8.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/mpu_armv8.h new file mode 100644 index 0000000000..0ccfc74fe5 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/mpu_armv8.h @@ -0,0 +1,333 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + ((BASE & MPU_RBAR_BASE_Pos) | \ + ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/Include/tz_context.h b/bsp/essemi/es32f0271/libraries/CMSIS/Include/tz_context.h new file mode 100644 index 0000000000..0d09749f3a --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/Include/tz_context.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * @file tz_context.h + * @brief Context Management for Armv8-M TrustZone + * @version V1.0.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef TZ_CONTEXT_H +#define TZ_CONTEXT_H + +#include + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + +/// \details TZ Memory ID identifies an allocated memory slot. +typedef uint32_t TZ_MemoryId_t; + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +uint32_t TZ_InitContextSystem_S (void); + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); + +#endif // TZ_CONTEXT_H diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/RTOS/Template/cmsis_os.h b/bsp/essemi/es32f0271/libraries/CMSIS/RTOS/Template/cmsis_os.h new file mode 100644 index 0000000000..02930af3e6 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/RTOS/Template/cmsis_os.h @@ -0,0 +1,707 @@ +/* ---------------------------------------------------------------------- + * $Date: 5. February 2013 + * $Revision: V1.02 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h template header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * Version 1.02 + * Control functions for short timeouts in microsecond resolution: + * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec + * Removed: osSignalGet + *---------------------------------------------------------------------------- + * + * Copyright (c) 2013 ARM LIMITED + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + + +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_KERNEL 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "KERNEL V1.00" ///< RTOS identification string + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 8 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 1 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; + +/// Entry point of a thread. +/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. +typedef void (*os_ptimer) (void const *argument); + +// >>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_cb *osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_cb *osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_cb *osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_cb *osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_cb *osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + uint32_t dummy; ///< dummy value. +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + uint32_t dummy; ///< dummy value. +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation. +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue. +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for mail +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +int32_t osKernelRunning(void); + +#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available + +/// Get the RTOS kernel system timer counter +/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS. +/// \return RTOS kernel system timer as 32-bit value +uint32_t osKernelSysTick (void); + +/// The RTOS kernel system timer frequency in Hz +/// \note Reflects the system timer setting and is typically defined in a configuration file. +#define osKernelSysTickFrequency 100000000 + +/// Convert a microseconds value to a RTOS kernel system timer value. +/// \param microsec time value in microseconds. +/// \return time value normalized to the \ref osKernelSysTickFrequency +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) + +#endif // System Timer available + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz) } +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name +#else // define the object +#define osTimerDef(name, function) \ +const osTimerDef_t os_timer_def_##name = \ +{ (function) } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +const osMutexDef_t os_mutex_def_##name = { 0 } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +const osSemaphoreDef_t os_semaphore_def_##name = { 0 } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), NULL } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), sizeof (type) } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern const osMailQDef_t os_mailQ_def_##name +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof (type) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + + +#ifdef __cplusplus +} +#endif + +#endif // _CMSIS_OS_H diff --git a/bsp/essemi/es32f0271/libraries/CMSIS/index.html b/bsp/essemi/es32f0271/libraries/CMSIS/index.html new file mode 100644 index 0000000000..c6da0802b4 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/CMSIS/index.html @@ -0,0 +1,14 @@ + + + +Redirect to the CMSIS main page after 0 seconds + + + + + + +If the automatic redirection is failing, click open CMSIS Documentation. + + + diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_ad16c4t.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_ad16c4t.h new file mode 100644 index 0000000000..672719a20b --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_ad16c4t.h @@ -0,0 +1,4484 @@ +/** + ************************************************************************************** + * @file md_AD16C4T.h + * @brief ES32F0271 Header file of MD AD16C4T module. + * + * @version V0.01 + * @date 3/12/2018 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. AMD rights reserved. + * + ************************************************************************************** + */ + /* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_AD16C4T_H__ +#define __MD_AD16C4T_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/* Includes -------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_ad16c4t.h" + + +/** @addtogroup Micro_Driver + * @{ + */ +#if defined (AD16C4T1) + +/** @defgroup AD16C4T AD16C4T + * @brief AD16C4T module driver + * @{ + */ + + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private Macros ----------------------------------------------------------*/ + + + +/* Public Constants -----------------------------------------------------------*/ + +/** @defgroup MD_AD16C4T_Public_Constants Public Constants + * @brief AD16C4T module driver + * @{ + */ +/* AD16C4T_CON1 macros define*/ +#define MD_AD16C4T_DEBUGSELECT_INPUT (0 << AD16C4T_CON1_DBGSEL_POS) /*!< Channel input*/ +#define MD_AD16C4T_DEBUGSELECT_OUTPUT (1 << AD16C4T_CON1_DBGSEL_POS) /*!< Channel output*/ + +#define MD_AD16C4T_COMPAREINPUT_DISABLE (0 << AD16C4T_CON1_CMPSEL_POSS) /*!< Compare input is disabled*/ +#define MD_AD16C4T_COMPAREINPUT_0 (1 << AD16C4T_CON1_CMPSEL_POSS) /*!< Compare input(CMP_IN)=Compare output 0*/ +#define MD_AD16C4T_COMPAREINPUT_1 (2 << AD16C4T_CON1_CMPSEL_POSS) /*!< Compare input(CMP_IN)=Compare output 1*/ +#define MD_AD16C4T_COMPAREINPUT_2 (3 << AD16C4T_CON1_CMPSEL_POSS) /*!< Compare input(CMP_IN)=Compare output 2*/ +#define MD_AD16C4T_COMPAREINPUT_3 (4 << AD16C4T_CON1_CMPSEL_POSS) /*!< Compare input(CMP_IN)=Compare output 3*/ + +#define MD_AD16C4T_COMPAREPOLARITY_LOW (0 << AD16C4T_CON1_CMPSELP_POS) /*!< Compare input is active low*/ +#define MD_AD16C4T_COMPAREPOLARITY_HIGH (1 << AD16C4T_CON1_CMPSELP_POS) /*!< Compare input is active high*/ + +#define MD_AD16C4T_CLOCKDIVSION_DIV1 (0 << AD16C4T_CON1_DFCKSEL_POSS) /*!< tDTS=tCK_INT*/ +#define MD_AD16C4T_CLOCKDIVSION_DIV2 (1 << AD16C4T_CON1_DFCKSEL_POSS) /*!< tDTS=2*tCK_INT*/ +#define MD_AD16C4T_CLOCKDIVSION_DIV4 (2 << AD16C4T_CON1_DFCKSEL_POSS) /*!< tDTS=4*tCK_INT*/ + +#define MD_AD16C4T_CENTERALIGNED_DISABLE (0 << AD16C4T_CON1_CMSEL_POSS) /*!< Edge-aligned mode*/ +#define MD_AD16C4T_CENTERALIGNED_DOWN (1 << AD16C4T_CON1_CMSEL_POSS) /*!< Center-aligned mode 1*/ +#define MD_AD16C4T_CENTERALIGNED_UP (2 << AD16C4T_CON1_CMSEL_POSS) /*!< Center-aligned mode 2*/ +#define MD_AD16C4T_CENTERALIGNED_BOTH (3 << AD16C4T_CON1_CMSEL_POSS) /*!< Center-aligned mode 3*/ + +#define MD_AD16C4T_UPCOUNTER (0 << AD16C4T_CON1_DIRSEL_POS) /*!< Counter used as upcounter*/ +#define MD_AD16C4T_DOWNCOUNTER (1 << AD16C4T_CON1_DIRSEL_POS) /*!< Counter used as downcounter*/ + +#define MD_AD16C4T_ONEPULSEMODE_DISABLE (0 << AD16C4T_CON1_SPMEN_POS) /*!< Counter is not stopped at update event*/ +#define MD_AD16C4T_ONEPULSEMODE_ENABLE (1 << AD16C4T_CON1_SPMEN_POS) /*!< Counter stops counting at the next update event*/ + +#define MD_AD16C4T_UPDATESOURCE_NORMAL (0 << AD16C4T_CON1_UERSEL_POS) /*!< Counter overflow/underflow, Setting the UG bit, Update generation through the slave mode controller generate an update interrupt*/ +#define MD_AD16C4T_UPDATESOURCE_COUNTER (1 << AD16C4T_CON1_UERSEL_POS) /*!< Only counter overflow/underflow generates an update interrupt or DMA request if Enabled*/ + +/* AD16C4T_CON2 macros define*/ +#define MD_AD16C4T_IDLEOUTPUT_LOW 0 /*!< OC1=0 (after a dead-time if OC1N is implemented) when MOE=0*/ +#define MD_AD16C4T_IDLEOUTPUT_HIGH 1 /*!< OC1=1 (after a dead-time if OC1N is implemented) when MOE=0*/ + +#define MD_AD16C4T_TI1INPUT_CH1 (0 << AD16C4T_CON2_I1SEL_POS) /*!< The TIMx_CH1 pin is connected to TI1 input*/ +#define MD_AD16C4T_TI1INPUT_XOR (1 << AD16C4T_CON2_I1SEL_POS) /*!< The TIMx_CH1, CH2 and CH3 pins are connected to the TI1 input (XOR combination)*/ + +#define MD_AD16C4T_MASTERMODE_RESET (0 << AD16C4T_CON2_MMSEL_POSS) /*!< Reset mode*/ +#define MD_AD16C4T_MASTERMODE_ENABLE (1 << AD16C4T_CON2_MMSEL_POSS) /*!< Enable mode*/ +#define MD_AD16C4T_MASTERMODE_UPDATE (2 << AD16C4T_CON2_MMSEL_POSS) /*!< Update mode*/ +#define MD_AD16C4T_MASTERMODE_COMPAREPULSE (3 << AD16C4T_CON2_MMSEL_POSS) /*!< Compare Pulse mode*/ +#define MD_AD16C4T_MASTERMODE_COMPARE1 (4 << AD16C4T_CON2_MMSEL_POSS) /*!< Compare 1 mode*/ +#define MD_AD16C4T_MASTERMODE_COMPARE2 (5 << AD16C4T_CON2_MMSEL_POSS) /*!< Compare 2 mode*/ +#define MD_AD16C4T_MASTERMODE_COMPARE3 (6 << AD16C4T_CON2_MMSEL_POSS) /*!< Compare 3 mode*/ +#define MD_AD16C4T_MASTERMODE_COMPARE4 (7 << AD16C4T_CON2_MMSEL_POSS) /*!< Compare 4 mode*/ + +#define MD_AD16C4T_DMASELECTION_COMPARE (0 << AD16C4T_CON2_CCDMASEL_POS) /*!< CCx DMA request sent when CCx event occurs*/ +#define MD_AD16C4T_DMASELECTION_UPDATE (1 << AD16C4T_CON2_CCDMASEL_POS) /*!< CCx DMA requests sent when update event occurs*/ + +#define MD_AD16C4T_UPDATESELECTION_COMG (0 << AD16C4T_CON2_CCUSEL_POS) /*!< When capture/compare control bits are preloaded (CCPC=1), they are updated by setting the COMG bit only*/ +#define MD_AD16C4T_UPDATESELECTION_BOTH (1 << AD16C4T_CON2_CCUSEL_POS) /*!< When capture/compare control bits are preloaded (CCPC=1), they are updated by setting the COMG bit or when an rising edge occurs on TRGI*/ + +#define MD_AD16C4T_CCPRELOAD_DISABLE (0 << AD16C4T_CON2_CCPCEN_POS) /*!< CCxE, CCxNE and OCxM bits are not preloaded*/ +#define MD_AD16C4T_CCPRELOAD_ENABLE (1 << AD16C4T_CON2_CCPCEN_POS) /*!< CCxE, CCxNE and OCxM bits are preloaded*/ + +/* AD16C4T_SMCON macros define*/ +#define MD_AD16C4T_ETRPOLARITY_NONINVERTED (0 << AD16C4T_SMCON_ETPOL_POS) /*!< ETR is non-inverted*/ +#define MD_AD16C4T_ETRPOLARITY_INVERTED (1 << AD16C4T_SMCON_ETPOL_POS) /*!< ETR is inverted*/ + +#define MD_AD16C4T_ETRFILTER_FDIV1 (0 << AD16C4T_SMCON_ETFLT_POSS) /*!< No filter*/ +#define MD_AD16C4T_ETRFILTER_FDIV1N2 (1 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fCK_INT, N = 2*/ +#define MD_AD16C4T_ETRFILTER_FDIV1N4 (2 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fCK_INT, N = 4*/ +#define MD_AD16C4T_ETRFILTER_FDIV1N8 (3 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fCK_INT, N = 8*/ +#define MD_AD16C4T_ETRFILTER_FDIV2N6 (4 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 2, N = 6*/ +#define MD_AD16C4T_ETRFILTER_FDIV2N8 (5 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 2, N = 8*/ +#define MD_AD16C4T_ETRFILTER_FDIV4N6 (6 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 4, N = 6*/ +#define MD_AD16C4T_ETRFILTER_FDIV4N8 (7 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 4, N = 8*/ +#define MD_AD16C4T_ETRFILTER_FDIV8N6 (8 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 8, N = 6*/ +#define MD_AD16C4T_ETRFILTER_FDIV8N8 (9 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 8, N = 8*/ +#define MD_AD16C4T_ETRFILTER_FDIV16N5 (10 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 16, N = 5*/ +#define MD_AD16C4T_ETRFILTER_FDIV16N6 (11 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 16, N = 6*/ +#define MD_AD16C4T_ETRFILTER_FDIV16N8 (12 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 16, N = 8*/ +#define MD_AD16C4T_ETRFILTER_FDIV32N5 (13 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 32, N = 5*/ +#define MD_AD16C4T_ETRFILTER_FDIV32N6 (14 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 32, N = 6*/ +#define MD_AD16C4T_ETRFILTER_FDIV32N8 (15 << AD16C4T_SMCON_ETFLT_POSS) /*!< fSAMPLING = fDTS / 32, N = 8*/ + +#define MD_AD16C4T_MASTERSLAVE_NODELAY (0 << AD16C4T_SMCON_MSCFG_POS) /*!< No action*/ +#define MD_AD16C4T_MASTERSLAVE_DELAY (1 << AD16C4T_SMCON_MSCFG_POS) /*!< The effect of an event on the trigger input (TRGI) is delayed to allow a perfect*/ + +#define MD_AD16C4T_TRIGGERSELECT_ITR0 (0 << AD16C4T_SMCON_TSSEL_POSS) /*!< Internal Trigger 0*/ +#define MD_AD16C4T_TRIGGERSELECT_ITR1 (1 << AD16C4T_SMCON_TSSEL_POSS) /*!< Internal Trigger 1*/ +#define MD_AD16C4T_TRIGGERSELECT_ITR2 (2 << AD16C4T_SMCON_TSSEL_POSS) /*!< Internal Trigger 2*/ +#define MD_AD16C4T_TRIGGERSELECT_ITR3 (3 << AD16C4T_SMCON_TSSEL_POSS) /*!< Internal Trigger 3*/ +#define MD_AD16C4T_TRIGGERSELECT_TI1FED (4 << AD16C4T_SMCON_TSSEL_POSS) /*!< TI1 Edge Detector*/ +#define MD_AD16C4T_TRIGGERSELECT_TI1FP1 (5 << AD16C4T_SMCON_TSSEL_POSS) /*!< Filtered Timer Input 1*/ +#define MD_AD16C4T_TRIGGERSELECT_TI2FP2 (6 << AD16C4T_SMCON_TSSEL_POSS) /*!< Filtered Timer Input 2*/ +#define MD_AD16C4T_TRIGGERSELECT_ETRF (7 << AD16C4T_SMCON_TSSEL_POSS) /*!< External Trigger input*/ + +#define MD_AD16C4T_OCREFCLEAR_CMP (0 << AD16C4T_SMCON_CHCSEL_POS) /*!< OCREF_CLR is connected to the CMP_IN input*/ +#define MD_AD16C4T_OCREFCLEAR_ETRF (1 << AD16C4T_SMCON_CHCSEL_POS) /*!< OCREF_CLR is connected to ETRF*/ + +#define MD_AD16C4T_SLAVEMODE_DISABLE (0 << AD16C4T_SMCON_SMODS_POSS) /*!< Slave mode disabled*/ +#define MD_AD16C4T_SLAVEMODE_ENCODER1 (1 << AD16C4T_SMCON_SMODS_POSS) /*!< Encoder mode 1*/ +#define MD_AD16C4T_SLAVEMODE_ENCODER2 (2 << AD16C4T_SMCON_SMODS_POSS) /*!< Encoder mode 2*/ +#define MD_AD16C4T_SLAVEMODE_ENCODER3 (3 << AD16C4T_SMCON_SMODS_POSS) /*!< Encoder mode 3*/ +#define MD_AD16C4T_SLAVEMODE_RESET (4 << AD16C4T_SMCON_SMODS_POSS) /*!< Reset Mode*/ +#define MD_AD16C4T_SLAVEMODE_GATED (5 << AD16C4T_SMCON_SMODS_POSS) /*!< Gated Mode*/ +#define MD_AD16C4T_SLAVEMODE_TRIGGER (6 << AD16C4T_SMCON_SMODS_POSS) /*!< Trigger Mode*/ +#define MD_AD16C4T_SLAVEMODE_EXTERNALCLOCK (7 << AD16C4T_SMCON_SMODS_POSS) /*!< External Clock Mode 1*/ + +/* AD16C4T_IER IDR IVS RIF IFM ICR macros define*/ +#define MD_AD16C4T_INTERRUPTFALG_CC4OI (1 << AD16C4T_IER_CH4OVI_POS) /*!< Capture/Compare 4 overcapture interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_CC3OI (1 << AD16C4T_IER_CH3OVI_POS) /*!< Capture/Compare 3 overcapture interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_CC2OI (1 << AD16C4T_IER_CH2OVI_POS) /*!< Capture/Compare 2 overcapture interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_CC1OI (1 << AD16C4T_IER_CH1OVI_POS) /*!< Capture/Compare 1 overcapture interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_BI (1 << AD16C4T_IER_BRKI_POS) /*!< Break interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_TI (1 << AD16C4T_IER_TRGI_POS) /*!< Trigger interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_COMI (1 << AD16C4T_IER_COMI_POS) /*!< COM interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_CC4I (1 << AD16C4T_IER_CH4I_POS) /*!< Capture/Compare 4 interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_CC3I (1 << AD16C4T_IER_CH3I_POS) /*!< Capture/Compare 3 interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_CC2I (1 << AD16C4T_IER_CH2I_POS) /*!< Capture/Compare 2 interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_CC1I (1 << AD16C4T_IER_CH1I_POS) /*!< Capture/Compare 1 interrupt*/ +#define MD_AD16C4T_INTERRUPTFALG_UI (1 << AD16C4T_IER_UI_POS) /*!< Update interrupt*/ + +/* AD16C4T_SGE macros define*/ +#define MD_AD16C4T_EVENTGENERATION_BG (1 << AD16C4T_SGE_SGBRK_POS) /*!< Break generation*/ +#define MD_AD16C4T_EVENTGENERATION_TG (1 << AD16C4T_SGE_SGTRG_POS) /*!< Trigger generation*/ +#define MD_AD16C4T_EVENTGENERATION_COMG (1 << AD16C4T_SGE_SGCOM_POS) /*!< Capture/Compare control update generation*/ +#define MD_AD16C4T_EVENTGENERATION_CC4G (1 << AD16C4T_SGE_SGCH4_POS) /*!< Capture/Compare 4 generation*/ +#define MD_AD16C4T_EVENTGENERATION_CC3G (1 << AD16C4T_SGE_SGCH3_POS) /*!< Capture/Compare 3 generation*/ +#define MD_AD16C4T_EVENTGENERATION_CC2G (1 << AD16C4T_SGE_SGCH2_POS) /*!< Capture/Compare 2 generation*/ +#define MD_AD16C4T_EVENTGENERATION_CC1G (1 << AD16C4T_SGE_SGCH1_POS) /*!< Capture/Compare 1 generation*/ +#define MD_AD16C4T_EVENTGENERATION_UG (1 << AD16C4T_SGE_SGU_POS) /*!< Update generation*/ + +/* AD16C4T_CHMR1 CHMR2 output macros define*/ +#define MD_AD16C4T_OUTPUTMODE_DISABLE 0 /*!< Frozen*/ +#define MD_AD16C4T_OUTPUTMODE_HIGHONMSTCH 1 /*!< Set channel 1 to active level on match*/ +#define MD_AD16C4T_OUTPUTMODE_LOWONMSTCH 2 /*!< Set channel 1 to inactive level on match*/ +#define MD_AD16C4T_OUTPUTMODE_TOGGLE 3 /*!< Toggle*/ +#define MD_AD16C4T_OUTPUTMODE_FORCELOW 4 /*!< Force inactive level*/ +#define MD_AD16C4T_OUTPUTMODE_FORCEHIGH 5 /*!< Force active level*/ +#define MD_AD16C4T_OUTPUTMODE_PWMMODE1 6 /*!< PWM mode 1*/ +#define MD_AD16C4T_OUTPUTMODE_PWMMODE2 7 /*!< PWM mode 2*/ + +#define MD_AD16C4T_CHMODE_OUTPUT 0 /*!< CCx channel is configured as output*/ +#define MD_AD16C4T_CHMODE_INPUT_DIRECT 1 /*!< CCx channel is configured as input, ICx is mapped direct*/ +#define MD_AD16C4T_CHMODE_INPUT_INDIRECT 2 /*!< CCx channel is configured as input, ICx is mapped indirect*/ +#define MD_AD16C4T_CHMODE_INPUT_TRC 3 /*!< CCx channel is configured as input, ICx is mapped TRC*/ + +/* AD16C4T_CHMR1 CHMR2 input macros define*/ +#define MD_AD16C4T_INPUTFILTER_FDIV1 0 /*!< No filter*/ +#define MD_AD16C4T_INPUTFILTER_FDIV1N2 1 /*!< fSAMPLING = fCK_INT, N = 2*/ +#define MD_AD16C4T_INPUTFILTER_FDIV1N4 2 /*!< fSAMPLING = fCK_INT, N = 4*/ +#define MD_AD16C4T_INPUTFILTER_FDIV1N8 3 /*!< fSAMPLING = fCK_INT, N = 8*/ +#define MD_AD16C4T_INPUTFILTER_FDIV2N6 4 /*!< fSAMPLING = fDTS / 2, N = 6*/ +#define MD_AD16C4T_INPUTFILTER_FDIV2N8 5 /*!< fSAMPLING = fDTS / 2, N = 8*/ +#define MD_AD16C4T_INPUTFILTER_FDIV4N6 6 /*!< fSAMPLING = fDTS / 4, N = 6*/ +#define MD_AD16C4T_INPUTFILTER_FDIV4N8 7 /*!< fSAMPLING = fDTS / 4, N = 8*/ +#define MD_AD16C4T_INPUTFILTER_FDIV8N6 8 /*!< fSAMPLING = fDTS / 8, N = 6*/ +#define MD_AD16C4T_INPUTFILTER_FDIV8N8 9 /*!< fSAMPLING = fDTS / 8, N = 8*/ +#define MD_AD16C4T_INPUTFILTER_FDIV16N5 10 /*!< fSAMPLING = fDTS / 16, N = 5*/ +#define MD_AD16C4T_INPUTFILTER_FDIV16N6 11 /*!< fSAMPLING = fDTS / 16, N = 6*/ +#define MD_AD16C4T_INPUTFILTER_FDIV16N8 12 /*!< fSAMPLING = fDTS / 16, N = 8*/ +#define MD_AD16C4T_INPUTFILTER_FDIV32N5 13 /*!< fSAMPLING = fDTS / 32, N = 5*/ +#define MD_AD16C4T_INPUTFILTER_FDIV32N6 14 /*!< fSAMPLING = fDTS / 32, N = 6*/ +#define MD_AD16C4T_INPUTFILTER_FDIV32N8 15 /*!< fSAMPLING = fDTS / 32, N = 8*/ + +#define MD_AD16C4T_INPUTPRESCALE_DIV1 0 /*!< no prescaler*/ +#define MD_AD16C4T_INPUTPRESCALE_DIV2 1 /*!< capture is done once every 2 events*/ +#define MD_AD16C4T_INPUTPRESCALE_DIV4 2 /*!< capture is done once every 4 events*/ +#define MD_AD16C4T_INPUTPRESCALE_DIV8 3 /*!< capture is done once every 8 events*/ + +/* AD16C4T_CCEP input macros define*/ +#define MD_AD16C4T_OUTPUTPOLARITY_HIGH 0 /*!< active high*/ +#define MD_AD16C4T_OUTPUTPOLARITY_LOW 1 /*!< active low*/ + +/* AD16C4T_BDCFG input macros define*/ +#define MD_AD16C4T_BREAKPOLARITY_LOW (0 << AD16C4T_BDCFG_BRKP_POS) /*!< Break input BRK is active low*/ +#define MD_AD16C4T_BREAKPOLARITY_HIGH (1 << AD16C4T_BDCFG_BRKP_POS) /*!< Break input BRK is active high */ + +#define MD_AD16C4T_OFFSTATERUN_DISABLE (0 << AD16C4T_BDCFG_OFFSSR_POS) /*!< This bit is used when MOE=1, when inactive, OC/OCN outputs are disabled*/ +#define MD_AD16C4T_OFFSTATERUN_ENABLE (1 << AD16C4T_BDCFG_OFFSSR_POS) /*!< This bit is used when MOE=1, when inactive, OC/OCN outputs are enabled*/ + +#define MD_AD16C4T_OFFSTATEIDLE_DISABLE (0 << AD16C4T_BDCFG_OFFSSI_POS) /*!< This bit is used when MOE=0, when inactive, OC/OCN outputs are disabled*/ +#define MD_AD16C4T_OFFSTATEIDLE_ENABLE (1 << AD16C4T_BDCFG_OFFSSI_POS) /*!< This bit is used when MOE=0, when inactive, OC/OCN outputs are forced*/ + +#define MD_AD16C4T_LOCKLEVEL_0 (0 << AD16C4T_BDCFG_LOCKLVL_POSS) /*!< LOCK OFF*/ +#define MD_AD16C4T_LOCKLEVEL_1 (1 << AD16C4T_BDCFG_LOCKLVL_POSS) /*!< LOCK Level 1*/ +#define MD_AD16C4T_LOCKLEVEL_2 (2 << AD16C4T_BDCFG_LOCKLVL_POSS) /*!< LOCK Level 2*/ +#define MD_AD16C4T_LOCKLEVEL_3 (3 << AD16C4T_BDCFG_LOCKLVL_POSS) /*!< LOCK Level 3*/ + +/** + * @} MD_AD16C4T_Public_Constants + */ + +/* Public Macro ------------------------------------------------------------*/ +/** @defgroup MD_AD16C4T_Public_Macro Public Macro + * @brief AD16C4T module driver + * @{ + */ + +/** + * @brief Timer CON1 setup. + * @param timx AD16C4T instance + * @param value (DBGSEL | CMPSEL | CMPSELP | DFCKSEL | ARPEN | CMSEL | DIRSEL | SPMEN | UERSEL | DISUE | CNTEN) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con1(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CON1, value); +} + +/** + * @brief GET Timer CON1 register value. + * @param timx AD16C4T instance + * @retval Timer CON1 register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con1(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CON1)); +} + +/** + * @brief Timer debug mode select. + * @param timx AD16C4T instance + * @param DebugSelect Debug mode output select + @arg @ref MD_AD16C4T_DEBUGSELECT_INPUT + @arg @ref MD_AD16C4T_DEBUGSELECT_OUTPUT + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con1_dbgsel(AD16C4T_TypeDef *timx, uint32_t DebugSelect) +{ + MODIFY_REG(timx->CON1, AD16C4T_CON1_DBGSEL_MSK, DebugSelect); +} + +/** + * @brief Get timer debug mode select. + * @param timx AD16C4T instance + * @retval Timer debug mode select. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con1_dbgsel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_DBGSEL_MSK) >> AD16C4T_CON1_DBGSEL_POS); +} + +/** + * @brief Timer compare input selection. + * @param timx AD16C4T instance + * @param CompareSelection Compare input selection + @arg @ref MD_AD16C4T_COMPAREINPUT_DISABLE + @arg @ref MD_AD16C4T_COMPAREINPUT_0 + @arg @ref MD_AD16C4T_COMPAREINPUT_1 + @arg @ref MD_AD16C4T_COMPAREINPUT_2 + @arg @ref MD_AD16C4T_COMPAREINPUT_3 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con1_cmpsel(AD16C4T_TypeDef *timx, uint32_t CompareSelection) +{ + MODIFY_REG(timx->CON1, AD16C4T_CON1_CMPSEL_MSK, CompareSelection); +} + +/** + * @brief Get timer compare input selection. + * @param timx AD16C4T instance + * @retval Timer compare input selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con1_cmpsel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_CMPSEL_MSK) >> AD16C4T_CON1_CMPSEL_POSS); +} + +/** + * @brief Timer compare input selection polarity setup. + * @param timx AD16C4T instance + * @param ComparePolarity compare input selection polarity + @arg @ref MD_AD16C4T_COMPAREPOLARITY_LOW + @arg @ref MD_AD16C4T_COMPAREPOLARITY_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con1_cmpselp(AD16C4T_TypeDef *timx, uint32_t ComparePolarity) +{ + MODIFY_REG(timx->CON1, AD16C4T_CON1_CMPSELP_MSK, ComparePolarity); +} + +/** + * @brief Get timer compare input selection polarity. + * @param timx AD16C4T instance + * @retval Timer compare input selection polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con1_cmpselp(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_CMPSELP_MSK) >> AD16C4T_CON1_CMPSELP_POS); +} + +/** + * @brief Timer clock division setup. + * @param timx AD16C4T instance + * @param ClockDivision Clock division + @arg @ref MD_AD16C4T_CLOCKDIVSION_DIV1 + @arg @ref MD_AD16C4T_CLOCKDIVSION_DIV2 + @arg @ref MD_AD16C4T_CLOCKDIVSION_DIV4 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con1_dfcksel(AD16C4T_TypeDef *timx, uint32_t ClockDivision) +{ + MODIFY_REG(timx->CON1, AD16C4T_CON1_DFCKSEL_MSK, ClockDivision); +} + +/** + * @brief Get timer Clock division. + * @param timx AD16C4T instance + * @retval Timer Clock division. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con1_dfcksel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_DFCKSEL_MSK) >> AD16C4T_CON1_DFCKSEL_POSS); +} + +/** + * @brief Timer auto-reload preload enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_con1_arpen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CON1, AD16C4T_CON1_ARPEN_MSK); +} + +/** + * @brief Timer auto-reload preload disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_con1_arpen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CON1, AD16C4T_CON1_ARPEN_MSK); +} + +/** + * @brief Indicates whether the timer auto-reload preload is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_con1_arpen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_ARPEN_MSK) == (AD16C4T_CON1_ARPEN_MSK)); +} + +/** + * @brief Timer center-aligned mode selection setup. + * @param timx AD16C4T instance + * @param CenterAlignedMode center-aligned mode selection + @arg @ref MD_AD16C4T_CENTERALIGNED_DISABLE + @arg @ref MD_AD16C4T_CENTERALIGNED_DOWN + @arg @ref MD_AD16C4T_CENTERALIGNED_UP + @arg @ref MD_AD16C4T_CENTERALIGNED_BOTH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con1_cmsel(AD16C4T_TypeDef *timx, uint32_t CenterAlignedMode) +{ + MODIFY_REG(timx->CON1, AD16C4T_CON1_CMSEL_MSK, CenterAlignedMode); +} + +/** + * @brief Get timer center-aligned mode selection. + * @param timx AD16C4T instance + * @retval Timer center-aligned mode selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con1_cmsel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_CMSEL_MSK) >> AD16C4T_CON1_CMSEL_POSS); +} + +/** + * @brief Timer counting direction setup. + * @param timx AD16C4T instance + * @param direction Counting direction + @arg @ref MD_AD16C4T_UPCOUNTER + @arg @ref MD_AD16C4T_DOWNCOUNTER + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con1_dirsel(AD16C4T_TypeDef *timx, uint32_t direction) +{ + MODIFY_REG(timx->CON1, AD16C4T_CON1_DIRSEL_MSK, direction); +} + +/** + * @brief Get timer counting direction. + * @param timx AD16C4T instance + * @retval Timer counting direction. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con1_dirsel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_DIRSEL_MSK) >> AD16C4T_CON1_DIRSEL_POS); +} + +/** + * @brief Timer one pulse mode enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_con1_spmen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CON1, AD16C4T_CON1_SPMEN_MSK); +} + +/** + * @brief Timer one pulse mode disable. + * @param timx AD16C4T instance + * @retval None. + */ + +__STATIC_INLINE void md_ad16c4t_disable_con1_spmen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CON1, AD16C4T_CON1_SPMEN_MSK); +} + +/** + * @brief Indicates whether the timer one pulse mode is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_con1_spmen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_SPMEN_MSK) == (AD16C4T_CON1_SPMEN_MSK)); +} + +/** + * @brief Timer update request source setup. + * @param timx AD16C4T instance + * @param UpdateSource Update request source select + @arg @ref MD_AD16C4T_UPDATESOURCE_NORMAL + @arg @ref MD_AD16C4T_UPDATESOURCE_COUNTER + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con1_uersel(AD16C4T_TypeDef *timx, uint32_t UpdateSource) +{ + MODIFY_REG(timx->CON1, AD16C4T_CON1_UERSEL_MSK, UpdateSource); +} + +/** + * @brief Get timer update request source. + * @param timx AD16C4T instance + * @retval Timer update request source. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con1_uersel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_UERSEL_MSK) >> AD16C4T_CON1_UERSEL_POS); +} + +/** + * @brief Timer update event enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_con1_disue(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CON1, AD16C4T_CON1_DISUE_MSK); +} + +/** + * @brief Timer update event disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disble_con1_disue(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CON1, AD16C4T_CON1_DISUE_MSK); +} + +/** + * @brief Indicates whether the timer update event is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_con1_disue(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_DISUE_MSK) == (AD16C4T_CON1_DISUE_MSK)); +} + +/** + * @brief Timer counter enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_con1_cnten(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CON1, AD16C4T_CON1_CNTEN_MSK); +} + + +/** + * @brief Timer counter disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_con1_cnten(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CON1, AD16C4T_CON1_CNTEN_MSK); +} + +/** + * @brief Indicates whether the timer counter is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_con1_cnten(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON1, AD16C4T_CON1_CNTEN_MSK) == (AD16C4T_CON1_CNTEN_MSK)); +} + +/** + * @brief Timer CON2 setup. + * @param timx AD16C4T instance + * @param value (OISS4 | OISS3N | OISS3 | OISS2N | OISS2 | OISS1N | OISS1 | I1SEL | MMSEL | CCDMASEL | CCUSEL | CCPCEN) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CON2, value); +} + +/** + * @brief GET Timer CON2 register value. + * @param timx AD16C4T instance + * @retval Timer CON2 register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CON2)); +} + +/** + * @brief Timer output idle state 4 setup. + * @param timx AD16C4T instance + * @param IdleOutput Output idle state + @arg @ref MD_AD16C4T_IDLEOUTPUT_LOW + @arg @ref MD_AD16C4T_IDLEOUTPUT_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_oiss4(AD16C4T_TypeDef *timx, uint32_t IdleOutput) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_OISS4_MSK, (IdleOutput << AD16C4T_CON2_OISS4_POS)); +} + +/** + * @brief Get timer output idle state 4. + * @param timx AD16C4T instance + * @retval Timer output idle state 4. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_oiss4(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_OISS4_MSK) >> AD16C4T_CON2_OISS4_POS); +} + +/** + * @brief Timer output idle state 3N setup. + * @param timx AD16C4T instance + * @param IdleOutput Output idle state + @arg @ref MD_AD16C4T_IDLEOUTPUT_LOW + @arg @ref MD_AD16C4T_IDLEOUTPUT_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_oiss3n(AD16C4T_TypeDef *timx, uint32_t IdleOutput) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_OISS3N_MSK, (IdleOutput << AD16C4T_CON2_OISS3N_POS)); +} + +/** + * @brief Get timer output idle state 3N. + * @param timx AD16C4T instance + * @retval Timer output idle state 3N. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_oiss3n(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_OISS3N_MSK) >> AD16C4T_CON2_OISS3N_POS); +} + +/** + * @brief Timer output idle state 3 setup. + * @param timx AD16C4T instance + * @param IdleOutput Output idle state + @arg @ref MD_AD16C4T_IDLEOUTPUT_LOW + @arg @ref MD_AD16C4T_IDLEOUTPUT_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_oiss3(AD16C4T_TypeDef *timx, uint32_t IdleOutput) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_OISS3_MSK, (IdleOutput << AD16C4T_CON2_OISS3_POS)); +} + +/** + * @brief Get timer output idle state 3. + * @param timx AD16C4T instance + * @retval Timer output idle state 3. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_oiss3(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_OISS3_MSK) >> AD16C4T_CON2_OISS3_POS); +} + +/** + * @brief Timer output idle state 2N setup. + * @param timx AD16C4T instance + * @param IdleOutput Output idle state + @arg @ref MD_AD16C4T_IDLEOUTPUT_LOW + @arg @ref MD_AD16C4T_IDLEOUTPUT_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_oiss2n(AD16C4T_TypeDef *timx, uint32_t IdleOutput) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_OISS2N_MSK, (IdleOutput << AD16C4T_CON2_OISS2N_POS)); +} + +/** + * @brief Get timer output idle state 2N. + * @param timx AD16C4T instance + * @retval Timer output idle state 2N. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_oiss2n(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_OISS2N_MSK) >> AD16C4T_CON2_OISS2N_POS); +} + +/** + * @brief Timer output idle state 2 setup. + * @param timx AD16C4T instance + * @param IdleOutput Output idle state + @arg @ref MD_AD16C4T_IDLEOUTPUT_LOW + @arg @ref MD_AD16C4T_IDLEOUTPUT_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_oiss2(AD16C4T_TypeDef *timx, uint32_t IdleOutput) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_OISS2_MSK, (IdleOutput << AD16C4T_CON2_OISS2_POS)); +} + +/** + * @brief Get timer output idle state 2. + * @param timx AD16C4T instance + * @retval Timer output idle state 2. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_oiss2(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_OISS2_MSK) >> AD16C4T_CON2_OISS2_POS); +} + +/** + * @brief Timer output idle state 1N setup. + * @param timx AD16C4T instance + * @param IdleOutput Output idle state + @arg @ref MD_AD16C4T_IDLEOUTPUT_LOW + @arg @ref MD_AD16C4T_IDLEOUTPUT_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_oiss1n(AD16C4T_TypeDef *timx, uint32_t IdleOutput) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_OISS1N_MSK, (IdleOutput << AD16C4T_CON2_OISS1N_POS)); +} + +/** + * @brief Get timer output idle state 1N. + * @param timx AD16C4T instance + * @retval Timer output idle state 1N. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_oiss1n(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_OISS1N_MSK) >> AD16C4T_CON2_OISS1N_POS); +} + +/** + * @brief Timer output idle state 1 setup. + * @param timx AD16C4T instance + * @param IdleOutput Output idle state + @arg @ref MD_AD16C4T_IDLEOUTPUT_LOW + @arg @ref MD_AD16C4T_IDLEOUTPUT_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_oiss1(AD16C4T_TypeDef *timx, uint32_t IdleOutput) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_OISS1_MSK, (IdleOutput << AD16C4T_CON2_OISS1_POS)); +} + +/** + * @brief Get timer output idle state 1. + * @param timx AD16C4T instance + * @retval Timer output idle state 1. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_oiss1(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_OISS1_MSK) >> AD16C4T_CON2_OISS1_POS); +} + +/** + * @brief Timer TI1 selection setup. + * @param timx AD16C4T instance + * @param TI1Input TI1 input select + @arg @ref MD_AD16C4T_TI1INPUT_CH1 + @arg @ref MD_AD16C4T_TI1INPUT_XOR + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_i1sel(AD16C4T_TypeDef *timx, uint32_t TI1Input) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_I1SEL_MSK, TI1Input); +} + +/** + * @brief Get timer TI1 selection. + * @param timx AD16C4T instance + * @retval Timer TI1 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_i1sel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_I1SEL_MSK) >> AD16C4T_CON2_I1SEL_POS); +} + +/** + * @brief Timer master mode selection setup. + * @param timx AD16C4T instance + * @param MasterMode Master mode selection + @arg @ref MD_AD16C4T_MASTERMODE_RESET + @arg @ref MD_AD16C4T_MASTERMODE_ENABLE + @arg @ref MD_AD16C4T_MASTERMODE_UPDATE + @arg @ref MD_AD16C4T_MASTERMODE_COMPAREPULSE + @arg @ref MD_AD16C4T_MASTERMODE_COMPARE1 + @arg @ref MD_AD16C4T_MASTERMODE_COMPARE2 + @arg @ref MD_AD16C4T_MASTERMODE_COMPARE3 + @arg @ref MD_AD16C4T_MASTERMODE_COMPARE4 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_mmsel(AD16C4T_TypeDef *timx, uint32_t MasterMode) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_MMSEL_MSK, MasterMode); +} + +/** + * @brief Get timer master mode selection. + * @param timx AD16C4T instance + * @retval Timer master mode selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_mmsel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_MMSEL_MSK) >> AD16C4T_CON2_MMSEL_POSS); +} + +/** + * @brief Timer capture/compare DMA selection setup. + * @param timx AD16C4T instance + * @param DMASelection Capture/compare DMA selection + @arg @ref MD_AD16C4T_DMASELECTION_COMPARE + @arg @ref MD_AD16C4T_DMASELECTION_UPDATE + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_ccdmasel(AD16C4T_TypeDef *timx, uint32_t DMASelection) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_CCDMASEL_MSK, DMASelection); +} + +/** + * @brief Get timer capture/compare DMA selection. + * @param timx AD16C4T instance + * @retval Timer capture/compare DMA selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_ccdmasel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_CCDMASEL_MSK) >> AD16C4T_CON2_CCDMASEL_POS); +} + +/** + * @brief Timer capture/compare control update selection setup. + * @param timx AD16C4T instance + * @param UpdateSelection Capture/compare control update selection + @arg @ref MD_AD16C4T_UPDATESELECTION_COMG + @arg @ref MD_AD16C4T_UPDATESELECTION_BOTH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_con2_ccusel(AD16C4T_TypeDef *timx, uint32_t UpdateSelection) +{ + MODIFY_REG(timx->CON2, AD16C4T_CON2_CCUSEL_MSK, UpdateSelection); +} + +/** + * @brief Get timer capture/compare control update selection. + * @param timx AD16C4T instance + * @retval Timer capture/compare control update selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_con2_ccusel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_CCUSEL_MSK) >> AD16C4T_CON2_CCUSEL_POS); +} + +/** + * @brief Timer capture/compare preloaded control enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_con2_ccpcen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CON2, AD16C4T_CON2_CCPCEN_MSK); +} + +/** + * @brief Timer capture/compare preloaded control disable. + * @param timx AD16C4T instance + * @retval None. + */ + +__STATIC_INLINE void md_ad16c4t_disable_con2_ccpcen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CON2, AD16C4T_CON2_CCPCEN_MSK); +} + +/** + * @brief Indicates whether the timer capture/compare preloaded control is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_con2_ccpcen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CON2, AD16C4T_CON2_CCPCEN_MSK) == (AD16C4T_CON2_CCPCEN_MSK)); +} + +/** + * @brief Timer SMCON setup. + * @param timx AD16C4T instance + * @param value (ETPOL | ECM2EN | ETFLT | MSCFG | TSSEL | CHCSEL | SMODS) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_smcon(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->SMCON, value); +} + +/** + * @brief GET Timer SMCON register value. + * @param timx AD16C4T instance + * @retval Timer SMCON register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_smcon(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->SMCON)); +} + +/** + * @brief Timer external trigger polarity setup. + * @param timx AD16C4T instance + * @param ETRPolarity External trigger polarity + @arg @ref MD_AD16C4T_ETRPOLARITY_NONINVERTED + @arg @ref MD_AD16C4T_ETRPOLARITY_INVERTED + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_smcon_etpol(AD16C4T_TypeDef *timx, uint32_t ETRPolarity) +{ + MODIFY_REG(timx->SMCON, AD16C4T_SMCON_ETPOL_MSK, ETRPolarity); +} + +/** + * @brief Get timer external trigger polarity. + * @param timx AD16C4T instance + * @retval Timer external trigger polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_smcon_etpol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->SMCON, AD16C4T_SMCON_ETPOL_MSK) >> AD16C4T_SMCON_ETPOL_POS); +} + +/** + * @brief Timer external clock enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_smcon_ecm2en(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SMCON, AD16C4T_SMCON_ECM2EN_MSK); +} + + +/** + * @brief Timer external clock disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_smcon_ecm2en(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->SMCON, AD16C4T_SMCON_ECM2EN_MSK); +} + +/** + * @brief Indicates whether the timer external clock is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_smcon_ecm2en(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->SMCON, AD16C4T_SMCON_ECM2EN_MSK) == (AD16C4T_SMCON_ECM2EN_MSK)); +} + +/** + * @brief Timer external trigger filter setup. + * @param timx AD16C4T instance + * @param ETRFilter External trigger filter + @arg @ref MD_AD16C4T_ETRFILTER_FDIV1 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV1N2 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV1N4 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV1N8 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV2N6 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV2N8 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV4N6 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV4N8 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV8N6 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV8N8 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV16N5 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV16N6 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV16N8 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV32N5 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV32N6 + @arg @ref MD_AD16C4T_ETRFILTER_FDIV32N8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_smcon_etflt(AD16C4T_TypeDef *timx, uint32_t ETRFilter) +{ + MODIFY_REG(timx->SMCON, AD16C4T_SMCON_ETFLT_MSK, ETRFilter); +} + +/** + * @brief Get timer external trigger filter. + * @param timx AD16C4T instance + * @retval Timer external trigger filter. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_smcon_etflt(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->SMCON, AD16C4T_SMCON_ETFLT_MSK) >> AD16C4T_SMCON_ETFLT_POSS); +} + +/** + * @brief Timer master/slave mode setup. + * @param timx AD16C4T instance + * @param MSMode master/slave mode + @arg @ref MD_AD16C4T_MASTERSLAVE_NODELAY + @arg @ref MD_AD16C4T_MASTERSLAVE_DELAY + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_smcon_mscfg(AD16C4T_TypeDef *timx, uint32_t MSMode) +{ + MODIFY_REG(timx->SMCON, AD16C4T_SMCON_MSCFG_MSK, MSMode); +} + +/** + * @brief Get timer master/slave mode. + * @param timx AD16C4T instance + * @retval Timer master/slave mode. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_smcon_mscfg(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->SMCON, AD16C4T_SMCON_MSCFG_MSK) >> AD16C4T_SMCON_MSCFG_POS); +} + +/** + * @brief Timer trigger selection setup. + * @param timx AD16C4T instance + * @param TriggerSelect Trigger selection + @arg @ref MD_AD16C4T_TRIGGERSELECT_ITR0 + @arg @ref MD_AD16C4T_TRIGGERSELECT_ITR1 + @arg @ref MD_AD16C4T_TRIGGERSELECT_ITR2 + @arg @ref MD_AD16C4T_TRIGGERSELECT_ITR3 + @arg @ref MD_AD16C4T_TRIGGERSELECT_TI1FED + @arg @ref MD_AD16C4T_TRIGGERSELECT_TI1FP1 + @arg @ref MD_AD16C4T_TRIGGERSELECT_TI2FP2 + @arg @ref MD_AD16C4T_TRIGGERSELECT_ETRF + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_smcon_tssel(AD16C4T_TypeDef *timx, uint32_t TriggerSelect) +{ + MODIFY_REG(timx->SMCON, AD16C4T_SMCON_TSSEL_MSK, TriggerSelect); +} + +/** + * @brief Get timer trigger selection. + * @param timx AD16C4T instance + * @retval Timer trigger selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_smcon_tssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->SMCON, AD16C4T_SMCON_TSSEL_MSK) >> AD16C4T_SMCON_TSSEL_POSS); +} + +/** + * @brief Timer OCREF clear selection setup. + * @param timx AD16C4T instance + * @param OCREFSelect OCREF clear selection + @arg @ref MD_AD16C4T_OCREFCLEAR_CMP + @arg @ref MD_AD16C4T_OCREFCLEAR_ETRF + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_smcon_chcsel(AD16C4T_TypeDef *timx, uint32_t OCREFSelect) +{ + MODIFY_REG(timx->SMCON, AD16C4T_SMCON_CHCSEL_MSK, OCREFSelect); +} + +/** + * @brief Get timer OCREF clear selection. + * @param timx AD16C4T instance + * @retval Timer OCREF clear selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_smcon_chcsel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->SMCON, AD16C4T_SMCON_CHCSEL_MSK) >> AD16C4T_SMCON_CHCSEL_POS); +} + +/** + * @brief Timer slave mode selection setup. + * @param timx AD16C4T instance + * @param SlaveMode Slave mode selection + @arg @ref MD_AD16C4T_SLAVEMODE_DISABLE + @arg @ref MD_AD16C4T_SLAVEMODE_ENCODER1 + @arg @ref MD_AD16C4T_SLAVEMODE_ENCODER2 + @arg @ref MD_AD16C4T_SLAVEMODE_ENCODER3 + @arg @ref MD_AD16C4T_SLAVEMODE_RESET + @arg @ref MD_AD16C4T_SLAVEMODE_GATED + @arg @ref MD_AD16C4T_SLAVEMODE_TRIGGER + @arg @ref MD_AD16C4T_SLAVEMODE_EXTERNALCLOCK + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_smcon_smods(AD16C4T_TypeDef *timx, uint32_t SlaveMode) +{ + MODIFY_REG(timx->SMCON, AD16C4T_SMCON_SMODS_MSK, SlaveMode); +} + +/** + * @brief Get timer slave mode selection. + * @param timx AD16C4T instance + * @retval Timer slave mode selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_smcon_smods(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->SMCON, AD16C4T_SMCON_SMODS_MSK) >> AD16C4T_SMCON_SMODS_POSS); +} + +/** + * @brief Timer IER setup. + * @param timx AD16C4T instance + * @param value (CH4OVI | CH3OVI | CH2OVI | CH1OVI | BRKI | TRGI | COMI | CH4I | CH3I | CH2I | CH1I | UI) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ier(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->IER, value); +} + +/** + * @brief Timer cpture/compare 4 overcapture interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ch4ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_CH4OVI_MSK); +} + +/** + * @brief Timer cpture/compare 3 overcapture interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ch3ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_CH3OVI_MSK); +} + +/** + * @brief Timer cpture/compare 2 overcapture interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ch2ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_CH2OVI_MSK); +} + +/** + * @brief Timer cpture/compare 1 overcapture interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ch1ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_CH1OVI_MSK); +} + +/** + * @brief Timer break interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_brki(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_BRKI_MSK); +} + +/** + * @brief Timer trigger interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_trgi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_TRGI_MSK); +} + +/** + * @brief Timer COM interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_comi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_COMI_MSK); +} + +/** + * @brief Timer capture/compare 4 interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ch4i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_CH4I_MSK); +} + +/** + * @brief Timer capture/compare 3 interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ch3i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_CH3I_MSK); +} + +/** + * @brief Timer capture/compare 2 interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ch2i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_CH2I_MSK); +} + +/** + * @brief Timer capture/compare 1 interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ch1i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_CH1I_MSK); +} + +/** + * @brief Timer update interrupt enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ier_ui(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IER, AD16C4T_IER_UI_MSK); +} + +/** + * @brief Timer IDR setup. + * @param timx AD16C4T instance + * @param value (CH4OVI | CH3OVI | CH2OVI | CH1OVI | BRKI | TRGI | COMI | CH4I | CH3I | CH2I | CH1I | UI) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_idr(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->IDR, value); +} + +/** + * @brief Timer cpture/compare 4 overcapture interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ch4ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_CH4OVI_MSK); +} + +/** + * @brief Timer cpture/compare 3 overcapture interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ch3ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_CH3OVI_MSK); +} + +/** + * @brief Timer cpture/compare 2 overcapture interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ch2ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_CH2OVI_MSK); +} + +/** + * @brief Timer cpture/compare 1 overcapture interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ch1ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_CH1OVI_MSK); +} + +/** + * @brief Timer break interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_brki(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_BRKI_MSK); +} + +/** + * @brief Timer trigger interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_trgi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_TRGI_MSK); +} + +/** + * @brief Timer COM interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_comi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_COMI_MSK); +} + +/** + * @brief Timer capture/compare 4 interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ch4i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_CH4I_MSK); +} + +/** + * @brief Timer capture/compare 3 interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ch3i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_CH3I_MSK); +} + +/** + * @brief Timer capture/compare 2 interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ch2i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_CH2I_MSK); +} + +/** + * @brief Timer capture/compare 1 interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ch1i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_CH1I_MSK); +} + +/** + * @brief Timer update interrupt disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_idr_ui(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->IDR, AD16C4T_IDR_UI_MSK); +} + +/** + * @brief Get timer IVS setup. + * @param timx AD16C4T instance + * @retval Timer IVS setup. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ivs(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->IVS)); +} + +/** + * @brief Indicates whether the timer capture/compare 4 overcapture interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ch4ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_CH4OVI_MSK) == (AD16C4T_IVS_CH4OVI_MSK)); +} + +/** + * @brief Indicates whether the timer capture/compare 3 overcapture interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ch3ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_CH3OVI_MSK) == (AD16C4T_IVS_CH3OVI_MSK)); +} + +/** + * @brief Indicates whether the timer cpture/compare 2 overcapture interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ch2ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_CH2OVI_MSK) == (AD16C4T_IVS_CH2OVI_MSK)); +} + +/** + * @brief Indicates whether the timer capture/compare 1 overcapture interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ch1ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_CH1OVI_MSK) == (AD16C4T_IVS_CH1OVI_MSK)); +} + +/** + * @brief Indicates whether the timer break interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_brki(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_BRKI_MSK) == (AD16C4T_IVS_BRKI_MSK)); +} + +/** + * @brief Indicates whether the timer trigger interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_trgi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_TRGI_MSK) == (AD16C4T_IVS_TRGI_MSK)); +} + +/** + * @brief Indicates whether the timer COM interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_comi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_COMI_MSK) == (AD16C4T_IVS_COMI_MSK)); +} + +/** + * @brief Indicates whether the timer Capture/Compare 4 interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ch4i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_CH4I_MSK) == (AD16C4T_IVS_CH4I_MSK)); +} + +/** + * @brief Indicates whether the timer Capture/Compare 3 interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ch3i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_CH3I_MSK) == (AD16C4T_IVS_CH3I_MSK)); +} + +/** + * @brief Indicates whether the timer Capture/Compare 2 interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ch2i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_CH2I_MSK) == (AD16C4T_IVS_CH2I_MSK)); +} + +/** + * @brief Indicates whether the timer Capture/Compare 1 interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ch1i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_CH1I_MSK) == (AD16C4T_IVS_CH1I_MSK)); +} + +/** + * @brief Indicates whether the timer update interrupt is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ivs_ui(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IVS, AD16C4T_IVS_UI_MSK) == (AD16C4T_IVS_UI_MSK)); +} + +/** + * @brief Get timer RIF flag. + * @param timx AD16C4T instance + * @retval Timer RIF flag. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_rif(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->RIF)); +} + +/** + * @brief Get timer capture/compare 4 overcapture interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ch4ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_CH4OVI_MSK) == (AD16C4T_RIF_CH4OVI_MSK)); +} + +/** + * @brief Get timer capture/compare 3 overcapture interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ch3ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_CH3OVI_MSK) == (AD16C4T_RIF_CH3OVI_MSK)); +} + +/** + * @brief Get timer capture/compare 2 overcapture interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ch2ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_CH2OVI_MSK) == (AD16C4T_RIF_CH2OVI_MSK)); +} + +/** + * @brief Get timer capture/compare 1 overcapture interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ch1ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_CH1OVI_MSK) == (AD16C4T_RIF_CH1OVI_MSK)); +} + +/** + * @brief Get timer break interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_brki(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_BRKI_MSK) == (AD16C4T_RIF_BRKI_MSK)); +} + +/** + * @brief Get timer trigger interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_trgi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_TRGI_MSK) == (AD16C4T_RIF_TRGI_MSK)); +} + +/** + * @brief Get timer COM interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_comi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_COMI_MSK) == (AD16C4T_RIF_COMI_MSK)); +} + +/** + * @brief Get timer capture/compare 4 interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ch4i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_CH4I_MSK) == (AD16C4T_RIF_CH4I_MSK)); +} + +/** + * @brief Get timer capture/compare 3 interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ch3i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_CH3I_MSK) == (AD16C4T_RIF_CH3I_MSK)); +} + +/** + * @brief Get timer capture/compare 2 interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ch2i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_CH2I_MSK) == (AD16C4T_RIF_CH2I_MSK)); +} + +/** + * @brief Get timer capture/compare 1 interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ch1i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_CH1I_MSK) == (AD16C4T_RIF_CH1I_MSK)); +} + +/** + * @brief Get timer update interrupt flag. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_rif_ui(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->RIF, AD16C4T_RIF_UI_MSK) == (AD16C4T_RIF_UI_MSK)); +} + +/** + * @brief Get timer IFM flag. + * @param timx AD16C4T instance + * @retval Timer IFM flag. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ifm(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->IFM)); +} + +/** + * @brief Get timer capture/compare 4 overcapture interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ch4ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_CH4OVI_MSK) == (AD16C4T_IFM_CH4OVI_MSK)); +} + +/** + * @brief Get timer capture/compare 3 overcapture interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ch3ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_CH3OVI_MSK) == (AD16C4T_IFM_CH3OVI_MSK)); +} + +/** + * @brief Get timer capture/compare 2 overcapture interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ch2ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_CH2OVI_MSK) == (AD16C4T_IFM_CH2OVI_MSK)); +} + +/** + * @brief Get timer capture/compare 1 overcapture interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ch1ovi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_CH1OVI_MSK) == (AD16C4T_IFM_CH1OVI_MSK)); +} + +/** + * @brief Get timer break interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_brki(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_BRKI_MSK) == (AD16C4T_IFM_BRKI_MSK)); +} + +/** + * @brief Get timer trigger interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_trgi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_TRGI_MSK) == (AD16C4T_IFM_TRGI_MSK)); +} + +/** + * @brief Get timer COM interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_comi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_COMI_MSK) == (AD16C4T_IFM_COMI_MSK)); +} + +/** + * @brief Get timer capture/compare 4 interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ch4i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_CH4I_MSK) == (AD16C4T_IFM_CH4I_MSK)); +} + +/** + * @brief Get timer capture/compare 3 interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ch3i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_CH3I_MSK) == (AD16C4T_IFM_CH3I_MSK)); +} + +/** + * @brief Get timer capture/compare 2 interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ch2i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_CH2I_MSK) == (AD16C4T_IFM_CH2I_MSK)); +} + +/** + * @brief Get timer capture/compare 1 interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ch1i(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_CH1I_MSK) == (AD16C4T_IFM_CH1I_MSK)); +} + +/** + * @brief Get timer update interrupt flag masked. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_ad16c4t_is_active_flag_ifm_ui(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->IFM, AD16C4T_IFM_UI_MSK) == (AD16C4T_IFM_UI_MSK)); +} + +/** + * @brief Timer ICR setup. + * @param timx AD16C4T instance + * @param value (CC4OI | CC3OI | CC2OI | CC1OI | BI | TI | COMI | CC4I | CC3I | CC2I | CC1I | UI) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_icr(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->ICR, value); +} + +/** + * @brief Clear timer cpture/compare 4 overcapture interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ch4ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_CH4OVI_MSK); +} + +/** + * @brief Clear timer cpture/compare 3 overcapture interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ch3ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_CH3OVI_MSK); +} + +/** + * @brief Clear timer cpture/compare 2 overcapture interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ch2ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_CH2OVI_MSK); +} + +/** + * @brief Clear timer cpture/compare 1 overcapture interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ch1ovi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_CH1OVI_MSK); +} + +/** + * @brief Clear timer break interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_brki(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_BRKI_MSK); +} + +/** + * @brief Clear timer trigger interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_trgi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_TRGI_MSK); +} + +/** + * @brief Clear timer COM interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_comi(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_COMI_MSK); +} + +/** + * @brief Clear timer capture/compare 4 interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ch4i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_CH4I_MSK); +} + +/** + * @brief Clear timer capture/compare 3 interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ch3i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_CH3I_MSK); +} + +/** + * @brief Clear timer capture/compare 2 interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ch2i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_CH2I_MSK); +} + +/** + * @brief Clear timer capture/compare 1 interrupt flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ch1i(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_CH1I_MSK); +} + +/** + * @brief Clear timer upadte flag. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_clear_flag_icr_ui(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->ICR, AD16C4T_ICR_UI_MSK); +} + +/** + * @brief Timer SGE setup. + * @param timx AD16C4T instance + * @param value (SGBRK | SGTRG | SGCOM | SGCH4 | SGCH3 | SGCH2 | SGCH1 | SGU) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->SGE, value); +} + +/** + * @brief Timer break generation. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge_sgbrk(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SGE, AD16C4T_SGE_SGBRK_MSK); +} + +/** + * @brief Timer trigger generation. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge_sgtrg(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SGE, AD16C4T_SGE_SGTRG_MSK); +} + +/** + * @brief Timer COM generation. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge_sgcom(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SGE, AD16C4T_SGE_SGCOM_MSK); +} + +/** + * @brief Timer Capture/Compare 4 generation. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge_sgch4(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SGE, AD16C4T_SGE_SGCH4_MSK); +} + +/** + * @brief Timer Capture/Compare 3 generation. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge_sgch3(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SGE, AD16C4T_SGE_SGCH3_MSK); +} + +/** + * @brief Timer Capture/Compare 2 generation. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge_sgch2(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SGE, AD16C4T_SGE_SGCH2_MSK); +} + +/** + * @brief Timer Capture/Compare 1 generation. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge_sgch1(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SGE, AD16C4T_SGE_SGCH1_MSK); +} + +/** + * @brief Timer update generation. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_sge_sgu(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->SGE, AD16C4T_SGE_SGU_MSK); +} + +/** + * @brief Timer CHMR1 setup. + * @param timx AD16C4T instance + * @param value output (CH2OCLREN | CH2MOD | CH2PEN | CH2FEN | CC2SSEL | CH1OCLREN | CH1MOD | CH1PEN | CH1FEN | CC1SSEL) + * input (I2FLT | I2PRES | CC2SSEL | I1FLT | I1PRES | CC1SSEL) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CHMR1, value); +} + +/** + * @brief GET Timer CHMR1 register value. + * @param timx AD16C4T instance + * @retval Timer CHMR1 register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CHMR1)); +} + +/** + * @brief Timer output compare 2 clear enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr1_output_ch2oclren(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2OCLREN_MSK); +} + +/** + * @brief Timer output compare 2 clear disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr1_output_ch2oclren(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2OCLREN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 2 clear is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr1_output_ch2oclren(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2OCLREN_MSK) == (AD16C4T_CHMR1_OUTPUT_CH2OCLREN_MSK)); +} + +/** + * @brief Timer output compare 2 mode setup. + * @param timx AD16C4T instance + * @param OutputMode Output compare mode + @arg @ref MD_AD16C4T_OUTPUTMODE_DISABLE + @arg @ref MD_AD16C4T_OUTPUTMODE_HIGHONMSTCH + @arg @ref MD_AD16C4T_OUTPUTMODE_LOWONMSTCH + @arg @ref MD_AD16C4T_OUTPUTMODE_TOGGLE + @arg @ref MD_AD16C4T_OUTPUTMODE_FORCELOW + @arg @ref MD_AD16C4T_OUTPUTMODE_FORCEHIGH + @arg @ref MD_AD16C4T_OUTPUTMODE_PWMMODE1 + @arg @ref MD_AD16C4T_OUTPUTMODE_PWMMODE2 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_output_ch2mod(AD16C4T_TypeDef *timx, uint32_t OutputMode) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2MOD_MSK, (OutputMode << AD16C4T_CHMR1_OUTPUT_CH2MOD_POSS)); +} + +/** + * @brief Get timer output compare 2 mode. + * @param timx AD16C4T instance + * @retval Timer output compare 2 mode. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_output_ch2mod(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2MOD_MSK) >> AD16C4T_CHMR1_OUTPUT_CH2MOD_POSS); +} + +/** + * @brief Timer output compare 2 preload enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr1_output_ch2pen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2PEN_MSK); +} + +/** + * @brief Timer output compare 2 preload disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr1_output_ch2pen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2PEN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 2 preload is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr1_output_ch2pen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2PEN_MSK) == (AD16C4T_CHMR1_OUTPUT_CH2PEN_MSK)); +} + +/** + * @brief Timer output compare 2 fast enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr1_output_ch2fen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2FEN_MSK); +} + +/** + * @brief Timer output compare 2 fast disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr1_output_ch2fen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2FEN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 2 fast is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr1_output_ch2fen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH2FEN_MSK) == (AD16C4T_CHMR1_OUTPUT_CH2FEN_MSK)); +} + +/** + * @brief Timer cpture/compare 2 selection setup. + * @param timx AD16C4T instance + * @param ChannelMode Channel mode selection + @arg @ref MD_AD16C4T_CHMODE_OUTPUT + @arg @ref MD_AD16C4T_CHMODE_INPUT_DIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_INDIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_TRC + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_output_cc2ssel(AD16C4T_TypeDef *timx, uint32_t ChannelMode) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CC2SSEL_MSK, (ChannelMode << AD16C4T_CHMR1_OUTPUT_CC2SSEL_POSS)); +} + +/** + * @brief Get timer cpture/compare 2 selection. + * @param timx AD16C4T instance + * @retval Timer cpture/compare 2 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_output_cc2ssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CC2SSEL_MSK) >> AD16C4T_CHMR1_OUTPUT_CC2SSEL_POSS); +} + +/** + * @brief Timer output compare 1 clear enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr1_output_ch1oclren(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1OCLREN_MSK); +} + +/** + * @brief Timer output compare 1 clear disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr1_output_ch1oclren(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1OCLREN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 1 clear is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr1_output_ch1oclren(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1OCLREN_MSK) == (AD16C4T_CHMR1_OUTPUT_CH1OCLREN_MSK)); +} + +/** + * @brief Timer output compare 1 mode setup. + * @param timx AD16C4T instance + * @param OutputMode Output compare mode + @arg @ref MD_AD16C4T_OUTPUTMODE_DISABLE + @arg @ref MD_AD16C4T_OUTPUTMODE_HIGHONMSTCH + @arg @ref MD_AD16C4T_OUTPUTMODE_LOWONMSTCH + @arg @ref MD_AD16C4T_OUTPUTMODE_TOGGLE + @arg @ref MD_AD16C4T_OUTPUTMODE_FORCELOW + @arg @ref MD_AD16C4T_OUTPUTMODE_FORCEHIGH + @arg @ref MD_AD16C4T_OUTPUTMODE_PWMMODE1 + @arg @ref MD_AD16C4T_OUTPUTMODE_PWMMODE2 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_output_ch1mod(AD16C4T_TypeDef *timx, uint32_t OutputMode) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1MOD_MSK, (OutputMode << AD16C4T_CHMR1_OUTPUT_CH1MOD_POSS)); +} + +/** + * @brief Get timer output compare 1 mode. + * @param timx AD16C4T instance + * @retval Timer output compare 1 mode. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_output_ch1mod(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1MOD_MSK) >> AD16C4T_CHMR1_OUTPUT_CH1MOD_POSS); +} + +/** + * @brief Timer output compare 1 preload enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr1_output_ch1pen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1PEN_MSK); +} + +/** + * @brief Timer output compare 1 preload disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr1_output_ch1pen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1PEN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 1 preload is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr1_output_ch1pen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1PEN_MSK) == (AD16C4T_CHMR1_OUTPUT_CH1PEN_MSK)); +} + +/** + * @brief Timer output compare 1 fast enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr1_output_ch1fen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1FEN_MSK); +} + +/** + * @brief Timer output compare 1 fast disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr1_output_ch1fen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1FEN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 1 fast is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr1_output_ch1fen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CH1FEN_MSK) == (AD16C4T_CHMR1_OUTPUT_CH1FEN_MSK)); +} + +/** + * @brief Timer cpture/compare 1 selection setup. + * @param timx AD16C4T instance + * @param ChannelMode Channel mode selection + @arg @ref MD_AD16C4T_CHMODE_OUTPUT + @arg @ref MD_AD16C4T_CHMODE_INPUT_DIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_INDIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_TRC + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_output_cc1ssel(AD16C4T_TypeDef *timx, uint32_t ChannelMode) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CC1SSEL_MSK, (ChannelMode << AD16C4T_CHMR1_OUTPUT_CC1SSEL_POSS)); +} + +/** + * @brief Get timer cpture/compare 1 selection. + * @param timx AD16C4T instance + * @retval Timer cpture/compare 1 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_output_cc1ssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_OUTPUT_CC1SSEL_MSK) >> AD16C4T_CHMR1_OUTPUT_CC1SSEL_POSS); +} + +/** + * @brief Timer input capture 2 filter setup. + * @param timx AD16C4T instance + * @param InputFliter Input capture filter + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N2 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N4 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV2N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV2N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV4N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV4N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV8N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV8N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N5 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N5 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_input_i2flt(AD16C4T_TypeDef *timx, uint32_t InputFliter) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_INPUT_I2FLT_MSK, (InputFliter << AD16C4T_CHMR1_INPUT_I2FLT_POSS)); +} + +/** + * @brief Get timer input capture 2 filter. + * @param timx AD16C4T instance + * @retval Timer input capture 2 filter. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_input_i2flt(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_INPUT_I2FLT_MSK) >> AD16C4T_CHMR1_INPUT_I2FLT_POSS); +} + +/** + * @brief Timer input capture 2 prescaler setup. + * @param timx AD16C4T instance + * @param InputPrescale Input capture prescaler + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV1 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV2 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV4 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_input_i2pres(AD16C4T_TypeDef *timx, uint32_t InputPrescale) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_INPUT_I2PRES_MSK, (InputPrescale << AD16C4T_CHMR1_INPUT_I2PRES_POSS)); +} + +/** + * @brief Get timer input capture 2 prescaler. + * @param timx AD16C4T instance + * @retval Timer input capture 2 prescaler. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_input_i2pres(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_INPUT_I2PRES_MSK) >> AD16C4T_CHMR1_INPUT_I2PRES_POSS); +} + +/** + * @brief Timer cpture/compare 2 selection setup. + * @param timx AD16C4T instance + * @param ChannelMode Channel mode selection + @arg @ref MD_AD16C4T_CHMODE_OUTPUT + @arg @ref MD_AD16C4T_CHMODE_INPUT_DIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_INDIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_TRC + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_input_cc2ssel(AD16C4T_TypeDef *timx, uint32_t ChannelMode) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_INPUT_CC2SSEL_MSK, (ChannelMode << AD16C4T_CHMR1_INPUT_CC2SSEL_POSS)); +} + +/** + * @brief Get timer cpture/compare 2 selection. + * @param timx AD16C4T instance + * @retval Timer cpture/compare 2 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_input_cc2ssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_INPUT_CC2SSEL_MSK) >> AD16C4T_CHMR1_INPUT_CC2SSEL_POSS); +} + +/** + * @brief Timer input capture 1 filter setup. + * @param timx AD16C4T instance + * @param InputFliter Input capture filter + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N2 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N4 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV2N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV2N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV4N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV4N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV8N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV8N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N5 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N5 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_input_i1flt(AD16C4T_TypeDef *timx, uint32_t InputFliter) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_INPUT_I1FLT_MSK, (InputFliter << AD16C4T_CHMR1_INPUT_I1FLT_POSS)); +} + +/** + * @brief Get timer input capture 1 filter. + * @param timx AD16C4T instance + * @retval Timer input capture 1 filter. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_input_i1flt(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_INPUT_I1FLT_MSK) >> AD16C4T_CHMR1_INPUT_I1FLT_POSS); +} + +/** + * @brief Timer input capture 1 prescaler setup. + * @param timx AD16C4T instance + * @param InputPrescale Input capture prescaler + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV1 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV2 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV4 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_input_i1pres(AD16C4T_TypeDef *timx, uint32_t InputPrescale) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_INPUT_I1PRES_MSK, (InputPrescale << AD16C4T_CHMR1_INPUT_I1PRES_POSS)); +} + +/** + * @brief Get timer input capture 1 prescaler. + * @param timx AD16C4T instance + * @retval Timer input capture 1 prescaler. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_input_i1pres(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_INPUT_I1PRES_MSK) >> AD16C4T_CHMR1_INPUT_I1PRES_POSS); +} + +/** + * @brief Timer cpture/compare 1 selection setup. + * @param timx AD16C4T instance + * @param ChannelMode Channel mode selection + @arg @ref MD_AD16C4T_CHMODE_OUTPUT + @arg @ref MD_AD16C4T_CHMODE_INPUT_DIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_INDIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_TRC + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr1_input_cc1ssel(AD16C4T_TypeDef *timx, uint32_t ChannelMode) +{ + MODIFY_REG(timx->CHMR1, AD16C4T_CHMR1_INPUT_CC1SSEL_MSK, (ChannelMode << AD16C4T_CHMR1_INPUT_CC1SSEL_POSS)); +} + +/** + * @brief Get timer cpture/compare 1 selection. + * @param timx AD16C4T instance + * @retval Timer cpture/compare 1 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr1_input_cc1ssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR1, AD16C4T_CHMR1_INPUT_CC1SSEL_MSK) >> AD16C4T_CHMR1_INPUT_CC1SSEL_POSS); +} + +/** + * @brief Timer CHMR2 setup. + + * @param timx AD16C4T instance + * @param value output (CH4OCLREN | CH4MOD | CH4PEN | CH4FEN | CC4SSEL | CH3OCLREN | CH3MOD | CH3PEN | CH3FEN | CC3SSEL) + * input (I4FLT | I4PRES | CC4SSEL | I3FLT | I3PRES | CC3SSEL) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CHMR2, value); +} + +/** + * @brief GET Timer CHMR2 register value. + * @param timx AD16C4T instance + * @retval Timer CHMR2 register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CHMR2)); +} + +/** + * @brief Timer output compare 4 clear enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr2_output_ch4oclren(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4OCLREN_MSK); +} + +/** + * @brief Timer output compare 4 clear disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr2_output_ch4oclren(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4OCLREN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 4 clear is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr2_output_ch4oclren(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4OCLREN_MSK) == (AD16C4T_CHMR2_OUTPUT_CH4OCLREN_MSK)); +} + +/** + * @brief Timer output compare 4 mode setup. + * @param timx AD16C4T instance + * @param OutputMode Output compare mode + @arg @ref MD_AD16C4T_OUTPUTMODE_DISABLE + @arg @ref MD_AD16C4T_OUTPUTMODE_HIGHONMSTCH + @arg @ref MD_AD16C4T_OUTPUTMODE_LOWONMSTCH + @arg @ref MD_AD16C4T_OUTPUTMODE_TOGGLE + @arg @ref MD_AD16C4T_OUTPUTMODE_FORCELOW + @arg @ref MD_AD16C4T_OUTPUTMODE_FORCEHIGH + @arg @ref MD_AD16C4T_OUTPUTMODE_PWMMODE1 + @arg @ref MD_AD16C4T_OUTPUTMODE_PWMMODE2 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_output_ch4mod(AD16C4T_TypeDef *timx, uint32_t OutputMode) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4MOD_MSK, (OutputMode << AD16C4T_CHMR2_OUTPUT_CH4MOD_POSS)); +} + +/** + * @brief Get timer output compare 4 mode. + * @param timx AD16C4T instance + * @retval Timer output compare 4 mode. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_output_ch4mod(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4MOD_MSK) >> AD16C4T_CHMR2_OUTPUT_CH4MOD_POSS); +} + +/** + * @brief Timer output compare 4 preload enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr2_output_ch4pen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4PEN_MSK); +} + +/** + * @brief Timer output compare 4 preload disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr2_output_ch4pen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4PEN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 4 preload is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr2_output_ch4pen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4PEN_MSK) == (AD16C4T_CHMR2_OUTPUT_CH4PEN_MSK)); +} + +/** + * @brief Timer output compare 4 fast enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr2_output_ch4fen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4FEN_MSK); +} + +/** + * @brief Timer output compare 4 fast disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr2_output_ch4fen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4FEN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 4 fast is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr2_output_ch4fen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH4FEN_MSK) == (AD16C4T_CHMR2_OUTPUT_CH4FEN_MSK)); +} + +/** + * @brief Timer cpture/compare 4 selection setup. + * @param timx AD16C4T instance + * @param ChannelMode Channel mode selection + @arg @ref MD_AD16C4T_CHMODE_OUTPUT + @arg @ref MD_AD16C4T_CHMODE_INPUT_DIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_INDIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_TRC + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_output_cc4ssel(AD16C4T_TypeDef *timx, uint32_t ChannelMode) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CC4SSEL_MSK, (ChannelMode << AD16C4T_CHMR2_OUTPUT_CC4SSEL_POSS)); +} + +/** + * @brief Get timer cpture/compare 4 selection. + * @param timx AD16C4T instance + * @retval Timer cpture/compare 4 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_output_cc4ssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CC4SSEL_MSK) >> AD16C4T_CHMR2_OUTPUT_CC4SSEL_POSS); +} + +/** + * @brief Timer output compare 3 clear enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr2_output_ch3oclren(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3OCLREN_MSK); +} + +/** + * @brief Timer output compare 3 clear disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr2_output_ch3oclren(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3OCLREN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 3 clear is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr2_output_ch3oclren(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3OCLREN_MSK) == (AD16C4T_CHMR2_OUTPUT_CH3OCLREN_MSK)); +} + +/** + * @brief Timer output compare 3 mode setup. + * @param timx AD16C4T instance + * @param OutputMode Output compare mode + @arg @ref MD_AD16C4T_OUTPUTMODE_DISABLE + @arg @ref MD_AD16C4T_OUTPUTMODE_HIGHONMSTCH + @arg @ref MD_AD16C4T_OUTPUTMODE_LOWONMSTCH + @arg @ref MD_AD16C4T_OUTPUTMODE_TOGGLE + @arg @ref MD_AD16C4T_OUTPUTMODE_FORCELOW + @arg @ref MD_AD16C4T_OUTPUTMODE_FORCEHIGH + @arg @ref MD_AD16C4T_OUTPUTMODE_PWMMODE1 + @arg @ref MD_AD16C4T_OUTPUTMODE_PWMMODE2 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_output_ch3mod(AD16C4T_TypeDef *timx, uint32_t OutputMode) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3MOD_MSK, (OutputMode << AD16C4T_CHMR2_OUTPUT_CH3MOD_POSS)); +} + +/** + * @brief Get timer output compare 3 mode. + * @param timx AD16C4T instance + * @retval Timer output compare 3 mode. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_output_ch3mod(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3MOD_MSK) >> AD16C4T_CHMR2_OUTPUT_CH3MOD_POSS); +} + +/** + * @brief Timer output compare 3 preload enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr2_output_ch3pen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3PEN_MSK); +} + +/** + * @brief Timer output compare 3 preload disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr2_output_ch3pen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3PEN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 3 preload is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr2_output_ch3pen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3PEN_MSK) == (AD16C4T_CHMR2_OUTPUT_CH3PEN_MSK)); +} + +/** + * @brief Timer output compare 3 fast enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_chmr2_output_ch3fen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3FEN_MSK); +} + +/** + * @brief Timer output compare 3 fast disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_chmr2_output_ch3fen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3FEN_MSK); +} + +/** + * @brief Indicates whether the timer output compare 3 fast is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_chmr2_output_ch3fen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CH3FEN_MSK) == (AD16C4T_CHMR2_OUTPUT_CH3FEN_MSK)); +} + +/** + * @brief Timer cpture/compare 3 selection setup. + * @param timx AD16C4T instance + * @param ChannelMode Channel mode selection + @arg @ref MD_AD16C4T_CHMODE_OUTPUT + @arg @ref MD_AD16C4T_CHMODE_INPUT_DIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_INDIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_TRC + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_output_cc3ssel(AD16C4T_TypeDef *timx, uint32_t ChannelMode) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CC3SSEL_MSK, (ChannelMode << AD16C4T_CHMR2_OUTPUT_CC3SSEL_POSS)); +} + +/** + * @brief Get timer cpture/compare 3 selection. + * @param timx AD16C4T instance + * @retval Timer cpture/compare 3 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_output_cc3ssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_OUTPUT_CC3SSEL_MSK) >> AD16C4T_CHMR2_OUTPUT_CC3SSEL_POSS); +} + +/** + * @brief Timer input capture 4 filter setup. + * @param timx AD16C4T instance + * @param InputFliter Input capture filter + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N2 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N4 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV2N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV2N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV4N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV4N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV8N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV8N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N5 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N5 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_input_i4flt(AD16C4T_TypeDef *timx, uint32_t InputFliter) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_INPUT_I4FLT_MSK, (InputFliter << AD16C4T_CHMR2_INPUT_I4FLT_POSS)); +} + +/** + * @brief Get timer input capture 4 filter. + * @param timx AD16C4T instance + * @retval Timer input capture 4 filter. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_input_i4flt(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_INPUT_I4FLT_MSK) >> AD16C4T_CHMR2_INPUT_I4FLT_POSS); +} + +/** + * @brief Timer input capture 4 prescaler setup. + * @param timx AD16C4T instance + * @param InputPrescale Input capture prescaler + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV1 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV2 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV4 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_input_i4pres(AD16C4T_TypeDef *timx, uint32_t InputPrescale) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_INPUT_I4PRES_MSK, (InputPrescale << AD16C4T_CHMR2_INPUT_I4PRES_POSS)); +} + +/** + * @brief Get timer input capture 4 prescaler. + * @param timx AD16C4T instance + * @retval Timer input capture 4 prescaler. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_input_i4pres(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_INPUT_I4PRES_MSK) >> AD16C4T_CHMR2_INPUT_I4PRES_POSS); +} + +/** + * @brief Timer cpture/compare 4 selection setup. + * @param timx AD16C4T instance + * @param ChannelMode Channel mode selection + @arg @ref MD_AD16C4T_CHMODE_OUTPUT + @arg @ref MD_AD16C4T_CHMODE_INPUT_DIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_INDIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_TRC + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_input_cc4ssel(AD16C4T_TypeDef *timx, uint32_t ChannelMode) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_INPUT_CC4SSEL_MSK, (ChannelMode << AD16C4T_CHMR2_INPUT_CC4SSEL_POSS)); +} + +/** + * @brief Get timer cpture/compare 4 selection. + * @param timx AD16C4T instance + * @retval Timer cpture/compare 4 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_input_cc4ssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_INPUT_CC4SSEL_MSK) >> AD16C4T_CHMR2_INPUT_CC4SSEL_POSS); +} + +/** + * @brief Timer input capture 3 filter setup. + * @param timx AD16C4T instance + * @param InputFliter Input capture filter + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N2 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N4 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV1N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV2N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV2N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV4N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV4N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV8N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV8N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N5 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV16N8 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N5 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N6 + @arg @ref MD_AD16C4T_INPUTFILTER_FDIV32N8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_input_i3flt(AD16C4T_TypeDef *timx, uint32_t InputFliter) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_INPUT_I3FLT_MSK, (InputFliter << AD16C4T_CHMR2_INPUT_I3FLT_POSS)); +} + +/** + * @brief Get timer input capture 3 filter. + * @param timx AD16C4T instance + * @retval Timer input capture 3 filter. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_input_i3flt(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_INPUT_I3FLT_MSK) >> AD16C4T_CHMR2_INPUT_I3FLT_POSS); +} + +/** + * @brief Timer input capture 3 prescaler setup. + * @param timx AD16C4T instance + * @param InputPrescale Input capture prescaler + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV1 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV2 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV4 + @arg @ref MD_AD16C4T_INPUTPRESCALE_DIV8 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_input_i3pres(AD16C4T_TypeDef *timx, uint32_t InputPrescale) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_INPUT_I3PRES_MSK, (InputPrescale << AD16C4T_CHMR2_INPUT_I3PRES_POSS)); +} + +/** + * @brief Get timer input capture 3 prescaler. + * @param timx AD16C4T instance + * @retval Timer input capture 3 prescaler. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_input_i3pres(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_INPUT_I3PRES_MSK) >> AD16C4T_CHMR2_INPUT_I3PRES_POSS); +} + +/** + * @brief Timer cpture/compare 3 selection setup. + * @param timx AD16C4T instance + * @param ChannelMode Channel mode selection + @arg @ref MD_AD16C4T_CHMODE_OUTPUT + @arg @ref MD_AD16C4T_CHMODE_INPUT_DIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_INDIRECT + @arg @ref MD_AD16C4T_CHMODE_INPUT_TRC + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_chmr2_input_cc3ssel(AD16C4T_TypeDef *timx, uint32_t ChannelMode) +{ + MODIFY_REG(timx->CHMR2, AD16C4T_CHMR2_INPUT_CC3SSEL_MSK, (ChannelMode << AD16C4T_CHMR2_INPUT_CC3SSEL_POSS)); +} + +/** + * @brief Get timer cpture/compare 3 selection. + * @param timx AD16C4T instance + * @retval Timer cpture/compare 3 selection. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_chmr2_input_cc3ssel(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CHMR2, AD16C4T_CHMR2_INPUT_CC3SSEL_MSK) >> AD16C4T_CHMR2_INPUT_CC3SSEL_POSS); +} + +/** + * @brief Timer CCEP setup. + * @param timx AD16C4T instance + * @param value (CC4NPOL | CC4POL | CC4EN | CC3NPOL | CC3NEN | CC3POL | CC3EN | CC2NPOL | + * CC2NEN | CC2POL | CC2EN | CC1NPOL | CC1NEN | CC1POL | CC1EN ) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CCEP, value); +} + +/** + * @brief GET Timer CCEP register value. + * @param timx AD16C4T instance + * @retval Timer CCEP register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CCEP)); +} + +/** + * @brief Timer capture/compare 4 complementary output polarity setup. + * @param timx AD16C4T instance + * @param OutputPolarity Output polarity + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_HIGH + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_LOW + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep_cc4npol(AD16C4T_TypeDef *timx, uint32_t OutputPolarity) +{ + MODIFY_REG(timx->CCEP, AD16C4T_CCEP_CC4NPOL_MSK, (OutputPolarity << AD16C4T_CCEP_CC4NPOL_POS)); +} + +/** + * @brief Get timer capture/compare 4 complementary output polarity. + * @param timx AD16C4T instance + * @retval Timer capture/compare 4 complementary output polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep_cc4npol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC4NPOL_MSK) >> AD16C4T_CCEP_CC4NPOL_POS); +} + +/** + * @brief Timer capture/compare 4 output polarity setup. + * @param timx AD16C4T instance + * @param OutputPolarity Output polarity + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_HIGH + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_LOW + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep_cc4pol(AD16C4T_TypeDef *timx, uint32_t OutputPolarity) +{ + MODIFY_REG(timx->CCEP, AD16C4T_CCEP_CC4POL_MSK, (OutputPolarity << AD16C4T_CCEP_CC4POL_POS)); +} + +/** + * @brief Get timer capture/compare 4 output polarity. + * @param timx AD16C4T instance + * @retval Timer capture/compare 4 output polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep_cc4pol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC4POL_MSK) >> AD16C4T_CCEP_CC4POL_POS); +} + +/** + * @brief Timer Capture/Compare 4 output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ccep_cc4en(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CCEP, AD16C4T_CCEP_CC4EN_MSK); +} + +/** + * @brief Timer Capture/Compare 4 output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_ccep_cc4en(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CCEP, AD16C4T_CCEP_CC4EN_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 4 output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ccep_cc4en(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC4EN_MSK) == (AD16C4T_CCEP_CC4EN_MSK)); +} + +/** + * @brief Timer capture/compare 3 complementary output polarity setup. + * @param timx AD16C4T instance + * @param OutputPolarity Output polarity + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_HIGH + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_LOW + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep_cc3npol(AD16C4T_TypeDef *timx, uint32_t OutputPolarity) +{ + MODIFY_REG(timx->CCEP, AD16C4T_CCEP_CC3NPOL_MSK, (OutputPolarity << AD16C4T_CCEP_CC3NPOL_POS)); +} + +/** + * @brief Get timer capture/compare 3 complementary output polarity. + * @param timx AD16C4T instance + * @retval Timer capture/compare 3 complementary output polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep_cc3npol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC3NPOL_MSK) >> AD16C4T_CCEP_CC3NPOL_POS); +} + +/** + * @brief Timer Capture/Compare 3 complementary output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ccep_cc3nen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CCEP, AD16C4T_CCEP_CC3NEN_MSK); +} + +/** + * @brief Timer Capture/Compare 3 complementary output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_ccep_cc3nen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CCEP, AD16C4T_CCEP_CC3NEN_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 3 complementary output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ccep_cc3nen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC3NEN_MSK) == (AD16C4T_CCEP_CC3NEN_MSK)); +} + +/** + * @brief Timer capture/compare 3 output polarity setup. + * @param timx AD16C4T instance + * @param OutputPolarity Output polarity + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_HIGH + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_LOW + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep_cc3pol(AD16C4T_TypeDef *timx, uint32_t OutputPolarity) +{ + MODIFY_REG(timx->CCEP, AD16C4T_CCEP_CC3POL_MSK, (OutputPolarity << AD16C4T_CCEP_CC3POL_POS)); +} + +/** + * @brief Get timer capture/compare 3 output polarity. + * @param timx AD16C4T instance + * @retval Timer capture/compare 3 output polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep_cc3pol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC3POL_MSK) >> AD16C4T_CCEP_CC3POL_POS); +} + +/** + * @brief Timer Capture/Compare 3 output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ccep_cc3en(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CCEP, AD16C4T_CCEP_CC3EN_MSK); +} + +/** + * @brief Timer Capture/Compare 3 output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_ccep_cc3en(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CCEP, AD16C4T_CCEP_CC3EN_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 3 output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ccep_cc3en(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC3EN_MSK) == (AD16C4T_CCEP_CC3EN_MSK)); +} + +/** + * @brief Timer capture/compare 2 complementary output polarity setup. + * @param timx AD16C4T instance + * @param OutputPolarity Output polarity + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_HIGH + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_LOW + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep_cc2npol(AD16C4T_TypeDef *timx, uint32_t OutputPolarity) +{ + MODIFY_REG(timx->CCEP, AD16C4T_CCEP_CC2NPOL_MSK, (OutputPolarity << AD16C4T_CCEP_CC2NPOL_POS)); +} + +/** + * @brief Get timer capture/compare 2 complementary output polarity. + * @param timx AD16C4T instance + * @retval Timer capture/compare 2 complementary output polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep_cc2npol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC2NPOL_MSK) >> AD16C4T_CCEP_CC2NPOL_POS); +} + +/** + * @brief Timer Capture/Compare 2 complementary output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ccep_cc2nen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CCEP, AD16C4T_CCEP_CC2NEN_MSK); +} + +/** + * @brief Timer Capture/Compare 2 complementary output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_ccep_cc2nen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CCEP, AD16C4T_CCEP_CC2NEN_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 2 complementary output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ccep_cc2nen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC2NEN_MSK) == (AD16C4T_CCEP_CC2NEN_MSK)); +} + +/** + * @brief Timer capture/compare 2 output polarity setup. + * @param timx AD16C4T instance + * @param OutputPolarity Output polarity + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_HIGH + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_LOW + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep_cc2pol(AD16C4T_TypeDef *timx, uint32_t OutputPolarity) +{ + MODIFY_REG(timx->CCEP, AD16C4T_CCEP_CC2POL_MSK, (OutputPolarity << AD16C4T_CCEP_CC2POL_POS)); +} + +/** + * @brief Get timer capture/compare 2 output polarity. + * @param timx AD16C4T instance + * @retval Timer capture/compare 2 output polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep_cc2pol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC2POL_MSK) >> AD16C4T_CCEP_CC2POL_POS); +} + +/** + * @brief Timer Capture/Compare 2 output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ccep_cc2en(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CCEP, AD16C4T_CCEP_CC2EN_MSK); +} + +/** + * @brief Timer Capture/Compare 2 output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_ccep_cc2en(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CCEP, AD16C4T_CCEP_CC2EN_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 2 output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ccep_cc2en(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC2EN_MSK) == (AD16C4T_CCEP_CC2EN_MSK)); +} + +/** + * @brief Timer capture/compare 1 complementary output polarity setup. + * @param timx AD16C4T instance + * @param OutputPolarity Output polarity + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_HIGH + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_LOW + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep_cc1npol(AD16C4T_TypeDef *timx, uint32_t OutputPolarity) +{ + MODIFY_REG(timx->CCEP, AD16C4T_CCEP_CC1NPOL_MSK, (OutputPolarity << AD16C4T_CCEP_CC1NPOL_POS)); +} + +/** + * @brief Get timer capture/compare 1 complementary output polarity. + * @param timx AD16C4T instance + * @retval Timer capture/compare 1 complementary output polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep_cc1npol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC1NPOL_MSK) >> AD16C4T_CCEP_CC1NPOL_POS); +} + +/** + * @brief Timer Capture/Compare 1 complementary output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ccep_cc1nen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CCEP, AD16C4T_CCEP_CC1NEN_MSK); +} + +/** + * @brief Timer Capture/Compare 1 complementary output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_ccep_cc1nen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CCEP, AD16C4T_CCEP_CC1NEN_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 1 complementary output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ccep_cc1nen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC1NEN_MSK) == (AD16C4T_CCEP_CC1NEN_MSK)); +} + +/** + * @brief Timer capture/compare 1 output polarity setup. + * @param timx AD16C4T instance + * @param OutputPolarity Output polarity + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_HIGH + @arg @ref MD_AD16C4T_OUTPUTPOLARITY_LOW + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccep_cc1pol(AD16C4T_TypeDef *timx, uint32_t OutputPolarity) +{ + MODIFY_REG(timx->CCEP, AD16C4T_CCEP_CC1POL_MSK, (OutputPolarity << AD16C4T_CCEP_CC1POL_POS)); +} + +/** + * @brief Get timer capture/compare 1 output polarity. + * @param timx AD16C4T instance + * @retval Timer capture/compare 1 output polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccep_cc1pol(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC1POL_MSK) >> AD16C4T_CCEP_CC1POL_POS); +} + +/** + * @brief Timer Capture/Compare 1 output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_ccep_cc1en(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->CCEP, AD16C4T_CCEP_CC1EN_MSK); +} + +/** + * @brief Timer Capture/Compare 1 output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_ccep_cc1en(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->CCEP, AD16C4T_CCEP_CC1EN_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 1 output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_ccep_cc1en(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCEP, AD16C4T_CCEP_CC1EN_MSK) == (AD16C4T_CCEP_CC1EN_MSK)); +} + +/** + * @brief Timer COUNT setup. + * @param timx AD16C4T instance + * @param value COUNT + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_count(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->COUNT, value); +} + +/** + * @brief GET Timer COUNT register value. + * @param timx AD16C4T instance + * @retval Timer COUNT register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_count(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->COUNT)); +} + +/** + * @brief Timer counter value setup. + * @param timx AD16C4T instance + * @param counter Counter value (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_count_cntv(AD16C4T_TypeDef *timx, uint32_t counter) +{ + MODIFY_REG(timx->COUNT, AD16C4T_COUNT_CNTV_MSK, counter); +} + +/** + * @brief Get timer counter value. + * @param timx AD16C4T instance + * @retval Timer counter value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_cnt_cntv(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->COUNT, AD16C4T_COUNT_CNTV_MSK) >> AD16C4T_COUNT_CNTV_POSS); +} + +/** + * @brief Timer PRES setup. + * @param timx AD16C4T instance + * @param value PRES + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_pres(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->PRES, value); +} + +/** + * @brief GET Timer PRES register value. + * @param timx AD16C4T instance + * @retval Timer PRES register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_pres(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->PRES)); +} + +/** + * @brief Timer prescaler value setup. + * @param timx AD16C4T instance + * @param prescaler Prescaler value (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_pres_pscv(AD16C4T_TypeDef *timx, uint32_t prescaler) +{ + MODIFY_REG(timx->PRES, AD16C4T_PRES_PSCV_MSK, prescaler); +} + +/** + * @brief Get timer prescaler value. + * @param timx AD16C4T instance + * @retval Timer prescaler value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_pres_pscv(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->PRES, AD16C4T_PRES_PSCV_MSK) >> AD16C4T_PRES_PSCV_POSS); +} + +/** + * @brief Timer AR setup. + * @param timx AD16C4T instance + * @param value AR + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ar(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->AR, value); +} + +/** + * @brief GET Timer AR register value. + * @param timx AD16C4T instance + * @retval Timer AR register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ar(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->AR)); +} + +/** + * @brief Timer auto-reload value setup. + * @param timx AD16C4T instance + * @param reload Auto-reload value (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ar_arv(AD16C4T_TypeDef *timx, uint32_t reload) +{ + MODIFY_REG(timx->AR, AD16C4T_AR_ARV_MSK, reload); +} + +/** + * @brief Get timer auto-reload value. + * @param timx AD16C4T instance + * @retval Timer auto-reload value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ar_arv(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->AR, AD16C4T_AR_ARV_MSK) >> AD16C4T_AR_ARV_POSS); +} + +/** + * @brief Timer REPAR setup. + * @param timx AD16C4T instance + * @param value REPAR + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_rcr(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->REPAR, value); +} + +/** + * @brief GET Timer REPAR register value. + * @param timx AD16C4T instance + * @retval Timer REPAR register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_repar(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->REPAR)); +} + +/** + * @brief Timer repetition counter value setup. + * @param timx AD16C4T instance + * @param repetition Repetition counter value (between Min_Data=0 and Max_Data=0xFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_repar_repv(AD16C4T_TypeDef *timx, uint32_t repetition) +{ + MODIFY_REG(timx->REPAR, AD16C4T_REPAR_REPV_MSK, repetition); +} + +/** + * @brief Get timer repetition counter value. + * @param timx AD16C4T instance + * @retval Timer repetition counter value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_repar_repv(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->REPAR, AD16C4T_REPAR_REPV_MSK) >> AD16C4T_REPAR_REPV_POSS); +} + +/** + * @brief Timer CCVAL1 setup. + * @param timx AD16C4T instance + * @param value CCVAL1 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccval1(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CCVAL1, value); +} + +/** + * @brief GET Timer CCVAL1 register value. + * @param timx AD16C4T instance + * @retval Timer CCVAL1 register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccval1(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CCVAL1)); +} + +/** + * @brief Timer capture/compare value 1 setup. + * @param timx AD16C4T instance + * @param CapCompValue Capture/Compare value 1 (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccval1_ccrv1(AD16C4T_TypeDef *timx, uint32_t CapCompValue) +{ + MODIFY_REG(timx->CCVAL1, AD16C4T_CCVAL1_CCRV1_MSK, CapCompValue); +} + +/** + * @brief Get timer capture/compare value 1. + * @param timx AD16C4T instance + * @retval Timer capture/compare value 1. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccval1_ccrv1(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCVAL1, AD16C4T_CCVAL1_CCRV1_MSK) >> AD16C4T_CCVAL1_CCRV1_POSS); +} + +/** + * @brief Timer CCVAL2 setup. + * @param timx AD16C4T instance + * @param value CCVAL2 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccval2(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CCVAL2, value); +} + +/** + * @brief GET Timer CCVAL2 register value. + * @param timx AD16C4T instance + * @retval Timer CCVAL2 register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccval2(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CCVAL2)); +} + +/** + * @brief Timer capture/compare value 2 setup. + * @param timx AD16C4T instance + * @param CapCompValue Capture/Compare value 2 (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccval2_ccrv2(AD16C4T_TypeDef *timx, uint32_t CapCompValue) +{ + MODIFY_REG(timx->CCVAL2, AD16C4T_CCVAL2_CCRV2_MSK, CapCompValue); +} + +/** + * @brief Get timer capture/compare value 2. + * @param timx AD16C4T instance + * @retval Timer capture/compare value 2. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccval2_ccrv2(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCVAL2, AD16C4T_CCVAL2_CCRV2_MSK) >> AD16C4T_CCVAL2_CCRV2_POSS); +} + +/** + * @brief Timer CCVAL3 setup. + * @param timx AD16C4T instance + * @param value CCVAL3 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccval3(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CCVAL3, value); +} + +/** + * @brief GET Timer CCVAL3 register value. + * @param timx AD16C4T instance + * @retval Timer CCVAL3 register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccval3(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CCVAL3)); +} + +/** + * @brief Timer capture/compare value 3 setup. + * @param timx AD16C4T instance + * @param CapCompValue Capture/Compare value 3 (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccval3_ccrv3(AD16C4T_TypeDef *timx, uint32_t CapCompValue) +{ + MODIFY_REG(timx->CCVAL3, AD16C4T_CCVAL3_CCRV3_MSK, CapCompValue); +} + +/** + * @brief Get timer capture/compare value 3. + * @param timx AD16C4T instance + * @retval Timer capture/compare value 3. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccval3_ccrv3(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCVAL3, AD16C4T_CCVAL3_CCRV3_MSK) >> AD16C4T_CCVAL3_CCRV3_POSS); +} + +/** + * @brief Timer CCVAL4 setup. + * @param timx AD16C4T instance + * @param value CCVAL4 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccval4(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->CCVAL4, value); +} + +/** + * @brief GET Timer CCVAL4 register value. + * @param timx AD16C4T instance + * @retval Timer CCVAL4 register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccval4(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->CCVAL4)); +} + +/** + * @brief Timer capture/compare value 4 setup. + * @param timx AD16C4T instance + * @param CapCompValue Capture/Compare value 4 (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_ccval4_ccrv4(AD16C4T_TypeDef *timx, uint32_t CapCompValue) +{ + MODIFY_REG(timx->CCVAL4, AD16C4T_CCVAL4_CCRV4_MSK, CapCompValue); +} + +/** + * @brief Get timer capture/compare value 4. + * @param timx AD16C4T instance + * @retval Timer capture/compare value 4. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_ccval4_ccrv4(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->CCVAL4, AD16C4T_CCVAL4_CCRV4_MSK) >> AD16C4T_CCVAL4_CCRV4_POSS); +} + +/** + * @brief Timer BDCFG setup. + * @param timx AD16C4T instance + * @param value (GOEN | AOEN | BRKP | BRKEN | OFFSSR | OFFSSI | LOCKLVL | DT) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_bdcfg(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->BDCFG, value); +} + +/** + * @brief GET Timer BDCFG register value. + * @param timx AD16C4T instance + * @retval Timer BDCFG register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_bdcfg(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->BDCFG)); +} + +/** + * @brief Timer main output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_bdcfg_goen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->BDCFG, AD16C4T_BDCFG_GOEN_MSK); +} + +/** + * @brief Timer main output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_bdcfg_goen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->BDCFG, AD16C4T_BDCFG_GOEN_MSK); +} + +/** + * @brief Indicates whether the timer main output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_bdcfg_goen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->BDCFG, AD16C4T_BDCFG_GOEN_MSK) == (AD16C4T_BDCFG_GOEN_MSK)); +} + +/** + * @brief Timer automatic output enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_bdcfg_aoen(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->BDCFG, AD16C4T_BDCFG_AOEN_MSK); +} + +/** + * @brief Timer automatic output disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_bdcfg_aoen(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->BDCFG, AD16C4T_BDCFG_AOEN_MSK); +} + +/** + * @brief Indicates whether the timer automatic output is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_bdcfg_aoen(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->BDCFG, AD16C4T_BDCFG_AOEN_MSK) == (AD16C4T_BDCFG_AOEN_MSK)); +} + +/** + * @brief Timer break polarity setup. + * @param timx AD16C4T instance + * @param BreakPolarity Break polarity + * @arg @ref MD_AD16C4T_BREAKPOLARITY_LOW + * @arg @ref MD_AD16C4T_BREAKPOLARITY_HIGH + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_bdcfg_brkp(AD16C4T_TypeDef *timx, uint32_t BreakPolarity) +{ + MODIFY_REG(timx->BDCFG, AD16C4T_BDCFG_BRKP_MSK, BreakPolarity); +} + +/** + * @brief Get timer break polarity. + * @param timx AD16C4T instance + * @retval Timer break polarity. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_bdcfg_brkp(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->BDCFG, AD16C4T_BDCFG_BRKP_MSK) >> AD16C4T_BDCFG_BRKP_POS); +} + +/** + * @brief Timer break enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_bdcfg_brken(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->BDCFG, AD16C4T_BDCFG_BRKEN_MSK); +} + +/** + * @brief Timer break disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_bdcfg_brken(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->BDCFG, AD16C4T_BDCFG_BRKEN_MSK); +} + +/** + * @brief Indicates whether the timer break is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_bdcfg_brken(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->BDCFG, AD16C4T_BDCFG_BRKEN_MSK) == (AD16C4T_BDCFG_BRKEN_MSK)); +} + +/** + * @brief Timer off-state selection for run mode setup. + * @param timx AD16C4T instance + * @param OffStateRun Off-state selection for run mode + * @arg @ref MD_AD16C4T_OFFSTATERUN_DISABLE + * @arg @ref MD_AD16C4T_OFFSTATERUN_ENABLE + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_bdcfg_offssr(AD16C4T_TypeDef *timx, uint32_t OffStateRun) +{ + MODIFY_REG(timx->BDCFG, AD16C4T_BDCFG_OFFSSR_MSK, OffStateRun); +} + +/** + * @brief Get timer off-state selection for run mode. + * @param timx AD16C4T instance + * @retval Timer off-state selection for run mode. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_bdcfg_offssr(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->BDCFG, AD16C4T_BDCFG_OFFSSR_MSK) >> AD16C4T_BDCFG_OFFSSR_POS); +} + +/** + * @brief Timer off-state selection for idle mode setup. + * @param timx AD16C4T instance + * @param OffStateIdle Off-state selection for idle mode + * @arg @ref MD_AD16C4T_OFFSTATEIDLE_DISABLE + * @arg @ref MD_AD16C4T_OFFSTATEIDLE_ENABLE + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_bdcfg_offssi(AD16C4T_TypeDef *timx, uint32_t OffStateIdle) +{ + MODIFY_REG(timx->BDCFG, AD16C4T_BDCFG_OFFSSI_MSK, OffStateIdle); +} + +/** + * @brief Get timer off-state selection for idle mode. + * @param timx AD16C4T instance + * @retval Timer off-state selection for idle mode. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_bdcfg_offssi(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->BDCFG, AD16C4T_BDCFG_OFFSSI_MSK) >> AD16C4T_BDCFG_OFFSSI_POS); +} + +/** + * @brief Timer lock configuration setup. + * @param timx AD16C4T instance + * @param LockLevel Lock configuration + * @arg @ref MD_AD16C4T_LOCKLEVEL_0 + * @arg @ref MD_AD16C4T_LOCKLEVEL_1 + * @arg @ref MD_AD16C4T_LOCKLEVEL_2 + * @arg @ref MD_AD16C4T_LOCKLEVEL_3 + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_bdcfg_locklvl(AD16C4T_TypeDef *timx, uint32_t LockLevel) +{ + MODIFY_REG(timx->BDCFG, AD16C4T_BDCFG_LOCKLVL_MSK, LockLevel); +} + +/** + * @brief Get timer lock configuration. + * @param timx AD16C4T instance + * @retval Timer lock configuration. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_bdcfg_locklvl(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->BDCFG, AD16C4T_BDCFG_LOCKLVL_MSK) >> AD16C4T_BDCFG_LOCKLVL_POSS); +} + +/** + * @brief Timer dead-time generator setup. + * @param timx AD16C4T instance + * @param DeadTime Dead-time generator (between Min_Data=0 and Max_Data=0xFF) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_bdcfg_dt(AD16C4T_TypeDef *timx, uint32_t DeadTime) +{ + MODIFY_REG(timx->BDCFG, AD16C4T_BDCFG_DT_MSK, DeadTime); +} + +/** + * @brief Get timer dead-time generator. + * @param timx AD16C4T instance + * @retval Timer dead-time generator. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_bdcfg_dt(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->BDCFG, AD16C4T_BDCFG_DT_MSK) >> AD16C4T_BDCFG_DT_POSS); +} + +/** + * @brief Timer DMAEN setup. + * @param timx AD16C4T instance + * @param value (TRGIDE | COMDE | CH4DE | CH3DE | CH2DE | CH1DE | UDE) + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_set_dmaen(AD16C4T_TypeDef *timx, uint32_t value) +{ + WRITE_REG(timx->DMAEN, value); +} + +/** + * @brief GET Timer DMAEN register value. + * @param timx AD16C4T instance + * @retval Timer DMAEN register value. + */ + +__STATIC_INLINE uint32_t md_ad16c4t_get_dmaen(AD16C4T_TypeDef *timx) +{ + return (READ_REG(timx->DMAEN)); +} + +/** + * @brief Timer trigger DMA request enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_dmaen_trgide(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->DMAEN, AD16C4T_DMAEN_TRGIDE_MSK); +} + +/** + * @brief Timer trigger DMA request disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_dmaen_trgide(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->DMAEN, AD16C4T_DMAEN_TRGIDE_MSK); +} + +/** + * @brief Indicates whether the timer trigger DMA request is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_dmaen_trgide(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->DMAEN, AD16C4T_DMAEN_TRGIDE_MSK) == (AD16C4T_DMAEN_TRGIDE_MSK)); +} + +/** + * @brief Timer COM DMA request enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_dmaen_comde(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->DMAEN, AD16C4T_DMAEN_COMDE_MSK); +} + +/** + * @brief Timer COM DMA request disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_dmaen_comde(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->DMAEN, AD16C4T_DMAEN_COMDE_MSK); +} + +/** + * @brief Indicates whether the timer trigger COM request is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_dmaen_comde(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->DMAEN, AD16C4T_DMAEN_COMDE_MSK) == (AD16C4T_DMAEN_COMDE_MSK)); +} + +/** + * @brief Timer Capture/Compare 4 DMA request enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_dmaen_ch4de(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->DMAEN, AD16C4T_DMAEN_CH4DE_MSK); +} + +/** + * @brief Timer Capture/Compare 4 DMA request disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_dmaen_ch4de(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->DMAEN, AD16C4T_DMAEN_CH4DE_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 4 DMA request is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_dmaen_ch4de(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->DMAEN, AD16C4T_DMAEN_CH4DE_MSK) == (AD16C4T_DMAEN_CH4DE_MSK)); +} + +/** + * @brief Timer Capture/Compare 3 DMA request enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_dmaen_ch3de(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->DMAEN, AD16C4T_DMAEN_CH3DE_MSK); +} + +/** + * @brief Timer Capture/Compare 3 DMA request disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_dmaen_ch3de(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->DMAEN, AD16C4T_DMAEN_CH3DE_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 3 DMA request is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_dmaen_ch3de(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->DMAEN, AD16C4T_DMAEN_CH3DE_MSK) == (AD16C4T_DMAEN_CH3DE_MSK)); +} + +/** + * @brief Timer Capture/Compare 2 DMA request enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_dmaen_ch2de(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->DMAEN, AD16C4T_DMAEN_CH2DE_MSK); +} + +/** + * @brief Timer Capture/Compare 2 DMA request disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_dmaen_ch2de(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->DMAEN, AD16C4T_DMAEN_CH2DE_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 2 DMA request is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_dmaen_ch2de(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->DMAEN, AD16C4T_DMAEN_CH2DE_MSK) == (AD16C4T_DMAEN_CH2DE_MSK)); +} + +/** + * @brief Timer Capture/Compare 1 DMA request enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_dmaen_ch1de(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->DMAEN, AD16C4T_DMAEN_CH1DE_MSK); +} + +/** + * @brief Timer Capture/Compare 1 DMA request disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_dmaen_ch1de(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->DMAEN, AD16C4T_DMAEN_CH1DE_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare 1 DMA request is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_dmaen_ch1de(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->DMAEN, AD16C4T_DMAEN_CH1DE_MSK) == (AD16C4T_DMAEN_CH1DE_MSK)); +} + +/** + * @brief Timer update DMA request enable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_enable_dmaen_ude(AD16C4T_TypeDef *timx) +{ + SET_BIT(timx->DMAEN, AD16C4T_DMAEN_UDE_MSK); +} + +/** + * @brief Timer update DMA request disable. + * @param timx AD16C4T instance + * @retval None + */ + +__STATIC_INLINE void md_ad16c4t_disable_dmaen_ude(AD16C4T_TypeDef *timx) +{ + CLEAR_BIT(timx->DMAEN, AD16C4T_DMAEN_UDE_MSK); +} + +/** + * @brief Indicates whether the timer Capture/Compare update DMA request is enabled. + * @param timx AD16C4T instance + * @retval State of bit (1 or 0). + */ + +__STATIC_INLINE uint32_t md_ad16c4t_is_enabled_dmaen_ude(AD16C4T_TypeDef *timx) +{ + return (READ_BIT(timx->DMAEN, AD16C4T_DMAEN_UDE_MSK) == (AD16C4T_DMAEN_UDE_MSK)); +} +/** + * @} MD_AD16C4T_Public_Macro + */ + +/* Public functions -----------------------------------------------------------*/ + + + +/** + * @} AD16C4T + */ + + +#endif + +/** + * @} Micro_Driver + */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_adc.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_adc.h new file mode 100644 index 0000000000..3c3bdbc5f8 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_adc.h @@ -0,0 +1,6109 @@ +/** + ****************************************************************************** + * @file md_ADC.h + * @brief ES32F0271 ADC Header File. + * + * @version V1.00.01 + * @date 04/12/2018 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_ADC_H__ +#define __MD_ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_adc.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined ADC + +/** @defgroup ADC ADC + * @brief ADC micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +/* Public types ---------------------------------------------------------------*/ +/* Public constants -----------------------------------------------------------*/ +/* Public functions -----------------------------------------------------------*/ + +/** @defgroup MD_ADC_Public_Constants ADC Public Constants + * @{ + */ + +/** + * @brief ADC Init structure. + */ +typedef struct +{ + uint8_t VRLS; + uint8_t SSx; + uint32_t Sel; + uint32_t Type; + uint32_t Cntini; + uint32_t Cnt; + uint8_t End; + uint8_t Ckdiv; +} md_adc_inittypedef; +/** @defgroup MD_ADC_CFG ADC_CFG Register + * @{ + */ +#define MD_ADC_CFG_TESTEN (0xEDU) /** @brief data ADC Test Enable */ + +#define MD_ADC_CFG_MODE_NORMAL (0x00000000U<CFG, ADC_CFG_TESTEN_MSK, MD_ADC_CFG_TESTEN<CFG, ADC_CFG_MODE_MSK, Mode<CFG, ADC_CFG_MODE_MSK))>>ADC_CFG_MODE_POS); +} + +/** + * @brief Set ADC Wait Counter Value. + * @note Set the wait cycle between each ADC sample. + * @param ADCx ADC Instance + * @param CNT Value between Min_Value=0x00 and Max_Value=0xFF + * @retval None + */ +__STATIC_INLINE void md_adc_set_srate_cnt(ADC_TypeDef *ADCx, uint32_t cnt) +{ + MODIFY_REG(ADCx->SRATE, ADC_SRATE_CNT_MSK, cnt<SRATE, ADC_SRATE_CNT_MSK))>>ADC_SRATE_CNT_POSS); +} + +/** + * @brief Set ADC Wait Counter Initial Value. + * @note Set the Initial Value of ADC wait counter. + * @param ADCx ADC Instance + * @param CNTINI + * @arg @ref CNTINI Value between Min_Value=0x00 and Max_Value=0xFF + * @retval None + */ +__STATIC_INLINE void md_adc_set_srate_cntini(ADC_TypeDef *adcx, uint32_t cntini) +{ + MODIFY_REG(adcx->SRATE, ADC_SRATE_CNTINI_MSK, cntini<SRATE, ADC_SRATE_CNTINI_MSK))>>ADC_SRATE_CNTINI_POSS); +} + +/** + * @brief Set ADC Converter Clock Division. + * @note Get the division ratio of ADC converter clock. 0 to 15 division ratio + * where 0 indicates no division is implemented. To modify CLKDIV, user + * should first set CLKEN to 0 and re-enable this bit after modification + * on CLKDIV. + * @param ADCx ADC Instance + * @param ADC Converter Clock Division + * @arg @ref MD_ADC_SRATE_CKDIV1 + * @arg @ref MD_ADC_SRATE_CKDIV2 + * @arg @ref MD_ADC_SRATE_CKDIV4 + * @arg @ref MD_ADC_SRATE_CKDIV6 + * @arg @ref MD_ADC_SRATE_CKDIV8 + * @arg @ref MD_ADC_SRATE_CKDIV10 + * @arg @ref MD_ADC_SRATE_CKDIV12 + * @arg @ref MD_ADC_SRATE_CKDIV14 + * @arg @ref MD_ADC_SRATE_CKDIV16 + * @arg @ref MD_ADC_SRATE_CKDIV18 + * @arg @ref MD_ADC_SRATE_CKDIV20 + * @arg @ref MD_ADC_SRATE_CKDIV22 + * @arg @ref MD_ADC_SRATE_CKDIV24 + * @arg @ref MD_ADC_SRATE_CKDIV26 + * @arg @ref MD_ADC_SRATE_CKDIV28 + * @arg @ref MD_ADC_SRATE_CKDIV30 + * @retval None + */ +__STATIC_INLINE void md_adc_set_srate_clkdiv(ADC_TypeDef *ADCx, uint32_t clkdiv) +{ + MODIFY_REG(ADCx->SRATE, ADC_SRATE_CKDIV_MSK, clkdiv<SRATE, ADC_SRATE_CKDIV_MSK))>>ADC_SRATE_CKDIV_POSS); +} + +/** + * @brief ADC clock enable. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_clken(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_SRATE_CKEN_MSK); +} + +/** + * @brief ADC clock sisable. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_clken(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_SRATE_CKEN_MSK); +} + +/** + * @brief Check if ADC clock is enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_clken(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_SRATE_CKEN_MSK) == (ADC_SRATE_CKEN_MSK)); +} + +/** + * @brief Channel 15 Invert Control enable. + * @note This is used to invert the data of channel 15. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch15inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH15INV_MSK); +} + +/** + * @brief Channel 15 Invert Control disable. + * @note This is used to invert the data of channel 15. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch15inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH15INV_MSK); +} + +/** + * @brief Check if Channel 15 Invert Control is enabled. + * @note This is used to invert the data of channel 15. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch15inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH15INV_MSK) == (ADC_CHINV_CH15INV_MSK)); +} + +/** + * @brief Channel 14 Invert Control enable. + * @note This is used to invert the data of channel 14. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch14inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH14INV_MSK); +} + +/** + * @brief Channel 14 Invert Control disable. + * @note This is used to invert the data of channel 14. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch14inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH14INV_MSK); +} + +/** + * @brief Check if Channel 14 Invert Control is enabled. + * @note This is used to invert the data of channel 14. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch14inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH14INV_MSK) == (ADC_CHINV_CH14INV_MSK)); +} + +/** + * @brief Channel 13 Invert Control enable. + * @note This is used to invert the data of channel 13. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch13inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH13INV_MSK); +} + +/** + * @brief Channel 13 Invert Control disable. + * @note This is used to invert the data of channel 13. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch13inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH13INV_MSK); +} + +/** + * @brief Check if Channel 13 Invert Control is enabled. + * @note This is used to invert the data of channel 13. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch13inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH13INV_MSK) == (ADC_CHINV_CH13INV_MSK)); +} + +/** + * @brief Channel 12 Invert Control enable. + * @note This is used to invert the data of channel 12. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch12inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH12INV_MSK); +} + +/** + * @brief Channel 12 Invert Control disable. + * @note This is used to invert the data of channel 12. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch12inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH12INV_MSK); +} + +/** + * @brief Check if Channel 12 Invert Control is enabled. + * @note This is used to invert the data of channel 12. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch12inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH12INV_MSK) == (ADC_CHINV_CH12INV_MSK)); +} + +/** + * @brief Channel 11 Invert Control enable. + * @note This is used to invert the data of channel 11. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch11inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH15INV_MSK); +} + +/** + * @brief Channel 11 Invert Control disable. + * @note This is used to invert the data of channel 11. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch11inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH11INV_MSK); +} + +/** + * @brief Check if Channel 11 Invert Control is enabled. + * @note This is used to invert the data of channel 11. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch11inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH11INV_MSK) == (ADC_CHINV_CH11INV_MSK)); +} + +/** + * @brief Channel 10 Invert Control enable. + * @note This is used to invert the data of channel 10. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch10inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH10INV_MSK); +} + +/** + * @brief Channel 10 Invert Control disable. + * @note This is used to invert the data of channel 10. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch10inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH10INV_MSK); +} + +/** + * @brief Check if Channel 10 Invert Control is enabled. + * @note This is used to invert the data of channel 10. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch10inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH10INV_MSK) == (ADC_CHINV_CH10INV_MSK)); +} + +/** + * @brief Channel 9 Invert Control enable. + * @note This is used to invert the data of channel 9. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch9inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH9INV_MSK); +} + +/** + * @brief Channel 9 Invert Control disable. + * @note This is used to invert the data of channel 9. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch9inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH9INV_MSK); +} + +/** + * @brief Check if Channel 9 Invert Control is enabled. + * @note This is used to invert the data of channel 9. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch9inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH9INV_MSK) == (ADC_CHINV_CH9INV_MSK)); +} + +/** + * @brief Channel 8 Invert Control enable. + * @note This is used to invert the data of channel 8. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch8inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH8INV_MSK); +} + +/** + * @brief Channel 8 Invert Control disable. + * @note This is used to invert the data of channel 8. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch8inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH8INV_MSK); +} + +/** + * @brief Check if Channel 8 Invert Control is enabled. + * @note This is used to invert the data of channel 8. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch8inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH8INV_MSK) == (ADC_CHINV_CH8INV_MSK)); +} + +/** + * @brief Channel 7 Invert Control enable. + * @note This is used to invert the data of channel 7. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch7inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH7INV_MSK); +} + +/** + * @brief Channel 7 Invert Control disable. + * @note Disable invert data channel 7. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch7inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH7INV_MSK); +} + +/** + * @brief Check if Channel 7 Invert Control is enabled. + * @note Check invert state of data channel 7. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch7inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH7INV_MSK) == (ADC_CHINV_CH7INV_MSK)); +} + +/** + * @brief Channel 6 Invert Control enable. + * @note This is used to invert the data of channel 6. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch6inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH6INV_MSK); +} + +/** + * @brief Channel 6 Invert Control disable. + * @note Disable invert data channel 6. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch6inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH6INV_MSK); +} + +/** + * @brief Check if Channel 6 Invert Control is enabled. + * @note Check invert state of data channel 6. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch6inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH6INV_MSK) == (ADC_CHINV_CH6INV_MSK)); +} + +/** + * @brief Channel 5 Invert Control enable. + * @note This is used to invert the data of channel 5. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch5inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH5INV_MSK); +} + +/** + * @brief Channel 5 Invert Control disable. + * @note Disable invert data channel 5. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch5inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH5INV_MSK); +} + +/** + * @brief Check if Channel 5 Invert Control is enabled. + * @note Check invert state of data channel 5. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch5inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH5INV_MSK) == (ADC_CHINV_CH5INV_MSK)); +} + +/** + * @brief Channel 4 Invert Control enable. + * @note This is used to invert the data of channel 4. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch4inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH4INV_MSK); +} + +/** + * @brief Channel 4 Invert Control disable. + * @note Disable invert data channel 4. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch4inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH4INV_MSK); +} + +/** + * @brief Check if Channel 4 Invert Control is enabled. + * @note Check invert state of data channel 4. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch4inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH4INV_MSK) == (ADC_CHINV_CH4INV_MSK)); +} + +/** + * @brief Channel 3 Invert Control enable. + * @note This is used to invert the data of channel 3. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch3inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH3INV_MSK); +} + +/** + * @brief Channel 3 Invert Control disable. + * @note Disable invert data channel 3. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch3inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH3INV_MSK); +} + +/** + * @brief Check if Channel 3 Invert Control is enabled. + * @note Check invert state of data of channel 3. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch3inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH3INV_MSK) == (ADC_CHINV_CH3INV_MSK)); +} + +/** + * @brief Channel 2 Invert Control enable. + * @note This is used to invert the data of channel 2. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch2inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH2INV_MSK); +} + +/** + * @brief Channel 2 Invert Control disable. + * @note Disable invert data channel 2. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch2inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH2INV_MSK); +} + +/** + * @brief Check if Channel 2 Invert Control is enabled. + * @note Check invert state of data of channel 2. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch2inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH2INV_MSK) == (ADC_CHINV_CH2INV_MSK)); +} + +/** + * @brief Channel 1 Invert Control enable. + * @note This is used to invert the data of channel 1. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch1inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH1INV_MSK); +} + +/** + * @brief Channel 1 Invert Control disable. + * @note Disable invert data channel 1. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch1inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH1INV_MSK); +} + +/** + * @brief Check if Channel 1 Invert Control is enabled. + * @note Check invert of data of channel 1. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch1inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH1INV_MSK) == (ADC_CHINV_CH1INV_MSK)); +} + +/** + * @brief Channel 0 Invert Control enable. + * @note This is used to invert the data of channel 0. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_srate_ch0inv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SRATE, ADC_CHINV_CH0INV_MSK); +} + +/** + * @brief Channel 0 Invert Control disable. + * @note Disable invert data channel 0. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_srate_ch0inv(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SRATE, ADC_CHINV_CH0INV_MSK); +} + +/** + * @brief Check if Channel 0 Invert Control is enabled. + * @note Check invert state of data of channel 0. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_srate_ch0inv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SRATE, ADC_CHINV_CH0INV_MSK) == (ADC_CHINV_CH0INV_MSK)); +} + +/** + * @brief Set ADC SRATE register. + * @note This is used to set SRATE register. + * @param ADCx ADC Instance + * @param SRATE + * @retval NONE. + */ +__STATIC_INLINE void md_adc_set_srate(ADC_TypeDef *adcx, uint32_t srate) +{ + WRITE_REG(adcx->SRATE, srate); +} + +/** + * @brief Get ADC SRATE register. + * @note This is used to read SRATE register. + * @param ADCx ADC Instance + * @param SRATE + * @retval SRATE Register Value. + */ +__STATIC_INLINE uint32_t md_adc_get_srate(ADC_TypeDef *adcx) +{ + return READ_REG(adcx->SRATE); +} + +/** + * @brief Set ADC Channel 7 PGA Gain. + * @note This is used to select channel 7 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl_ch7pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINL, ADC_GAINL_CH7PGA_MSK, Gain<GAINL, ADC_GAINL_CH7PGA_MSK)>>ADC_GAINL_CH7PGA_POSS); +} + +/** + * @brief Set ADC Channel 6 PGA Gain. + * @note This is used to select channel 6 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl_ch6pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINL, ADC_GAINL_CH6PGA_MSK, Gain<GAINL, ADC_GAINL_CH6PGA_MSK)>>ADC_GAINL_CH6PGA_POSS); +} + +/** + * @brief Set ADC Channel 5 PGA Gain. + * @note This is used to select channel 5 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl_ch5pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINL, ADC_GAINL_CH5PGA_MSK, Gain<GAINL, ADC_GAINL_CH5PGA_MSK)>>ADC_GAINL_CH5PGA_POSS); +} + +/** + * @brief Set ADC Channel 4 PGA Gain. + * @note This is used to select channel 4 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl_ch4pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINL, ADC_GAINL_CH4PGA_MSK, Gain<GAINL, ADC_GAINL_CH4PGA_MSK)>>ADC_GAINL_CH4PGA_POSS); +} + +/** + * @brief Set ADC Channel 3 PGA Gain. + * @note This is used to select channel 3 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl_ch3pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINL, ADC_GAINL_CH3PGA_MSK, Gain<GAINL, ADC_GAINL_CH3PGA_MSK)>>ADC_GAINL_CH3PGA_POSS); +} + +/** + * @brief Set ADC Channel 2 PGA Gain. + * @note This is used to select channel 2 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl_ch2pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINL, ADC_GAINL_CH2PGA_MSK, Gain<GAINL, ADC_GAINL_CH2PGA_MSK)>>ADC_GAINL_CH2PGA_POSS); +} + +/** + * @brief Set ADC Channel 1 PGA Gain. + * @note This is used to select channel 1 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl_ch1pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINL, ADC_GAINL_CH1PGA_MSK, Gain<GAINL, ADC_GAINL_CH1PGA_MSK)>>ADC_GAINL_CH1PGA_POSS); +} + +/** + * @brief Set ADC Channel 0 PGA Gain. + * @note This is used to select channel 0 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl_ch0pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINL, ADC_GAINL_CH0PGA_MSK, Gain<GAINL, ADC_GAINL_CH0PGA_MSK)>>ADC_GAINL_CH0PGA_POSS); +} + +/** + * @brief Set ADC Channels 0~7 PGA Gain. + * @note This is used to select channels 0-7 PGA gain. + * @param ADCx ADC Instance + * @param GainL Register Values for CH0~CH7. + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainl(ADC_TypeDef *ADCx, uint32_t GainL) +{ + WRITE_REG(ADCx->GAINL, GainL); +} + +/** + * @brief Get ADC Channels 0~7 PGA Gain. + * @note This is used to read channels 0-7 PGA gain. + * @param ADCx ADC Instance + * @retval GainL Register Values for CH0~CH7. + */ +__STATIC_INLINE uint32_t md_adc_get_gainl(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->GAINL); +} + +/** + * @brief Set ADC Channel 15 PGA Gain. + * @note This is used to select channel 15 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh_ch15pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINH, ADC_GAINH_CH15PGA_MSK, Gain<GAINH, ADC_GAINH_CH15PGA_MSK)>>ADC_GAINH_CH15PGA_POSS); +} + +/** + * @brief Set ADC Channel 14 PGA Gain. + * @note This is used to select channel 14 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh_ch14pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINH, ADC_GAINH_CH14PGA_MSK, Gain<GAINH, ADC_GAINH_CH14PGA_MSK)>>ADC_GAINH_CH14PGA_POSS); +} + +/** + * @brief Set ADC Channel 13 PGA Gain. + * @note This is used to select channel 13 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh_ch13pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINH, ADC_GAINH_CH13PGA_MSK, Gain<GAINH, ADC_GAINH_CH13PGA_MSK)>>ADC_GAINH_CH13PGA_POSS); +} + +/** + * @brief Set ADC Channel 12 PGA Gain. + * @note This is used to select channel 12 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh_ch12pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINH, ADC_GAINH_CH12PGA_MSK, Gain<GAINH, ADC_GAINH_CH12PGA_MSK)>>ADC_GAINH_CH12PGA_POSS); +} + +/** + * @brief Set ADC Channel 11 PGA Gain. + * @note This is used to select channel 11 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh_ch11pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINH, ADC_GAINH_CH11PGA_MSK, Gain<GAINH, ADC_GAINH_CH11PGA_MSK)>>ADC_GAINH_CH11PGA_POSS); +} + +/** + * @brief Set ADC Channel 10 PGA Gain. + * @note This is used to select channel 10 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh_ch10pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINH, ADC_GAINH_CH10PGA_MSK, Gain<GAINH, ADC_GAINH_CH10PGA_MSK)>>ADC_GAINH_CH10PGA_POSS); +} + +/** + * @brief Set ADC Channel 9 PGA Gain. + * @note This is used to select channel 9 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh_ch9pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINH, ADC_GAINH_CH9PGA_MSK, Gain<GAINH, ADC_GAINH_CH9PGA_MSK)>>ADC_GAINH_CH9PGA_POSS); +} + +/** + * @brief Set ADC Channel 8 PGA Gain. + * @note This is used to select channel 8 PGA gain. + * @param ADCx ADC Instance + * @param ADC PGA Gain + * @param Gain parameter can be one of the following values: + * @arg @ref MD_ADC_PGA_GAIN_X1 + * @arg @ref MD_ADC_PGA_GAIN_X2 + * @arg @ref MD_ADC_PGA_GAIN_X3 + * @arg @ref MD_ADC_PGA_GAIN_X4 + * @arg @ref MD_ADC_PGA_GAIN_X5 + * @arg @ref MD_ADC_PGA_GAIN_X6 + * @arg @ref MD_ADC_PGA_GAIN_X7 + * @arg @ref MD_ADC_PGA_GAIN_X8 + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh_ch8pga(ADC_TypeDef *ADCx, uint32_t Gain) +{ + MODIFY_REG(ADCx->GAINH, ADC_GAINH_CH8PGA_MSK, Gain<GAINH, ADC_GAINH_CH8PGA_MSK)>>ADC_GAINH_CH8PGA_POSS); +} + +/** + * @brief Set ADC Channels 8~15 PGA Gain. + * @note This register is used to select channels 8-15 PGA gain. + * @param GainH Register Values for CH8~CH15. + * @retval None + */ +__STATIC_INLINE void md_adc_set_gainh(ADC_TypeDef *ADCx, uint32_t GainH) +{ + WRITE_REG(ADCx->GAINH, GainH); +} + +/** + * @brief Get ADC Channels 8~15 PGA Gain. + * @note This register is used to read channels 8-15 PGA gain. + * @param ADCx ADC Instance + * @retval GainH Register Values for CH8~CH15. + */ +__STATIC_INLINE uint32_t md_adc_get_gainh(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->GAINH); +} + +/** + * @brief Refresh ADC FIFOs SS0~SS3. + * @note This register allowed users to reset ADC FIFO when starting a + * new Sample Sequencer. + * @param ADCx ADC Instance + * @param Value if bit (1 or 0) + * @retval None + */ +__STATIC_INLINE void md_adc_set_frf_ffrst(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->FRF, ADC_FRF_FFRST_MSK); +} + +/** + * @brief Get ADC FIFO Refresh Status. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_frf_ffrst(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->FRF, ADC_FRF_FFRST_MSK)>>ADC_FRF_FFRST_POS); +} + +/** + * @brief Refresh ADC SS3 FIFO. + * @note This register is used to refresh the FIFO of sequencer 3 at any + * time. This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_set_frf_ss3rf(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->FRF, ADC_FRF_SS3RF_MSK); +} + +/** + * @brief Refresh ADC SS32 FIFO. + * @note This register is used to refresh the FIFO of sequencer 2 at any + * time. This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_set_frf_ss2rf(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->FRF, ADC_FRF_SS2RF_MSK); +} + +/** + * @brief Refresh ADC SS1 FIFO. + * @note This register is used to refresh the FIFO of sequencer 1 at any + * time. This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_set_frf_ss1rf(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->FRF, ADC_FRF_SS1RF_MSK); +} + +/** + * @brief Refresh ADC SS0 FIFO. + * @note This register is used to refresh the FIFO of sequencer 0 at any + * time. This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_set_frf_ss0rf(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->FRF, ADC_FRF_SS0RF_MSK); +} + +/** + * @brief Refresh ADC FIFO Register. + * @note This is used to set RFR register. + * @param ADCx ADC Instance + * @param Register Value + * @retval None + */ +__STATIC_INLINE void md_adc_set_frf(ADC_TypeDef *ADCx, uint32_t Value) +{ + WRITE_REG(ADCx->FRF, Value); +} + +/** + * @brief Get ADC FIFO Refresh Register. + * @note This is used to get RFR register. + * @param ADCx ADC Instance + * @retval Register Value + */ +__STATIC_INLINE uint32_t md_adc_get_frf(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->FRF); +} + +/** + * @brief Check if all ADC Sequencer is idle. + * @note Check if SS0~SS3 is idle. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_idle(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SSEN, ADC_SSEN_IDLE_MSK) == (ADC_SSEN_IDLE_MSK)); +} + +/** + * @brief ADC Sample Sequencer 3 (SS3) Enable. + * @note User can set this bit to enable sample sequencer 3 (SS3). + * This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ssen_ss3en(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SSEN, ADC_SSEN_SS3EN_MSK); +} + +/** + * @brief ADC Sample Sequencer 3 (SS3) Disable. + * @note Disable sample sequencer 3 (SS3). + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ssen_ss3en(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SSEN, ADC_SSEN_SS3EN_MSK); +} + +/** + * @brief Check if ADC Sample Sequencer 3 (SS3) is enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ssen_ss3en(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SSEN, ADC_SSEN_SS3EN_MSK) == (ADC_SSEN_SS3EN_MSK)); +} + +/** + * @brief ADC Sample Sequencer 2 (SS2) Enable. + * @note User can set this bit to enable sample sequencer 2 (SS2). + * This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ssen_ss2en(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SSEN, ADC_SSEN_SS2EN_MSK); +} + +/** + * @brief ADC Sample Sequencer 2 (SS2) Disable. + * @note Disable sample sequencer 2 (SS2). + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ssen_ss2en(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SSEN, ADC_SSEN_SS2EN_MSK); +} + +/** + * @brief Check if ADC Sample Sequencer 2 (SS2) is enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ssen_ss2en(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SSEN, ADC_SSEN_SS2EN_MSK) == (ADC_SSEN_SS2EN_MSK)); +} + +/** + * @brief ADC Sample Sequencer 1 (SS1) Enable. + * @note User can set this bit to enable sample sequencer 1 (SS1). + * This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ssen_ss1en(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SSEN, ADC_SSEN_SS1EN_MSK); +} + +/** + * @brief ADC Sample Sequencer 1 (SS1) Disable. + * @note Disable sample sequencer 1 (SS1). + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ssen_ss1en(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SSEN, ADC_SSEN_SS1EN_MSK); +} + +/** + * @brief Check if ADC Sample Sequencer 1 (SS1) is enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ssen_ss1en(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SSEN, ADC_SSEN_SS1EN_MSK) == (ADC_SSEN_SS1EN_MSK)); +} + +/** + * @brief ADC Sample Sequencer 0 (SS0) Enable. + * @note User can set this bit to enable sequencer 0 (SS0). + * This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ssen_ss0en(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SSEN, ADC_SSEN_SS0EN_MSK); +} + +/** + * @brief AADC Sample Sequencer 0 (SS0) Disable. + * @note Disable sample sequencer 0 (SS0). + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ssen_ss0en(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SSEN, ADC_SSEN_SS0EN_MSK); +} + +/** + * @brief Check if ADC Sample Sequencer 0 (SS0) is enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ssen_ss0en(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SSEN, ADC_SSEN_SS0EN_MSK) == (ADC_SSEN_SS0EN_MSK)); +} + +/** + * @brief ADC Sample Sequencer 3 (SS3) Initiate. + * @note Triggers smapling on SS3 if the sequencer is enabled in the ADC_SSEN_SS3EN. + * This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_set_swtri_ss3(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SWTRI, ADC_SWTRI_SS3_MSK); +} + +/** + * @brief ADC Sample Sequencer 2 (SS2) Initiate. + * @note Triggers smapling on SS2 if the sequencer is enabled in the ADC_SSEN_SS2EN. + * This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_set_swtri_ss2(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SWTRI, ADC_SWTRI_SS2_MSK); +} + +/** + * @brief ADC Sample Sequencer 1 (SS1) Initiate. + * @note Triggers smapling on SS1 if the sequencer is enabled in the ADC_SSEN_SS1EN. + * This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_set_swtri_ss1(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SWTRI, ADC_SWTRI_SS1_MSK); +} + +/** + * @brief ADC Sample Sequencer 0 (SS0) Initiate. + * @note Triggers smapling on SS0 if the sequencer is enabled in the ADC_SSEN_SS0EN. + * This bit will cleared by itself. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_set_swtri_ss0(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SWTRI, ADC_SWTRI_SS0_MSK); +} + +/** + * @brief ADC Timeout Interrupt Enable. + * @note User can set this bit to enable timeout Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ier_toie(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, ADC_IER_TOIE_MSK); +} + +/** + * @brief ADC Sample Sequencer 3 (SS3) Interrupt Enable. + * @note User can set this bit to enable sequencer 3 Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ier_ss3ie(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, ADC_IER_SS3IE_MSK); +} + +/** + * @brief ADC Sample Sequencer 2 (SS2) Interrupt Enable. + * @note User can set this bit to enable sequencer 2 Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ier_ss2ie(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, ADC_IER_SS2IE_MSK); +} + +/** + * @brief ADC Sample Sequencer 1 (SS1) Interrupt Enable. + * @note User can set this bit to enable sequencer 1 Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ier_ss1ie(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, ADC_IER_SS1IE_MSK); +} + +/** + * @brief ADC Sample Sequencer 0 (SS0) Interrupt Enable. + * @note User can set this bit to enable sequencer 0 Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ier_ss0ie(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, ADC_IER_SS0IE_MSK); +} + +/** + * @brief ADC Timeout Interrupt Disable. + * @note User can set this bit to disable timeout Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_idr_toid(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IDR, ADC_IDR_TOID_MSK); +} + +/** + * @brief ADC Sample Sequencer 3 (SS3) Interrupt Disable. + * @note User can set this bit to disable sequencer 3 Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_idr_ss3id(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IDR, ADC_IDR_SS3ID_MSK); +} + +/** + * @brief ADC Sample Sequencer 2 (SS2) Interrupt Disable. + * @note User can set this bit to disable sequencer 2 Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_idr_ss2id(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IDR, ADC_IDR_SS2ID_MSK); +} + +/** + * @brief ADC Sample Sequencer 1 (SS1) Interrupt Disable. + * @note User can set this bit to disable sequencer 1 Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_idr_ss1id(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IDR, ADC_IDR_SS1ID_MSK); +} + +/** + * @brief ADC Sample Sequencer 0 (SS0) Interrupt Disable. + * @note User can set this bit to disable sequencer 0 Interrupt function. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_idr_ss0id(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IDR, ADC_IDR_SS0ID_MSK); +} + +/** + * @brief Check if ADC Timeout Interrupt is Enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ivs_toivs(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IVS, ADC_IVS_TOIVS_MSK) == (ADC_IVS_TOIVS_MSK)); +} + +/** + * @brief Check if ADC Sample Sequencer 3 (SS3) Interrupt is Enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ivs_ss3ivs(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IVS, ADC_IVS_SS3IVS_MSK) == (ADC_IVS_SS3IVS_MSK)); +} + +/** + * @brief Check if ADC Sample Sequencer 2 (SS2) Interrupt is Enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ivs_ss2ivs(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IVS, ADC_IVS_SS2IVS_MSK) == (ADC_IVS_SS2IVS_MSK)); +} + +/** + * @brief Check if ADC Sample Sequencer 1 (SS1) Interrupt is Enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ivs_ss1ivs(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IVS, ADC_IVS_SS1IVS_MSK) == (ADC_IVS_SS1IVS_MSK)); +} + +/** + * @brief Check if ADC Sample Sequencer 0 (SS0) Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ivs_ss0ivs(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IVS, ADC_IVS_SS0IVS_MSK) == (ADC_IVS_SS0IVS_MSK)); +} + +/** + * @brief Check Timeout Raw Interrupt Flag Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_rif_torif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->RIF, ADC_RIF_TORIF_MSK) == (ADC_RIF_TORIF_MSK)); +} + +/** + * @brief Check ADC Sample Sequencer 3 (SS3) Raw Interrupt Flag Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_rif_ss3rif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->RIF, ADC_RIF_SS3RIF_MSK) == (ADC_RIF_SS3RIF_MSK)); +} + +/** + * @brief Check ADC Sample Sequencer 2 (SS2) Raw Interrupt Flag Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_rif_ss2rif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->RIF, ADC_RIF_SS2RIF_MSK) == (ADC_RIF_SS2RIF_MSK)); +} + +/** + * @brief Check ADC Sample Sequencer 1 (SS1) Raw Interrupt Flag Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_rif_ss1rif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->RIF, ADC_RIF_SS1RIF_MSK) == (ADC_RIF_SS1RIF_MSK)); +} + +/** + * @brief Check ADC Sample Sequencer 0 (SS0) Raw Interrupt Flag Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_rif_ss0rif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->RIF, ADC_RIF_SS0RIF_MSK) == (ADC_RIF_SS0RIF_MSK)); +} + +/** + * @brief Check Timeout Interrupt Flag Masked Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ifm_torif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IFM, ADC_IFM_TOIFM_MSK) == (ADC_IFM_TOIFM_MSK)); +} + +/** + * @brief Check ADC Sample Sequencer 3 (SS3) Interrupt Flag Masked Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ifm_ss3rif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IFM, ADC_IFM_SS3IFM_MSK) == (ADC_IFM_SS3IFM_MSK)); +} + +/** + * @brief Check ADC Sample Sequencer 2 (SS2) Interrupt Flag Masked Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ifm_ss2rif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IFM, ADC_IFM_SS2IFM_MSK) == (ADC_IFM_SS2IFM_MSK)); +} + +/** + * @brief Check ADC Sample Sequencer 1 (SS1) Interrupt Flag Masked Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ifm_ss1rif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IFM, ADC_IFM_SS1IFM_MSK) == (ADC_IFM_SS1IFM_MSK)); +} + +/** + * @brief Check ADC Sample Sequencer 0 (SS0) Interrupt Flag Masked Status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ifm_ss0rif(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->IFM, ADC_IFM_SS0IFM_MSK) == (ADC_IFM_SS0IFM_MSK)); +} + +/** + * @brief ADC Timeout Interrupt Clear. + * @note User can set this bit to clear timeout interrupt status. + * @param ADCx ADC Instance + * @retval None. + */ +__STATIC_INLINE void md_uart_clear_flag_icr_toicr(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->ICR, ADC_ICR_TOICR_MSK); +} + +/** + * @brief ADC Sample Sequencer 3 (SS3) Interrupt Clear. + * @note User can set this bit to clear SS3 interrupt status. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_clear_flag_icr_ss3icr(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->ICR, ADC_ICR_SS3ICR_MSK); +} + +/** + * @brief ADC Sample Sequencer 2 (SS2) Interrupt Clear. + * @note User can set this bit to clear SS2 interrupt status. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_clear_flag_icr_ss2icr(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->ICR, ADC_ICR_SS2ICR_MSK); +} + +/** + * @brief ADC Sample Sequencer 1 (SS1) Interrupt Clear. + * @note User can set this bit to clear SS1 interrupt status. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_clear_flag_icr_ss1icr(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->ICR, ADC_ICR_SS1ICR_MSK); +} + +/** + * @brief ADC Sample Sequencer 0 (SS0) Interrupt Clear. + * @note User can set this bit to clear SS0 interrupt status. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_clear_flag_icr_ss0icr(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->ICR, ADC_ICR_SS0ICR_MSK); +} + +/** + * @brief ADC SS3 DMA Function Enable. + * @note User can set this register to enable DMA function. + * For S3, if set when FIFO is not empty, DMA Single REQ will rise. + * @param UARTx UART Instance + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_dma_ss3dmaen(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->DMA, ADC_DMA_SS3_DMAEN_MSK); +} + +/** + * @brief ADC SS3 DMA Function Disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_dma_ss3dmaen(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->DMA, ADC_DMA_SS3_DMAEN_MSK); +} + +/** + * @brief Check if ADC SS3 DMA is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_dma_ss3dmaen(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->DMA, ADC_DMA_SS3_DMAEN_MSK) == (ADC_DMA_SS3_DMAEN_MSK)); +} + +/** + * @brief ADC SS2 DMA Function Enable. + * @note User can set this register to enable DMA function. + * For S2, if set when FIFO is not empty, DMA Single REQ will rise. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_dma_ss2dmaen(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->DMA, ADC_DMA_SS2_DMAEN_MSK); +} + +/** + * @brief ADC SS2 DMA Function Disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_dma_ss2dmaen(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->DMA, ADC_DMA_SS2_DMAEN_MSK); +} + +/** + * @brief Check if ADC SS2 DMA is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_dma_ss2dmaen(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->DMA, ADC_DMA_SS2_DMAEN_MSK) == (ADC_DMA_SS2_DMAEN_MSK)); +} + +/** + * @brief ADC SS1 DMA Function Enable. + * @note User can set this register to enable DMA function. + * For S1, if set when FIFO is not empty, DMA Single REQ will rise. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_dma_ss1dmaen(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->DMA, ADC_DMA_SS1_DMAEN_MSK); +} + +/** + * @brief ADC SS1 DMA Function Disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_dma_ss1dmaen(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->DMA, ADC_DMA_SS1_DMAEN_MSK); +} + +/** + * @brief Check if ADC SS1 DMA is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_dma_ss1dmaen(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->DMA, ADC_DMA_SS1_DMAEN_MSK) == (ADC_DMA_SS1_DMAEN_MSK)); +} + +/** + * @brief ADC SS0 DMA Function Enable. + * @note User can set this register to enable DMA function. + * For S0, if set when FIFO is not empty, DMA Single REQ will rise. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_dma_ss0dmaen(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->DMA, ADC_DMA_SS0_DMAEN_MSK); +} + +/** + * @brief ADC SS0 DMA Function Disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_dma_ss0dmaen(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->DMA, ADC_DMA_SS0_DMAEN_MSK); +} + +/** + * @brief Check if ADC SS3 DMA is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_dma_ss0dmaen(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->DMA, ADC_DMA_SS0_DMAEN_MSK) == (ADC_DMA_SS0_DMAEN_MSK)); +} + +/** + * @brief Set SS0 Trigger Select. + * @note This field selects the trigger source for Sample Sequencer 0. + * @param ADCx ADC Instance. + * @param Sample sequencer trigger sources. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_SEL_SW + * @arg @ref MD_ADC_SS_CON_SEL_BS16T1 + * @arg @ref MD_ADC_SS_CON_SEL_ALWAYS + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T2 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T3 + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T2 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T3 + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T4 + * @arg @ref MD_ADC_SS_CON_SEL_AD16C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GPIO + * @arg @ref MD_ADC_SS_CON_SEL_CMP0 + * @arg @ref MD_ADC_SS_CON_SEL_CMP1 + * @arg @ref MD_ADC_SS_CON_SEL_CMP2 + * @arg @ref MD_ADC_SS_CON_SEL_CMP3 + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss0_con_sel(ADC_TypeDef *ADCx, uint32_t TrigSource) +{ + MODIFY_REG(ADCx->SS0_CON, ADC_SS0_CON_SEL_MSK, TrigSource<SS0_CON, ADC_SS0_CON_SEL_MSK)>>ADC_SS0_CON_SEL_POSS); +} + +/** + * @brief Set ADC Sample Sequencer 0 (SS0) Trigger Type select. + * @note User can set this bit to select the type of trigger. + * @param Sample sequencer trigger types. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_TYP_EDGE + * @arg @ref MD_ADC_SS_COM_TYP_LEVEL + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss0_con_type(ADC_TypeDef *ADCx, uint32_t TrigType) +{ + MODIFY_REG(ADCx->SS0_CON, ADC_SS0_CON_TYP_MSK, TrigType<SS0_CON, ADC_SS0_CON_TYP_MSK)>>ADC_SS0_CON_TYP_POS); +} + +/** + * @brief Set ADC Sample Sequencer 0 (SS0) Priority. + * @note This field contains a binary-encoded value specifying the + * priority encoding of SS0. The prioriteies assigned to the + * sequencers must be uniquely mapped. + * @param ADCx ADC Instance. + * @param Sample sequencer trigger priorities. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS0_CON_PRI_HIGHEST + * @arg @ref MD_ADC_SS0_CON_PRI_SECOND + * @arg @ref MD_ADC_SS0_CON_PRI_THIRD + * @arg @ref MD_ADC_SS0_CON_PRI_LOWEST + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss0_con_pri(ADC_TypeDef *ADCx, uint32_t priority) +{ + MODIFY_REG(ADCx->SS0_CON, ADC_SS0_CON_PRI_MSK, priority<SS0_CON, ADC_SS0_CON_PRI_MSK)>>ADC_SS0_CON_PRI_POSS); +} + +/** + * @brief Enable One Shot Trigger Mode. + * @note When set HIGH, each trigger will only sample once and use one slot in FIFO. + * @param ADCx ADC Instance. + * @retval None + */ +__STATIC_INLINE void md_adc_enable_ss0_con_one(ADC_TypeDef *adcx) +{ + SET_BIT(adcx->SS0_CON, ADC_SS0_CON_ONE_MSK); +} + +/** + * @brief Disable One Shot Trigger Mode. + * @param ADCx ADC Instance. + * @retval None + */ +__STATIC_INLINE void md_adc_disable_ss0_con_one(ADC_TypeDef *adcx) +{ + CLEAR_BIT(adcx->SS0_CON, ADC_SS0_CON_ONE_MSK); +} + +/** + * @brief Set 8th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux0_mux7(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX0, ADC_SS0_MUX0_MUX7_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX0_MUX7_MSK)>>ADC_SS0_MUX0_MUX7_POSS); +} + +/** + * @brief Set 7th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux0_mux6(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX0, ADC_SS0_MUX0_MUX6_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX0_MUX6_MSK)>>ADC_SS0_MUX0_MUX6_POSS); +} + +/** + * @brief Set 6th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux0_mux5(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX0, ADC_SS0_MUX0_MUX5_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX0_MUX5_MSK)>>ADC_SS0_MUX0_MUX5_POSS); +} + +/** + * @brief Set 5th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux0_mux4(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX0, ADC_SS0_MUX0_MUX4_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX0_MUX4_MSK)>>ADC_SS0_MUX0_MUX4_POSS); +} + +/** + * @brief Set 4th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux0_mux3(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX0, ADC_SS0_MUX0_MUX3_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX0_MUX3_MSK)>>ADC_SS0_MUX0_MUX3_POSS); +} + +/** + * @brief Set 3rd Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux0_mux2(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX0, ADC_SS0_MUX0_MUX2_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX0_MUX2_MSK)>>ADC_SS0_MUX0_MUX2_POSS); +} + +/** + * @brief Set 2nd Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux0_mux1(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX0, ADC_SS0_MUX0_MUX1_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX0_MUX1_MSK)>>ADC_SS0_MUX0_MUX1_POSS); +} + +/** + * @brief Set 1st Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux0_mux0(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX0, ADC_SS0_MUX0_MUX0_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX0_MUX0_MSK)>>ADC_SS0_MUX0_MUX0_POSS); +} + +/** + * @brief Set ADC channels MUX 0~7. + * @note Set ADC SS0_MUX0 register. + * @note Mapping ADINx to ADC channels 0~7. + + * @param ADC Channel + * @param MUX Register + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss0_mux0(ADC_TypeDef *ADCx, uint32_t RegValue) +{ + WRITE_REG(ADCx->SS0_MUX0, RegValue); +} + +/** + * @brief Get ADC channels MUX 0~7. + * @note Get ADC SS0_MUX0 register. + * @param ADCx ADC Instance + * @retval SS0_MUX0 Register Value + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_mux0(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->SS0_MUX0); +} + +/** + * @brief Set 16th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux1_mux15(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX1, ADC_SS0_MUX1_MUX15_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX1_MUX15_MSK)>>ADC_SS0_MUX1_MUX15_POSS); +} + +/** + * @brief Set 15th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux1_mux14(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX1, ADC_SS0_MUX1_MUX14_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX1_MUX14_MSK)>>ADC_SS0_MUX1_MUX14_POSS); +} + +/** + * @brief Set 14th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux1_mux13(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX1, ADC_SS0_MUX1_MUX13_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX1_MUX13_MSK)>>ADC_SS0_MUX1_MUX13_POSS); +} + +/** + * @brief Set 13th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux1_mux12(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX1, ADC_SS0_MUX1_MUX12_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX1_MUX12_MSK)>>ADC_SS0_MUX1_MUX12_POSS); +} + +/** + * @brief Set 12th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux1_mux11(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX1, ADC_SS0_MUX1_MUX11_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX1_MUX11_MSK)>>ADC_SS0_MUX1_MUX11_POSS); +} + +/** + * @brief Set 11th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux1_mux10(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX1, ADC_SS0_MUX1_MUX10_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX1_MUX10_MSK)>>ADC_SS0_MUX1_MUX10_POSS); +} + +/** + * @brief Set 10th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux1_mux9(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX1, ADC_SS0_MUX1_MUX9_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX1_MUX9_MSK)>>ADC_SS0_MUX1_MUX9_POSS); +} + +/** + * @brief Set 9th Sample Input Select. + * @note User can set this register to select which channel will be + * sampled. For example, a value of n indicates the input is + * channel n. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss0_mux1_mux8(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS0_MUX1, ADC_SS0_MUX1_MUX8_MSK, AdinPin<SS0_MUX0, ADC_SS0_MUX1_MUX8_MSK)>>ADC_SS0_MUX1_MUX8_POSS); +} + +/** + * @brief Set ADC channels MUX 8~15. + * @note Set SS0_MUX1 register for channels 8~15. + * @param ADCx ADC Instance. + * @param SS0 MUX1 Register. + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss0_mux1(ADC_TypeDef *ADCx, uint32_t RegValue) +{ + WRITE_REG(ADCx->SS0_MUX1, RegValue); +} + +/** + * @brief Get ADC channels MUX 8~15. + * @note Get SS0_MUX1 register for channels 8~15. + * @param ADCx ADC Instance. + * @retval SS0 MUX1 Register. + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_mux1(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->SS0_MUX1); +} + +/** + * @brief 16th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie15(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE15_MSK); +} + +/** + * @brief 16th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie15(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE15_MSK); +} + +/** + * @brief Check if 16th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie15(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE15_MSK) == (ADC_SS0_END_IE15_MSK)); +} + +/** + * @brief 15th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie14(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE14_MSK); +} + +/** + * @brief 15th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie14(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE14_MSK); +} + +/** + * @brief Check if 15th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie14(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE14_MSK) == (ADC_SS0_END_IE14_MSK)); +} + +/** + * @brief 14th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie13(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE13_MSK); +} + +/** + * @brief 14th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie13(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE13_MSK); +} + +/** + * @brief Check if 14th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie13(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE13_MSK) == (ADC_SS0_END_IE13_MSK)); +} + +/** + * @brief 13th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie12(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE12_MSK); +} + +/** + * @brief 13th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie12(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE12_MSK); +} + +/** + * @brief Check if 13th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie12(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE12_MSK) == (ADC_SS0_END_IE12_MSK)); +} + +/** + * @brief 12th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie11(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE11_MSK); +} + +/** + * @brief 12th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie11(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE11_MSK); +} + +/** + * @brief Check 12th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie11(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE11_MSK) == (ADC_SS0_END_IE11_MSK)); +} + +/** + * @brief 11th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie10(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE10_MSK); +} + +/** + * @brief 11th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie10(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE10_MSK); +} + +/** + * @brief Check if 11th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie10(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE10_MSK) == (ADC_SS0_END_IE10_MSK)); +} + +/** + * @brief 10th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie9(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE9_MSK); +} + +/** + * @brief 10th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie9(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE9_MSK); +} + +/** + * @brief Check if 10th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie9(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE9_MSK) == (ADC_SS0_END_IE9_MSK)); +} + +/** + * @brief 9th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie8(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE8_MSK); +} + +/** + * @brief 9th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie8(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE8_MSK); +} + +/** + * @brief Check if 9th Sample Interrupt is Enable. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie8(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE8_MSK) == (ADC_SS0_END_IE8_MSK)); +} + +/** + * @brief 8th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie7(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE7_MSK); +} + +/** + * @brief 8th Sample Interrupt Disable + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie7(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE7_MSK); +} + +/** + * @brief Check if 8th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie7(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE7_MSK) == (ADC_SS0_END_IE7_MSK)); +} + +/** + * @brief 7th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie6(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE6_MSK); +} + +/** + * @brief 7th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie6(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE6_MSK); +} + +/** + * @brief Check if 7th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie6(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE6_MSK) == (ADC_SS0_END_IE6_MSK)); +} + + +/** + * @brief 6th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie5(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE5_MSK); +} + +/** + * @brief 6th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie5(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE5_MSK); +} + +/** + * @brief Check if 6th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie5(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE5_MSK) == (ADC_SS0_END_IE5_MSK)); +} + +/** + * @brief 5th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie4(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE4_MSK); +} + +/** + * @brief 5th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie4(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE4_MSK); +} + +/** + * @brief Check if 5th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie4(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE4_MSK) == (ADC_SS0_END_IE4_MSK)); +} + +/** + * @brief 4th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie3(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE3_MSK); +} + +/** + * @brief 4th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie3(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE3_MSK); +} + +/** + * @brief Check if 4th Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie3(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE3_MSK) == (ADC_SS0_END_IE3_MSK)); +} + +/** + * @brief 3rd Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie2(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE2_MSK); +} + +/** + * @brief 3rd Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie2(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE2_MSK); +} + +/** + * @brief Check if 3rd Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie2(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE2_MSK) == (ADC_SS0_END_IE2_MSK)); +} + +/** + * @brief 2nd Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie1(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE1_MSK); +} + +/** + * @brief 2nd Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie1(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE1_MSK); +} + +/** + * @brief Check if 2nd Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie1(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE1_MSK) == (ADC_SS0_END_IE1_MSK)); +} + +/** + * @brief 1st Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss0_end_ie0(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_END_IE0_MSK); +} + +/** + * @brief 1st Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss0_end_ie0(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS0_END, ADC_SS0_END_IE0_MSK); +} + +/** + * @brief Check if 1st Sample Interrupt is Enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss0_end_ie0(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_END, ADC_SS0_END_IE0_MSK) == (ADC_SS0_END_IE0_MSK)); +} + +/** + * @brief Set ADC SS0 sample counts. + * @note User can set this register to select how many times will ADC samples data. + * @param ADCx ADC Instance. + * @param End Value Min_Value=0x00 Max_Value=0x0F. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss0_end_end(ADC_TypeDef *ADCx, uint32_t EndValue) +{ + MODIFY_REG(ADCx->SS0_END, ADC_SS0_END_END_MSK, EndValue<SS0_END, ADC_SS0_END_END_MSK)>>ADC_SS0_END_END_POSS); +} + +/** + * @brief Set ADC Sample Sequence 0 End Control Register. + * @note Set ADC_SS0_END register + * @param ADCx ADC Instance + * @param ADC_SS0_END Register Value + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss0_end(ADC_TypeDef *ADCx, uint32_t RegValue) +{ + MODIFY_REG(ADCx->SS0_END, ADC_SS0_END_END_MSK, RegValue); +} + +/** + * @brief Get ADC Sample Sequence 0 End Control Register. + * @param ADCx ADC Instance + * @retval ADC_SS0_END Register Value + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_end(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->SS0_END); +} + +/** + * @brief Set ADC Sample Sequencer 0 (SS0) FIFO Overflow status + * @note When the FIFO is full and a write was requested. + * When an overflow is detected, the most recent write is dropped. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss0_fstat_ov(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_FSTAT_OV_MSK); +} + +/** + * @brief Get ADC Sample Sequencer 0 (SS0) FIFO Overflow status + * @param ADCx ADC Instance + * @retval 1 or 0 + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_fstat_ov(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_OV_MSK)>>ADC_SS0_FSTAT_OV_POS); +} + +/** + * @brief Check if ADC SS0 FSTAT OV is actived. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss0_fstat_ov(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_OV_MSK) == (ADC_SS0_FSTAT_OV_MSK)); +} + +/** + * @brief Get ADC SS0 FSTAT FULL + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_fstat_full(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_FULL_MSK)>>ADC_SS0_FSTAT_FULL_POS); +} + +/** + * @brief Check if ADC SS0 FSTAT FULL is actived. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss0_fstat_full(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_FULL_MSK) == (ADC_SS0_FSTAT_FULL_MSK)); +} + +/** + * @brief Set ADC SS0 FSTAT UV. + * @note When the FIFO is empty and a read was requested. + * The problematic read does not move the FIFO pointers, and 0s are returned. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss0_fstat_uv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS0_END, ADC_SS0_FSTAT_UV_MSK); +} + +/** + * @brief Get ADC SS0 FSTAT UV + * @param ADCx ADC Instance + * @retval 1 or 0 + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_fstat_uv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_UV_MSK)>>ADC_SS0_FSTAT_UV_POS); +} + +/** + * @brief Check if ADC SS0 FSTAT UV is actived. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss0_fstat_uv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_UV_MSK) == (ADC_SS0_FSTAT_UV_MSK)); +} + +/** + * @brief Get ADC SS0 FSTAT EMPTY + * @param ADCx ADC Instance + * @retval 1 or 0 + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_fstat_empty(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_EMPTY_MSK)>>ADC_SS0_FSTAT_EMPTY_POS); +} + +/** + * @brief Check if ADC SS0 FSTAT EMPTY is actived. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss0_fstat_empty(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_EMPTY_MSK) == (ADC_SS0_FSTAT_EMPTY_MSK)); +} + +/** + * @brief Get ADC SS0 FSTAT HPTR + * @note The field contains the current head pointer index, which is the + * next entry to be written to FIFO. + * @param ADCx ADC Instance + * @retval 1 or 0 + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_fstat_hptr(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_HPTR_MSK)>>ADC_SS0_FSTAT_HPTR_POSS); +} + +/** + * @brief Get ADC SS0 FSTAT TPTR + * @note The field contains the current tail pointer index, which is the + * next entry to be read from FIFO. + * @param ADCx ADC Instance + * @retval 1 or 0 + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_fstat_tptr(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS0_FSTAT, ADC_SS0_FSTAT_TPTR_MSK)>>ADC_SS0_FSTAT_TPTR_POSS); +} + +/** + * @brief Get ADC sample sequencer 0(SS0) result FIFO data. + * @note User can read conversion result data by reading this register. + * @param ADCx ADC Instance + * @retval ADC Sampled Data + */ +__STATIC_INLINE uint32_t md_adc_get_ss0_data(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_REG(ADC->SS0_DATA)); +} + +/** + * @brief Set SS1 Trigger Select. + * @note This field selects the trigger source for Sample Sequencer 1. + * @param ADCx ADC Instance + * @param Sample sequencer trigger sources. + * This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_SEL_SW + * @arg @ref MD_ADC_SS_CON_SEL_BS16T1 + * @arg @ref MD_ADC_SS_CON_SEL_ALWAYS + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T2 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T3 + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T2 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T3 + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T4 + * @arg @ref MD_ADC_SS_CON_SEL_AD16C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GPIO + * @arg @ref MD_ADC_SS_CON_SEL_CMP0 + * @arg @ref MD_ADC_SS_CON_SEL_CMP1 + * @arg @ref MD_ADC_SS_CON_SEL_CMP2 + * @arg @ref MD_ADC_SS_CON_SEL_CMP3 + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss1_con_sel(ADC_TypeDef *ADCx, uint32_t TrigSource) +{ + MODIFY_REG(ADCx->SS1_CON, ADC_SS1_CON_SEL_MSK, TrigSource<SS1_CON, ADC_SS1_CON_SEL_MSK)>>ADC_SS1_CON_SEL_POSS); +} + +/** + * @brief ADC Sample Sequencer 1 (SS1) Trigger Type select. + * @note User can set this bit to select the type of trigger. + * @param ADCx ADC Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_TYP_EDGE + * @arg @ref MD_ADC_SS_COM_TYP_LEVEL + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss1_con_type(ADC_TypeDef *ADCx, uint32_t TrigType) +{ + MODIFY_REG(ADCx->SS1_CON, ADC_SS1_CON_TYP_MSK, TrigType<SS1_CON, ADC_SS1_CON_TYP_MSK)>>ADC_SS1_CON_TYP_POS); +} + +/** + * @brief Set ADC Sample Sequencer 1 (SS1) Priority. + * @note This field contains a binary-encoded value specifying the + * priority encoding of SS1. The prioriteies assigned to the + * sequencers must be uniquely mapped. + * @param ADCx ADC Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS0_CON_PRI_HIGHEST + * @arg @ref MD_ADC_SS0_CON_PRI_SECOND + * @arg @ref MD_ADC_SS0_CON_PRI_THIRD + * @arg @ref MD_ADC_SS0_CON_PRI_LOWEST + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss1_con_pri(ADC_TypeDef *adcx, uint32_t priority) +{ + MODIFY_REG(adcx->SS1_CON, ADC_SS1_CON_PRI_MSK, priority<SS1_CON, ADC_SS1_CON_PRI_MSK)>>ADC_SS1_CON_PRI_POSS); +} + +/** + * @brief One Shot Trigger Mode enable. + * @note When set HIGH, each trigger will only sample once and use one + * slot in FIFO. + * @param ADCx ADC Instance. + * @retval None + */ +__STATIC_INLINE void md_adc_enable_ss1_con_one(ADC_TypeDef *adcx) +{ + SET_BIT(adcx->SS1_CON, ADC_SS1_CON_ONE_MSK); +} + +/** + * @brief One Shot Trigger Mode disable. + * @param ADCx ADC Instance. + * @retval None + */ +__STATIC_INLINE void md_adc_disable_ss1_con_one(ADC_TypeDef *adcx) +{ + CLEAR_BIT(adcx->SS1_CON, ADC_SS1_CON_ONE_MSK); +} + +/** + * @brief Set ADC SS1 MUX7 ADINx Input Pin. + * @note 8th Sample Input Select. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss1_mux0_mux7(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS1_MUX0, ADC_SS1_MUX0_MUX7_MSK, AdinPin<SS1_MUX0, ADC_SS1_MUX0_MUX7_MSK)>>ADC_SS1_MUX0_MUX7_POSS); +} + +/** + * @brief Set ADC SS1 MUX6 Input ADIN Pin. + * @note 7th Sample Input Select. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss1_mux0_mux6(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS1_MUX0, ADC_SS1_MUX0_MUX6_MSK, AdinPin<SS1_MUX0, ADC_SS1_MUX0_MUX6_MSK)>>ADC_SS1_MUX0_MUX6_POSS); +} + +/** + * @brief Set ADC SS1 MUX0 MUX5 Input ADIN Pin. + * @note 6th Sample Input Select. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss1_mux0_mux5(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS1_MUX0, ADC_SS1_MUX0_MUX5_MSK, AdinPin<SS1_MUX0, ADC_SS1_MUX0_MUX5_MSK)>>ADC_SS1_MUX0_MUX5_POSS); +} + +/** + * @brief Set ADC SS1 MUX0 MUX4 Input ADIN Pin. + * @note 5th Sample Input Select. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss1_mux0_mux4(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS1_MUX0, ADC_SS1_MUX0_MUX4_MSK, AdinPin<SS1_MUX0, ADC_SS1_MUX0_MUX4_MSK)>>ADC_SS1_MUX0_MUX4_POSS); +} + +/** + * @brief Set ADC SS1 MUX0 MUX3 Input ADIN Pin. + * @note 4th Sample Input Select. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss1_mux0_mux3(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS1_MUX0, ADC_SS1_MUX0_MUX3_MSK, AdinPin<SS1_MUX0, ADC_SS1_MUX0_MUX3_MSK)>>ADC_SS1_MUX0_MUX3_POSS); +} + +/** + * @brief Set ADC SS1 MUX0 MUX2 Input ADIN Pin. + * @note 3rd Sample Input Select. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss1_mux0_mux2(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS1_MUX0, ADC_SS1_MUX0_MUX2_MSK, AdinPin<SS1_MUX0, ADC_SS1_MUX0_MUX2_MSK)>>ADC_SS1_MUX0_MUX2_POSS); +} + +/** + * @brief Set ADC SS1 MUX0 MUX1 Input ADIN Pin. + * @note 2nd Sample Input Select. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss1_mux0_mux1(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS1_MUX0, ADC_SS1_MUX0_MUX1_MSK, AdinPin<SS1_MUX0, ADC_SS1_MUX0_MUX1_MSK)>>ADC_SS1_MUX0_MUX1_POSS); +} + +/** + * @brief Set ADC SS1 MUX0 MUX0 Input ADIN Pin. + * @note 1st Sample Input Select. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss1_mux0_mux0(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS1_MUX0, ADC_SS1_MUX0_MUX0_MSK, AdinPin<SS1_MUX0, ADC_SS1_MUX0_MUX0_MSK)>>ADC_SS1_MUX0_MUX0_POSS); +} + +/** + * @brief Set ADC_SS1_MUX0 register. + * @note Set ADC_SS1_MUX0 channels 0~7. + * @param ADCx ADC Instance. + * @param ADC_SS1_MUX0 register value. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss1_mux0(ADC_TypeDef *ADCx, uint32_t RegValue) +{ + WRITE_REG(ADCx->SS1_MUX0, RegValue); +} + +/** + * @brief Get ADC_SS1_MUX0 register. + * @param ADCx ADC Instance. + * @retval ADC_SS1_MUX0 register value. + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_mux0(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->SS1_MUX0); +} + +/** + * @brief 8th Sample Interrupt Enable. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_enable_ss1_end_ie7(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_END_IE7_MSK); +} + +/** + * @brief 8th Sample Interrupt Disable. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_ss1_end_ie7(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS1_END, ADC_SS1_END_IE7_MSK); +} + +/** + * @brief Check if 8th Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss1_end_ie7(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS1_END_IE7_MSK) == (ADC_SS1_END_IE7_MSK)); +} + +/** + * @brief 7th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss1_end_ie6(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_END_IE6_MSK); +} + +/** + * @brief 7th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss1_end_ie6(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS1_END, ADC_SS1_END_IE6_MSK); +} + +/** + * @brief Check if 7th Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss1_end_ie6(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS1_END_IE6_MSK) == (ADC_SS1_END_IE6_MSK)); +} + + +/** + * @brief 6th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss10_end_ie5(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_END_IE5_MSK); +} + +/** + * @brief 8th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss1_end_ie5(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS1_END, ADC_SS1_END_IE5_MSK); +} + +/** + * @brief Check if 6th Sample Interrupt is enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss1_end_ie5(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS1_END_IE5_MSK) == (ADC_SS1_END_IE5_MSK)); +} + +/** + * @brief 5th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss1_end_ie4(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_END_IE4_MSK); +} + +/** + * @brief 5th Sample Interrupt Disable. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_disable_ss1_end_ie4(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS1_END, ADC_SS1_END_IE4_MSK); +} + +/** + * @brief Check if 5th Sample Interrupt is enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss1_end_ie4(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS1_END_IE4_MSK) == (ADC_SS1_END_IE4_MSK)); +} + +/** + * @brief 4th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss1_end_ie3(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_END_IE3_MSK); +} + +/** + * @brief 8th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss1_end_ie3(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS1_END, ADC_SS1_END_IE3_MSK); +} + +/** + * @brief Check if 4th Sample Interrupt is enabled. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss1_end_ie3(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS1_END_IE3_MSK) == (ADC_SS1_END_IE3_MSK)); +} + +/** + * @brief 3rd Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss1_end_ie2(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_END_IE2_MSK); +} + +/** + * @brief 3rd Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss1_end_ie2(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS1_END, ADC_SS1_END_IE2_MSK); +} + +/** + * @brief Check if 3rd Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss1_end_ie2(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS1_END_IE2_MSK) == (ADC_SS1_END_IE2_MSK)); +} + +/** + * @brief 2nd Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss1_end_ie1(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_END_IE1_MSK); +} + +/** + * @brief 2nd Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss1_end_ie1(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS1_END, ADC_SS1_END_IE1_MSK); +} + +/** + * @brief Check if 2nd Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss1_end_ie1(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS1_END_IE1_MSK) == (ADC_SS1_END_IE1_MSK)); +} + +/** + * @brief 1st Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss1_end_ie0(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_END_IE0_MSK); +} + +/** + * @brief 1st Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss1_end_ie0(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS1_END, ADC_SS1_END_IE0_MSK); +} + +/** + * @brief Check if 1st Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss1_end_ie0(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS1_END_IE0_MSK) == (ADC_SS1_END_IE0_MSK)); +} + +/** + * @brief Set end sample counts. + * @note User can set this register to select how many times will ADC + * samples data. + * @param ADCx ADC Instance. + * @param End Value Min_Value=0x00 Max_Value=0x07. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss1_end_end(ADC_TypeDef *ADCx, uint32_t EndValue) +{ + MODIFY_REG(ADCx->SS1_END, ADC_SS1_END_END_MSK, EndValue<SS1_END, ADC_SS1_END_END_MSK)>>ADC_SS1_END_END_POSS); +} + +/** + * @brief Set ADC_SS1_END Control Register + * @param ADCx ADC Instance. + * @param ADC_SS1_END register value. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss1_end(ADC_TypeDef *ADCx, uint32_t RegValue) +{ + MODIFY_REG(ADCx->SS1_END, ADC_SS1_END_END_MSK, RegValue); +} + +/** + * @brief Get ADC_SS1_End Control Register + * @param ADCx ADC Instance. + * @retval ADC_SS1_END register value. + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_end(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->SS1_END); +} + +/** + * @brief Set ADC Sample Sequencer 1 (SS1) FIFO Overflow status. + * @note When the FIFO is full and a write was requested, the + * most recent write is dropped. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss1_fstat_ov(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_FSTAT_OV_MSK); +} + +/** + * @brief Get ADC Sample Sequencer 1 (SS1) FIFO Overflow status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_fstat_ov(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_OV_MSK)>>ADC_SS1_FSTAT_OV_POS); +} + +/** + * @brief Check if ADC Sample Sequencer 1 (SS1) FIFO Overflow is actived. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss1_fstat_ov(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_OV_MSK) == (ADC_SS1_FSTAT_OV_MSK)); +} + +/** + * @brief Get ADC SS1 FIFO Full status + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_fstat_full(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_FULL_MSK)>>ADC_SS1_FSTAT_FULL_POS); +} + +/** + * @brief Check if ADC SS1 FIFO Full is actived. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss1_fstat_full(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_FULL_MSK) == (ADC_SS1_FSTAT_FULL_MSK)); +} + +/** + * @brief Set ADC Sample Sequencer 1 (SS1) FIFO Underflow status. + * @note When the FIFO is empty and a read was requested. + * The problematic read does not move the FIFO pointers, and 0s are returned. + * @param ADCx ADC Instance + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss1_fstat_uv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS1_FSTAT_UV_MSK); +} + +/** + * @brief Get ADC Sample Sequencer 1 (SS1) FIFO Underflow status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_fstat_uv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_UV_MSK)>>ADC_SS1_FSTAT_UV_POS); +} + +/** + * @brief Check if ADC Sample Sequencer 1 (SS1) FIFO Underflow status is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss1_fstat_uv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_UV_MSK) == (ADC_SS1_FSTAT_UV_MSK)); +} + +/** + * @brief Get ADC SS1 FIFO Empty status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_fstat_empty(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_EMPTY_MSK)>>ADC_SS1_FSTAT_EMPTY_POS); +} + +/** + * @brief Check if ADC SS1 FIFO Empty is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss1_fstat_empty(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_EMPTY_MSK) == (ADC_SS1_FSTAT_EMPTY_MSK)); +} + +/** + * @brief Get ADC SS1 FIFO Head Pointer. + * @note The field contains the current head pointer index, which is the + * next entry to be written to FIFO. + * @param ADCx ADC Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0x0F + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_fstat_hptr(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_HPTR_MSK)>>ADC_SS1_FSTAT_HPTR_POSS); +} + +/** + * @brief Get ADC SS1 FIFO Tail Pointer. + * @note The field contains the current tail pointer index, which is the + * next entry to be read from FIFO. + * @param ADCx ADC Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0x0F + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_fstat_tptr(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_FSTAT, ADC_SS1_FSTAT_TPTR_MSK)>>ADC_SS1_FSTAT_TPTR_POSS); +} + +/** + * @brief Get ADC sample sequencer 1(SS1) Conversion Result Data. + * @note User can read conversion result data by reading this register. + * @param ADCx ADC Instance. + * @retval ADC Sampled Data. + */ +__STATIC_INLINE uint32_t md_adc_get_ss1_data(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_REG(ADC->SS1_DATA)); +} + +/** + * @brief Set ADC SS2 Trigger Select. + * @note This field selects the trigger source for Sample Sequencer 1. + * @param ADCx ADC Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_SEL_SW + * @arg @ref MD_ADC_SS_CON_SEL_BS16T1 + * @arg @ref MD_ADC_SS_CON_SEL_ALWAYS + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T2 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T3 + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T2 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T3 + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T4 + * @arg @ref MD_ADC_SS_CON_SEL_AD16C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GPIO + * @arg @ref MD_ADC_SS_CON_SEL_CMP0 + * @arg @ref MD_ADC_SS_CON_SEL_CMP1 + * @arg @ref MD_ADC_SS_CON_SEL_CMP2 + * @arg @ref MD_ADC_SS_CON_SEL_CMP3 + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss2_con_sel(ADC_TypeDef *ADCx, uint32_t TrigSource) +{ + MODIFY_REG(ADCx->SS2_CON, ADC_SS2_CON_SEL_MSK, TrigSource<SS2_CON, ADC_SS2_CON_SEL_MSK)>>ADC_SS2_CON_SEL_POSS); +} + +/** + * @brief ADC Sample Sequencer 2 (SS2) Trigger Type select. + * @param ADCx ADC Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_TYP_EDGE + * @arg @ref MD_ADC_SS_COM_TYP_LEVEL + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss2_con_type(ADC_TypeDef *ADCx, uint32_t TrigType) +{ + MODIFY_REG(ADCx->SS2_CON, ADC_SS2_CON_TYP_MSK, TrigType<SS2_CON, ADC_SS2_CON_TYP_MSK)>>ADC_SS2_CON_TYP_POS); +} + +/** + * @brief Set ADC Sample Sequencer 2(SS2) Priority. + * @note This field contains a binary-encoded value specifying the + * priority encoding of SS2. The prioriteies assigned to the + * sequencers must be uniquely mapped. + * @param ADCx ADC Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_PRI_HIGHEST + * @arg @ref MD_ADC_SS_CON_PRI_SECOND + * @arg @ref MD_ADC_SS_CON_PRI_THIRD + * @arg @ref MD_ADC_SS_CON_PRI_LOWEST + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss2_con_pri(ADC_TypeDef *adcx, uint32_t priority) +{ + MODIFY_REG(adcx->SS2_CON, ADC_SS2_CON_PRI_MSK, priority<SS2_CON, ADC_SS2_CON_PRI_MSK)>>ADC_SS2_CON_PRI_POSS); +} + +/** + * @brief Enable One Shot Trigger Mode. + * @note When set HIGH, each trigger will only sample once and use one + * slot in FIFO. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss2_con_one(ADC_TypeDef *adcx) +{ + SET_BIT(adcx->SS2_CON, ADC_SS2_CON_ONE_MSK); +} + +/** + * @brief Disable One Shot Trigger Mode. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss2_con_one(ADC_TypeDef *adcx) +{ + CLEAR_BIT(adcx->SS2_CON, ADC_SS2_CON_ONE_MSK); +} + +/** + * @brief 4th Sample Input Select.. + * @param ADCx ADC Instance + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss2_mux0_mux3(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS2_MUX0, ADC_SS2_MUX0_MUX3_MSK, AdinPin<SS2_MUX0, ADC_SS2_MUX0_MUX3_MSK)>>ADC_SS2_MUX0_MUX3_POSS); +} + +/** + * @brief 3rd Sample Input Select. + * @param ADCx ADC Instance. + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss2_mux0_mux2(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS2_MUX0, ADC_SS2_MUX0_MUX2_MSK, AdinPin<SS2_MUX0, ADC_SS2_MUX0_MUX2_MSK)>>ADC_SS2_MUX0_MUX2_POSS); +} + +/** + * @brief 2nd Sample Input Select. + * @param ADCx ADC Instance. + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss2_mux0_mux1(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS2_MUX0, ADC_SS2_MUX0_MUX1_MSK, AdinPin<SS2_MUX0, ADC_SS2_MUX0_MUX1_MSK)>>ADC_SS2_MUX0_MUX1_POSS); +} + +/** + * @brief 1st Sample Input Select. + * @param ADCx ADC Instance. + * @param ADIN Pin: + * @arg @ref MD_ADC_SS_MUX_ADIN15 + * @arg @ref MD_ADC_SS_MUX_ADIN14 + * @arg @ref MD_ADC_SS_MUX_ADIN13 + * @arg @ref MD_ADC_SS_MUX_ADIN12 + * @arg @ref MD_ADC_SS_MUX_ADIN11 + * @arg @ref MD_ADC_SS_MUX_ADIN10 + * @arg @ref MD_ADC_SS_MUX_ADIN9 + * @arg @ref MD_ADC_SS_MUX_ADIN8 + * @arg @ref MD_ADC_SS_MUX_ADIN7 + * @arg @ref MD_ADC_SS_MUX_ADIN6 + * @arg @ref MD_ADC_SS_MUX_ADIN5 + * @arg @ref MD_ADC_SS_MUX_ADIN4 + * @arg @ref MD_ADC_SS_MUX_ADIN3 + * @arg @ref MD_ADC_SS_MUX_ADIN2 + * @arg @ref MD_ADC_SS_MUX_ADIN1 + * @arg @ref MD_ADC_SS_MUX_ADIN0 + */ +__STATIC_INLINE void md_adc_set_ss2_mux0_mux0(ADC_TypeDef *ADCx, uint32_t AdinPin) +{ + MODIFY_REG(ADCx->SS2_MUX0, ADC_SS2_MUX0_MUX0_MSK, AdinPin<SS2_MUX0, ADC_SS2_MUX0_MUX0_MSK)>>ADC_SS2_MUX0_MUX0_POSS); +} + +/** + * @brief Set ADC_SS2_MUX0 register value. + * @param ADCx ADC Instance. + * @param ADC_SS2_MUX0 Register + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss2_mux0(ADC_TypeDef *ADCx, uint32_t RegValue) +{ + WRITE_REG(ADCx->SS2_MUX0, RegValue); +} + +/** + * @brief Get ADC_SS2_MUX0 register value. + * @param ADCx ADC Instance. + * @retval ADC_SS2_MUX0 Register + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_mux0(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->SS2_MUX0); +} + +/** + * @brief 4th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss2_end_ie3(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS2_END, ADC_SS2_END_IE3_MSK); +} + +/** + * @brief 4th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss2_end_ie3(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS2_END, ADC_SS2_END_IE3_MSK); +} + +/** + * @brief Check if 4th Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss2_end_ie3(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_END, ADC_SS2_END_IE3_MSK) == (ADC_SS2_END_IE3_MSK)); +} + +/** + * @brief 3rd Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss2_end_ie2(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS2_END, ADC_SS2_END_IE2_MSK); +} + +/** + * @brief 3rd Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss2_end_ie2(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS2_END, ADC_SS2_END_IE2_MSK); +} + +/** + * @brief Check if 3rd Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss2_end_ie2(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_END, ADC_SS2_END_IE2_MSK) == (ADC_SS2_END_IE2_MSK)); +} + +/** + * @brief 2nd Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss2_end_ie1(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS1_END, ADC_SS2_END_IE1_MSK); +} + +/** + * @brief 2nd Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss2_end_ie1(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS2_END, ADC_SS2_END_IE1_MSK); +} + +/** + * @brief Check if 2nd Sample Interrupt Enable is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss2_end_ie1(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS1_END, ADC_SS2_END_IE1_MSK) == (ADC_SS2_END_IE1_MSK)); +} + +/** + * @brief 1st Sample Interrupt Enable + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss2_end_ie0(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS2_END, ADC_SS2_END_IE0_MSK); +} + +/** + * @brief 4th Sample Interrupt Disable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss2_end_ie0(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS2_END, ADC_SS2_END_IE0_MSK); +} + +/** + * @brief Check if 1st Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss2_end_ie0(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_END, ADC_SS2_END_IE0_MSK) == (ADC_SS2_END_IE0_MSK)); +} + +/** + * @brief Set ADC SS2 END sample. + * @param ADCx ADC Instance. + * @param End Value Min_Value=0x00 Max_Value=0x03 + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss2_end_end(ADC_TypeDef *ADCx, uint32_t EndValue) +{ + MODIFY_REG(ADCx->SS2_END, ADC_SS2_END_END_MSK, EndValue<SS2_END, ADC_SS2_END_END_MSK)>>ADC_SS2_END_END_POSS); +} + +/** + * @brief Set ADC_SS2_End Control Register. + * @param ADCx ADC Instance. + * @param ADC_SS2_End Register Value. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss2_end(ADC_TypeDef *ADCx, uint32_t RegValue) +{ + MODIFY_REG(ADCx->SS2_END, ADC_SS2_END_END_MSK, RegValue); +} + +/** + * @brief Get ADC_SS2_End Control Register. + * @param ADCx ADC Instance. + * @retval ADC_SS2_End Register Value. + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_end(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->SS2_END); +} + +/** + * @brief Set ADC Sample Sequencer 2(SS2) FIFO Overflow status. + * @note When the FIFO is full and a write was requested, the + * most recent write is dropped. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss2_fstat_ov(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS2_END, ADC_SS2_FSTAT_OV_MSK); +} + +/** + * @brief Get ADC Sample Sequencer 2(SS2) FIFO Overflow status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_fstat_ov(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_OV_MSK)>>ADC_SS2_FSTAT_OV_POS); +} + +/** + * @brief Check if ADC Sample Sequencer 2(SS2) FIFO Overflow status is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss2_fstat_ov(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_OV_MSK) == (ADC_SS2_FSTAT_OV_MSK)); +} + +/** + * @brief Get ADC SS2 FIFO Full status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_fstat_full(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_FULL_MSK)>>ADC_SS2_FSTAT_FULL_POS); +} + +/** + * @brief Check if ADC SS2 FIFO Full is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss2_fstat_full(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_FULL_MSK) == (ADC_SS2_FSTAT_FULL_MSK)); +} + +/** + * @brief Set ADC Sample Sequencer 2(SS2) FIFO Underflow status. + * @note When the FIFO is empty and a read was requested. + * The problematic read does not move the FIFO pointers, and 0s are returned. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss2_fstat_uv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS2_END, ADC_SS2_FSTAT_UV_MSK); +} + +/** + * @brief Get ADC Sample Sequencer 2(SS2) FIFO Underflow status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_fstat_uv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_UV_MSK)>>ADC_SS2_FSTAT_UV_POS); +} + +/** + * @brief Check if ADC Sample Sequencer 2(SS2) FIFO Underflow status is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss2_fstat_uv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_UV_MSK) == (ADC_SS2_FSTAT_UV_MSK)); +} + +/** + * @brief Get ADC SS2 FIFO Empty status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_fstat_empty(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_EMPTY_MSK)>>ADC_SS2_FSTAT_EMPTY_POS); +} + +/** + * @brief Check if ADC SS2 FIFO Empty is actived. + * @param ADCx ADC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss2_fstat_empty(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_EMPTY_MSK) == (ADC_SS2_FSTAT_EMPTY_MSK)); +} + +/** + * @brief Get ADC SS2 FIFO Head Pointer. + * @param ADCx ADC Instance. + * @retval Return value between Min_Data=0x00 and Max_Data=0x0F. + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_fstat_hptr(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_HPTR_MSK)>>ADC_SS2_FSTAT_HPTR_POSS); +} + +/** + * @brief Get ADC SS2 FSTAT TPTR + * @param ADCx ADC Instance + * @retval Return value between Min_Data=0x00 and Max_Data=0x0F. + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_fstat_tptr(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS2_FSTAT, ADC_SS2_FSTAT_TPTR_MSK)>>ADC_SS2_FSTAT_TPTR_POSS); +} + +/** + * @brief Get ADC sample sequencer 2(SS2) Conversion Result Data. + * @note User can read conversion result data by reading this register. + * @param ADCx ADC Instance. + * @retval ADC Sampled Data. + */ +__STATIC_INLINE uint32_t md_adc_get_ss2_data(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_REG(ADC->SS2_DATA)); +} + +/** + * @brief Set SS3 Trigger Select. + * @note This field selects the trigger source for Sample Sequencer 3. + * @param ADCx ADC Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_SEL_SW + * @arg @ref MD_ADC_SS_CON_SEL_BS16T1 + * @arg @ref MD_ADC_SS_CON_SEL_ALWAYS + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T2 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C4T3 + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T2 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T3 + * @arg @ref MD_ADC_SS_CON_SEL_GP32C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GP16C2T4 + * @arg @ref MD_ADC_SS_CON_SEL_AD16C4T1 + * @arg @ref MD_ADC_SS_CON_SEL_GPIO + * @arg @ref MD_ADC_SS_CON_SEL_CMP0 + * @arg @ref MD_ADC_SS_CON_SEL_CMP1 + * @arg @ref MD_ADC_SS_CON_SEL_CMP2 + * @arg @ref MD_ADC_SS_CON_SEL_CMP3 + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss3_con_sel(ADC_TypeDef *ADCx, uint32_t TrigSource) +{ + MODIFY_REG(ADCx->SS3_CON, ADC_SS3_CON_SEL_MSK, TrigSource<SS3_CON, ADC_SS3_CON_SEL_MSK)>>ADC_SS3_CON_SEL_POSS); +} + +/** + * @brief ADC Sample Sequencer 2 (SS2) Trigger Type select. + * @param ADCx ADC Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_TYP_EDGE + * @arg @ref MD_ADC_SS_COM_TYP_LEVEL + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss3_con_type(ADC_TypeDef *ADCx, uint32_t TrigType) +{ + MODIFY_REG(ADCx->SS3_CON, ADC_SS3_CON_TYP_MSK, TrigType<SS3_CON, ADC_SS3_CON_TYP_MSK)>>ADC_SS3_CON_TYP_POS); +} + +/** + * @brief Set ADC Sample Sequencer 3(SS3) Priority. + * @note This field contains a binary-encoded value specifying the + * priority encoding of SS2. The prioriteies assigned to the + * sequencers must be uniquely mapped. + * @param ADCx ADC Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_ADC_SS_CON_PRI_HIGHEST + * @arg @ref MD_ADC_SS_CON_PRI_SECOND + * @arg @ref MD_ADC_SS_CON_PRI_THIRD + * @arg @ref MD_ADC_SS_CON_PRI_LOWEST + * @retval None + */ +__STATIC_INLINE void md_adc_set_ss3_con_pri(ADC_TypeDef *adcx, uint32_t priority) +{ + MODIFY_REG(adcx->SS3_CON, ADC_SS3_CON_PRI_MSK, priority<SS3_CON, ADC_SS3_CON_PRI_MSK)>>ADC_SS3_CON_PRI_POSS); +} + +/** + * @brief Enable ADC sample sequencer 3(SS3) one shot mode. + * @note When set HIGH, each trigger will only sample once and use one + * slot in FIFO. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss3_con_one(ADC_TypeDef *adcx) +{ + SET_BIT(adcx->SS3_CON, ADC_SS3_CON_ONE_MSK); +} + +/** + * @brief Disable ADC sample sequencer 3(SS3) one shot mode. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss3_con_one(ADC_TypeDef *adcx) +{ + CLEAR_BIT(adcx->SS3_CON, ADC_SS3_CON_ONE_MSK); +} + +/** + * @brief Enable ADC SS3 1th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_enable_ss3_end_ie0(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS3_END, ADC_SS3_END_IE0_MSK); +} + +/** + * @brief Disable ADC SS3 1th Sample Interrupt Enable. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_disable_ss3_end_ie0(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->SS3_END, ADC_SS3_END_IE0_MSK); +} + +/** + * @brief Check if ADC SS3 1th Sample Interrupt is enabled. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_enabled_ss3_end_ie0(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_END, ADC_SS3_END_IE0_MSK) == (ADC_SS3_END_IE0_MSK)); +} + +/** + * @brief Set ADC SS3 END sample. + * @param ADCx ADC Instance. + * @param End Value Min_Value=0x00 Max_Value=0x01. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss3_end_end(ADC_TypeDef *ADCx, uint32_t EndValue) +{ + MODIFY_REG(ADCx->SS3_END, ADC_SS3_END_END_MSK, EndValue<SS3_END, ADC_SS3_END_END_MSK)>>ADC_SS3_END_END_POS); +} + +/** + * @brief Set ADC_SS3_End Control Register. + * @param ADCx ADC Instance. + * @param ADC_SS3_END Register Value. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss3_end(ADC_TypeDef *ADCx, uint32_t RegValue) +{ + MODIFY_REG(ADCx->SS2_END, ADC_SS3_END_END_MSK, RegValue); +} + +/** + * @brief Get ADC_SS3_End Control Register + * @param ADCx ADC Instance. + * @retval ADC_SS3_End Register Value. + */ +__STATIC_INLINE uint32_t md_adc_get_ss3_end(ADC_TypeDef *ADCx) +{ + return READ_REG(ADCx->SS3_END); +} + +/** + * @brief Set ADC Sample Sequencer 3 (SS3) FIFO Overflow status. + * @note When the FIFO is full and a write was requested, the + * most recent write is dropped. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss3_fstat_ov(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS3_END, ADC_SS3_FSTAT_OV_MSK); +} + +/** + * @brief Get ADC Sample Sequencer 3 (SS3) FIFO Overflow status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss3_fstat_ov(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_OV_MSK)>>ADC_SS3_FSTAT_OV_POS); +} + +/** + * @brief Check if ADC Sample Sequencer 3 (SS3) FIFO Overflow status is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss3_fstat_ov(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_OV_MSK) == (ADC_SS3_FSTAT_OV_MSK)); +} + +/** + * @brief Get ADC SS3 FIFO Full status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss3_fstat_full(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_FULL_MSK)>>ADC_SS3_FSTAT_FULL_POS); +} + +/** + * @brief Check if ADC SS3 FIFO Full status is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss3_fstat_full(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_FULL_MSK) == (ADC_SS3_FSTAT_FULL_MSK)); +} + +/** + * @brief Set ADC Sample Sequencer 3 (SS3) FIFO Underflow status. + * @note When the FIFO is empty and a read was requested. + * The problematic read does not move the FIFO pointers, and 0s are returned. + * @param ADCx ADC Instance. + * @retval None. + */ +__STATIC_INLINE void md_adc_set_ss3_fstat_uv(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->SS3_END, ADC_SS3_FSTAT_UV_MSK); +} + +/** + * @brief Get ADC Sample Sequencer 3 (SS3) FIFO Underflow status. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss3_fstat_uv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_UV_MSK)>>ADC_SS3_FSTAT_UV_POS); +} + +/** + * @brief Check if ADC Sample Sequencer 3 (SS3) FIFO Underflow status is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss3_fstat_uv(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_UV_MSK) == (ADC_SS3_FSTAT_UV_MSK)); +} + +/** + * @brief Get ADC SS3 FIFO Empty. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_get_ss3_fstat_empty(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_EMPTY_MSK)>>ADC_SS3_FSTAT_EMPTY_POS); +} + +/** + * @brief Check if ADC SS3 FIFO Empty is actived. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_adc_is_active_flag_ss3_fstat_empty(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_EMPTY_MSK) == (ADC_SS3_FSTAT_EMPTY_MSK)); +} + +/** + * @brief Get ADC SS3 FIFO Head Pointer. + * @param ADCx ADC Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0x01. + */ +__STATIC_INLINE uint32_t md_adc_get_ss23_fstat_hptr(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_HPTR_MSK)>>ADC_SS3_FSTAT_HPTR_POSS); +} + +/** + * @brief Get ADC SS3 FIFO Tail Pointer. + * @param ADCx ADC Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0x01. + */ +__STATIC_INLINE uint32_t md_adc_get_ss3_fstat_tptr(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SS3_FSTAT, ADC_SS3_FSTAT_TPTR_MSK)>>ADC_SS3_FSTAT_TPTR_POSS); +} + +/** + * @brief Get ADC sample sequencer 3(SS3) Conversion Result Data. + * @note User can read conversion result data by reading this register. + * @param ADCx ADC Instance. + * @retval ADC Sampled Data. + */ +__STATIC_INLINE uint32_t md_adc_get_ss3_data(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_REG(ADC->SS3_DATA)); +} + +/** @defgroup MD_ADC_PM_WRITE_READ Common Write and read registers Macros + * @} + */ +#endif + +void md_adc_init(ADC_TypeDef *ADCx, md_adc_inittypedef *ADC_InitStruct,uint8_t *); +void md_adc_calibration_data(double, double ,double * ,double *); +void md_adc_get_data(uint8_t, double, double, uint16_t *); +/** + * @} MD_ADC_Public_Macros + */ + +/** @} ADC + */ + +/** + * @} Micro_Driver + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_aes.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_aes.h new file mode 100644 index 0000000000..e4e16693d5 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_aes.h @@ -0,0 +1,941 @@ +/** + ****************************************************************************** + * @file md_aes.h + * @brief M601 AES Head File. + * + * @version V0.01 + * @date 28/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_AES_H__ +#define __MD_AES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (AES) + +/** @defgroup AES AES + * @brief AES micro driver + * @{ + */ + +/* Private Types --------------------------------------------------------------*/ +/* Private Variables ----------------------------------------------------------*/ +/* Private Macros -------------------------------------------------------------*/ +/* Public Types ---------------------------------------------------------------*/ +/** @defgroup MD_AES_INIT AES public init structure + * @brief + * @{ + */ +typedef struct +{ + volatile uint8_t aes_con_bl; + volatile uint8_t aes_con_mode; + volatile uint32_t aes_key[4]; + volatile uint32_t aes_iv[4]; + volatile uint32_t aes_din[4]; + volatile uint32_t aes_dout[4]; +} md_aes_init_typedef; +/** + * @} MD_AES_INIT + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_AES_Public_Constants AES Public Constants + * @brief + * @{ + */ + +/** @defgroup MD_AES_CON_registers AES Control Registers + * @brief + * @{ + */ +#define MD_AES_CON_READY_BUSY 0 /*!< This allow user to read AES Encryption/Decryption Ready Status. */ +#define MD_AES_CON_READY_READY 1 /*!< This allow user to read AES Encryption/Decryption Ready Status. */ +#define MD_AES_CON_OT_DMA_ST_PASS 1 /*!< This allow user to read AES DMA Output Status. */ +#define MD_AES_CON_OT_DMA_ST_FAIL 0 /*!< This allow user to read AES DMA Output Status. */ +#define MD_AES_CON_IT_DMA_ST_PASS 1 /*!< This allow user to read AES DMA Input Status. */ +#define MD_AES_CON_IT_DMA_ST_FAIL 0 /*!< This allow user to read AES DMA Input Status. */ +#define MD_AES_CON_OT_DEPTH_0 0 /*!< This allow user to read AES DIO data depth status (X=0). */ +#define MD_AES_CON_OT_DEPTH_1 1 /*!< This allow user to read AES DIO data depth status (X=1). */ +#define MD_AES_CON_OT_DEPTH_2 2 /*!< This allow user to read AES DIO data depth status (X=2). */ +#define MD_AES_CON_OT_DEPTH_3 3 /*!< This allow user to read AES DIO data depth status (X=3). */ +#define MD_AES_CON_IT_DEPTH_0 0 /*!< This allow user to read AES DIO data depth status (X=0). */ +#define MD_AES_CON_IT_DEPTH_1 1 /*!< This allow user to read AES DIO data depth status (X=1). */ +#define MD_AES_CON_IT_DEPTH_2 2 /*!< This allow user to read AES DIO data depth status (X=2). */ +#define MD_AES_CON_IT_DEPTH_3 3 /*!< This allow user to read AES DIO data depth status (X=3). */ +#define MD_AES_CON_RE_INIT_SET 1 /*!< This allow user to set AES Re-initial. */ +#define MD_AES_CON_RE_INIT_UNSET 0 /*!< This allow user to set AES Re-initial. */ +#define MD_AES_CON_DMA_EN_INPUT_ENABLE (1 << 0) /*!< This allow user to set AES DMA Function Enable. 0:AES input DMA disable */ +#define MD_AES_CON_DMA_EN_INPUT_DISABLE (0 << 0) /*!< This allow user to set AES DMA Function Enable. 1:AES input DMA enable */ +#define MD_AES_CON_DMA_EN_OUTPUT_ENABLE (1 << 1 /*!< This allow user to set AES DMA Function Enable. 0:AES output DMA disable */ +#define MD_AES_CON_DMA_EN_OUTPUT_DISABLE (0 << 1) /*!< This allow user to set AES DMA Function Enable. 1:AES outut DMA enable */ +#define MD_AES_CON_BL_CBC 0 /*!< This allow user to set Block Cipher Encryption / Decryption Mode. 000:CBC */ +#define MD_AES_CON_BL_CFB 1 /*!< This allow user to set Block Cipher Encryption / Decryption Mode. 001:CFB */ +#define MD_AES_CON_BL_OFB 2 /*!< This allow user to set Block Cipher Encryption / Decryption Mode. 010:OFB */ +#define MD_AES_CON_BL_CTR 3 /*!< This allow user to set Block Cipher Encryption / Decryption Mode. 011:CTR */ +#define MD_AES_CON_BL_ECB 4 /*!< This allow user to set Block Cipher Encryption / Decryption Mode. 100:ECB */ +#define MD_AES_CON_BL_GCM 5 /*!< This allow user to set Block Cipher Encryption / Decryption Mode. 101:GCM */ +#define MD_AES_CON_REV_NORMAL 0 /*!< This allow user to set AES Input Reverse. 0:Normal Mode */ +#define MD_AES_CON_REV_REVERSE 1 /*!< This allow user to set AES Input Reverse. 1:KEY, IV, DI, DO Byte Reverse Mode */ +#define MD_AES_CON_MODE_ENCRYPT 0 /*!< This allow user to set AES Mode Control. 0:Encryption Mode */ +#define MD_AES_CON_MODE_DECRYPT 1 /*!< This allow user to set AES Mode Control. 1:Decryption Mode */ +#define MD_AES_CON_START 1 /*!< This allow user to set AES Start. AES function will start after this bit is set to 1. */ +/** + * @} MD_AES_CON_registers + */ + +/** @defgroup MD_AES_IER_registers AES Interrupt Enable Registers + * @brief + * @{ + */ +#define MD_AES_IER_DECIE 1 /*!< This allow user to set AES Decryption Interrupt Enable. */ +#define MD_AES_IER_ENCIE 1 /*!< This allow user to set AES Encryption Interrupt Enable. */ +/** + * @} MD_AES_IER_registers + */ + +/** @defgroup MD_AES_IDR_registers AES Interrupt Disable Registers + * @brief + * @{ + */ +#define MD_AES_IDR_DECID 1 /*!< This allow user to set AES Decryption Interrupt Disable. */ +#define MD_AES_IDR_ENCID 1 /*!< This allow user to set AES Encryption Interrupt Disable. */ +/** + * @} MD_AES_IDR_registers + */ + +/** @defgroup MD_AES_IVS_registers AES Interrupt Valid Status Registers + * @brief + * @{ + */ +#define MD_AES_IVS_DECIVS_DISABLE 0 /*!< This allow user to set AES Decryption Interrupt Valid Status. 0:AES Decryption interrupt is disabled. */ +#define MD_AES_IVS_DECIVS_ENABLE 1 /*!< This allow user to set AES Decryption Interrupt Valid Status. 1:AES Decryption interrupt is enabled. */ +#define MD_AES_IVS_ENCIVS_DISABLE 0 /*!< This allow user to set AES Encryption Interrupt Valid Status. 0:AES Encryption interrupt is disabled. */ +#define MD_AES_IVS_ENCIVS_ENABLE 1 /*!< This allow user to set AES Encryption Interrupt Valid Status. 1:AES Encryption interrupt is enabled. */ +/** + * @} MD_AES_IVS_registers + */ + +/** @defgroup MD_AES_RIF_registers AES Raw Interrupt Flag Registers + * @brief + * @{ + */ +#define MD_AES_RIF_DECRIF_NO_INTERRUPT 0 /*!< This allow user to set AES Decryption Raw Interrupt Flag Status. 0: No interrupt. */ +#define MD_AES_RIF_DECRIF_INTERRUPT 1 /*!< This allow user to set AES Decryption Raw Interrupt Flag Status. 1: AES Decryption interrupt is asserting. */ +#define MD_AES_RIF_ENCRIF_NO_INTERRUPT 0 /*!< This allow user to set AES Encryption Raw Interrupt Flag Status. 0: No interrupt. */ +#define MD_AES_RIF_ENCRIF_INTERRUPT 1 /*!< This allow user to set AES Encryption Raw Interrupt Flag Status. 1: AES Encryption interrupt is asserting. */ +/** + * @} MD_AES_RIF_registers + */ + +/** @defgroup MD_AES_IFM_registers AES Interrupt Flag Mask Registers + * @brief + * @{ + */ +#define MD_AES_IFM_DECRIF_MASK 0 /*!< This allow user to set AES Decryption Interrupt Flag Masked Status. 0: No interrupt or the interrupt has been masked. */ +#define MD_AES_IFM_DECRIF_SIGNAL 1 /*!< This allow user to set AES Decryption Interrupt Flag Masked Status. 1: AES Decryption interrupt has been signalled. */ +#define MD_AES_IFM_ENCRIF_MASK 0 /*!< This allow user to set AES Encryption Interrupt Flag Masked Status. 0: No interrupt or the interrupt has been masked. */ +#define MD_AES_IFM_ENCRIF_SIGNAL 1 /*!< This allow user to set AES Encryption Interrupt Flag Masked Status. 1: AES Encryption interrupt has been signalled. */ +/** + * @} MD_AES_IFM_registers + */ + +/** @defgroup MD_AES_ICR_registers AES Interrupt Clear Registers + * @brief + * @{ + */ +#define MD_AES_ICR_DECICR 1 /*!< This allow user to set AES Decryption Interrupt Clear. User can set this bit to clear AES Decryption interrupt status. */ +#define MD_AES_ICR_ENCICR 1 /*!< This allow user to set AES Decryption Interrupt Clear. User can set this bit to clear AES Encryption interrupt status. */ +/** + * @} MD_AES_ICR_registers + */ + +/** + * @} MD_AES_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_AES_Public_Macros AES Public Macros + * @brief + * @{ + */ + +/** + * @brief AES Control Register + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_READY_BUSY 0 + * @arg @ref MD_AES_CON_READY_READY 1 + * @arg @ref MD_AES_CON_OT_DMA_ST_PASS 1 + * @arg @ref MD_AES_CON_OT_DMA_ST_FAIL 0 + * @arg @ref MD_AES_CON_IT_DMA_ST_PASS 1 + * @arg @ref MD_AES_CON_IT_DMA_ST_FAIL 0 + * @arg @ref MD_AES_CON_OT_DEPTH_0 0 + * @arg @ref MD_AES_CON_OT_DEPTH_1 1 + * @arg @ref MD_AES_CON_OT_DEPTH_2 2 + * @arg @ref MD_AES_CON_OT_DEPTH_3 3 + * @arg @ref MD_AES_CON_IT_DEPTH_0 0 + * @arg @ref MD_AES_CON_IT_DEPTH_1 1 + * @arg @ref MD_AES_CON_IT_DEPTH_2 2 + * @arg @ref MD_AES_CON_IT_DEPTH_3 3 + * @arg @ref MD_AES_CON_RE_INIT_SET 1 + * @arg @ref MD_AES_CON_RE_INIT_UNSET 0 + * @arg @ref MD_AES_CON_DMA_EN_INPUT_ENABLE (1 << 0) + * @arg @ref MD_AES_CON_DMA_EN_INPUT_DISABLE (0 << 0) + * @arg @ref MD_AES_CON_DMA_EN_OUTPUT_ENABLE (1 << 1) + * @arg @ref MD_AES_CON_DMA_EN_OUTPUT_DISABLE (0 << 1) + * @arg @ref MD_AES_CON_BL_CBC 0 + * @arg @ref MD_AES_CON_BL_CFB 1 + * @arg @ref MD_AES_CON_BL_OFB 2 + * @arg @ref MD_AES_CON_BL_CTR 3 + * @arg @ref MD_AES_CON_BL_ECB 4 + * @arg @ref MD_AES_CON_BL_GCM 5 + * @arg @ref MD_AES_CON_REV_NORMAL 0 + * @arg @ref MD_AES_CON_REV_REVERSE 1 + * @arg @ref MD_AES_CON_MODE_ENCRYPT 0 + * @arg @ref MD_AES_CON_MODE_DECRYPT 1 + * @arg @ref MD_AES_CON_START 1 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_con(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->CON, value); +} + +/** + * @brief AES Control Register + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_READY_BUSY 0 + * @arg @ref MD_AES_CON_READY_READY 1 + * @arg @ref MD_AES_CON_OT_DMA_ST_PASS 1 + * @arg @ref MD_AES_CON_OT_DMA_ST_FAIL 0 + * @arg @ref MD_AES_CON_IT_DMA_ST_PASS 1 + * @arg @ref MD_AES_CON_IT_DMA_ST_FAIL 0 + * @arg @ref MD_AES_CON_OT_DEPTH_0 0 + * @arg @ref MD_AES_CON_OT_DEPTH_1 1 + * @arg @ref MD_AES_CON_OT_DEPTH_2 2 + * @arg @ref MD_AES_CON_OT_DEPTH_3 3 + * @arg @ref MD_AES_CON_IT_DEPTH_0 0 + * @arg @ref MD_AES_CON_IT_DEPTH_1 1 + * @arg @ref MD_AES_CON_IT_DEPTH_2 2 + * @arg @ref MD_AES_CON_IT_DEPTH_3 3 + * @arg @ref MD_AES_CON_RE_INIT_SET 1 + * @arg @ref MD_AES_CON_RE_INIT_UNSET 0 + * @arg @ref MD_AES_CON_DMA_EN_INPUT_ENABLE (1 << 0) + * @arg @ref MD_AES_CON_DMA_EN_INPUT_DISABLE (0 << 0) + * @arg @ref MD_AES_CON_DMA_EN_OUTPUT_ENABLE (1 << 1) + * @arg @ref MD_AES_CON_DMA_EN_OUTPUT_DISABLE (0 << 1) + * @arg @ref MD_AES_CON_BL_CBC 0 + * @arg @ref MD_AES_CON_BL_CFB 1 + * @arg @ref MD_AES_CON_BL_OFB 2 + * @arg @ref MD_AES_CON_BL_CTR 3 + * @arg @ref MD_AES_CON_BL_ECB 4 + * @arg @ref MD_AES_CON_BL_GCM 5 + * @arg @ref MD_AES_CON_REV_NORMAL 0 + * @arg @ref MD_AES_CON_REV_REVERSE 1 + * @arg @ref MD_AES_CON_MODE_ENCRYPT 0 + * @arg @ref MD_AES_CON_MODE_DECRYPT 1 + * @arg @ref MD_AES_CON_START 1 + */ +__STATIC_INLINE uint32_t md_aes_get_con(AES_TypeDef *aes) +{ + return (READ_REG(aes->CON)); +} + +/** + * @brief AES Encryption / Decryption Ready Status + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_READY_BUSY 0 + * @arg @ref MD_AES_CON_READY_READY 1 + */ +__STATIC_INLINE uint32_t md_aes_get_con_ready(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_READY_MSK) >> AES_CON_READY_POS) & 0x1); +} + +/** + * @brief AES DMA Output Status + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_OT_DMA_ST_PASS 0 + * @arg @ref MD_AES_CON_OT_DMA_ST_FAIL 1 + */ +__STATIC_INLINE uint32_t md_aes_get_con_ot_dma_st(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_OT_DMA_ST_MSK) >> AES_CON_OT_DMA_ST_POS) & 0x1); +} + +/** + * @brief AES DMA Intput Status + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_IT_DMA_ST_PASS 0 + * @arg @ref MD_AES_CON_IT_DMA_ST_FAIL 1 + */ +__STATIC_INLINE uint32_t md_aes_get_con_it_dma_st(AES_TypeDef *aes, uint32_t value) +{ + return ((READ_BIT(aes->CON, AES_CON_IT_DMA_ST_MSK) >> AES_CON_IT_DMA_ST_POS) & 0x1); +} + +/** + * @brief AES DIO data depth status (X=0,1,2,3) + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_OT_DEPTH_0 0 + * @arg @ref MD_AES_CON_OT_DEPTH_1 1 + * @arg @ref MD_AES_CON_OT_DEPTH_2 2 + * @arg @ref MD_AES_CON_OT_DEPTH_3 3 + */ +__STATIC_INLINE uint32_t md_aes_get_con_ot_depth(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_OT_DEPTH_MSK) >> AES_CON_OT_DEPTH_POSS) & 0x3); +} + +/** + * @brief AES DIO data depth status (X=0,1,2,3) + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_IT_DEPTH_0 0 + * @arg @ref MD_AES_CON_IT_DEPTH_1 1 + * @arg @ref MD_AES_CON_IT_DEPTH_2 2 + * @arg @ref MD_AES_CON_IT_DEPTH_3 3 + */ +__STATIC_INLINE uint32_t md_aes_get_con_it_depth(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_IT_DEPTH_MSK) >> AES_CON_IT_DEPTH_POSS) & 0x3); +} + +/** + * @brief AES Re-initial + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_RE_INIT_SET 1 + * @arg @ref MD_AES_CON_RE_INIT_UNSET 0 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_con_re_init(AES_TypeDef *aes, uint32_t value) +{ + MODIFY_REG(aes->CON, AES_CON_RE_INIT_MSK, (value << AES_CON_RE_INIT_POS)); +} + +/** + * @brief AES Re-initial + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_RE_INIT_SET 1 + * @arg @ref MD_AES_CON_RE_INIT_UNSET 0 + */ +__STATIC_INLINE uint32_t md_aes_get_con_re_init(AES_TypeDef *aes) +{ + + return ((READ_BIT(aes->CON, AES_CON_RE_INIT_MSK) >> AES_CON_RE_INIT_POS) & 0x1); +} + +/** + * @brief AES DMA Function Enable + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_DMA_EN_INPUT_ENABLE (1 << 0) + * @arg @ref MD_AES_CON_DMA_EN_INPUT_DISABLE (0 << 0) + * @arg @ref MD_AES_CON_DMA_EN_OUTPUT_ENABLE (1 << 1) + * @arg @ref MD_AES_CON_DMA_EN_OUTPUT_DISABLE (0 << 1) + * @retval None. + */ +__STATIC_INLINE void md_aes_set_con_dma_en(AES_TypeDef *aes, uint32_t value) +{ + MODIFY_REG(aes->CON, AES_CON_DMA_EN_MSK, (value << AES_CON_DMA_EN_POSS)); +} + +/** + * @brief AES DMA Function Enable + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_DMA_EN_INPUT_ENABLE (1 << 0) + * @arg @ref MD_AES_CON_DMA_EN_INPUT_DISABLE (0 << 0) + * @arg @ref MD_AES_CON_DMA_EN_OUTPUT_ENABLE (1 << 1) + * @arg @ref MD_AES_CON_DMA_EN_OUTPUT_DISABLE (0 << 1) + */ +__STATIC_INLINE uint32_t md_aes_get_con_dma_en(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_DMA_EN_MSK) >> AES_CON_DMA_EN_POSS) & 0x3); +} + +/** + * @brief Block Cipher Encryption / Decryption Mode + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_BL_CBC 0 + * @arg @ref MD_AES_CON_BL_CFB 1 + * @arg @ref MD_AES_CON_BL_OFB 2 + * @arg @ref MD_AES_CON_BL_CTR 3 + * @arg @ref MD_AES_CON_BL_ECB 4 + * @arg @ref MD_AES_CON_BL_GCM 5 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_con_bl(AES_TypeDef *aes, uint32_t value) +{ + MODIFY_REG(aes->CON, AES_CON_BL_MSK, (value << AES_CON_BL_POSS)); +} + +/** + * @brief Block Cipher Encryption / Decryption Mode + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_BL_CBC 0 + * @arg @ref MD_AES_CON_BL_CFB 1 + * @arg @ref MD_AES_CON_BL_OFB 2 + * @arg @ref MD_AES_CON_BL_CTR 3 + * @arg @ref MD_AES_CON_BL_ECB 4 + * @arg @ref MD_AES_CON_BL_GCM 5 + */ +__STATIC_INLINE uint32_t md_aes_get_con_bl(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_BL_MSK) >> AES_CON_BL_POSS) & 0x7); +} + +/** + * @brief AES Input Reverse + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_REV_NORMAL 0 + * @arg @ref MD_AES_CON_REV_REVERSE 1 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_con_rev(AES_TypeDef *aes, uint32_t value) +{ + MODIFY_REG(aes->CON, AES_CON_REV_MSK, (value << AES_CON_REV_POS)); +} + +/** + * @brief AES Input Reverse + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_REV_NORMAL 0 + * @arg @ref MD_AES_CON_REV_REVERSE 1 + */ +__STATIC_INLINE uint32_t md_aes_get_con_rev(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_REV_MSK) >> AES_CON_REV_POS) & 0x1); +} + +/** + * @brief AES Mode Control + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_MODE_ENCRYPT 0 + * @arg @ref MD_AES_CON_MODE_DECRYPT 1 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_con_mode(AES_TypeDef *aes, uint32_t value) +{ + MODIFY_REG(aes->CON, AES_CON_MODE_MSK, (value << AES_CON_MODE_POS)); +} + +/** + * @brief AES Mode Control + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_MODE_ENCRYPT 0 + * @arg @ref MD_AES_CON_MODE_DECRYPT 1 + */ +__STATIC_INLINE uint32_t md_aes_get_con_mode(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_MODE_MSK) >> AES_CON_MODE_POS) & 0x1); +} + +/** + * @brief AES Start + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_START 1 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_con_start(AES_TypeDef *aes, uint32_t value) +{ + MODIFY_REG(aes->CON, AES_CON_START_MSK, (value << AES_CON_START_POS)); +} + +/** + * @brief AES Start + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_CON_START 1 + */ +__STATIC_INLINE uint32_t md_aes_get_con_start(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->CON, AES_CON_START_MSK) >> AES_CON_START_POS) & 0x1); +} + +/** + * @brief AES Interrupt Enable Register + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_IER_DECIE 1 + * @arg @ref MD_AES_IER_ENCIE 1 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_ier(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->IER, value); +} + +/** + * @brief AES Decryption Interrupt Enable + * @param AES Instance + * @retval None. + */ +__STATIC_INLINE void md_aes_enable_ier_decie(AES_TypeDef *aes) +{ + MODIFY_REG(aes->IER, AES_IER_DECIE_MSK, (1 << AES_IER_DECIE_POS)); +} + +/** + * @brief AES Encryption Interrupt Enable + * @param AES Instance + * @retval None. + */ +__STATIC_INLINE void md_aes_enable_ier_encie(AES_TypeDef *aes) +{ + MODIFY_REG(aes->IER, AES_IER_ENCIE_MSK, (1 << AES_IER_ENCIE_POS)); +} + +/** + * @brief AES Interrupt Disable Register + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_AES_IDR_DECID 1 + * @arg @ref MD_AES_IDR_ENCID 1 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_idr(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->IDR, value); +} + +/** + * @brief AES Decryption Interrupt Disable + * @param AES Instance + * @retval None. + */ +__STATIC_INLINE void md_aes_disable_idr_decid(AES_TypeDef *aes) +{ + MODIFY_REG(aes->IDR, AES_IDR_DECID_MSK, (1 << AES_IDR_DECID_POS)); +} + +/** + * @brief AES Encryption Interrupt Disable + * @param AES Instance + * @retval None. + */ +__STATIC_INLINE void md_aes_disable_idr_encid(AES_TypeDef *aes) +{ + MODIFY_REG(aes->IDR, AES_IDR_DECID_MSK, (1 << AES_IDR_DECID_POS)); +} + +/** + * @brief AES Interrupt Valid Status Register + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @ref MD_AES_IVS_DECIVS_DISABLE 0 + * @arg @ref MD_AES_IVS_DECIVS_ENABLE 1 + * @arg @ref MD_AES_IVS_ENCIVS_DISABLE 0 + * @arg @ref MD_AES_IVS_ENCIVS_ENABLE 1 + */ +__STATIC_INLINE uint32_t md_aes_get_ivs(AES_TypeDef *aes) +{ + return (READ_REG(aes->IVS)); +} + +/** + * @brief AES Decryption Interrupt Valid Status + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg value true, false + */ +__STATIC_INLINE bool md_aes_is_enabled_ivs_decivs(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->IVS, AES_IVS_DECIVS_MSK) >> AES_IVS_DECIVS_POS) & 0x1) ? true : false; +} + +/** + * @brief AES Encryption Interrupt Valid Status + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg value true, false + */ +__STATIC_INLINE bool md_aes_is_enabled_ivs_encivs(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->IVS, AES_IVS_ENCIVS_MSK) >> AES_IVS_ENCIVS_POS) & 0x1) ? true : false; +} + +/** + * @brief AES Raw Interrupt Flag Status + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @reg MD_AES_RIF_DECRIF_NO_INTERRUPT 0 + * @arg @reg MD_AES_RIF_DECRIF_INTERRUPT 1 + */ +__STATIC_INLINE uint32_t md_aes_get_rif(AES_TypeDef *aes) +{ + return (READ_REG(aes->RIF)); +} + +/** + * @brief AES Encryption Raw Interrupt Flag Status + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg value true, false + */ +__STATIC_INLINE bool md_aes_is_active_rif_decrif(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->RIF, AES_RIF_DECRIF_MSK) >> AES_RIF_DECRIF_POS) & 0x1) ? true : false; +} + +/** + * @brief AES Encryption Raw Interrupt Flag Status + * @param Mode This parameter can be one of the following values: + * @arg value true, false + * @retval None. + */ +__STATIC_INLINE bool md_aes_is_active_rif_encrif(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->RIF, AES_RIF_ENCRIF_MSK) >> AES_RIF_ENCRIF_POS) & 0x1) ? true : false; +} + +/** + * @brief AES Interrupt Flag Mask Status Register + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg @reg MD_AES_IFM_DECRIF_MASK 0 + * @arg @reg MD_AES_IFM_DECRIF_SIGNAL 1 + * @arg @reg MD_AES_IFM_ENCRIF_MASK 0 + * @arg @reg MD_AES_IFM_ENCRIF_SIGNAL 1 + */ +__STATIC_INLINE uint32_t md_aes_get_ifm(AES_TypeDef *aes) +{ + return (READ_REG(aes->IFM)); +} + +/** + * @brief AES Interrupt Flag Mask Status Register + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg value true, false + */ +__STATIC_INLINE bool md_aes_is_active_ifm_decifm(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->IFM, AES_IFM_DECIFM_MSK) >> AES_IFM_DECIFM_POS) & 0x1) ? true : false; +} + +/** + * @brief AES Interrupt Flag Mask Status Register + * @param AES Instance + * @retval value This parameter can be one of the following values: + * @arg value true, false + */ +__STATIC_INLINE bool md_aes_is_active_ifm_encifm(AES_TypeDef *aes) +{ + return ((READ_BIT(aes->IFM, AES_IFM_ENCIFM_MSK) >> AES_IFM_ENCIFM_POS) & 0x1) ? true : false; +} + +/** + * @brief AES Interrupt Clear Register + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg @reg MD_AES_ICR_DECICR 1 + * @arg @reg MD_AES_ICR_ENCICR 1 + * @retval None. + */ +__STATIC_INLINE void md_aes_set_icr(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->ICR, value); +} + +/** + * @brief AES Decryption Interrupt Clear + * @param AES Instance + * @retval None. + */ +__STATIC_INLINE void md_aes_clear_icr_decicr(AES_TypeDef *aes) +{ + MODIFY_REG(aes->ICR, AES_ICR_DECICR_MSK, (1 << AES_ICR_DECICR_POS)); +} + +/** + * @brief AES Encryption Interrupt Clear + * @param AES Instance + * @retval None. + */ +__STATIC_INLINE void md_aes_clear_icr_encicr(AES_TypeDef *aes) +{ + MODIFY_REG(aes->ICR, AES_ICR_ENCICR_MSK, (1 << AES_ICR_ENCICR_POS)); +} + +/** + * @brief AES 128-bit Input / Ouput Data Register + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_dio(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->DIO, value); +} + +/** + * @brief AES 128-bit Input / Ouput Data Register + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +//#pragma push +//#pragma O0 +__STATIC_INLINE uint32_t md_aes_get_dio(AES_TypeDef *aes) +{ + return (READ_REG(aes->DIO)); +} +//#pragma pop + +/** + * @brief AES 128-bit Keyword Register 0 + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_key0(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->KEY0, value); +} + +/** + * @brief AES 128-bit Keyword Register 0 + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +__STATIC_INLINE uint32_t md_aes_get_key0(AES_TypeDef *aes) +{ + return (READ_REG(aes->KEY0)); +} + +/** + * @brief AES 128-bit Keyword Register 1 + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_key1(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->KEY1, value); +} + +/** + * @brief AES 128-bit Keyword Register 1 + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +__STATIC_INLINE uint32_t md_aes_get_key1(AES_TypeDef *aes) +{ + return (READ_REG(aes->KEY1)); +} + +/** + * @brief AES 128-bit Keyword Register 2 + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_key2(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->KEY2, value); +} + +/** + * @brief AES 128-bit Keyword Register 2 + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +__STATIC_INLINE uint32_t md_aes_get_key2(AES_TypeDef *aes) +{ + return (READ_REG(aes->KEY2)); +} + +/** + * @brief AES 128-bit Keyword Register 3 + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_key3(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->KEY3, value); +} + +/** + * @brief AES 128-bit Keyword Register 3 + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +__STATIC_INLINE uint32_t md_aes_get_key3(AES_TypeDef *aes) +{ + return (READ_REG(aes->KEY3)); +} + +/** + * @brief AES 128-bit Initial Vector Register 0 + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_iv0(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->IV0, value); +} + +/** + * @brief AES 128-bit Initial Vector Register 0 + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +__STATIC_INLINE uint32_t md_aes_get_iv0(AES_TypeDef *aes) +{ + return (READ_REG(aes->IV0)); +} + +/** + * @brief AES 128-bit Initial Vector Register 1 + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_iv1(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->IV1, value); +} + +/** + * @brief AES 128-bit Initial Vector Register 1 + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +__STATIC_INLINE uint32_t md_aes_get_iv1(AES_TypeDef *aes) +{ + return (READ_REG(aes->IV1)); +} + +/** + * @brief AES 128-bit Initial Vector Register 2 + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_iv2(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->IV2, value); +} + +/** + * @brief AES 128-bit Initial Vector Register 2 + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +__STATIC_INLINE uint32_t md_aes_get_iv2(AES_TypeDef *aes) +{ + return (READ_REG(aes->IV2)); +} + +/** + * @brief AES 128-bit Initial Vector Register 3 + * @param AES Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_aes_set_iv3(AES_TypeDef *aes, uint32_t value) +{ + WRITE_REG(aes->IV3, value); +} + +/** + * @brief AES 128-bit Initial Vector Register 3 + * @param AES Instance + * @retval value + * @arg Minimum 0x0000000 + * @arg Maximum 0xFFFFFFF + */ +__STATIC_INLINE uint32_t md_aes_get_iv3(AES_TypeDef *aes) +{ + return (READ_REG(aes->IV3)); +} + +/** + * @} MD_AES_Public_Macros + */ + +/** + * @} AES + */ + +#endif + +/** + * @} Micro_Driver + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_cmp.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_cmp.h new file mode 100644 index 0000000000..b2b6d2b2e0 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_cmp.h @@ -0,0 +1,573 @@ +/** + ****************************************************************************** + * @file md_CMP.h + * @brief ES32F0271 CMP Head File. + * + * @version V1.00.01 + * @date 11/23/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + + /* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_CMP_H__ +#define __MD_CMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_cmp.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (CMP) +/** @defgroup CMP CMP + * @brief CMP micro driver + * @{ + */ + + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +/* Public types ---------------------------------------------------------------*/ +/* Public constants -----------------------------------------------------------*/ + +/** @defgroup MD_CMP_Public_Constants CMP Public Constants + * @{ + */ + +/** @defgroup MD_CMP_PC_CARS CMP Reference voltage + * @{ + */ +#define MD_CMP_CARS_1_25V (0x00000000UL) /*!< @brief Select CARS for 0.25*5V */ +#define MD_CMP_CARS_2_50V (0x00000001UL) /*!< @brief Select CARS for 0.5*5V */ +#define MD_CMP_CARS_3_75V (0x00000002UL) /*!< @brief Select CARS for 0.75*5V */ +#define MD_CMP_CARS_5_00V (0x00000003UL) /*!< @brief Select CARS for 5V */ + +/** + * @} MD_CMP_PC_CARS + */ + + +/** + * @} MD_CMP_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_CMP_Public_Macros CMP Public Macros + * @{ + */ + +/** @defgroup MD_CMP_PF_CON CMP Control Register + * @{ + */ +/** + * @brief Set CMP control register (CMP_CON) + * @param cmp CMP Instance + * @param value The value write in CMP_CON + * @retval None + */ +__STATIC_INLINE void md_cmp_set_con(CMP_TypeDef *cmp, uint32_t value) +{ + WRITE_REG(cmp->CON, value); +} + +/** + * @brief Get CMP control register (CMP_CON) + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_get_con(CMP_TypeDef *cmp) +{ + return (uint32_t)(READ_REG(cmp->CON)); +} + +/** + * @brief Enable Comparator 1 enable set + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_con_cmpon1(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CON, CMP_CON_CMPON1_MSK); +} +/** + * @brief Disable Comparator 1 enable set + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_con_cmpon1(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CON, CMP_CON_CMPON1_MSK); +} + +/** + * @brief Check if Comparator 1 enable set is enable + * @param cmp CMP Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_con_cmpon1(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CON, CMP_CON_CMPON1_MSK)); +} + +/** + * @brief Enable Comparator 2 enable set + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_con_cmpon2(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CON, CMP_CON_CMPON2_MSK); +} +/** + * @brief Disable Comparator 2 enable set + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_con_cmpon2(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CON, CMP_CON_CMPON2_MSK); +} + +/** + * @brief Check if Comparator 2 enable set is enable + * @param cmp CMP Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_con_caon2(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CON, CMP_CON_CMPON2_MSK)); +} + +/** + * @} MD_CMP_PF_CON + */ + + +/** @defgroup MD_CMP_PF_Configuration CMP Configuration Manangement + * @{ + */ + + +/** + * @brief Set CMP control register 1(CMP_CFG1) + * @param cmp CMP Instance + * @param value The value write in CMP_CFG1 + * @retval None + */ +__STATIC_INLINE void md_cmp_set_cfg1(CMP_TypeDef *cmp, uint32_t value) +{ + WRITE_REG(cmp->CFG1, value); +} +/** + * @brief Get CMP control register 1(CMP_CFG1) + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_get_cfg1(CMP_TypeDef *cmp) +{ + return (uint32_t)(READ_REG(cmp->CFG1)); +} + + +/** + * @brief Set Comparator 1 reference voltage selection. + * @param cmp CMP Instance + * @param RefVol This parameter can be one of the following values: + * @arg MD_CMP_CARS_1_25V + * @arg MD_CMP_CARS_2_50V + * @arg MD_CMP_CARS_3_75V + * @arg MD_CMP_CARS_5_00V + * @retval None + */ +__STATIC_INLINE void md_cmp_set_cfg1_rs(CMP_TypeDef *cmp, uint32_t RefVol) +{ + MODIFY_REG(cmp->CFG1, CMP_CFG1_RS_MSK, RefVol<CFG1, CMP_CFG1_RS_MSK) >> CMP_CFG1_RS_POSS); +} + + +/** + * @brief Enable Comparator 1 Filter circuit + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_cfg1_fen(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CFG1, CMP_CFG1_FEN_MSK); +} +/** + * @brief Disable Comparator 1 Filter circuit + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_cfg1_fen(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CFG1, CMP_CFG1_FEN_MSK); +} + +/** + * @brief Check if Comparator 1 Filter circuit is enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_cfg1_fen(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CFG1, CMP_CFG1_FEN_MSK) == (CMP_CFG1_FEN_MSK)); +} + + +/** + * @brief Enable comparator 1 reverse circuit enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_cfg1_psen(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CFG1, CMP_CFG1_PSEN_MSK); +} +/** + * @brief Disable comparator 1 reverse circuit enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_cfg1_psen(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CFG1, CMP_CFG1_PSEN_MSK); +} + +/** + * @brief Check if comparator 1 reverse circuit enable is enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_cfg1_capsen(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CFG1, CMP_CFG1_PSEN_MSK) == (CMP_CFG1_PSEN_MSK) ); +} + + +/** + * @brief Enable Comparator 1 Negative input select + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_cfg1_insel(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CFG1, CMP_CFG1_INSEL_MSK); +} +/** + * @brief Disable Comparator 1 Negative input select + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_cfg1_insel(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CFG1, CMP_CFG1_INSEL_MSK); +} + +/** + * @brief Check if comparator 1 Negative input select is enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_cfg1_insel(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CFG1, CMP_CFG1_INSEL_MSK) == (CMP_CFG1_INSEL_MSK)); +} + + +/** + * @brief Enable comparator 1 Positive input select + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_cfg1_ipsel(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CFG1, CMP_CFG1_IPSEL_MSK); +} +/** + * @brief Disable comparator 1 Positive input select + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_cfg1_ipsel(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CFG1, CMP_CFG1_IPSEL_MSK); +} + +/** + * @brief Check if comparator 1 Positive input select is enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_cfg1_ipsel(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CFG1, CMP_CFG1_IPSEL_MSK) == (CMP_CFG1_IPSEL_MSK)); +} + + +/** + * @brief Set CMP control register 2(CMP_CFG2) + * @param cmp CMP Instance + * @param value The value write in CMP_CFG2 + * @retval None + */ +__STATIC_INLINE void md_cmp_set_cfg2(CMP_TypeDef *cmp, uint32_t value) +{ + WRITE_REG(cmp->CFG2, value); +} +/** + * @brief Get CMP control register 2(CMP_CFG2) + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_get_cfg2(CMP_TypeDef *cmp) +{ + return (uint32_t)(READ_REG(cmp->CFG2)); +} + + +/** + * @brief Set Comparator 2 reference voltage selection. + * @param cmp CMP Instance + * @param RefVol This parameter can be one of the following values: + * @arg MD_CMP_CARS_1_25V + * @arg MD_CMP_CARS_2_50V + * @arg MD_CMP_CARS_3_75V + * @arg MD_CMP_CARS_5_00V + * @retval None + */ +__STATIC_INLINE void md_cmp_set_cfg2_rs(CMP_TypeDef *cmp, uint32_t RefVol) +{ + MODIFY_REG(cmp->CFG2, CMP_CFG2_RS_MSK, RefVol << CMP_CFG2_RS_POSS); +} + +/** + * @brief Return Comparator 2 reference voltage + * @param cmp CMP Instance + * @retval None + * @arg MD_CMP_CARS_1_25V + * @arg MD_CMP_CARS_2_50V + * @arg MD_CMP_CARS_3_75V + * @arg MD_CMP_CARS_5_00V + */ +__STATIC_INLINE uint32_t md_cmp_get_cfg2_rs(CMP_TypeDef *cmp) +{ + return (uint32_t)(READ_BIT(cmp->CFG2, CMP_CFG2_RS_MSK) >> CMP_CFG2_RS_POSS); +} + + +/** + * @brief Enable Comparator 2 Filter circuit + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_cfg2_fen(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CFG2, CMP_CFG2_FEN_MSK); +} +/** + * @brief Disable Comparator 2 Filter circuit + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_cfg2_fen(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CFG2, CMP_CFG2_FEN_MSK); +} + +/** + * @brief Check if Comparator 2 Filter circuit is enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_cfg2_fen(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CFG2, CMP_CFG2_FEN_MSK) == (CMP_CFG2_FEN_MSK)) ; +} + + +/** + * @brief Enable comparator 2 reverse circuit enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_cfg2_psen(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CFG2, CMP_CFG2_PSEN_MSK); +} +/** + * @brief Disable comparator 2 reverse circuit enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_cfg2_psen(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CFG2, CMP_CFG2_PSEN_MSK); +} + +/** + * @brief Check if comparator 2 reverse circuit enable is enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_cfg2_psen(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CFG2, CMP_CFG2_PSEN_MSK) == (CMP_CFG2_PSEN_MSK)); +} + + +/** + * @brief Enable Comparator 2 Negative input select + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_cfg2_insel(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CFG2, CMP_CFG2_INSEL_MSK); +} +/** + * @brief Disable Comparator 2 Negative input select + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_cfg2_insel(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CFG2, CMP_CFG2_INSEL_MSK); +} + +/** + * @brief Check if comparator 2 Negative input select is enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_cfg2_insel(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CFG2, CMP_CFG2_INSEL_MSK) == (CMP_CFG2_INSEL_MSK)); +} + + +/** + * @brief Enable comparator 2 Positive input select + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_enable_cfg2_ipsel(CMP_TypeDef *cmp) +{ + SET_BIT(cmp->CFG2, CMP_CFG2_IPSEL_MSK); +} +/** + * @brief Disable comparator 2 Positive input select + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE void md_cmp_disable_cfg2_ipsel(CMP_TypeDef *cmp) +{ + CLEAR_BIT(cmp->CFG2, CMP_CFG2_IPSEL_MSK); +} + +/** + * @brief Check if comparator 2 Positive input select is enable + * @param cmp CMP Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_cmp_is_enable_cfg2_ipsel(CMP_TypeDef *cmp) +{ + return (READ_BIT(cmp->CFG2, CMP_CFG2_IPSEL_MSK) == (CMP_CFG2_IPSEL_MSK)); +} + + +/** + * @} MD_CMP_PF_Configuration + */ + +/** @defgroup MD_CMP_PC_RULT CMP Comparator Output Register. + * @{ + */ + +/** + * @brief Return Comparator output result(CMP_RULT) + * @param cmp CMP Instance + * @retval The state of 1 or 0 + */ +__STATIC_INLINE uint32_t md_cmp_get_rult(CMP_TypeDef *cmp) +{ + return (uint32_t)(READ_REG(cmp->RULT)); +} + +/** + * @brief Return Comparator 1 output result + * @param cmp CMP Instance + * @retval The state of 1 or 0 + */ +__STATIC_INLINE uint32_t md_cmp_get_rult_cmpo1(CMP_TypeDef *cmp) +{ + return (uint32_t)(READ_BIT(cmp->RULT, CMP_RULT_CMPO1_MSK)); +} +/** + * @brief Return Comparator 2 output result + * @param cmp CMP Instance + * @retval The state of 1 or 0 + */ +__STATIC_INLINE uint32_t md_cmp_get_rult_cmpo2(CMP_TypeDef *cmp) +{ + return (uint32_t)(READ_BIT(cmp->RULT, CMP_RULT_CMPO2_MSK)); +} + + +/** + * @} MD_CMP_PC_RULT + */ + + +/** + * @} MD_CMP_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ + +/** + * @} CMP + */ + +#endif + + +/** + * @} Micro_Driver + */ + +#endif + +#ifdef __cplusplus +} +#endif + + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_crc.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_crc.h new file mode 100644 index 0000000000..f1b65692e7 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_crc.h @@ -0,0 +1,519 @@ +/** + ****************************************************************************** + * @file md_crc.h + * @brief M601 CRC Head File. + * + * @version V0.01 + * @date 28/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_CRC_H__ +#define __MD_CRC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (CRC) + +/** @defgroup CRC CRC + * @brief CRC module driver + * @{ + */ + +/* Private Types --------------------------------------------------------------*/ +/* Private Variables ----------------------------------------------------------*/ +/* Private Macros -------------------------------------------------------------*/ +/* Public Types ---------------------------------------------------------------*/ +/** @defgroup MD_CRC_INIT CRC public init structure + * @brief + * @{ + */ +typedef struct +{ + uint32_t xorout; + uint32_t refout; + uint32_t refin; + uint32_t byte; + uint32_t mode; + uint32_t req; + uint32_t ds; + uint32_t rst; +} md_crc_init_typedef; +/** + * @} MD_CRC_INIT + */ + +/* Public Constants -----------------------------------------------------------*/ +/** @defgroup MD_CRC_Public_Constants CRC Public Constants + * @brief + * @{ + */ + +/** @defgroup MD_CRC_CON_registers CRC Control Registers + * @brief + * @{ + */ +#define MD_CRC_CON_DMA_ON 1 /*!< This allow user to enable DMA function. */ +#define MD_CRC_CON_DMA_OFF 0 /*!< This allow user to disable DMA function. */ +#define MD_CRC_CON_MSB_ON 1 /*!< User can set this bit to change the 'byte' order of input data. */ +#define MD_CRC_CON_MSB_OFF 1 /*!< User can set this bit to change the 'byte' order of input data. */ +#define MD_CRC_CON_REOUT 0 /*!< This allow user to reverse the order of CRC output data. */ +#define MD_CRC_CON_REOUT_REV 1 /*!< This allow user to reverse the order of CRC output data. */ +#define MD_CRC_CON_REIN 0 /*!< This allow user to reverse the order of CRC input data. */ +#define MD_CRC_CON_REIN_REV 1 /*!< This allow user to reverse the order of CRC input data. */ +#define MD_CRC_CON_SIZE_POLY32 0 /*!< This allow user to select polynomial size. */ +#define MD_CRC_CON_SIZE_POLY16 1 /*!< This allow user to select polynomial size. */ +#define MD_CRC_CON_SIZE_POLY8 2 /*!< This allow user to select polynomial size. */ +#define MD_CRC_CON_MODE_COMP_DISABLE 0 /*!< This allow user to check CRC result. */ +#define MD_CRC_CON_MODE_COMP_ZERO 1 /*!< This allow user to check CRC result. */ +#define MD_CRC_CON_MODE_COMP_ENABLE 2 /*!< This allow user to check CRC result. */ +#define MD_CRC_CON_RESET 1 /*!< User can set this bit to reset CRC function. */ +/** + * @} MD_CRC_CON_registers + */ + +/** @defgroup MD_CRC_STAT_registers CRC Status Registers + * @brief + * @{ + */ +#define MD_CRC_STAT_FAIL 1 /*!< This bit is set when CRC result is not correct. */ +#define MD_CRC_STAT_EMPTY 1 /*!< This bit is cleaned after an CRC calculation. */ +#define MD_CRC_STAT_BUSY 1 /*!< This bit is set when CRC module is calculating result. */ +#define MD_CRC_STAT_DONE 1 /*!< This bit is set when CRC calculation is finish. */ +/** + * @} MD_CRC_STAT_registers + */ + +/** + * @} MD_CRC_Public_Constants + */ + +/* Public Macros --------------------------------------------------------------*/ +/** @defgroup MD_CRC_Public_Macros CRC Public Macros + * @brief + * @{ + */ + +/** + * @brief This register is used to write the CRC initial data. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x00000000 + * @arg Maximum 0xFFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_crc_set_init(CRC_TypeDef *crc, uint32_t value) +{ + WRITE_REG(crc->INIT, value); +} + +/** + * @brief This register is used to read the CRC initial data. + * @param CRC Instance + * @retval value 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_init(CRC_TypeDef *crc) +{ + return (READ_REG(crc->INIT)); +} + +/** + * @brief This register is used to write the coefficient of the CRC polynomial. Default coefficient is for CRC32. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x00000000 + * @arg Maximum 0xFFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_crc_set_poly(CRC_TypeDef *crc, uint32_t value) +{ + WRITE_REG(crc->POLY, value); +} + +/** + * @brief This register is used to read the coefficient of the CRC polynomial. Default coefficient is for CRC32. + * @param CRC Instance + * @retval value 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_poly(CRC_TypeDef *crc) +{ + return (READ_REG(crc->POLY)); +} + +/** + * @brief This register is used to write the CRC input data. CRC will start to calculate result after this register is written. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x00000000 + * @arg Maximum 0xFFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_crc_set_data(CRC_TypeDef *crc, uint32_t value) +{ + WRITE_REG(crc->DATA, value); +} + +/** + * @brief This register is used to read the CRC input data. CRC will start to calculate result after this register is written. + * @param CRC Instance + * @retval value 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_data(CRC_TypeDef *crc) +{ + return (READ_REG(crc->DATA)); +} + +/** + * @brief This register is used to compare with the CRC output data. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x00000000 + * @arg Maximum 0xFFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_crc_set_comp(CRC_TypeDef *crc, uint32_t value) +{ + WRITE_REG(crc->COMP, value); +} + +/** + * @brief This register is used to compare with the CRC output data. + * @param CRC Instance + * @retval value 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_comp(CRC_TypeDef *crc) +{ + return (READ_REG(crc->COMP)); +} + +/** + * @brief This register is used to set a parameter to do exclusive OR with CRC output data. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg Minimum 0x00000000 + * @arg Maximum 0xFFFFFFFF + * @retval None. + */ +__STATIC_INLINE void md_crc_set_rema(CRC_TypeDef *crc, uint32_t value) +{ + WRITE_REG(crc->REMA, value); +} + +/** + * @brief This register is used to set a parameter to do exclusive OR with CRC output data. + * @param CRC Instance + * @retval value 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_rema(CRC_TypeDef *crc) +{ + return (READ_REG(crc->REMA)); +} + +/** + * @brief This register is used to set a parameter. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_CRC_CON_DMA_ON 1 + * @arg @ref MD_CRC_CON_DMA_OFF 0 + * @arg @ref MD_CRC_CON_MSB_ON 1 + * @arg @ref MD_CRC_CON_MSB_OFF 0 + * @arg @ref MD_CRC_CON_REOUT 0 + * @arg @ref MD_CRC_CON_REOUT_REV 1 + * @arg @ref MD_CRC_CON_REIN 0 + * @arg @ref MD_CRC_CON_REIN_REV 1 + * @arg @ref MD_CRC_CON_SIZE_POLY32 0 + * @arg @ref MD_CRC_CON_SIZE_POLY16 1 + * @arg @ref MD_CRC_CON_SIZE_POLY8 2 + * @arg @ref MD_CRC_CON_MODE_COMP_DISABLE 0 + * @arg @ref MD_CRC_CON_MODE_COMP_ZERO 1 + * @arg @ref MD_CRC_CON_MODE_COMP_ENABLE 2 + * @arg @ref MD_CRC_CON_RESET 1 + * @retval None. + */ +__STATIC_INLINE void md_crc_set_con(CRC_TypeDef *crc, uint32_t value) +{ + WRITE_REG(crc->CON, value); +} + +/** + * @brief This register is used to get a parameter. + * @param CRC Instance + * @retval value 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_con(CRC_TypeDef *crc) +{ + return (READ_REG(crc->CON)); +} + +/** + * @brief This function allow user to enable DMA function. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_CRC_CON_DMA_ON 1 + * @arg @ref MD_CRC_CON_DMA_OFF 0 + * @retval None. + */ +__STATIC_INLINE void md_crc_set_con_dma(CRC_TypeDef *crc, uint32_t value) +{ + MODIFY_REG(crc->CON, CRC_CON_DMA_MSK, value << CRC_CON_DMA_POS); +} + +/** + * @brief This function allow user to enable DMA function. + * @param CRC Instance + * @retval value 0: disable, 1: enable. + */ +__STATIC_INLINE uint32_t md_crc_get_con_dma(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->CON, CRC_CON_DMA_MSK) >> CRC_CON_DMA_POS) & 0x1); +} + +/** + * @brief User can set this bit to change the 'byte' order of input data. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_CRC_CON_MSB_ON 1 + * @arg @ref MD_CRC_CON_MSB_OFF 0 + * @retval None. + */ +__STATIC_INLINE void md_crc_set_con_msb(CRC_TypeDef *crc, uint32_t value) +{ + MODIFY_REG(crc->CON, CRC_CON_MSB_MSK, value << CRC_CON_MSB_POS); +} + +/** + * @brief User can set this bit to change the 'byte' order of input data. + * @param CRC Instance + * @retval value 0: disable, 1: enable. + */ +__STATIC_INLINE uint32_t md_crc_get_con_msb(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->CON, CRC_CON_MSB_MSK) >> CRC_CON_MSB_POS) & 0x1); +} + +/** + * @brief This function allow user to reverse the order of CRC output data. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg @reg MD_CRC_CON_REOUT 0 + * @arg @reg MD_CRC_CON_REOUT_REV 1 + * @retval None. + */ +__STATIC_INLINE void md_crc_set_con_reout(CRC_TypeDef *crc, uint32_t value) +{ + MODIFY_REG(crc->CON, CRC_CON_REOUT_MSK, value << CRC_CON_REOUT_POS); +} + +/** + * @brief This function allow user to reverse the order of CRC output data. + * @param CRC Instance + * @retval value 0: Disable reverse operation, 1: Reverse output data. + */ +__STATIC_INLINE uint32_t md_crc_get_con_reout(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->CON, CRC_CON_REOUT_MSK) >> CRC_CON_REOUT_POS) & 0x1); +} + +/** + * @brief This function allow user to reverse the order of CRC input data. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg @reg MD_CRC_CON_REIN 0 + * @arg @reg MD_CRC_CON_REIN_REV 1 + * @retval None. + */ +__STATIC_INLINE void md_crc_set_con_rein(CRC_TypeDef *crc, uint32_t value) +{ + MODIFY_REG(crc->CON, CRC_CON_REIN_MSK, value << CRC_CON_REIN_POS); +} + +/** + * @brief User can set this bit to change the 'byte' order of input data. + * @param CRC Instance + * @retval value 0: Disable reverse operation, 1: Bit reversal done by byte. + */ +__STATIC_INLINE uint32_t md_crc_get_con_rein(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->CON, CRC_CON_REIN_MSK) >> CRC_CON_REIN_POS) & 0x1); +} + +/** + * @brief User can set this bit to change the 'byte' order of input data. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_CRC_CON_SIZE_POLY32 0 + * @arg @ref MD_CRC_CON_SIZE_POLY16 1 + * @arg @ref MD_CRC_CON_SIZE_POLY8 2 + * @retval None. + */ +__STATIC_INLINE void md_crc_set_con_size(CRC_TypeDef *crc, uint32_t value) +{ + MODIFY_REG(crc->CON, CRC_CON_SIZE_MSK, value << CRC_CON_SIZE_POSS); +} + +/** + * @brief User can set this bit to change the 'byte' order of input data. + * @param CRC Instance + * @retval value 00: 32 bit polynomial, 01: 16 bit polynomial, 10: 8 bit polynomial. + */ +__STATIC_INLINE uint32_t md_crc_get_con_size(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->CON, CRC_CON_SIZE_MSK) >> CRC_CON_SIZE_POSS) & 0x3); +} + +/** + * @brief This function allow user to check CRC result. If CRC result is not correct, the status “FAIL” in CRC_STA will be set to 1. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_CRC_CON_MODE_COMP_DISABLE 0 + * @arg @ref MD_CRC_CON_MODE_COMP_ZERO 1 + * @arg @ref MD_CRC_CON_MODE_COMP_ENABLE 2 + * @retval None. + */ +__STATIC_INLINE void md_crc_set_con_mode(CRC_TypeDef *crc, uint32_t value) +{ + MODIFY_REG(crc->CON, CRC_CON_MODE_MSK, value << CRC_CON_MODE_POSS); +} + +/** + * @brief This function allow user to check CRC result. If CRC result is not correct, the status “FAIL” in CRC_STA will be set to 1. + * @param CRC Instance + * @retval value 00: Disable compare function, 01: Compare CRC result with 32’h0000_0000, 10: Compare CRC result with CRC_COMP. + */ +__STATIC_INLINE uint32_t md_crc_get_con_mode(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->CON, CRC_CON_MODE_MSK) >> CRC_CON_MODE_POSS) & 0x3); +} + +/** + * @brief User can set this bit to reset CRC function. This bit will be cleared by itself. + * @param CRC Instance + * @param value This parameter can be one of the following values: + * @arg @ref MD_CRC_CON_RESET 1 + * @retval None. + */ +__STATIC_INLINE void md_crc_set_con_reset(CRC_TypeDef *crc, uint32_t value) +{ + MODIFY_REG(crc->CON, CRC_CON_RESET_MSK, value << CRC_CON_RESET_POS); +} + +/** + * @brief User can set this bit to reset CRC function. This bit will be cleared by itself. + * @param CRC Instance + * @retval value 0. + */ +__STATIC_INLINE uint32_t md_crc_get_con_reset(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->CON, CRC_CON_RESET_MSK) >> CRC_CON_RESET_POS) & 0x1); +} + +/** + * @brief This register is used to show the CRC calculation result. + * @param CRC Instance + * @retval value: 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_dout(CRC_TypeDef *crc) +{ + return (READ_REG(crc->DOUT)); +} + +/** + * @brief This register is used to show the CRC calculation exculsive OR result. + * @param CRC Instance + * @retval value: 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_dout_xor(CRC_TypeDef *crc) +{ + return (READ_REG(crc->DOUT_XOR)); +} + +/** + * @brief This register is used to show the CRC calculation exculsive OR result. + * @param CRC Instance + * @retval value: 0x00000000 ~ 0xffffffff. + */ +__STATIC_INLINE uint32_t md_crc_get_stat(CRC_TypeDef *crc) +{ + return (READ_REG(crc->STAT)); +} + +/** + * @brief This bit is set when CRC result is not correct. + * @param CRC Instance + * @retval value: 1 = FAIL, 0 = PASS. + @arg @ref MD_CRC_STAT_FAIL 1 + */ +__STATIC_INLINE uint32_t md_crc_get_stat_fail(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->STAT, CRC_STAT_FAIL_MSK) >> CRC_STAT_FAIL_POS) & 0x1); +} + +/** + * @brief This bit is cleaned after an CRC calculation. + * @param CRC Instance + * @retval value: 1 = FAIL, 0 = PASS. + @arg @ref MD_CRC_STAT_EMPTY 1 + */ +__STATIC_INLINE uint32_t md_crc_get_stat_empty(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->STAT, CRC_STAT_EMPTY_MSK) >> CRC_STAT_EMPTY_POS) & 0x1); +} + +/** + * @brief This bit is set when CRC module is calculating result. + * @param CRC Instance + * @retval value: 1 = FAIL, 0 = PASS. + @arg @ref MD_CRC_STAT_BUSY 1 + */ +__STATIC_INLINE uint32_t md_crc_get_stat_busy(CRC_TypeDef *crc) +{ + return ((READ_BIT(crc->STAT, CRC_STAT_BUSY_MSK) >> CRC_STAT_BUSY_POS) & 0x1); +} + +/** + * @brief This bit is set when CRC module is calculating result. + * @param CRC Instance + * @retval value: 1 = FAIL, 0 = PASS. + @arg @ref MD_CRC_STAT_DONE 1 + */ +__STATIC_INLINE uint32_t md_crc_get_stat_done(CRC_TypeDef *crc) +{ + return (READ_BIT(crc->STAT, CRC_STAT_DONE_MSK) >> CRC_STAT_DONE_POS); +} + +/** + * @} MD_CRC_Public_Macros + */ + +/** + * @} CRC + */ + +#endif + +/** + * @} Micro_Driver + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_dac.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_dac.h new file mode 100644 index 0000000000..199fc195b1 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_dac.h @@ -0,0 +1,290 @@ +/** + ****************************************************************************** + * @file md_ADC.h + * @brief ES32F0271 DAC Header File. + * + * @version V1.00.01 + * @date 01/14/2019 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_DAC_H__ +#define __MD_DAC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_dac.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined DAC + +/** @defgroup DAC DAC + * @brief DAC micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +/* Public types ---------------------------------------------------------------*/ +/* Public constants -----------------------------------------------------------*/ +/* Public functions -----------------------------------------------------------*/ + +/** @defgroup MD_DAC_Public_Constants DAC Public Constants + * @{ + */ + +/** @defgroup MD_DAC_CON DAC_CON Register + * @{ + */ + +#define MD_ADC_CON_TSEL_SW (0x00000000U<CON, DAC_CON_INVREN_MSK); +} + +/** + * @brief DAC INVREN Disable. + * @param None + * @retval None + */ +__STATIC_INLINE void md_dac_disable_con_invren(DAC_TypeDef *DACx) +{ + CLEAR_BIT(DACx->CON, DAC_CON_INVREN_MSK); +} + +/** + * @brief Check if DAC INVREN is enabled. + * @param None + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dac_is_enabled_con_invren(DAC_TypeDef *DACx) +{ + return (READ_BIT(DACx->CON, DAC_CON_INVREN_MSK) == (DAC_CON_INVREN_MSK)); +} + +/** + * @brief TRIGGER enable. + * @param DACx DAC Instance + * @retval None + */ +__STATIC_INLINE void md_dac_enable_con_trien(DAC_TypeDef *DACx) +{ + SET_BIT(DACx->CON, DAC_CON_TRIEN_MSK); +} + +/** + * @brief TRIGGER Disable. + * @param DACx DAC Instance + * @retval None + */ +__STATIC_INLINE void md_dac_disable_en_trien(DAC_TypeDef *DACx) +{ + CLEAR_BIT(DACx->CON, DAC_CON_TRIEN_MSK); +} + +/** + * @brief Check if DAC TRIGGER is enabled. + * @param DACx DAC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dac_is_enabled_con_trien(DAC_TypeDef *DACx) +{ + return (READ_BIT(DACx->EN, DAC_CON_TRIEN_MSK) == (DAC_CON_TRIEN_MSK)); +} + +/** + * @brief Set DACx DIV register. + * @note This bits can only be written none zero value. + * @param DACx DAC Instance. + * @param DIV value. + * @retval None + */ +__STATIC_INLINE void md_dac_set_div(DAC_TypeDef *DACx, uint32_t div) +{ + WRITE_REG(DACx->DIV, div); +} + +/** + * @brief Set DACx DAC_CON WAVE value. + * @param DACx DAC Instance. + * @param WAVE value. + * @retval None + */ +__STATIC_INLINE void md_dac_set_con_wave(DAC_TypeDef *DACx, uint32_t wave) +{ + MODIFY_REG(DACx->CON, DAC_CON_MAMP_MSK, wave<CON, DAC_CON_MAMP_MSK, mamp<CON, DAC_CON_T_SEL_MSK, tsel<TRIG, DAC_TRIG_S_TRIG_MSK); +} + +/** + * @brief Check if Transmit FIFO full. + * @note This bit is set and cleared by hardware when the TX FIFO is no + * longer full. + * @param DACx DAC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dac_is_active_flag_stat_txfull(DAC_TypeDef *DACx) +{ + return (READ_BIT(DACx->STAT, DAC_STAT_TX_FULL_MSK) == (DAC_STAT_TX_FULL_MSK)); +} + +/** + * @brief Check if Transmit DAC is busy. + * @param DACx DAC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dac_is_active_flag_stat_busy(DAC_TypeDef *DACx) +{ + return (READ_BIT(DACx->STAT, DAC_STAT_BUSY_MSK) == (DAC_STAT_BUSY_MSK)); +} + +/** + * @brief DAC enable. + * @param DACx DAC Instance + * @retval None + */ +__STATIC_INLINE void md_dac_enable_en_dacen(DAC_TypeDef *DACx) +{ + SET_BIT(DACx->EN, DAC_EN_DAC_EN_MSK); +} + +/** + * @brief DAC Disable. + * @param DACx DAC Instance + * @retval None + */ +__STATIC_INLINE void md_dac_disable_en_dacen(DAC_TypeDef *DACx) +{ + CLEAR_BIT(DACx->EN, DAC_EN_DAC_EN_MSK); +} + +/** + * @brief Set DACx data register. + * @param DACx DAC Instance. + * @param Tx data value. + * @retval None + */ +__STATIC_INLINE void md_dac_set_txdata(DAC_TypeDef *DACx, uint32_t data) +{ + WRITE_REG(DACx->DATA, data); +} + +#endif + +/** + * @} MD_GPIO_Public_Macros + */ + +/** @} ADC + */ + +/** + * @} Micro_Driver + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_dma.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_dma.h new file mode 100644 index 0000000000..521ce1e61e --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_dma.h @@ -0,0 +1,5561 @@ +/** + ****************************************************************************** + * @file md_DMA.h + * @brief ES32F0271 DMA HEAD File. + * + * @version V1.00.02 + * @date 30/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_DMA_H__ +#define __MD_DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_dma.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (DMA1) + +/** @defgroup DMA DMA + * @brief DMA micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ +/** @defgroup MD_DMA_PT_INIT DMA Public Init structures + * @{ + */ + +/** + * @brief MD DMA Init Structure definition + */ + + +/** + * @} MD_DMA_PT_INIT + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_DMA_Public_Constants DMA Public Constants + * @{ + */ + +/** @defgroup MD_DMA_DINCOS Destination Increment Offset Size + * @{ + */ +#define MD_DMA_DINCOS_LINKED_DWSEL (0x00000000UL) /** @brief The offset size for the peripheral address calculation is + linked to the DWSEL */ +#define MD_DMA_DINCOS_FIXED_TO_4 (0X00000001UL) /** @brief The offset size for the peripheral address calculation is + fixed to 4 (32-bit alignment). */ +/** + * @} MD_DMA_DINCOS + */ + +/** @defgroup MD_DMA_DBUSEL Destination Transfer Burst Selection + * @{ + */ +#define MD_DMA_DBUSEL_SINGLE (0x00000000U) +#define MD_DMA_DBUSEL_WRAP4 (0x00000002U) +#define MD_DMA_DBUSEL_INCR4 (0x00000003U) +#define MD_DMA_DBUSEL_WRAP8 (0x00000004U) +#define MD_DMA_DBUSEL_INCR8 (0x00000005U) +#define MD_DMA_DBUSEL_WRAP16 (0x00000006U) +#define MD_DMA_DBUSEL_INCR16 (0x00000007U) +/** + * @} MD_DMA_DBUSEL + */ + +/** @defgroup MD_DMA_DDWSEL Destination Transfer Data Width Selection. + * @{ + */ +#define MD_DMA_DDWSEL_ONE_BYTE (0x00000000UL) /** @brief One byte (8-bit) is transferred for every DMA operation. */ +#define MD_DMA_DDWSEL_ONE_HALF_WORD (0x00000001UL) /** @brief One half-word (16-bit) is transferred for every DMA operation. */ +#define MD_DMA_DDWSEL_ONE_WORD (0x00000002UL) /** @brief One word (32-bit) is transferred for every DMA operation. */ +/** + * @} MD_DMA_DDWSEL + */ + +/** @defgroup MD_DMA_SINCOS Source Increment Offset Size + * @{ + */ +#define MD_DMA_SINCOS_LINKED_SWSEL (0x00000000UL) /** @brief The offset size for the peripheral address calculation is + linked to the SWSEL */ +#define MD_DMA_SINCOS_FIXED_TO_4 (0X00000001UL) /** @brief The offset size for the peripheral address calculation is + fixed to 4 (32-bit alignment). */ +/** + * @} MD_DMA_SINCOS + */ + +/** @defgroup MD_DMA_SBUSEL Source Transfer Burst Selection. + * @{ + */ +#define MD_DMA_SBUSEL_SINGLE (0x00000000U) +#define MD_DMA_SBUSEL_WRAP4 (0x00000002U) +#define MD_DMA_SBUSEL_INCR4 (0x00000003U) +#define MD_DMA_SBUSEL_WRAP8 (0x00000004U) +#define MD_DMA_SBUSEL_INCR8 (0x00000005U) +#define MD_DMA_SBUSEL_WRAP16 (0x00000006U) +#define MD_DMA_SBUSEL_INCR16 (0x00000007U) +/** + * @} MD_DMA_SBUSEL + */ + +/** @defgroup MD_DMA_SDWSEL Source Transfer Data Width Selection. + * @{ + */ +#define MD_DMA_SDWSEL_ONE_BYTE (0x00000000UL) /** @brief One byte (8-bit) is transferred for every DMA operation. */ +#define MD_DMA_SDWSEL_ONE_HALF_WORD (0x00000001UL) /** @brief One half-word (16-bit) is transferred for every DMA operation. */ +#define MD_DMA_SDWSEL_ONE_WORD (0x00000002UL) /** @brief One word (32-bit) is transferred for every DMA operation. */ +/** + * @} MD_DMA_SDWSEL + */ + +/** @defgroup MD_DMA_CHPRI DMA Channel Priority. + * @{ + */ +#define MD_DMA_CHPRI_LV0 (0x00000000U) +#define MD_DMA_CHPRI_LV1 (0x00000001U) +#define MD_DMA_CHPRI_LV2 (0x00000002U) +#define MD_DMA_CHPRI_LV3 (0x00000003U) +#define MD_DMA_CHPRI_LV4 (0x00000004U) +#define MD_DMA_CHPRI_LV5 (0x00000005U) +/** + * @} MD_DMA_CHPRI + */ + +/** @defgroup MD_DMA_MODESEL DMA Mode Select. + * @{ + */ +#define MD_DMA_MODESEL_MEM_TO_MEM (0x0000000UL) /** @brief Memory to Memory mode (Memory-to-Memory). */ +#define MD_DMA_MODESEL_PER_TO_MEM (0x0000001UL) /** @brief Peripheral to Memory mode (Peripheral-to-Memory). */ +#define MD_DMA_MODESEL_MEM_TO_PER (0x0000002UL) /** @brief Memory to Peripheral mode (Memory-to-Peripheral). */ +/** + * @} MD_DMA_MODESEL + */ + +/** @defgroup MD_DMA_PFCTRL Peripheral flow controller + * @{ + */ +#define MD_DMA_PFCTRL_DMA_CTRL (0x0000000UL) /** @brief The DMA is the flow controller */ +#define MD_DMA_PFCTRL_PER_CTRL (0x0000001UL) /** @brief The peripheral is the flow controller */ +/** + * @} MD_DMA_PFCTRL + */ + +/** @defgroup MD_DMA_PHSS Peripheral Handshake Software Select + * @{ + */ +#define MD_DMA_PHSS_UART1_TX (0x0000000UL) +#define MD_DMA_PHSS_UART2_TX (0x0000001UL) +#define MD_DMA_PHSS_UART3_TX (0x0000002UL) +#define MD_DMA_PHSS_SUART1_TX (0x0000003UL) +#define MD_DMA_PHSS_SUART2_TX (0x0000004UL) +#define MD_DMA_PHSS_SPI1_TX (0x0000005UL) +#define MD_DMA_PHSS_SPI2_TX (0x0000006UL) +#define MD_DMA_PHSS_I2C1_TX (0x0000007UL) +#define MD_DMA_PHSS_I2C2_TX (0x0000008UL) +#define MD_DMA_PHSS_AES_IN (0x0000009UL) +#define MD_DMA_PHSS_DAC (0x000000AUL) +#define MD_DMA_PHSS_CRC (0x000000BUL) +#define MD_DMA_PHSS_UART1_RX (0x000000FUL) +#define MD_DMA_PHSS_UART2_RX (0x0000010UL) +#define MD_DMA_PHSS_UART3_RX (0x0000011UL) +#define MD_DMA_PHSS_SUART1_RX (0x0000012UL) +#define MD_DMA_PHSS_SUART2_RX (0x0000013UL) +#define MD_DMA_PHSS_SPI1_RTX (0x0000014UL) +#define MD_DMA_PHSS_SPI2_RX (0x0000015UL) +#define MD_DMA_PHSS_I2C1_RX (0x0000016UL) +#define MD_DMA_PHSS_I2C2_RX (0x0000017UL) +#define MD_DMA_PHSS_AES_OUT (0x0000018UL) +#define MD_DMA_PHSS_ADCSS0 (0x0000019UL) +#define MD_DMA_PHSS_ADCSS1 (0x000001AUL) +#define MD_DMA_PHSS_ADCSS2 (0x000001BUL) +#define MD_DMA_PHSS_ADCSS3 (0x000001CUL) +#define MD_DMA_PHSS_BS16T1_UP (0x0000020UL) +#define MD_DMA_PHSS_AD16C4T1_CH1 (0x0000021UL) +#define MD_DMA_PHSS_AD16C4T1_CH2 (0x0000022UL) +#define MD_DMA_PHSS_AD16C4T1_CH3 (0x0000023UL) +#define MD_DMA_PHSS_AD16C4T1_CH4 (0x0000024UL) +#define MD_DMA_PHSS_AD16C4T1_UP (0x0000025UL) +#define MD_DMA_PHSS_AD16C4T1_TRIG (0x0000026UL) +#define MD_DMA_PHSS_AD16C4T1_COM (0x0000027UL) +#define MD_DMA_PHSS_GP32C4T1_CH1 (0x0000028UL) +#define MD_DMA_PHSS_GP32C4T1_CH2 (0x0000029UL) +#define MD_DMA_PHSS_GP32C4T1_CH3 (0x000002AUL) +#define MD_DMA_PHSS_GP32C4T1_CH4 (0x000002BUL) +#define MD_DMA_PHSS_GP32C4T1_UP (0x000002CUL) +#define MD_DMA_PHSS_GP32C4T1_TRIG (0x000002DUL) +#define MD_DMA_PHSS_GP16C4T1_CH1 (0x000002EUL) +#define MD_DMA_PHSS_GP16C4T1_CH2 (0x000002FUL) +#define MD_DMA_PHSS_GP16C4T1_CH3 (0x0000030UL) +#define MD_DMA_PHSS_GP16C4T1_CH4 (0x0000031UL) +#define MD_DMA_PHSS_GP16C4T1_UP (0x0000032UL) +#define MD_DMA_PHSS_GP16C4T1_TRIG (0x0000033UL) +#define MD_DMA_PHSS_GP16C4T2_CH1 (0x0000034UL) +#define MD_DMA_PHSS_GP16C4T2_CH2 (0x0000035UL) +#define MD_DMA_PHSS_GP16C4T2_CH3 (0x0000036UL) +#define MD_DMA_PHSS_GP16C4T2_CH4 (0x0000037UL) +#define MD_DMA_PHSS_GP16C4T2_UP (0x0000038UL) +#define MD_DMA_PHSS_GP16C4T2_TRIG (0x0000039UL) +#define MD_DMA_PHSS_GP16C4T3_CH1 (0x000003AUL) +#define MD_DMA_PHSS_GP16C4T3_CH2 (0x000003BUL) +#define MD_DMA_PHSS_GP16C4T3_CH3 (0x000003CUL) +#define MD_DMA_PHSS_GP16C4T3_CH4 (0x000003DUL) +#define MD_DMA_PHSS_GP16C4T3_UP (0x000003EUL) +#define MD_DMA_PHSS_GP16C4T3_TRIG (0x000003FUL) +#define MD_DMA_PHSS_GP16C2T1_CH1 (0x0000040UL) +#define MD_DMA_PHSS_GP16C2T1_CH2 (0x0000041UL) +#define MD_DMA_PHSS_GP16C2T1_UP (0x0000042UL) +#define MD_DMA_PHSS_GP16C2T1_TRIG (0x0000043UL) +#define MD_DMA_PHSS_GP16C2T1_COM (0x0000044UL) +#define MD_DMA_PHSS_GP16C2T2_CH1 (0x0000046UL) +#define MD_DMA_PHSS_GP16C2T2_CH2 (0x0000047UL) +#define MD_DMA_PHSS_GP16C2T2_UP (0x0000048UL) +#define MD_DMA_PHSS_GP16C2T2_TRIG (0x0000049UL) +#define MD_DMA_PHSS_GP16C2T2_COM (0x000004AUL) +#define MD_DMA_PHSS_GP16C2T3_CH1 (0x000004CUL) +#define MD_DMA_PHSS_GP16C2T3_CH2 (0x000004DUL) +#define MD_DMA_PHSS_GP16C2T3_UP (0x000004EUL) +#define MD_DMA_PHSS_GP16C2T3_TRIG (0x000004FUL) +#define MD_DMA_PHSS_GP16C2T3_COM (0x0000050UL) +#define MD_DMA_PHSS_GP16C2T4_CH1 (0x0000052UL) +#define MD_DMA_PHSS_GP16C2T4_CH2 (0x0000053UL) +#define MD_DMA_PHSS_GP16C2T4_UP (0x0000054UL) +#define MD_DMA_PHSS_GP16C2T4_TRIG (0x0000055UL) +#define MD_DMA_PHSS_GP16C2T4_COM (0x0000056UL) +/** + * @} MD_DMA_PHSS + */ + +/** + * @} MD_DMA_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_DMA_Public_Macros DMA Public Macros + * @{ + */ + +/** + * @brief DMA Channel 5 TABORT Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch5tabie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH5TABIE_MSK); +} +/** + * @brief DMA Channel 5 Block Transmit Done Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch5btdie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH5BTDIE_MSK); +} +/** + * @brief DMA Channel 4 TABORT Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch4tabie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH4TABIE_MSK); +} +/** + * @brief DMA Channel 4 Block Transmit Done Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch4btdie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH4BTDIE_MSK); +} +/** + * @brief DMA Channel 3 TABORT Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch3tabie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH3TABIE_MSK); +} +/** + * @brief DMA Channel 3 Block Transmit Done Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch3btdie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH3BTDIE_MSK); +} +/** + * @brief DMA Channel 2 TABORT Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch2tabie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH2TABIE_MSK); +} +/** + * @brief DMA Channel 2 Block Transmit Done Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch2btdie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH2BTDIE_MSK); +} +/** + * @brief DMA Channel 1 TABORT Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch1tabie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH1TABIE_MSK); +} +/** + * @brief DMA Channel 1 Block Transmit Done Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch1btdie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH1BTDIE_MSK); +} +/** + * @brief DMA Channel 0 TABORT Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch0tabie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH0TABIE_MSK); +} +/** + * @brief DMA Channel 0 Block Transmit Done Interrupt Enable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_ier_ch0btdie(DMA_TypeDef *dma) +{ + SET_BIT(dma->IER, DMA_IER_CH0BTDIE_MSK); +} + +/** @defgroup MD_DMA_IER_CH5TABIE CH5TABIE + * @brief Set DMA Channel 5 TABORT Interrupt Enable bit for md_dma_set_ier() function used + * @param ch5tabie This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_dma_set_ier_ch5tabie_fun(ch5tabie) (ch5tabie<IER, (ch5tabie|ch5btdie|ch4tabie|ch4btdie|ch3tabie|ch3btdie|ch2tabie|ch2btdie|ch1tabie|ch1btdie|ch0tabie|ch0btdie)); +} + +/** + * @brief DMA Channel 5 TABORT Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch5tabid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH5TABID_MSK); +} +/** + * @brief DMA Channel 5 Block Transmit Done Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch5btdid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH5BTDID_MSK); +} +/** + * @brief DMA Channel 4 TABORT Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch4tabid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH4TABID_MSK); +} +/** + * @brief DMA Channel 4 Block Transmit Done Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch4btdid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH4BTDID_MSK); +} +/** + * @brief DMA Channel 3 TABORT Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch3tabid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH3TABID_MSK); +} +/** + * @brief DMA Channel 3 Block Transmit Done Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch3btdid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH3BTDID_MSK); +} +/** + * @brief DMA Channel 2 TABORT Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch2tabid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH2TABID_MSK); +} +/** + * @brief DMA Channel 2 Block Transmit Done Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch2btdid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH2BTDID_MSK); +} +/** + * @brief DMA Channel 1 TABORT Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch1tabid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH1TABID_MSK); +} +/** + * @brief DMA Channel 1 Block Transmit Done Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch1btdid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH1BTDID_MSK); +} +/** + * @brief DMA Channel 0 TABORT Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch0tabid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH0TABID_MSK); +} +/** + * @brief DMA Channel 0 Block Transmit Done Interrupt Disable bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_enable_idr_ch0btdid(DMA_TypeDef *dma) +{ + SET_BIT(dma->IDR, DMA_IDR_CH0BTDID_MSK); +} + + +/** + * @brief DMA Channel 5 TABORT Interrupt Valid Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch5tabivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH5TABIVS_MSK)>>DMA_IVS_CH5TABIVS_POS); +} +/** + * @brief DMA Channel 5 Block Transmit Done Interrupt Valid Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch5btdivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH5BTDIVS_MSK)>>DMA_IVS_CH5BTDIVS_POS); +} +/** + * @brief DMA Channel 4 TABORT Interrupt Valid Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch4tabivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH4TABIVS_MSK)>>DMA_IVS_CH4TABIVS_POS); +} +/** + * @brief DMA Channel 4 Block Transmit Done Interrupt Valid Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch4btdivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH4BTDIVS_MSK)>>DMA_IVS_CH4BTDIVS_POS); +} +/** + * @brief DMA Channel 3 TABORT Interrupt Valid Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch3tabivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH3TABIVS_MSK)>>DMA_IVS_CH3TABIVS_POS); +} +/** + * @brief DMA Channel 3 Block Transmit Done Interrupt Valid Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch3btdivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH3BTDIVS_MSK)>>DMA_IVS_CH3BTDIVS_POS); +} +/** + * @brief DMA Channel 2 TABORT Interrupt Valid Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch2tabivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH2TABIVS_MSK)>>DMA_IVS_CH2TABIVS_POS); +} +/** + * @brief DMA Channel 2 Block Transmit Done Interrupt Valid Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch2btdivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH2BTDIVS_MSK)>>DMA_IVS_CH2BTDIVS_POS); +} +/** + * @brief DMA Channel 1 TABORT Interrupt Valid Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch1tabivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH1TABIVS_MSK)>>DMA_IVS_CH1TABIVS_POS); +} +/** + * @brief DMA Channel 1 Block Transmit Done Interrupt Valid Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch1btdivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH1BTDIVS_MSK)>>DMA_IVS_CH1BTDIVS_POS); +} +/** + * @brief DMA Channel 0 TABORT Interrupt Valid Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch0tabivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH0TABIVS_MSK)>>DMA_IVS_CH0TABIVS_POS); +} +/** + * @brief DMA Channel 0 Block Transmit Done Interrupt Valid Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch0btdivs(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IVS, DMA_IVS_CH0BTDIVS_MSK)>>DMA_IVS_CH0BTDIVS_POS); +} +/** + * @brief Get DMA interrupt valid status register + * @param dma DMA Instance + * @retval DMA channel interrupt valid status + */ +__STATIC_INLINE uint32_t md_dma_get_ivs(DMA_TypeDef *dma) +{ + return (READ_REG(dma->IVS)); +} + +/** + * @brief DMA Channel 5 TABORT Raw Interrupt Flag Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch5tabrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH5TABRIF_MSK)>>DMA_RIF_CH5TABRIF_POS); +} +/** + * @brief DMA Channel 5 Block Transmit Done Raw Interrupt Flag Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch5btdrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH5BTDRIF_MSK)>>DMA_RIF_CH5BTDRIF_POS); +} +/** + * @brief DMA Channel 4 TABORT Raw Interrupt Flag Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch4tabrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH4TABRIF_MSK)>>DMA_RIF_CH4TABRIF_POS); +} +/** + * @brief DMA Channel 4 Block Transmit Done Raw Interrupt Flag Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch4btdrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH4BTDRIF_MSK)>>DMA_RIF_CH4BTDRIF_POS); +} +/** + * @brief DMA Channel 3 TABORT Raw Interrupt Flag Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch3tabrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH3TABRIF_MSK)>>DMA_RIF_CH3TABRIF_POS); +} +/** + * @brief DMA Channel 3 Block Transmit Done Raw Interrupt Flag Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch3btdrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH3BTDRIF_MSK)>>DMA_RIF_CH3BTDRIF_POS); +} +/** + * @brief DMA Channel 2 TABORT Raw Interrupt Flag Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch2tabrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH2TABRIF_MSK)>>DMA_RIF_CH2TABRIF_POS); +} +/** + * @brief DMA Channel 2 Block Transmit Done Raw Interrupt Flag Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch2btdrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH2BTDRIF_MSK)>>DMA_RIF_CH2BTDRIF_POS); +} +/** + * @brief DMA Channel 1 TABORT Raw Interrupt Flag Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch1tabrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH1TABRIF_MSK)>>DMA_RIF_CH1TABRIF_POS); +} +/** + * @brief DMA Channel 1 Block Transmit Done Raw Interrupt Flag Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch1btdrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH1BTDRIF_MSK)>>DMA_RIF_CH1BTDRIF_POS); +} +/** + * @brief DMA Channel 0 TABORT Raw Interrupt Flag Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch0tabrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH0TABRIF_MSK)>>DMA_RIF_CH0TABRIF_POS); +} +/** + * @brief DMA Channel 0 Block Transmit Done Raw Interrupt Flag Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ivs_ch0btdrif(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->RIF, DMA_RIF_CH0BTDRIF_MSK)>>DMA_RIF_CH0BTDRIF_POS); +} +/** + * @brief Get DMA raw interrupt flag status register + * @param dma DMA Instance + * @retval DMA channel raw interrupt flag status + */ +__STATIC_INLINE uint32_t md_dma_get_rif(DMA_TypeDef *dma) +{ + return (READ_REG(dma->RIF)); +} + +/** + * @brief DMA Channel 5 TABORT Interrupt Flag Masked Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch5tabifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH5TABIFM_MSK)>>DMA_IFM_CH5TABIFM_POS); +} +/** + * @brief DMA Channel 5 Block Transmit Done Interrupt Flag Masked Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch5btdifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH5BTDIFM_MSK)>>DMA_IFM_CH5BTDIFM_POS); +} +/** + * @brief DMA Channel 4 TABORT Interrupt Flag Masked Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch4tabifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH4TABIFM_MSK)>>DMA_IFM_CH4TABIFM_POS); +} +/** + * @brief DMA Channel 4 Block Transmit Done Interrupt Flag Masked Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch4btdifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH4BTDIFM_MSK)>>DMA_IFM_CH4BTDIFM_POS); +} +/** + * @brief DMA Channel 3 TABORT Interrupt Flag Masked Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch3tabifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH3TABIFM_MSK)>>DMA_IFM_CH3TABIFM_POS); +} +/** + * @brief DMA Channel 3 Block Transmit Done Interrupt Flag Masked Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch3btdifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH3BTDIFM_MSK)>>DMA_IFM_CH3BTDIFM_POS); +} +/** + * @brief DMA Channel 2 TABORT Interrupt Flag Masked Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch2tabifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH2TABIFM_MSK)>>DMA_IFM_CH2TABIFM_POS); +} +/** + * @brief DMA Channel 2 Block Transmit Done Interrupt Flag Masked Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch2btdifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH2BTDIFM_MSK)>>DMA_IFM_CH2BTDIFM_POS); +} +/** + * @brief DMA Channel 1 TABORT Interrupt Flag Masked Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch1tabifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH1TABIFM_MSK)>>DMA_IFM_CH1TABIFM_POS); +} +/** + * @brief DMA Channel 1 Block Transmit Done Interrupt Flag Masked Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch1btdifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH1BTDIFM_MSK)>>DMA_IFM_CH1BTDIFM_POS); +} +/** + * @brief DMA Channel 0 TABORT Interrupt Flag Masked Status bit + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch0tabifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH0TABIFM_MSK)>>DMA_IFM_CH0TABIFM_POS); +} +/** + * @brief DMA Channel 0 Block Transmit Done Interrupt Flag Masked Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_ifm_ch0btdifm(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->IFM, DMA_IFM_CH0BTDIFM_MSK)>>DMA_IFM_CH0BTDIFM_POS); +} +/** + * @brief Get DMA interrupt flag masked status register + * @param dma DMA Instance + * @retval DMA channel interrupt flag masked status + */ +__STATIC_INLINE uint32_t md_dma_get_ifm(DMA_TypeDef *dma) +{ + return (READ_REG(dma->IFM)); +} + + +/** + * @brief DMA Channel 5 TABORT Interrupt Clear bit + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch5tabicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH5TABICR_MSK); +} +/** + * @brief DMA Channel 5 Block Transmit Done Interrupt Clear bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch5btdicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH5BTDICR_MSK); +} +/** + * @brief DMA Channel 4 TABORT Interrupt Clear bit + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch4tabicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH4TABICR_MSK); +} +/** + * @brief DMA Channel 4 Block Transmit Done Interrupt Clear bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch4btdicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH4BTDICR_MSK); +} +/** + * @brief DMA Channel 3 TABORT Interrupt Clear bit + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch3tabicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH3TABICR_MSK); +} +/** + * @brief DMA Channel 3 Block Transmit Done Interrupt Clear bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch3btdicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH3BTDICR_MSK); +} +/** + * @brief DMA Channel 2 TABORT Interrupt Clear bit + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch2tabicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH2TABICR_MSK); +} +/** + * @brief DMA Channel 2 Block Transmit Done Interrupt Clear bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch2btdicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH2BTDICR_MSK); +} +/** + * @brief DMA Channel 1 TABORT Interrupt Clear bit + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch1tabicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH1TABICR_MSK); +} +/** + * @brief DMA Channel 1 Block Transmit Done Interrupt Clear bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch1btdicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH1BTDICR_MSK); +} +/** + * @brief DMA Channel 0 TABORT Interrupt Clear bit + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch0tabicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH0TABICR_MSK); +} +/** + * @brief DMA Channel 0 Block Transmit Done Interrupt Clear bit. + * @param dma DMA Instance + * @retval None + */ +__STATIC_INLINE void md_dma_clear_icr_ch0btdicr(DMA_TypeDef *dma) +{ + SET_BIT(dma->ICR, DMA_ICR_CH0BTDICR_MSK); +} + +/** @defgroup MD_DMA_ICR_CH5TABICR CH5TABICR + * @brief Set DMA Channel 5 TABORT Interrupt Clear bit for md_dma_set_icr() function used + * @param ch5tabicr This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_dma_set_icr_ch5tabicr_fun(ch5tabicr) (ch5tabicr<ICR, ( ch5tabicr|ch5btdicr|ch4tabicr|ch4btdicr|ch3tabicr|ch3btdicr|ch2tabicr|ch2btdicr| + ch1tabicr|ch1btdicr|ch0tabicr|ch0btdicr)); +} +/** + * @brief Set DMA interrupt clear register(2) + * @param dma DMA Instance + * @param icr is interrupt clear register + * @retval None + */ +__STATIC_INLINE void md_dma_set_icr_icr(DMA_TypeDef *dma, uint32_t icr) +{ + WRITE_REG(dma->ICR, icr); +} + + +/** + * @brief DMA Channel 5 PFCTRL Size not match,last data have error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch5pfser(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH5PFSER_MSK)>>DMA_EMSG_CH5PFSER_POS); +} +/** + * @brief DMA Channel 5 PFCTRL Over run Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch5pfov(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH5PFOV_MSK)>>DMA_EMSG_CH5PFOV_POS); +} +/** + * @brief DMA Channel 5 Setting Burst Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch5setbuer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH5SETBUER_MSK)>>DMA_EMSG_CH5SETBUER_POS); +} +/** + * @brief DMA Channel 5 Setting BCR Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch5setbcer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH5SETBCER_MSK)>>DMA_EMSG_CH5SETBCER_POS); +} +/** + * @brief DMA Channel 4 PFCTRL Size not match,last data have error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch4pfser(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH4PFSER_MSK)>>DMA_EMSG_CH4PFSER_POS); +} +/** + * @brief DMA Channel 4 PFCTRL Over run Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch4pfov(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH4PFOV_MSK)>>DMA_EMSG_CH4PFOV_POS); +} +/** + * @brief DMA Channel 4 Setting Burst Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch4setbuer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH4SETBUER_MSK)>>DMA_EMSG_CH4SETBUER_POS); +} +/** + * @brief DMA Channel 4 Setting BCR Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch4setbcer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH4SETBCER_MSK)>>DMA_EMSG_CH4SETBCER_POS); +} +/** + * @brief DMA Channel 3 PFCTRL Size not match,last data have error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch3pfser(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH3PFSER_MSK)>>DMA_EMSG_CH3PFSER_POS); +} +/** + * @brief DMA Channel 3 PFCTRL Over run Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch3pfov(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH3PFOV_MSK)>>DMA_EMSG_CH3PFOV_POS); +} +/** + * @brief DMA Channel 3 Setting Burst Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch3setbuer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH3SETBUER_MSK)>>DMA_EMSG_CH3SETBUER_POS); +} +/** + * @brief DMA Channel 3 Setting BCR Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch3setbcer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH3SETBCER_MSK)>>DMA_EMSG_CH3SETBCER_POS); +} +/** + * @brief DMA Channel 2 PFCTRL Size not match,last data have error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch2pfser(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH2PFSER_MSK)>>DMA_EMSG_CH2PFSER_POS); +} +/** + * @brief DMA Channel 2 PFCTRL Over run Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch2pfov(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH2PFOV_MSK)>>DMA_EMSG_CH2PFOV_POS); +} +/** + * @brief DMA Channel 2 Setting Burst Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch2setbuer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH2SETBUER_MSK)>>DMA_EMSG_CH2SETBUER_POS); +} +/** + * @brief DMA Channel 2 Setting BCR Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch2setbcer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH2SETBCER_MSK)>>DMA_EMSG_CH2SETBCER_POS); +} +/** + * @brief DMA Channel 1 PFCTRL Size not match,last data have error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch1pfser(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH1PFSER_MSK)>>DMA_EMSG_CH1PFSER_POS); +} +/** + * @brief DMA Channel 1 PFCTRL Over run Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch1pfov(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH1PFOV_MSK)>>DMA_EMSG_CH1PFOV_POS); +} +/** + * @brief DMA Channel 1 Setting Burst Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch1setbuer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH1SETBUER_MSK)>>DMA_EMSG_CH1SETBUER_POS); +} +/** + * @brief DMA Channel 1 Setting BCR Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch1setbcer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH1SETBCER_MSK)>>DMA_EMSG_CH1SETBCER_POS); +} +/** + * @brief DMA Channel 0 PFCTRL Size not match,last data have error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch0pfser(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH0PFSER_MSK)>>DMA_EMSG_CH0PFSER_POS); +} +/** + * @brief DMA Channel 0 PFCTRL Over run Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch0pfov(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH0PFOV_MSK)>>DMA_EMSG_CH0PFOV_POS); +} +/** + * @brief DMA Channel 0 Setting Burst Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch0setbuer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH0SETBUER_MSK)>>DMA_EMSG_CH0SETBUER_POS); +} +/** + * @brief DMA Channel 0 Setting BCR Error Status bit. + * @param dma DMA Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_dma_get_emsg_ch0setbcer(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->EMSG, DMA_EMSG_CH0SETBCER_MSK)>>DMA_EMSG_CH0SETBCER_POS); +} +/** + * @brief Get DMA error message register + * @param dma DMA Instance + * @retval DMA channel error message status + */ +__STATIC_INLINE uint32_t md_dma_get_emsg(DMA_TypeDef *dma) +{ + return (READ_REG(dma->EMSG)); +} + +/** + * @brief Set Destination Increment Offset Size bit. + * @note This bit has no meaning if bit DINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if DBUSEL are different from 00. + * @param dma DMA Instance + * @param dincos can be one of the following values: + * @arg @ref MD_DMA_DINCOS_LINKED_DWSEL + * @arg @ref MD_DMA_DINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_dincos(DMA_TypeDef *dma, uint32_t dincos) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_DINCOS_MSK, (dincos<CSR0, DMA_CSR0_DINCOS_MSK)>>DMA_CSR0_DINCOS_POS); +} +/** + * @brief Set Destination Transfer Burst Selection. + * @param dma DMA Instance + * @param dbusel can be one of the following values: + * @arg @ref MD_DMA_DBUSEL_SINGLE + * @arg @ref MD_DMA_DBUSEL_WRAP4 + * @arg @ref MD_DMA_DBUSEL_INCR4 + * @arg @ref MD_DMA_DBUSEL_WRAP8 + * @arg @ref MD_DMA_DBUSEL_INCR8 + * @arg @ref MD_DMA_DBUSEL_WRAP16 + * @arg @ref MD_DMA_DBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_dbusel(DMA_TypeDef *dma, uint32_t dbusel) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_DBUSEL_MSK, (dbusel<CSR0, DMA_CSR0_DBUSEL_MSK)>>DMA_CSR0_DBUSEL_POSS); +} +/** + * @brief Set Destination Transfer Data Width Selection. + * @param dma DMA Instance + * @param ddwsel can be one of the following values: + * @arg @ref MD_DMA_DDWSEL_ONE_BYTE + * @arg @ref MD_DMA_DDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_DDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_ddwsel(DMA_TypeDef *dma, uint32_t ddwsel) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_DDWSEL_MSK, (ddwsel<CSR0, DMA_CSR0_DDWSEL_MSK)>>DMA_CSR0_DDWSEL_POSS); +} +/** + * @brief Set Destination Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_dinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_DINC_MSK, (dinc<CSR0, DMA_CSR0_DINC_MSK)>>DMA_CSR0_DINC_POS); +} +/** + * @brief Set Source Increment Offset Size bit. + * @note This bit has no meaning if bit SINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if SBUSEL are different from 00. + * @param dma DMA Instance + * @param sincos can be one of the following values: + * @arg @ref MD_DMA_SINCOS_LINKED_SWSEL + * @arg @ref MD_DMA_SINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_sincos(DMA_TypeDef *dma, uint32_t sincos) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_SINCOS_MSK, (sincos<CSR0, DMA_CSR0_SINCOS_MSK)>>DMA_CSR0_SINCOS_POS); +} +/** + * @brief Set Source Transfer Burst Selection. + * @param dma DMA Instance + * @param sbusel can be one of the following values: + * @arg @ref MD_DMA_SBUSEL_SINGLE + * @arg @ref MD_DMA_SBUSEL_WRAP4 + * @arg @ref MD_DMA_SBUSEL_INCR4 + * @arg @ref MD_DMA_SBUSEL_WRAP8 + * @arg @ref MD_DMA_SBUSEL_INCR8 + * @arg @ref MD_DMA_SBUSEL_WRAP16 + * @arg @ref MD_DMA_SBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_sbusel(DMA_TypeDef *dma, uint32_t sbusel) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_SBUSEL_MSK, (sbusel<CSR0, DMA_CSR0_SBUSEL_MSK)>>DMA_CSR0_SBUSEL_POSS); +} +/** + * @brief Set Source Transfer Data Width Selection. + * @param dma DMA Instance + * @param sdwsel can be one of the following values: + * @arg @ref MD_DMA_SDWSEL_ONE_BYTE + * @arg @ref MD_DMA_SDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_SDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_sdwsel(DMA_TypeDef *dma, uint32_t sdwsel) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_SDWSEL_MSK, (sdwsel<CSR0, DMA_CSR0_SDWSEL_MSK)>>DMA_CSR0_SDWSEL_POSS); +} +/** + * @brief Set Source Transfer Increment Mode + * @param dma DMA Instance + * @param sinc can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_sinc(DMA_TypeDef *dma, uint32_t sinc) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_SINC_MSK, (sinc<CSR0, DMA_CSR0_SINC_MSK)>>DMA_CSR0_SINC_POS); +} +/** + * @brief Set Peripheral Handshake Software Select + * @param dma DMA Instance + * @param phss can be one of the following values: + * @arg @ref MD_DMA_PHSS_UART1_TX + * @arg @ref MD_DMA_PHSS_UART2_TX + * @arg @ref MD_DMA_PHSS_UART3_TX + * @arg @ref MD_DMA_PHSS_SUART1_TX + * @arg @ref MD_DMA_PHSS_SUART2_TX + * @arg @ref MD_DMA_PHSS_SPI1_TX + * @arg @ref MD_DMA_PHSS_SPI2_TX + * @arg @ref MD_DMA_PHSS_I2C1_TX + * @arg @ref MD_DMA_PHSS_I2C2_TX + * @arg @ref MD_DMA_PHSS_AES_IN + * @arg @ref MD_DMA_PHSS_DAC + * @arg @ref MD_DMA_PHSS_CRC + * @arg @ref MD_DMA_PHSS_UART1_RX + * @arg @ref MD_DMA_PHSS_UART2_RX + * @arg @ref MD_DMA_PHSS_UART3_RX + * @arg @ref MD_DMA_PHSS_SUART1_RX + * @arg @ref MD_DMA_PHSS_SUART2_RX + * @arg @ref MD_DMA_PHSS_SPI1_RTX + * @arg @ref MD_DMA_PHSS_SPI2_RX + * @arg @ref MD_DMA_PHSS_I2C1_RX + * @arg @ref MD_DMA_PHSS_I2C2_RX + * @arg @ref MD_DMA_PHSS_AES_OUT + * @arg @ref MD_DMA_PHSS_ADCSS0 + * @arg @ref MD_DMA_PHSS_ADCSS1 + * @arg @ref MD_DMA_PHSS_ADCSS2 + * @arg @ref MD_DMA_PHSS_ADCSS3 + * @arg @ref MD_DMA_PHSS_BS16T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_AD16C4T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_AD16C4T1_COM + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP32C4T1_UP + * @arg @ref MD_DMA_PHSS_GP32C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T1_UP + * @arg @ref MD_DMA_PHSS_GP16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T2_UP + * @arg @ref MD_DMA_PHSS_GP16C4T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T3_UP + * @arg @ref MD_DMA_PHSS_GP16C4T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T1_UP + * @arg @ref MD_DMA_PHSS_GP16C2T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_COM + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T2_UP + * @arg @ref MD_DMA_PHSS_GP16C2T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T2_COM + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T3_UP + * @arg @ref MD_DMA_PHSS_GP16C2T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T3_COM + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T4_UP + * @arg @ref MD_DMA_PHSS_GP16C2T4_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T4_COM + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_phss(DMA_TypeDef *dma, uint32_t phss) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_PHSS_MSK, (phss<CSR0, DMA_CSR0_PHSS_MSK)>>DMA_CSR0_PHSS_POSS); +} +/** + * @brief Set DMA Channel Priority. + * @param dma DMA Instance + * @param chpri can be one of the following values: + * @arg @ref MD_DMA_CHPRI_LV0 + * @arg @ref MD_DMA_CHPRI_LV1 + * @arg @ref MD_DMA_CHPRI_LV2 + * @arg @ref MD_DMA_CHPRI_LV3 + * @arg @ref MD_DMA_CHPRI_LV4 + * @arg @ref MD_DMA_CHPRI_LV5 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_chpri(DMA_TypeDef *dma, uint32_t chpri) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_CHPRI_MSK, (chpri<CSR0, DMA_CSR0_CHPRI_MSK)>>DMA_CSR0_CHPRI_POSS); +} +/** + * @brief Set DMA Mode Select. + * @param dma DMA Instance + * @param modesel can be one of the following values: + * @arg @ref MD_DMA_MODESEL_MEM_TO_MEM + * @arg @ref MD_DMA_MODESEL_PER_TO_MEM + * @arg @ref MD_DMA_MODESEL_MEM_TO_PER + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_modesel(DMA_TypeDef *dma, uint32_t modesel) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_MODESEL_MSK, (modesel<CSR0, DMA_CSR0_MODESEL_MSK)>>DMA_CSR0_MODESEL_POSS); +} +/** + * @brief Set Direct Mode Enable. + * @param dma DMA Instance + * @param dirmden can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_dirmden(DMA_TypeDef *dma, uint32_t dirmden) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_DIRMDEN_MSK, (dirmden<CSR0, DMA_CSR0_DIRMDEN_MSK)>>DMA_CSR0_DIRMDEN_POS); +} +/** + * @brief Set Peripheral flow controller + * @param dma DMA Instance + * @param pfctrl can be one of the following values: + * @arg @ref MD_DMA_PFCTRL_DMA_CTRL + * @arg @ref MD_DMA_PFCTRL_PER_CTRL + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_pfctrl(DMA_TypeDef *dma, uint32_t pfctrl) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_PFCTRL_MSK, (pfctrl<CSR0, DMA_CSR0_PFCTRL_MSK)>>DMA_CSR0_PFCTRL_POS); +} +/** + * @brief Set Circular mode + * @param dma DMA Instance + * @param circ can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_circ(DMA_TypeDef *dma, uint32_t circ) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_CIRC_MSK, (circ<CSR0, DMA_CSR0_CIRC_MSK)>>DMA_CSR0_CIRC_POS); +} +/** + * @brief Set DMA Channel Enable. + * @param dma DMA Instance + * @param chen can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr0_chen(DMA_TypeDef *dma, uint32_t chen) +{ + MODIFY_REG(dma->CSR0, DMA_CSR0_CHEN_MSK, (chen<CSR0, DMA_CSR0_CHEN_MSK)>>DMA_CSR0_CHEN_POS); +} + +/** @defgroup MD_DMA_CSR0_DINCOS DINCOS + * @brief Set Destination Increment Offset Size bit for md_dma_set_cs0() function used + * @param dincos This parameter can be one of the following values: + * @arg @ref MD_DMA_DINCOS_LINKED_DWSEL + * @arg @ref MD_DMA_DINCOS_FIXED_TO_4 + * @{ + */ +#define md_dma_set_csr0_dincos_fun(dincos) (dincos<CSR0, (dincos|dbusel|ddwsel|dinc|sincos|sbusel|sdwsel|sinc| + phss|chpri|modesel|dirmden|pfctrl|circ|chen)); +} + + +/** + * @brief Set DMA Transfer Source Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param sar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_sar0_sar(DMA_TypeDef *dma, uint32_t sar) +{ + MODIFY_REG(dma->SAR0, DMA_SAR0_SAR_MSK, (sar<SAR0, DMA_SAR0_SAR_MSK)>>DMA_SAR0_SAR_POSS); +} + +/** + * @brief Set DMA Transfer Destination Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param dar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_dar0_dar(DMA_TypeDef *dma, uint32_t dar) +{ + MODIFY_REG(dma->DAR0, DMA_DAR0_DAR_MSK, (dar<DAR0, DMA_DAR0_DAR_MSK)>>DMA_DAR0_DAR_POSS); +} + +/** + * @brief Get DMA Current Transfer Byte Count + * @param dma DMA Instance + * @retval The retval can be one of the following values: + * @arg Max Value 65535 + * @arg Min Value 0 + */ +__STATIC_INLINE uint32_t md_dma_get_bcr0_cbcr(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->BCR0, DMA_BCR0_CBCR_MSK)>>DMA_BCR0_CBCR_POSS); +} +/** + * @brief Set DMA Transfer Byte Count Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param bcr This field indicates a 16-bit transfer byte count of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_bcr0_bcr(DMA_TypeDef *dma, uint32_t bcr) +{ + MODIFY_REG(dma->BCR0, DMA_BCR0_BCR_MSK, (bcr<BCR0, DMA_BCR0_BCR_MSK)>>DMA_BCR0_BCR_POSS); +} + +/** + * @brief Set Destination Increment Offset Size bit. + * @note This bit has no meaning if bit DINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if DBUSEL are different from 00. + * @param dma DMA Instance + * @param dincos can be one of the following values: + * @arg @ref MD_DMA_DINCOS_LINKED_DWSEL + * @arg @ref MD_DMA_DINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_dincos(DMA_TypeDef *dma, uint32_t dincos) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_DINCOS_MSK, (dincos<CSR1, DMA_CSR1_DINCOS_MSK)>>DMA_CSR1_DINCOS_POS); +} +/** + * @brief Set Destination Transfer Burst Selection. + * @param dma DMA Instance + * @param dbusel can be one of the following values: + * @arg @ref MD_DMA_DBUSEL_SINGLE + * @arg @ref MD_DMA_DBUSEL_WRAP4 + * @arg @ref MD_DMA_DBUSEL_INCR4 + * @arg @ref MD_DMA_DBUSEL_WRAP8 + * @arg @ref MD_DMA_DBUSEL_INCR8 + * @arg @ref MD_DMA_DBUSEL_WRAP16 + * @arg @ref MD_DMA_DBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_dbusel(DMA_TypeDef *dma, uint32_t dbusel) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_DBUSEL_MSK, (dbusel<CSR1, DMA_CSR1_DBUSEL_MSK)>>DMA_CSR1_DBUSEL_POSS); +} +/** + * @brief Set Destination Transfer Data Width Selection. + * @param dma DMA Instance + * @param ddwsel can be one of the following values: + * @arg @ref MD_DMA_DDWSEL_ONE_BYTE + * @arg @ref MD_DMA_DDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_DDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_ddwsel(DMA_TypeDef *dma, uint32_t ddwsel) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_DDWSEL_MSK, (ddwsel<CSR1, DMA_CSR1_DDWSEL_MSK)>>DMA_CSR1_DDWSEL_POSS); +} +/** + * @brief Set Destination Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_dinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_DINC_MSK, (dinc<CSR1, DMA_CSR1_DINC_MSK)>>DMA_CSR1_DINC_POS); +} +/** + * @brief Set Source Increment Offset Size bit. + * @note This bit has no meaning if bit SINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if SBUSEL are different from 00. + * @param dma DMA Instance + * @param sincos can be one of the following values: + * @arg @ref MD_DMA_SINCOS_LINKED_SWSEL + * @arg @ref MD_DMA_SINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_sincos(DMA_TypeDef *dma, uint32_t sincos) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_SINCOS_MSK, (sincos<CSR1, DMA_CSR1_SINCOS_MSK)>>DMA_CSR1_SINCOS_POS); +} +/** + * @brief Set Source Transfer Burst Selection. + * @param dma DMA Instance + * @param sbusel can be one of the following values: + * @arg @ref MD_DMA_SBUSEL_SINGLE + * @arg @ref MD_DMA_SBUSEL_WRAP4 + * @arg @ref MD_DMA_SBUSEL_INCR4 + * @arg @ref MD_DMA_SBUSEL_WRAP8 + * @arg @ref MD_DMA_SBUSEL_INCR8 + * @arg @ref MD_DMA_SBUSEL_WRAP16 + * @arg @ref MD_DMA_SBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_sbusel(DMA_TypeDef *dma, uint32_t sbusel) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_SBUSEL_MSK, (sbusel<CSR1, DMA_CSR1_SBUSEL_MSK)>>DMA_CSR1_SBUSEL_POSS); +} +/** + * @brief Set Source Transfer Data Width Selection. + * @param dma DMA Instance + * @param sdwsel can be one of the following values: + * @arg @ref MD_DMA_SDWSEL_ONE_BYTE + * @arg @ref MD_DMA_SDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_SDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_sdwsel(DMA_TypeDef *dma, uint32_t sdwsel) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_SDWSEL_MSK, (sdwsel<CSR1, DMA_CSR1_SDWSEL_MSK)>>DMA_CSR1_SDWSEL_POSS); +} +/** + * @brief Set Source Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_sinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_SINC_MSK, (dinc<CSR1, DMA_CSR1_SINC_MSK)>>DMA_CSR1_SINC_POS); +} +/** + * @brief Set Peripheral Handshake Software Select + * @param dma DMA Instance + * @param phss can be one of the following values: + * @arg @ref MD_DMA_PHSS_UART1_TX + * @arg @ref MD_DMA_PHSS_UART2_TX + * @arg @ref MD_DMA_PHSS_UART3_TX + * @arg @ref MD_DMA_PHSS_SUART1_TX + * @arg @ref MD_DMA_PHSS_SUART2_TX + * @arg @ref MD_DMA_PHSS_SPI1_TX + * @arg @ref MD_DMA_PHSS_SPI2_TX + * @arg @ref MD_DMA_PHSS_I2C1_TX + * @arg @ref MD_DMA_PHSS_I2C2_TX + * @arg @ref MD_DMA_PHSS_AES_IN + * @arg @ref MD_DMA_PHSS_DAC + * @arg @ref MD_DMA_PHSS_CRC + * @arg @ref MD_DMA_PHSS_UART1_RX + * @arg @ref MD_DMA_PHSS_UART2_RX + * @arg @ref MD_DMA_PHSS_UART3_RX + * @arg @ref MD_DMA_PHSS_SUART1_RX + * @arg @ref MD_DMA_PHSS_SUART2_RX + * @arg @ref MD_DMA_PHSS_SPI1_RTX + * @arg @ref MD_DMA_PHSS_SPI2_RX + * @arg @ref MD_DMA_PHSS_I2C1_RX + * @arg @ref MD_DMA_PHSS_I2C2_RX + * @arg @ref MD_DMA_PHSS_AES_OUT + * @arg @ref MD_DMA_PHSS_ADCSS0 + * @arg @ref MD_DMA_PHSS_ADCSS1 + * @arg @ref MD_DMA_PHSS_ADCSS2 + * @arg @ref MD_DMA_PHSS_ADCSS3 + * @arg @ref MD_DMA_PHSS_BS16T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_AD16C4T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_AD16C4T1_COM + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP32C4T1_UP + * @arg @ref MD_DMA_PHSS_GP32C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T1_UP + * @arg @ref MD_DMA_PHSS_GP16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T2_UP + * @arg @ref MD_DMA_PHSS_GP16C4T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T3_UP + * @arg @ref MD_DMA_PHSS_GP16C4T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T1_UP + * @arg @ref MD_DMA_PHSS_GP16C2T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_COM + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T2_UP + * @arg @ref MD_DMA_PHSS_GP16C2T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T2_COM + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T3_UP + * @arg @ref MD_DMA_PHSS_GP16C2T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T3_COM + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T4_UP + * @arg @ref MD_DMA_PHSS_GP16C2T4_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T4_COM + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_phss(DMA_TypeDef *dma, uint32_t phss) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_PHSS_MSK, (phss<CSR1, DMA_CSR1_PHSS_MSK)>>DMA_CSR1_PHSS_POSS); +} +/** + * @brief Set DMA Channel Priority. + * @param dma DMA Instance + * @param chpri can be one of the following values: + * @arg @ref MD_DMA_CHPRI_LV0 + * @arg @ref MD_DMA_CHPRI_LV1 + * @arg @ref MD_DMA_CHPRI_LV2 + * @arg @ref MD_DMA_CHPRI_LV3 + * @arg @ref MD_DMA_CHPRI_LV4 + * @arg @ref MD_DMA_CHPRI_LV5 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_chpri(DMA_TypeDef *dma, uint32_t chpri) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_CHPRI_MSK, (chpri<CSR1, DMA_CSR1_CHPRI_MSK)>>DMA_CSR1_CHPRI_POSS); +} +/** + * @brief Set DMA Mode Select. + * @param dma DMA Instance + * @param modesel can be one of the following values: + * @arg @ref MD_DMA_MODESEL_MEM_TO_MEM + * @arg @ref MD_DMA_MODESEL_PER_TO_MEM + * @arg @ref MD_DMA_MODESEL_MEM_TO_PER + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_modesel(DMA_TypeDef *dma, uint32_t modesel) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_MODESEL_MSK, (modesel<CSR1, DMA_CSR1_MODESEL_MSK)>>DMA_CSR1_MODESEL_POSS); +} +/** + * @brief Set Direct Mode Enable. + * @param dma DMA Instance + * @param dirmden can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_dirmden(DMA_TypeDef *dma, uint32_t dirmden) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_DIRMDEN_MSK, (dirmden<CSR1, DMA_CSR1_DIRMDEN_MSK)>>DMA_CSR1_DIRMDEN_POS); +} +/** + * @brief Set Peripheral flow controller + * @param dma DMA Instance + * @param pfctrl can be one of the following values: + * @arg @ref MD_DMA_PFCTRL_DMA_CTRL + * @arg @ref MD_DMA_PFCTRL_PER_CTRL + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_pfctrl(DMA_TypeDef *dma, uint32_t pfctrl) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_PFCTRL_MSK, (pfctrl<CSR1, DMA_CSR1_PFCTRL_MSK)>>DMA_CSR1_PFCTRL_POS); +} +/** + * @brief Set Circular mode + * @param dma DMA Instance + * @param circ can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_circ(DMA_TypeDef *dma, uint32_t circ) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_CIRC_MSK, (circ<CSR1, DMA_CSR1_CIRC_MSK)>>DMA_CSR1_CIRC_POS); +} +/** + * @brief Set DMA Channel Enable. + * @param dma DMA Instance + * @param chen can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr1_chen(DMA_TypeDef *dma, uint32_t chen) +{ + MODIFY_REG(dma->CSR1, DMA_CSR1_CHEN_MSK, (chen<CSR1, DMA_CSR1_CHEN_MSK)>>DMA_CSR1_CHEN_POS); +} + +/** + * @brief Set DMA Transfer Source Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param sar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_sar1_sar(DMA_TypeDef *dma, uint32_t sar) +{ + MODIFY_REG(dma->SAR1, DMA_SAR1_SAR_MSK, (sar<SAR1, DMA_SAR1_SAR_MSK)>>DMA_SAR1_SAR_POSS); +} + +/** + * @brief Set DMA Transfer Destination Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param dar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_dar1_dar(DMA_TypeDef *dma, uint32_t dar) +{ + MODIFY_REG(dma->DAR1, DMA_DAR1_DAR_MSK, (dar<DAR1, DMA_DAR1_DAR_MSK)>>DMA_DAR1_DAR_POSS); +} + +/** + * @brief Get DMA Current Transfer Byte Count + * @param dma DMA Instance + * @retval The retval can be one of the following values: + * @arg Max Value 65535 + * @arg Min Value 0 + */ +__STATIC_INLINE uint32_t md_dma_get_bcr1_cbcr(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->BCR1, DMA_BCR1_CBCR_MSK)>>DMA_BCR1_CBCR_POSS); +} +/** + * @brief Set DMA Transfer Byte Count Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param bcr This field indicates a 16-bit transfer byte count of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_bcr1_bcr(DMA_TypeDef *dma, uint32_t bcr) +{ + MODIFY_REG(dma->BCR1, DMA_BCR1_BCR_MSK, (bcr<BCR1, DMA_BCR1_BCR_MSK)>>DMA_BCR1_BCR_POSS); +} + +/** + * @brief Set Destination Increment Offset Size bit. + * @note This bit has no meaning if bit DINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if DBUSEL are different from 00. + * @param dma DMA Instance + * @param dincos can be one of the following values: + * @arg @ref MD_DMA_DINCOS_LINKED_DWSEL + * @arg @ref MD_DMA_DINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_dincos(DMA_TypeDef *dma, uint32_t dincos) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_DINCOS_MSK, (dincos<CSR2, DMA_CSR2_DINCOS_MSK)>>DMA_CSR2_DINCOS_POS); +} +/** + * @brief Set Destination Transfer Burst Selection. + * @param dma DMA Instance + * @param dbusel can be one of the following values: + * @arg @ref MD_DMA_DBUSEL_SINGLE + * @arg @ref MD_DMA_DBUSEL_WRAP4 + * @arg @ref MD_DMA_DBUSEL_INCR4 + * @arg @ref MD_DMA_DBUSEL_WRAP8 + * @arg @ref MD_DMA_DBUSEL_INCR8 + * @arg @ref MD_DMA_DBUSEL_WRAP16 + * @arg @ref MD_DMA_DBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_dbusel(DMA_TypeDef *dma, uint32_t dbusel) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_DBUSEL_MSK, (dbusel<CSR2, DMA_CSR2_DBUSEL_MSK)>>DMA_CSR2_DBUSEL_POSS); +} +/** + * @brief Set Destination Transfer Data Width Selection. + * @param dma DMA Instance + * @param ddwsel can be one of the following values: + * @arg @ref MD_DMA_DDWSEL_ONE_BYTE + * @arg @ref MD_DMA_DDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_DDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_ddwsel(DMA_TypeDef *dma, uint32_t ddwsel) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_DDWSEL_MSK, (ddwsel<CSR2, DMA_CSR2_DDWSEL_MSK)>>DMA_CSR2_DDWSEL_POSS); +} +/** + * @brief Set Destination Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_dinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_DINC_MSK, (dinc<CSR2, DMA_CSR2_DINC_MSK)>>DMA_CSR2_DINC_POS); +} +/** + * @brief Set Source Increment Offset Size bit. + * @note This bit has no meaning if bit SINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if SBUSEL are different from 00. + * @param dma DMA Instance + * @param sincos can be one of the following values: + * @arg @ref MD_DMA_SINCOS_LINKED_SWSEL + * @arg @ref MD_DMA_SINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_sincos(DMA_TypeDef *dma, uint32_t sincos) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_SINCOS_MSK, (sincos<CSR2, DMA_CSR2_SINCOS_MSK)>>DMA_CSR2_SINCOS_POS); +} +/** + * @brief Set Source Transfer Burst Selection. + * @param dma DMA Instance + * @param sbusel can be one of the following values: + * @arg @ref MD_DMA_SBUSEL_SINGLE + * @arg @ref MD_DMA_SBUSEL_WRAP4 + * @arg @ref MD_DMA_SBUSEL_INCR4 + * @arg @ref MD_DMA_SBUSEL_WRAP8 + * @arg @ref MD_DMA_SBUSEL_INCR8 + * @arg @ref MD_DMA_SBUSEL_WRAP16 + * @arg @ref MD_DMA_SBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_sbusel(DMA_TypeDef *dma, uint32_t sbusel) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_SBUSEL_MSK, (sbusel<CSR2, DMA_CSR2_SBUSEL_MSK)>>DMA_CSR2_SBUSEL_POSS); +} +/** + * @brief Set Source Transfer Data Width Selection. + * @param dma DMA Instance + * @param sdwsel can be one of the following values: + * @arg @ref MD_DMA_SDWSEL_ONE_BYTE + * @arg @ref MD_DMA_SDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_SDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_sdwsel(DMA_TypeDef *dma, uint32_t sdwsel) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_SDWSEL_MSK, (sdwsel<CSR2, DMA_CSR2_SDWSEL_MSK)>>DMA_CSR2_SDWSEL_POSS); +} +/** + * @brief Set Source Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_sinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_SINC_MSK, (dinc<CSR2, DMA_CSR2_SINC_MSK)>>DMA_CSR2_SINC_POS); +} +/** + * @brief Set Peripheral Handshake Software Select + * @param dma DMA Instance + * @param phss can be one of the following values: + * @arg @ref MD_DMA_PHSS_UART1_TX + * @arg @ref MD_DMA_PHSS_UART2_TX + * @arg @ref MD_DMA_PHSS_UART3_TX + * @arg @ref MD_DMA_PHSS_SUART1_TX + * @arg @ref MD_DMA_PHSS_SUART2_TX + * @arg @ref MD_DMA_PHSS_SPI1_TX + * @arg @ref MD_DMA_PHSS_SPI2_TX + * @arg @ref MD_DMA_PHSS_I2C1_TX + * @arg @ref MD_DMA_PHSS_I2C2_TX + * @arg @ref MD_DMA_PHSS_AES_IN + * @arg @ref MD_DMA_PHSS_DAC + * @arg @ref MD_DMA_PHSS_CRC + * @arg @ref MD_DMA_PHSS_UART1_RX + * @arg @ref MD_DMA_PHSS_UART2_RX + * @arg @ref MD_DMA_PHSS_UART3_RX + * @arg @ref MD_DMA_PHSS_SUART1_RX + * @arg @ref MD_DMA_PHSS_SUART2_RX + * @arg @ref MD_DMA_PHSS_SPI1_RTX + * @arg @ref MD_DMA_PHSS_SPI2_RX + * @arg @ref MD_DMA_PHSS_I2C1_RX + * @arg @ref MD_DMA_PHSS_I2C2_RX + * @arg @ref MD_DMA_PHSS_AES_OUT + * @arg @ref MD_DMA_PHSS_ADCSS0 + * @arg @ref MD_DMA_PHSS_ADCSS1 + * @arg @ref MD_DMA_PHSS_ADCSS2 + * @arg @ref MD_DMA_PHSS_ADCSS3 + * @arg @ref MD_DMA_PHSS_BS16T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_AD16C4T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_AD16C4T1_COM + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP32C4T1_UP + * @arg @ref MD_DMA_PHSS_GP32C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T1_UP + * @arg @ref MD_DMA_PHSS_GP16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T2_UP + * @arg @ref MD_DMA_PHSS_GP16C4T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T3_UP + * @arg @ref MD_DMA_PHSS_GP16C4T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T1_UP + * @arg @ref MD_DMA_PHSS_GP16C2T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_COM + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T2_UP + * @arg @ref MD_DMA_PHSS_GP16C2T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T2_COM + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T3_UP + * @arg @ref MD_DMA_PHSS_GP16C2T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T3_COM + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T4_UP + * @arg @ref MD_DMA_PHSS_GP16C2T4_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T4_COM + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_phss(DMA_TypeDef *dma, uint32_t phss) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_PHSS_MSK, (phss<CSR2, DMA_CSR2_PHSS_MSK)>>DMA_CSR2_PHSS_POSS); +} +/** + * @brief Set DMA Channel Priority. + * @param dma DMA Instance + * @param chpri can be one of the following values: + * @arg @ref MD_DMA_CHPRI_LV0 + * @arg @ref MD_DMA_CHPRI_LV1 + * @arg @ref MD_DMA_CHPRI_LV2 + * @arg @ref MD_DMA_CHPRI_LV3 + * @arg @ref MD_DMA_CHPRI_LV4 + * @arg @ref MD_DMA_CHPRI_LV5 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_chpri(DMA_TypeDef *dma, uint32_t chpri) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_CHPRI_MSK, (chpri<CSR2, DMA_CSR2_CHPRI_MSK)>>DMA_CSR2_CHPRI_POSS); +} +/** + * @brief Set DMA Mode Select. + * @param dma DMA Instance + * @param modesel can be one of the following values: + * @arg @ref MD_DMA_MODESEL_MEM_TO_MEM + * @arg @ref MD_DMA_MODESEL_PER_TO_MEM + * @arg @ref MD_DMA_MODESEL_MEM_TO_PER + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_modesel(DMA_TypeDef *dma, uint32_t modesel) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_MODESEL_MSK, (modesel<CSR2, DMA_CSR2_MODESEL_MSK)>>DMA_CSR2_MODESEL_POSS); +} +/** + * @brief Set Direct Mode Enable. + * @param dma DMA Instance + * @param dirmden can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_dirmden(DMA_TypeDef *dma, uint32_t dirmden) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_DIRMDEN_MSK, (dirmden<CSR2, DMA_CSR2_DIRMDEN_MSK)>>DMA_CSR2_DIRMDEN_POS); +} +/** + * @brief Set Peripheral flow controller + * @param dma DMA Instance + * @param pfctrl can be one of the following values: + * @arg @ref MD_DMA_PFCTRL_DMA_CTRL + * @arg @ref MD_DMA_PFCTRL_PER_CTRL + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_pfctrl(DMA_TypeDef *dma, uint32_t pfctrl) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_PFCTRL_MSK, (pfctrl<CSR2, DMA_CSR2_PFCTRL_MSK)>>DMA_CSR2_PFCTRL_POS); +} +/** + * @brief Set Circular mode + * @param dma DMA Instance + * @param circ can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_circ(DMA_TypeDef *dma, uint32_t circ) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_CIRC_MSK, (circ<CSR2, DMA_CSR2_CIRC_MSK)>>DMA_CSR2_CIRC_POS); +} +/** + * @brief Set DMA Channel Enable. + * @param dma DMA Instance + * @param chen can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr2_chen(DMA_TypeDef *dma, uint32_t chen) +{ + MODIFY_REG(dma->CSR2, DMA_CSR2_CHEN_MSK, (chen<CSR2, DMA_CSR2_CHEN_MSK)>>DMA_CSR2_CHEN_POS); +} + +/** + * @brief Set DMA Transfer Source Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param sar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_sar2_sar(DMA_TypeDef *dma, uint32_t sar) +{ + MODIFY_REG(dma->SAR2, DMA_SAR2_SAR_MSK, (sar<SAR2, DMA_SAR2_SAR_MSK)>>DMA_SAR2_SAR_POSS); +} + +/** + * @brief Set DMA Transfer Destination Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param dar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_dar2_dar(DMA_TypeDef *dma, uint32_t dar) +{ + MODIFY_REG(dma->DAR2, DMA_DAR2_DAR_MSK, (dar<DAR2, DMA_DAR2_DAR_MSK)>>DMA_DAR2_DAR_POSS); +} + +/** + * @brief Get DMA Current Transfer Byte Count + * @param dma DMA Instance + * @retval The retval can be one of the following values: + * @arg Max Value 65535 + * @arg Min Value 0 + */ +__STATIC_INLINE uint32_t md_dma_get_bcr2_cbcr(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->BCR2, DMA_BCR2_CBCR_MSK)>>DMA_BCR2_CBCR_POSS); +} +/** + * @brief Set DMA Transfer Byte Count Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param bcr This field indicates a 16-bit transfer byte count of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_bcr2_bcr(DMA_TypeDef *dma, uint32_t bcr) +{ + MODIFY_REG(dma->BCR2, DMA_BCR2_BCR_MSK, (bcr<BCR2, DMA_BCR2_BCR_MSK)>>DMA_BCR2_BCR_POSS); +} + +/** + * @brief Set Destination Increment Offset Size bit. + * @note This bit has no meaning if bit DINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if DBUSEL are different from 00. + * @param dma DMA Instance + * @param dincos can be one of the following values: + * @arg @ref MD_DMA_DINCOS_LINKED_DWSEL + * @arg @ref MD_DMA_DINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_dincos(DMA_TypeDef *dma, uint32_t dincos) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_DINCOS_MSK, (dincos<CSR3, DMA_CSR3_DINCOS_MSK)>>DMA_CSR3_DINCOS_POS); +} +/** + * @brief Set Destination Transfer Burst Selection. + * @param dma DMA Instance + * @param dbusel can be one of the following values: + * @arg @ref MD_DMA_DBUSEL_SINGLE + * @arg @ref MD_DMA_DBUSEL_WRAP4 + * @arg @ref MD_DMA_DBUSEL_INCR4 + * @arg @ref MD_DMA_DBUSEL_WRAP8 + * @arg @ref MD_DMA_DBUSEL_INCR8 + * @arg @ref MD_DMA_DBUSEL_WRAP16 + * @arg @ref MD_DMA_DBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_dbusel(DMA_TypeDef *dma, uint32_t dbusel) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_DBUSEL_MSK, (dbusel<CSR3, DMA_CSR3_DBUSEL_MSK)>>DMA_CSR3_DBUSEL_POSS); +} +/** + * @brief Set Destination Transfer Data Width Selection. + * @param dma DMA Instance + * @param ddwsel can be one of the following values: + * @arg @ref MD_DMA_DDWSEL_ONE_BYTE + * @arg @ref MD_DMA_DDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_DDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_ddwsel(DMA_TypeDef *dma, uint32_t ddwsel) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_DDWSEL_MSK, (ddwsel<CSR3, DMA_CSR3_DDWSEL_MSK)>>DMA_CSR3_DDWSEL_POSS); +} +/** + * @brief Set Destination Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_dinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_DINC_MSK, (dinc<CSR3, DMA_CSR3_DINC_MSK)>>DMA_CSR3_DINC_POS); +} +/** + * @brief Set Source Increment Offset Size bit. + * @note This bit has no meaning if bit SINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if SBUSEL are different from 00. + * @param dma DMA Instance + * @param sincos can be one of the following values: + * @arg @ref MD_DMA_SINCOS_LINKED_SWSEL + * @arg @ref MD_DMA_SINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_sincos(DMA_TypeDef *dma, uint32_t sincos) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_SINCOS_MSK, (sincos<CSR3, DMA_CSR3_SINCOS_MSK)>>DMA_CSR3_SINCOS_POS); +} +/** + * @brief Set Source Transfer Burst Selection. + * @param dma DMA Instance + * @param sbusel can be one of the following values: + * @arg @ref MD_DMA_SBUSEL_SINGLE + * @arg @ref MD_DMA_SBUSEL_WRAP4 + * @arg @ref MD_DMA_SBUSEL_INCR4 + * @arg @ref MD_DMA_SBUSEL_WRAP8 + * @arg @ref MD_DMA_SBUSEL_INCR8 + * @arg @ref MD_DMA_SBUSEL_WRAP16 + * @arg @ref MD_DMA_SBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_sbusel(DMA_TypeDef *dma, uint32_t sbusel) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_SBUSEL_MSK, (sbusel<CSR3, DMA_CSR3_SBUSEL_MSK)>>DMA_CSR3_SBUSEL_POSS); +} +/** + * @brief Set Source Transfer Data Width Selection. + * @param dma DMA Instance + * @param sdwsel can be one of the following values: + * @arg @ref MD_DMA_SDWSEL_ONE_BYTE + * @arg @ref MD_DMA_SDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_SDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_sdwsel(DMA_TypeDef *dma, uint32_t sdwsel) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_SDWSEL_MSK, (sdwsel<CSR3, DMA_CSR3_SDWSEL_MSK)>>DMA_CSR3_SDWSEL_POSS); +} +/** + * @brief Set Source Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_sinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_SINC_MSK, (dinc<CSR3, DMA_CSR3_SINC_MSK)>>DMA_CSR3_SINC_POS); +} +/** + * @brief Set Peripheral Handshake Software Select + * @param dma DMA Instance + * @param phss can be one of the following values: + * @arg @ref MD_DMA_PHSS_UART1_TX + * @arg @ref MD_DMA_PHSS_UART2_TX + * @arg @ref MD_DMA_PHSS_UART3_TX + * @arg @ref MD_DMA_PHSS_SUART1_TX + * @arg @ref MD_DMA_PHSS_SUART2_TX + * @arg @ref MD_DMA_PHSS_SPI1_TX + * @arg @ref MD_DMA_PHSS_SPI2_TX + * @arg @ref MD_DMA_PHSS_I2C1_TX + * @arg @ref MD_DMA_PHSS_I2C2_TX + * @arg @ref MD_DMA_PHSS_AES_IN + * @arg @ref MD_DMA_PHSS_DAC + * @arg @ref MD_DMA_PHSS_CRC + * @arg @ref MD_DMA_PHSS_UART1_RX + * @arg @ref MD_DMA_PHSS_UART2_RX + * @arg @ref MD_DMA_PHSS_UART3_RX + * @arg @ref MD_DMA_PHSS_SUART1_RX + * @arg @ref MD_DMA_PHSS_SUART2_RX + * @arg @ref MD_DMA_PHSS_SPI1_RTX + * @arg @ref MD_DMA_PHSS_SPI2_RX + * @arg @ref MD_DMA_PHSS_I2C1_RX + * @arg @ref MD_DMA_PHSS_I2C2_RX + * @arg @ref MD_DMA_PHSS_AES_OUT + * @arg @ref MD_DMA_PHSS_ADCSS0 + * @arg @ref MD_DMA_PHSS_ADCSS1 + * @arg @ref MD_DMA_PHSS_ADCSS2 + * @arg @ref MD_DMA_PHSS_ADCSS3 + * @arg @ref MD_DMA_PHSS_BS16T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_AD16C4T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_AD16C4T1_COM + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP32C4T1_UP + * @arg @ref MD_DMA_PHSS_GP32C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T1_UP + * @arg @ref MD_DMA_PHSS_GP16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T2_UP + * @arg @ref MD_DMA_PHSS_GP16C4T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T3_UP + * @arg @ref MD_DMA_PHSS_GP16C4T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T1_UP + * @arg @ref MD_DMA_PHSS_GP16C2T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_COM + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T2_UP + * @arg @ref MD_DMA_PHSS_GP16C2T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T2_COM + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T3_UP + * @arg @ref MD_DMA_PHSS_GP16C2T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T3_COM + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T4_UP + * @arg @ref MD_DMA_PHSS_GP16C2T4_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T4_COM + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_phss(DMA_TypeDef *dma, uint32_t phss) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_PHSS_MSK, (phss<CSR3, DMA_CSR3_PHSS_MSK)>>DMA_CSR3_PHSS_POSS); +} +/** + * @brief Set DMA Channel Priority. + * @param dma DMA Instance + * @param chpri can be one of the following values: + * @arg @ref MD_DMA_CHPRI_LV0 + * @arg @ref MD_DMA_CHPRI_LV1 + * @arg @ref MD_DMA_CHPRI_LV2 + * @arg @ref MD_DMA_CHPRI_LV3 + * @arg @ref MD_DMA_CHPRI_LV4 + * @arg @ref MD_DMA_CHPRI_LV5 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_chpri(DMA_TypeDef *dma, uint32_t chpri) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_CHPRI_MSK, (chpri<CSR3, DMA_CSR3_CHPRI_MSK)>>DMA_CSR3_CHPRI_POSS); +} +/** + * @brief Set DMA Mode Select. + * @param dma DMA Instance + * @param modesel can be one of the following values: + * @arg @ref MD_DMA_MODESEL_MEM_TO_MEM + * @arg @ref MD_DMA_MODESEL_PER_TO_MEM + * @arg @ref MD_DMA_MODESEL_MEM_TO_PER + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_modesel(DMA_TypeDef *dma, uint32_t modesel) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_MODESEL_MSK, (modesel<CSR3, DMA_CSR3_MODESEL_MSK)>>DMA_CSR3_MODESEL_POSS); +} +/** + * @brief Set Direct Mode Enable. + * @param dma DMA Instance + * @param dirmden can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_dirmden(DMA_TypeDef *dma, uint32_t dirmden) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_DIRMDEN_MSK, (dirmden<CSR3, DMA_CSR3_DIRMDEN_MSK)>>DMA_CSR3_DIRMDEN_POS); +} +/** + * @brief Set Peripheral flow controller + * @param dma DMA Instance + * @param pfctrl can be one of the following values: + * @arg @ref MD_DMA_PFCTRL_DMA_CTRL + * @arg @ref MD_DMA_PFCTRL_PER_CTRL + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_pfctrl(DMA_TypeDef *dma, uint32_t pfctrl) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_PFCTRL_MSK, (pfctrl<CSR3, DMA_CSR3_PFCTRL_MSK)>>DMA_CSR3_PFCTRL_POS); +} +/** + * @brief Set Circular mode + * @param dma DMA Instance + * @param circ can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_circ(DMA_TypeDef *dma, uint32_t circ) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_CIRC_MSK, (circ<CSR3, DMA_CSR3_CIRC_MSK)>>DMA_CSR3_CIRC_POS); +} +/** + * @brief Set DMA Channel Enable. + * @param dma DMA Instance + * @param chen can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr3_chen(DMA_TypeDef *dma, uint32_t chen) +{ + MODIFY_REG(dma->CSR3, DMA_CSR3_CHEN_MSK, (chen<CSR3, DMA_CSR3_CHEN_MSK)>>DMA_CSR3_CHEN_POS); +} + +/** + * @brief Set DMA Transfer Source Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param sar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_sar3_sar(DMA_TypeDef *dma, uint32_t sar) +{ + MODIFY_REG(dma->SAR3, DMA_SAR3_SAR_MSK, (sar<SAR3, DMA_SAR3_SAR_MSK)>>DMA_SAR3_SAR_POSS); +} + +/** + * @brief Set DMA Transfer Destination Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param dar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_dar3_dar(DMA_TypeDef *dma, uint32_t dar) +{ + MODIFY_REG(dma->DAR3, DMA_DAR3_DAR_MSK, (dar<DAR3, DMA_DAR3_DAR_MSK)>>DMA_DAR3_DAR_POSS); +} + +/** + * @brief Get DMA Current Transfer Byte Count + * @param dma DMA Instance + * @retval The retval can be one of the following values: + * @arg Max Value 65535 + * @arg Min Value 0 + */ +__STATIC_INLINE uint32_t md_dma_get_bcr3_cbcr(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->BCR3, DMA_BCR3_CBCR_MSK)>>DMA_BCR3_CBCR_POSS); +} +/** + * @brief Set DMA Transfer Byte Count Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param bcr This field indicates a 16-bit transfer byte count of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_bcr3_bcr(DMA_TypeDef *dma, uint32_t bcr) +{ + MODIFY_REG(dma->BCR3, DMA_BCR3_BCR_MSK, (bcr<BCR3, DMA_BCR3_BCR_MSK)>>DMA_BCR3_BCR_POSS); +} + +/** + * @brief Set Destination Increment Offset Size bit. + * @note This bit has no meaning if bit DINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if DBUSEL are different from 00. + * @param dma DMA Instance + * @param dincos can be one of the following values: + * @arg @ref MD_DMA_DINCOS_LINKED_DWSEL + * @arg @ref MD_DMA_DINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_dincos(DMA_TypeDef *dma, uint32_t dincos) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_DINCOS_MSK, (dincos<CSR4, DMA_CSR4_DINCOS_MSK)>>DMA_CSR4_DINCOS_POS); +} +/** + * @brief Set Destination Transfer Burst Selection. + * @param dma DMA Instance + * @param dbusel can be one of the following values: + * @arg @ref MD_DMA_DBUSEL_SINGLE + * @arg @ref MD_DMA_DBUSEL_WRAP4 + * @arg @ref MD_DMA_DBUSEL_INCR4 + * @arg @ref MD_DMA_DBUSEL_WRAP8 + * @arg @ref MD_DMA_DBUSEL_INCR8 + * @arg @ref MD_DMA_DBUSEL_WRAP16 + * @arg @ref MD_DMA_DBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_dbusel(DMA_TypeDef *dma, uint32_t dbusel) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_DBUSEL_MSK, (dbusel<CSR4, DMA_CSR4_DBUSEL_MSK)>>DMA_CSR4_DBUSEL_POSS); +} +/** + * @brief Set Destination Transfer Data Width Selection. + * @param dma DMA Instance + * @param ddwsel can be one of the following values: + * @arg @ref MD_DMA_DDWSEL_ONE_BYTE + * @arg @ref MD_DMA_DDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_DDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_ddwsel(DMA_TypeDef *dma, uint32_t ddwsel) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_DDWSEL_MSK, (ddwsel<CSR4, DMA_CSR4_DDWSEL_MSK)>>DMA_CSR4_DDWSEL_POSS); +} +/** + * @brief Set Destination Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_dinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_DINC_MSK, (dinc<CSR4, DMA_CSR4_DINC_MSK)>>DMA_CSR4_DINC_POS); +} +/** + * @brief Set Source Increment Offset Size bit. + * @note This bit has no meaning if bit SINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if SBUSEL are different from 00. + * @param dma DMA Instance + * @param sincos can be one of the following values: + * @arg @ref MD_DMA_SINCOS_LINKED_SWSEL + * @arg @ref MD_DMA_SINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_sincos(DMA_TypeDef *dma, uint32_t sincos) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_SINCOS_MSK, (sincos<CSR4, DMA_CSR4_SINCOS_MSK)>>DMA_CSR4_SINCOS_POS); +} +/** + * @brief Set Source Transfer Burst Selection. + * @param dma DMA Instance + * @param sbusel can be one of the following values: + * @arg @ref MD_DMA_SBUSEL_SINGLE + * @arg @ref MD_DMA_SBUSEL_WRAP4 + * @arg @ref MD_DMA_SBUSEL_INCR4 + * @arg @ref MD_DMA_SBUSEL_WRAP8 + * @arg @ref MD_DMA_SBUSEL_INCR8 + * @arg @ref MD_DMA_SBUSEL_WRAP16 + * @arg @ref MD_DMA_SBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_sbusel(DMA_TypeDef *dma, uint32_t sbusel) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_SBUSEL_MSK, (sbusel<CSR4, DMA_CSR4_SBUSEL_MSK)>>DMA_CSR4_SBUSEL_POSS); +} +/** + * @brief Set Source Transfer Data Width Selection. + * @param dma DMA Instance + * @param sdwsel can be one of the following values: + * @arg @ref MD_DMA_SDWSEL_ONE_BYTE + * @arg @ref MD_DMA_SDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_SDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_sdwsel(DMA_TypeDef *dma, uint32_t sdwsel) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_SDWSEL_MSK, (sdwsel<CSR4, DMA_CSR4_SDWSEL_MSK)>>DMA_CSR4_SDWSEL_POSS); +} +/** + * @brief Set Source Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_sinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_SINC_MSK, (dinc<CSR4, DMA_CSR4_SINC_MSK)>>DMA_CSR4_SINC_POS); +} +/** + * @brief Set Peripheral Handshake Software Select + * @param dma DMA Instance + * @param phss can be one of the following values: + * @arg @ref MD_DMA_PHSS_UART1_TX + * @arg @ref MD_DMA_PHSS_UART2_TX + * @arg @ref MD_DMA_PHSS_UART3_TX + * @arg @ref MD_DMA_PHSS_SUART1_TX + * @arg @ref MD_DMA_PHSS_SUART2_TX + * @arg @ref MD_DMA_PHSS_SPI1_TX + * @arg @ref MD_DMA_PHSS_SPI2_TX + * @arg @ref MD_DMA_PHSS_I2C1_TX + * @arg @ref MD_DMA_PHSS_I2C2_TX + * @arg @ref MD_DMA_PHSS_AES_IN + * @arg @ref MD_DMA_PHSS_DAC + * @arg @ref MD_DMA_PHSS_CRC + * @arg @ref MD_DMA_PHSS_UART1_RX + * @arg @ref MD_DMA_PHSS_UART2_RX + * @arg @ref MD_DMA_PHSS_UART3_RX + * @arg @ref MD_DMA_PHSS_SUART1_RX + * @arg @ref MD_DMA_PHSS_SUART2_RX + * @arg @ref MD_DMA_PHSS_SPI1_RTX + * @arg @ref MD_DMA_PHSS_SPI2_RX + * @arg @ref MD_DMA_PHSS_I2C1_RX + * @arg @ref MD_DMA_PHSS_I2C2_RX + * @arg @ref MD_DMA_PHSS_AES_OUT + * @arg @ref MD_DMA_PHSS_ADCSS0 + * @arg @ref MD_DMA_PHSS_ADCSS1 + * @arg @ref MD_DMA_PHSS_ADCSS2 + * @arg @ref MD_DMA_PHSS_ADCSS3 + * @arg @ref MD_DMA_PHSS_BS16T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_AD16C4T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_AD16C4T1_COM + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP32C4T1_UP + * @arg @ref MD_DMA_PHSS_GP32C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T1_UP + * @arg @ref MD_DMA_PHSS_GP16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T2_UP + * @arg @ref MD_DMA_PHSS_GP16C4T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T3_UP + * @arg @ref MD_DMA_PHSS_GP16C4T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T1_UP + * @arg @ref MD_DMA_PHSS_GP16C2T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_COM + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T2_UP + * @arg @ref MD_DMA_PHSS_GP16C2T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T2_COM + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T3_UP + * @arg @ref MD_DMA_PHSS_GP16C2T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T3_COM + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T4_UP + * @arg @ref MD_DMA_PHSS_GP16C2T4_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T4_COM + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_phss(DMA_TypeDef *dma, uint32_t phss) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_PHSS_MSK, (phss<CSR4, DMA_CSR4_PHSS_MSK)>>DMA_CSR4_PHSS_POSS); +} +/** + * @brief Set DMA Channel Priority. + * @param dma DMA Instance + * @param chpri can be one of the following values: + * @arg @ref MD_DMA_CHPRI_LV0 + * @arg @ref MD_DMA_CHPRI_LV1 + * @arg @ref MD_DMA_CHPRI_LV2 + * @arg @ref MD_DMA_CHPRI_LV3 + * @arg @ref MD_DMA_CHPRI_LV4 + * @arg @ref MD_DMA_CHPRI_LV5 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_chpri(DMA_TypeDef *dma, uint32_t chpri) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_CHPRI_MSK, (chpri<CSR4, DMA_CSR4_CHPRI_MSK)>>DMA_CSR4_CHPRI_POSS); +} +/** + * @brief Set DMA Mode Select. + * @param dma DMA Instance + * @param modesel can be one of the following values: + * @arg @ref MD_DMA_MODESEL_MEM_TO_MEM + * @arg @ref MD_DMA_MODESEL_PER_TO_MEM + * @arg @ref MD_DMA_MODESEL_MEM_TO_PER + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_modesel(DMA_TypeDef *dma, uint32_t modesel) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_MODESEL_MSK, (modesel<CSR4, DMA_CSR4_MODESEL_MSK)>>DMA_CSR4_MODESEL_POSS); +} +/** + * @brief Set Direct Mode Enable. + * @param dma DMA Instance + * @param dirmden can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_dirmden(DMA_TypeDef *dma, uint32_t dirmden) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_DIRMDEN_MSK, (dirmden<CSR4, DMA_CSR4_DIRMDEN_MSK)>>DMA_CSR4_DIRMDEN_POS); +} +/** + * @brief Set Peripheral flow controller + * @param dma DMA Instance + * @param pfctrl can be one of the following values: + * @arg @ref MD_DMA_PFCTRL_DMA_CTRL + * @arg @ref MD_DMA_PFCTRL_PER_CTRL + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_pfctrl(DMA_TypeDef *dma, uint32_t pfctrl) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_PFCTRL_MSK, (pfctrl<CSR4, DMA_CSR4_PFCTRL_MSK)>>DMA_CSR4_PFCTRL_POS); +} +/** + * @brief Set Circular mode + * @param dma DMA Instance + * @param circ can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_circ(DMA_TypeDef *dma, uint32_t circ) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_CIRC_MSK, (circ<CSR4, DMA_CSR4_CIRC_MSK)>>DMA_CSR4_CIRC_POS); +} +/** + * @brief Set DMA Channel Enable. + * @param dma DMA Instance + * @param chen can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr4_chen(DMA_TypeDef *dma, uint32_t chen) +{ + MODIFY_REG(dma->CSR4, DMA_CSR4_CHEN_MSK, (chen<CSR4, DMA_CSR4_CHEN_MSK)>>DMA_CSR4_CHEN_POS); +} + +/** + * @brief Set DMA Transfer Source Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param sar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_sar4_sar(DMA_TypeDef *dma, uint32_t sar) +{ + MODIFY_REG(dma->SAR4, DMA_SAR4_SAR_MSK, (sar<SAR4, DMA_SAR4_SAR_MSK)>>DMA_SAR4_SAR_POSS); +} + +/** + * @brief Set DMA Transfer Destination Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param dar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_dar4_dar(DMA_TypeDef *dma, uint32_t dar) +{ + MODIFY_REG(dma->DAR4, DMA_DAR4_DAR_MSK, (dar<DAR4, DMA_DAR4_DAR_MSK)>>DMA_DAR4_DAR_POSS); +} + +/** + * @brief Get DMA Current Transfer Byte Count + * @param dma DMA Instance + * @retval The retval can be one of the following values: + * @arg Max Value 65535 + * @arg Min Value 0 + */ +__STATIC_INLINE uint32_t md_dma_get_bcr4_cbcr(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->BCR4, DMA_BCR4_CBCR_MSK)>>DMA_BCR4_CBCR_POSS); +} +/** + * @brief Set DMA Transfer Byte Count Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param bcr This field indicates a 16-bit transfer byte count of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_bcr4_bcr(DMA_TypeDef *dma, uint32_t bcr) +{ + MODIFY_REG(dma->BCR4, DMA_BCR4_BCR_MSK, (bcr<BCR4, DMA_BCR4_BCR_MSK)>>DMA_BCR4_BCR_POSS); +} + +/** + * @brief Set Destination Increment Offset Size bit. + * @note This bit has no meaning if bit DINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if DBUSEL are different from 00. + * @param dma DMA Instance + * @param dincos can be one of the following values: + * @arg @ref MD_DMA_DINCOS_LINKED_DWSEL + * @arg @ref MD_DMA_DINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_dincos(DMA_TypeDef *dma, uint32_t dincos) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_DINCOS_MSK, (dincos<CSR5, DMA_CSR5_DINCOS_MSK)>>DMA_CSR5_DINCOS_POS); +} +/** + * @brief Set Destination Transfer Burst Selection. + * @param dma DMA Instance + * @param dbusel can be one of the following values: + * @arg @ref MD_DMA_DBUSEL_SINGLE + * @arg @ref MD_DMA_DBUSEL_WRAP4 + * @arg @ref MD_DMA_DBUSEL_INCR4 + * @arg @ref MD_DMA_DBUSEL_WRAP8 + * @arg @ref MD_DMA_DBUSEL_INCR8 + * @arg @ref MD_DMA_DBUSEL_WRAP16 + * @arg @ref MD_DMA_DBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_dbusel(DMA_TypeDef *dma, uint32_t dbusel) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_DBUSEL_MSK, (dbusel<CSR5, DMA_CSR5_DBUSEL_MSK)>>DMA_CSR5_DBUSEL_POSS); +} +/** + * @brief Set Destination Transfer Data Width Selection. + * @param dma DMA Instance + * @param ddwsel can be one of the following values: + * @arg @ref MD_DMA_DDWSEL_ONE_BYTE + * @arg @ref MD_DMA_DDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_DDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_ddwsel(DMA_TypeDef *dma, uint32_t ddwsel) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_DDWSEL_MSK, (ddwsel<CSR5, DMA_CSR5_DDWSEL_MSK)>>DMA_CSR5_DDWSEL_POSS); +} +/** + * @brief Set Destination Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_dinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_DINC_MSK, (dinc<CSR5, DMA_CSR5_DINC_MSK)>>DMA_CSR5_DINC_POS); +} +/** + * @brief Set Source Increment Offset Size bit. + * @note This bit has no meaning if bit SINC = '0'. + * This bit is protected and can be written only if EN = '0'. + * This bit is forced low by hardware when the stream is enabled (bit EN = '1') if the direct mode is selected or + * if SBUSEL are different from 00. + * @param dma DMA Instance + * @param sincos can be one of the following values: + * @arg @ref MD_DMA_SINCOS_LINKED_SWSEL + * @arg @ref MD_DMA_SINCOS_FIXED_TO_4 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_sincos(DMA_TypeDef *dma, uint32_t sincos) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_SINCOS_MSK, (sincos<CSR5, DMA_CSR5_SINCOS_MSK)>>DMA_CSR5_SINCOS_POS); +} +/** + * @brief Set Source Transfer Burst Selection. + * @param dma DMA Instance + * @param sbusel can be one of the following values: + * @arg @ref MD_DMA_SBUSEL_SINGLE + * @arg @ref MD_DMA_SBUSEL_WRAP4 + * @arg @ref MD_DMA_SBUSEL_INCR4 + * @arg @ref MD_DMA_SBUSEL_WRAP8 + * @arg @ref MD_DMA_SBUSEL_INCR8 + * @arg @ref MD_DMA_SBUSEL_WRAP16 + * @arg @ref MD_DMA_SBUSEL_INCR16 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_sbusel(DMA_TypeDef *dma, uint32_t sbusel) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_SBUSEL_MSK, (sbusel<CSR5, DMA_CSR5_SBUSEL_MSK)>>DMA_CSR5_SBUSEL_POSS); +} +/** + * @brief Set Source Transfer Data Width Selection. + * @param dma DMA Instance + * @param sdwsel can be one of the following values: + * @arg @ref MD_DMA_SDWSEL_ONE_BYTE + * @arg @ref MD_DMA_SDWSEL_ONE_HALF_WORD + * @arg @ref MD_DMA_SDWSEL_ONE_WORD + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_sdwsel(DMA_TypeDef *dma, uint32_t sdwsel) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_SDWSEL_MSK, (sdwsel<CSR5, DMA_CSR5_SDWSEL_MSK)>>DMA_CSR5_SDWSEL_POSS); +} +/** + * @brief Set Source Transfer Increment Mode + * @param dma DMA Instance + * @param dinc can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_sinc(DMA_TypeDef *dma, uint32_t dinc) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_SINC_MSK, (dinc<CSR5, DMA_CSR5_SINC_MSK)>>DMA_CSR5_SINC_POS); +} +/** + * @brief Set Peripheral Handshake Software Select + * @param dma DMA Instance + * @param phss can be one of the following values: + * @arg @ref MD_DMA_PHSS_UART1_TX + * @arg @ref MD_DMA_PHSS_UART2_TX + * @arg @ref MD_DMA_PHSS_UART3_TX + * @arg @ref MD_DMA_PHSS_SUART1_TX + * @arg @ref MD_DMA_PHSS_SUART2_TX + * @arg @ref MD_DMA_PHSS_SPI1_TX + * @arg @ref MD_DMA_PHSS_SPI2_TX + * @arg @ref MD_DMA_PHSS_I2C1_TX + * @arg @ref MD_DMA_PHSS_I2C2_TX + * @arg @ref MD_DMA_PHSS_AES_IN + * @arg @ref MD_DMA_PHSS_DAC + * @arg @ref MD_DMA_PHSS_CRC + * @arg @ref MD_DMA_PHSS_UART1_RX + * @arg @ref MD_DMA_PHSS_UART2_RX + * @arg @ref MD_DMA_PHSS_UART3_RX + * @arg @ref MD_DMA_PHSS_SUART1_RX + * @arg @ref MD_DMA_PHSS_SUART2_RX + * @arg @ref MD_DMA_PHSS_SPI1_RTX + * @arg @ref MD_DMA_PHSS_SPI2_RX + * @arg @ref MD_DMA_PHSS_I2C1_RX + * @arg @ref MD_DMA_PHSS_I2C2_RX + * @arg @ref MD_DMA_PHSS_AES_OUT + * @arg @ref MD_DMA_PHSS_ADCSS0 + * @arg @ref MD_DMA_PHSS_ADCSS1 + * @arg @ref MD_DMA_PHSS_ADCSS2 + * @arg @ref MD_DMA_PHSS_ADCSS3 + * @arg @ref MD_DMA_PHSS_BS16T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_AD16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_AD16C4T1_UP + * @arg @ref MD_DMA_PHSS_AD16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_AD16C4T1_COM + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP32C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP32C4T1_UP + * @arg @ref MD_DMA_PHSS_GP32C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T1_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T1_UP + * @arg @ref MD_DMA_PHSS_GP16C4T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T2_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T2_UP + * @arg @ref MD_DMA_PHSS_GP16C4T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH3 + * @arg @ref MD_DMA_PHSS_GP16C4T3_CH4 + * @arg @ref MD_DMA_PHSS_GP16C4T3_UP + * @arg @ref MD_DMA_PHSS_GP16C4T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T1_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T1_UP + * @arg @ref MD_DMA_PHSS_GP16C2T1_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T1_COM + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T2_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T2_UP + * @arg @ref MD_DMA_PHSS_GP16C2T2_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T2_COM + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T3_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T3_UP + * @arg @ref MD_DMA_PHSS_GP16C2T3_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T3_COM + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH1 + * @arg @ref MD_DMA_PHSS_GP16C2T4_CH2 + * @arg @ref MD_DMA_PHSS_GP16C2T4_UP + * @arg @ref MD_DMA_PHSS_GP16C2T4_TRIG + * @arg @ref MD_DMA_PHSS_GP16C2T4_COM + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_phss(DMA_TypeDef *dma, uint32_t phss) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_PHSS_MSK, (phss<CSR5, DMA_CSR5_PHSS_MSK)>>DMA_CSR5_PHSS_POSS); +} +/** + * @brief Set DMA Channel Priority. + * @param dma DMA Instance + * @param chpri can be one of the following values: + * @arg @ref MD_DMA_CHPRI_LV0 + * @arg @ref MD_DMA_CHPRI_LV1 + * @arg @ref MD_DMA_CHPRI_LV2 + * @arg @ref MD_DMA_CHPRI_LV3 + * @arg @ref MD_DMA_CHPRI_LV4 + * @arg @ref MD_DMA_CHPRI_LV5 + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_chpri(DMA_TypeDef *dma, uint32_t chpri) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_CHPRI_MSK, (chpri<CSR5, DMA_CSR5_CHPRI_MSK)>>DMA_CSR5_CHPRI_POSS); +} +/** + * @brief Set DMA Mode Select. + * @param dma DMA Instance + * @param modesel can be one of the following values: + * @arg @ref MD_DMA_MODESEL_MEM_TO_MEM + * @arg @ref MD_DMA_MODESEL_PER_TO_MEM + * @arg @ref MD_DMA_MODESEL_MEM_TO_PER + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_modesel(DMA_TypeDef *dma, uint32_t modesel) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_MODESEL_MSK, (modesel<CSR5, DMA_CSR5_MODESEL_MSK)>>DMA_CSR5_MODESEL_POSS); +} +/** + * @brief Set Direct Mode Enable. + * @param dma DMA Instance + * @param dirmden can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_dirmden(DMA_TypeDef *dma, uint32_t dirmden) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_DIRMDEN_MSK, (dirmden<CSR5, DMA_CSR5_DIRMDEN_MSK)>>DMA_CSR5_DIRMDEN_POS); +} +/** + * @brief Set Peripheral flow controller + * @param dma DMA Instance + * @param pfctrl can be one of the following values: + * @arg @ref MD_DMA_PFCTRL_DMA_CTRL + * @arg @ref MD_DMA_PFCTRL_PER_CTRL + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_pfctrl(DMA_TypeDef *dma, uint32_t pfctrl) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_PFCTRL_MSK, (pfctrl<CSR5, DMA_CSR5_PFCTRL_MSK)>>DMA_CSR5_PFCTRL_POS); +} +/** + * @brief Set Circular mode + * @param dma DMA Instance + * @param circ can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_circ(DMA_TypeDef *dma, uint32_t circ) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_CIRC_MSK, (circ<CSR5, DMA_CSR5_CIRC_MSK)>>DMA_CSR5_CIRC_POS); +} +/** + * @brief Set DMA Channel Enable. + * @param dma DMA Instance + * @param chen can be one of the following values: + * @arg Disable + * @arg Enable + * @retval None + */ +__STATIC_INLINE void md_dma_set_csr5_chen(DMA_TypeDef *dma, uint32_t chen) +{ + MODIFY_REG(dma->CSR5, DMA_CSR5_CHEN_MSK, (chen<CSR5, DMA_CSR5_CHEN_MSK)>>DMA_CSR5_CHEN_POS); +} + +/** + * @brief Set DMA Transfer Source Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param sar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_sar5_sar(DMA_TypeDef *dma, uint32_t sar) +{ + MODIFY_REG(dma->SAR5, DMA_SAR5_SAR_MSK, (sar<SAR5, DMA_SAR5_SAR_MSK)>>DMA_SAR5_SAR_POSS); +} + +/** + * @brief Set DMA Transfer Destination Address Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param dar This field indicates a 32-bit source address of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_dar5_dar(DMA_TypeDef *dma, uint32_t dar) +{ + MODIFY_REG(dma->DAR5, DMA_DAR5_DAR_MSK, (dar<DAR5, DMA_DAR5_DAR_MSK)>>DMA_DAR5_DAR_POSS); +} + +/** + * @brief Get DMA Current Transfer Byte Count + * @param dma DMA Instance + * @retval The retval can be one of the following values: + * @arg Max Value 65535 + * @arg Min Value 0 + */ +__STATIC_INLINE uint32_t md_dma_get_bcr5_cbcr(DMA_TypeDef *dma) +{ + return (READ_BIT(dma->BCR5, DMA_BCR5_CBCR_MSK)>>DMA_BCR5_CBCR_POSS); +} +/** + * @brief Set DMA Transfer Byte Count Register + * @note These bits are write-protected and can be written only when bit EN = '0' + * @param dma DMA Instance + * @param bcr This field indicates a 16-bit transfer byte count of DMA. + * @retval None + */ +__STATIC_INLINE void md_dma_set_bcr5_bcr(DMA_TypeDef *dma, uint32_t bcr) +{ + MODIFY_REG(dma->BCR5, DMA_BCR5_BCR_MSK, (bcr<BCR5, DMA_BCR5_BCR_MSK)>>DMA_BCR5_BCR_POSS); +} + +/** + * @} MD_DMA_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_DMA_Public_Functions DMA Public Functions + * @{ + */ + +/** @defgroup MD_DMA_Basic_Configuration Basic Configuration + * @{ + */ + +/** + * @} MD_DMA_Basic_Configuration + */ + + +/** + * @} MD_DMA_Public_Functions + */ + +#endif + +/** + * @} DMA + */ + +/** + * @} Micro_Driver + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_exti.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_exti.h new file mode 100644 index 0000000000..7f00f8320e --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_exti.h @@ -0,0 +1,5167 @@ +/** + ****************************************************************************** + * @file md_EXTI.h + * @brief ES32F0271 EXTI HEAD File. + * + * @version V1.00.01 + * @date 22/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_EXTI_H__ +#define __MD_EXTI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_exti.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (EXTI) +/** @defgroup EXTI EXTI + * @brief EXTI micro driver + * @{ + */ + + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +/* Public types ---------------------------------------------------------------*/ +/* Public constants -----------------------------------------------------------*/ + +/** @defgroup MD_EXTI_Public_Constants EXTI Public Constants + * @{ + */ + +/** @defgroup MD_EXTI_PC_Source EXTI Line Source + * @{ + */ +#define MD_EXTI_Pin_GPIOA (0x00000000UL) /*!< @brief Select GPIOA for EXTIx */ +#define MD_EXTI_Pin_GPIOB (0x00000001UL) /*!< @brief Select GPIOB for EXTIx */ +#define MD_EXTI_Pin_GPIOC (0x00000002UL) /*!< @brief Select GPIOC for EXTIx */ +#define MD_EXTI_Pin_GPIOD (0x00000003UL) /*!< @brief Select GPIOD for EXTIx */ + + /** + * @} MD_EXTI_PC_Source + */ + +/** +* @} MD_EXTI_Public_Constants +*/ + + + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_EXTI_Public_Macros EXTI Public Macros + * @{ + */ + + + +/** @defgroup MD_EXTI_PF_Basic_Configuration EXTI Configuration Management + * @{ + */ +/** + * @brief Set EXTI interrupt configuration register 1 + * @param exti EXTI Instance + * @param value The value write in EXTI->ICFG1 + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->ICFG1, value); +} + +/** + * @brief Get EXTI interrupt configuration register 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->ICFG1)); +} + +/** + * @brief Set EXTI interrupt configuration register 2 + * @param exti EXTI Instance + * @param value The value write in EXTI->ICFG2 + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->ICFG2, value); +} + +/** + * @brief Get EXTI interrupt configuration register 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->ICFG2)); +} + +/** + * @brief Set EXTI0 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1_gpio0(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG1, EXTI_ICFG1_GPIO0_MSK, Source); +} + +/** + * @brief Get EXTI0 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1_gpio0(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG1, EXTI_ICFG1_GPIO0_MSK)>>EXTI_ICFG1_GPIO0_POSS); +} + +/** + * @brief Set EXTI1 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1_gpio1(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG1, EXTI_ICFG1_GPIO1_MSK, Source << EXTI_ICFG1_GPIO1_POSS); +} + +/** + * @brief Get EXTI1 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1_gpio1(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG1, EXTI_ICFG1_GPIO1_MSK)>>EXTI_ICFG1_GPIO1_POSS); +} + +/** + * @brief Set EXTI2 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1_gpio2(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG1, EXTI_ICFG1_GPIO2_MSK, Source << EXTI_ICFG1_GPIO2_POSS); +} + +/** + * @brief Get EXTI2 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1_gpio2(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG1, EXTI_ICFG1_GPIO2_MSK)>>EXTI_ICFG1_GPIO2_POSS); +} + +/** + * @brief Set EXTI3 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1_gpio3(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG1, EXTI_ICFG1_GPIO3_MSK, Source << EXTI_ICFG1_GPIO3_POSS); +} + +/** + * @brief Get EXTI3 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1_gpio3(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG1, EXTI_ICFG1_GPIO3_MSK)>>EXTI_ICFG1_GPIO0_POSS); +} + +/** + * @brief Set EXTI4 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1_gpio4(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG1, EXTI_ICFG1_GPIO4_MSK, Source << EXTI_ICFG1_GPIO4_POSS); +} + +/** + * @brief Get EXTI4 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1_gpio4(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG1, EXTI_ICFG1_GPIO4_MSK)>>EXTI_ICFG1_GPIO4_POSS); +} + +/** + * @brief Set EXTI5 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1_gpio5(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG1, EXTI_ICFG1_GPIO5_MSK, Source << EXTI_ICFG1_GPIO5_POSS); +} + +/** + * @brief Get EXTI5 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1_gpio5(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG1, EXTI_ICFG1_GPIO5_MSK)>>EXTI_ICFG1_GPIO5_POSS); +} + +/** + * @brief Set EXTI6 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1_gpio6(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG1, EXTI_ICFG1_GPIO6_MSK, Source << EXTI_ICFG1_GPIO6_POSS); +} + +/** + * @brief Get EXTI6 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1_gpio6(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG1, EXTI_ICFG1_GPIO6_MSK)>>EXTI_ICFG1_GPIO6_POSS); +} + +/** + * @brief Set EXTI7 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg1_gpio7(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG1, EXTI_ICFG1_GPIO7_MSK, Source << EXTI_ICFG1_GPIO7_POSS); +} + +/** + * @brief Get EXTI7 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg1_gpio7(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG1, EXTI_ICFG1_GPIO7_MSK)>>EXTI_ICFG1_GPIO7_POSS); +} + + +/** + * @brief Set EXTI8 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2_gpio8(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG2, EXTI_ICFG2_GPIO8_MSK, Source << EXTI_ICFG2_GPIO8_POSS); +} + +/** + * @brief Get EXTI8 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2_gpio8(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG2, EXTI_ICFG2_GPIO8_MSK)>>EXTI_ICFG2_GPIO8_POSS); +} + +/** + * @brief Set EXTI9 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2_gpio9(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG2, EXTI_ICFG2_GPIO9_MSK, Source << EXTI_ICFG2_GPIO9_POSS); +} + +/** + * @brief Get EXTI9 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2_gpio9(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG2, EXTI_ICFG2_GPIO9_MSK)>>EXTI_ICFG2_GPIO9_POSS); +} + +/** + * @brief Set EXTI10 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2_gpio10(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG2, EXTI_ICFG2_GPIO10_MSK, Source << EXTI_ICFG2_GPIO10_POSS); +} + +/** + * @brief Get EXTI10 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2_gpio10(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG2, EXTI_ICFG2_GPIO10_MSK)>>EXTI_ICFG2_GPIO10_POSS); +} + +/** + * @brief Set EXTI11 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2_gpio11(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG2, EXTI_ICFG2_GPIO11_MSK, Source << EXTI_ICFG2_GPIO11_POSS); +} + +/** + * @brief Get EXTI11 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2_gpio11(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG2, EXTI_ICFG2_GPIO11_MSK)>>EXTI_ICFG2_GPIO11_POSS); +} + +/** + * @brief Set EXTI12 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2_gpio12(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG2, EXTI_ICFG2_GPIO12_MSK, Source << EXTI_ICFG2_GPIO12_POSS); +} + +/** + * @brief Get EXTI12 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2_gpio12(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG2, EXTI_ICFG2_GPIO12_MSK)>>EXTI_ICFG2_GPIO12_POSS); +} + +/** + * @brief Set EXTI13 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2_gpio13(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG2, EXTI_ICFG2_GPIO13_MSK, Source << EXTI_ICFG2_GPIO13_POSS); +} + +/** + * @brief Get EXTI13 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2_gpio13(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG2, EXTI_ICFG2_GPIO13_MSK)>>EXTI_ICFG2_GPIO13_POSS); +} + +/** + * @brief Set EXTI14 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2_gpio14(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG2, EXTI_ICFG2_GPIO14_MSK, Source << EXTI_ICFG2_GPIO14_POSS); +} + +/** + * @brief Get EXTI14 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2_gpio14(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG2, EXTI_ICFG2_GPIO14_MSK)>>EXTI_ICFG2_GPIO14_POSS); +} + +/** + * @brief Set EXTI15 configuration + * @param exti EXTI Instance + * @param Source This parameter can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + * @retval None + */ +__STATIC_INLINE void md_exti_set_icfg2_gpio15(EXTI_TypeDef *exti, uint32_t Source) +{ + MODIFY_REG(exti->ICFG2, EXTI_ICFG2_GPIO15_MSK, Source << EXTI_ICFG2_GPIO15_POSS); +} + +/** + * @brief Get EXTI15 configuration + * @param exti EXTI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_EXTI_Pin_GPIOA + * @arg @ref MD_EXTI_Pin_GPIOB + * @arg @ref MD_EXTI_Pin_GPIOC + * @arg @ref MD_EXTI_Pin_GPIOD + */ +__STATIC_INLINE uint32_t md_exti_get_icfg2_gpio15(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->ICFG2, EXTI_ICFG2_GPIO15_MSK)>>EXTI_ICFG2_GPIO15_POSS); +} + +/** + * @} MD_EXTI_PF_Basic_Configuration + */ + +/** @defgroup MD_EXTI_PF_RTS EXTI Rising Edge Trigger Selection Register + * @{ + */ + +/** + * @brief Set rising trigger event configuration bit of line + * @param exti EXTI Instance + * @param value The value write in EXTI->RTS + * @retval None + */ +__STATIC_INLINE void md_exti_set_rts(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->RTS, value); +} + +/** + * @brief Get rising trigger event configuration bit of line + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_get_rts(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->RTS)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO0_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO0_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 0 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO0_MSK) == (EXTI_RTS_GPIO0_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO1_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO1_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 1 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO1_MSK) == (EXTI_RTS_GPIO1_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO2_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO2_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 2 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO2_MSK) == (EXTI_RTS_GPIO2_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio3(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO3_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio3(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO3_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 3 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio3(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO3_MSK) == (EXTI_RTS_GPIO3_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio4(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO4_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio4(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO4_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 4 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio4(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO4_MSK) == (EXTI_RTS_GPIO4_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio5(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO5_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio5(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO5_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 5 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio5(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO5_MSK) == (EXTI_RTS_GPIO5_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio6(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO6_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio6(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO6_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 1 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio6(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO6_MSK) == (EXTI_RTS_GPIO6_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio7(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO7_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio7(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO7_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 7 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio7(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO7_MSK) == (EXTI_RTS_GPIO7_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio8(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO8_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio8(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO8_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 8 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio8(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO8_MSK) == (EXTI_RTS_GPIO8_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio9(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO9_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio9(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO9_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 9 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio9(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO9_MSK) == (EXTI_RTS_GPIO9_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio10(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO10_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio10(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO10_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 10 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio10(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO10_MSK) == (EXTI_RTS_GPIO10_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio11(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO11_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio11(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO11_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 11 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio11(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO11_MSK) == (EXTI_RTS_GPIO11_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio12(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO12_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio12(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO12_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 12 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio12(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO12_MSK) == (EXTI_RTS_GPIO12_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio13(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO13_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio13(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO13_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 13 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio13(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO13_MSK) == (EXTI_RTS_GPIO13_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio14(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO14_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio14(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO14_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 14 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio14(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO14_MSK) == (EXTI_RTS_GPIO14_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_gpio15(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_GPIO15_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_gpio15(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_GPIO15_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 15 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_gpio15(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_GPIO15_MSK) == (EXTI_RTS_GPIO15_MSK)); +} + + +/** + * @brief Enable rising trigger event configuration bit of line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_cmp1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_CMP1_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_cmp1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_CMP1_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 16 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_cmp1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_CMP1_MSK) == (EXTI_RTS_CMP1_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_cmp2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_CMP2_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_cmp2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_CMP2_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 17 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_cmp2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_CMP2_MSK) == (EXTI_RTS_CMP2_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_pvd0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_PVD0_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_pvd0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_PVD0_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 20 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_pvd0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_PVD0_MSK) == (EXTI_RTS_PVD0_MSK)); +} + +/** + * @brief Enable rising trigger event configuration bit of line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_rts_wakeup(EXTI_TypeDef *exti) +{ + SET_BIT(exti->RTS, EXTI_RTS_WAKEUP_MSK); +} + +/** + * @brief Disable rising trigger event configuration bit of line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_rts_wakeup(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->RTS, EXTI_RTS_WAKEUP_MSK); +} + +/** + * @brief Check if rising trigger event configuration bit of line 21 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_rts_wakeup(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->RTS, EXTI_RTS_WAKEUP_MSK) == (EXTI_RTS_WAKEUP_MSK)); +} + +/** + * @} MD_EXTI_PF_RTS + */ + +/** @defgroup MD_EXTI_PF_FTS EXTI Falling Edge Trigger Selection Register + * @{ + */ + +/** + * @brief Set falling trigger event configuration bit of line + * @param exti EXTI Instance + * @param value The value write in EXTI->FTS + * @retval None + */ +__STATIC_INLINE void md_exti_set_fts(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->FTS, value); +} + +/** + * @brief Get falling trigger event configuration bit of line + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_get_fts(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->FTS)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO0_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO0_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 0 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO0_MSK) == (EXTI_FTS_GPIO0_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO1_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO1_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 1 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO1_MSK) == (EXTI_FTS_GPIO1_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO2_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO2_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 2 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO2_MSK) == (EXTI_FTS_GPIO2_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio3(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO3_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio3(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO3_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 3 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio3(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO3_MSK) == (EXTI_FTS_GPIO3_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio4(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO4_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio4(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO4_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 4 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio4(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO4_MSK) == (EXTI_FTS_GPIO4_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio5(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO5_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio5(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO5_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 5 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio5(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO5_MSK) == (EXTI_FTS_GPIO5_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio6(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO6_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio6(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO6_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 6 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio6(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO6_MSK) == (EXTI_FTS_GPIO6_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio7(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO7_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio7(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO7_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 7 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio7(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO7_MSK) == (EXTI_FTS_GPIO7_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio8(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO8_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio8(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO8_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 8 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio8(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO8_MSK) == (EXTI_FTS_GPIO8_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio9(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO9_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio9(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO9_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 9 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio9(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO9_MSK) == (EXTI_FTS_GPIO9_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio10(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO10_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio10(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO10_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 10 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio10(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO10_MSK) == (EXTI_FTS_GPIO10_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio11(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO11_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio11(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO11_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 11 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio11(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO11_MSK) == (EXTI_FTS_GPIO11_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio12(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO12_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio12(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO12_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 12 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio12(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO12_MSK) == (EXTI_FTS_GPIO12_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio13(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO13_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio13(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO13_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 13 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio13(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO13_MSK) == (EXTI_FTS_GPIO13_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio14(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO14_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio14(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO14_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 14 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio14(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO14_MSK) == (EXTI_FTS_GPIO14_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_gpio15(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_GPIO15_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_gpio15(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO15_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 15 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_gpio15(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_GPIO15_MSK) == (EXTI_FTS_GPIO15_MSK)); +} + + + +/** + * @brief Enable falling trigger event configuration bit of line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_cmp1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_CMP1_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_cmp1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_CMP1_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 16 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_cmp1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_CMP1_MSK) == (EXTI_FTS_CMP1_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_cmp2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_CMP2_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 18 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_cmp2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_CMP2_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 18 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_cmp2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_CMP2_MSK) == (EXTI_RTS_CMP2_MSK)); +} + + +/** + * @brief Enable falling trigger event configuration bit of line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_pvd0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_PVD0_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_pvd0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_PVD0_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 17 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_pvd0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_PVD0_MSK) == (EXTI_FTS_PVD0_MSK)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_fts_wakeup(EXTI_TypeDef *exti) +{ + SET_BIT(exti->FTS, EXTI_FTS_WAKEUP_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_fts_wakeup(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_WAKEUP_MSK); +} + +/** + * @brief Check if falling trigger event configuration bit of line 21 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_fts_wakeup(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->FTS, EXTI_FTS_WAKEUP_MSK) == (EXTI_FTS_WAKEUP_MSK)); +} + + + +/** + * @} MD_EXTI_PF_FTS + */ + +/** @defgroup MD_EXTI_PF_SWI EXTI Software Interrupt Event register + * @{ + */ + +/** + * @brief Set software interrupt on line + * @param exti EXTI Instance + * @param value The value write in EXTI->SWI + * @retval None + */ +__STATIC_INLINE void md_exti_set_swi(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->SWI, value); +} + +/** + * @brief Get software interrupt on line + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_get_swi(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->SWI)); +} + +/** + * @brief Enable falling trigger event configuration bit of line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO0_MSK); +} + +/** + * @brief Disable software interrupt on line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO0_MSK); +} + +/** + * @brief Check if software interrupt on line 0 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO0_MSK) == (EXTI_SWI_GPIO0_MSK)); +} + +/** + * @brief Enable software interrupt on line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO1_MSK); +} + +/** + * @brief Disable software interrupt on line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO1_MSK); +} + +/** + * @brief Check if software interrupt on line 1 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO1_MSK) == (EXTI_SWI_GPIO1_MSK)); +} + +/** + * @brief Enable software interrupt on line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO2_MSK); +} + +/** + * @brief Disable software interrupt on line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO2_MSK); +} + +/** + * @brief Check if software interrupt on line 2 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO2_MSK) == (EXTI_SWI_GPIO2_MSK)); +} + +/** + * @brief Enable software interrupt on line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio3(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO3_MSK); +} + +/** + * @brief Disable software interrupt on line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio3(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO3_MSK); +} + +/** + * @brief Check if software interrupt on line 3 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio3(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO3_MSK) == (EXTI_SWI_GPIO3_MSK)); +} + +/** + * @brief Enable software interrupt on line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio4(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO4_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio4(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO4_MSK); +} + +/** + * @brief Check if software interrupt on line 4 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio4(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO4_MSK) == (EXTI_SWI_GPIO4_MSK)); +} + +/** + * @brief Enable software interrupt on line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio5(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO5_MSK); +} + +/** + * @brief Disable software interrupt on line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio5(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO5_MSK); +} + +/** + * @brief Check if software interrupt on line 5 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio5(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO5_MSK) == (EXTI_SWI_GPIO5_MSK)); +} + +/** + * @brief Enable software interrupt on line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio6(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO6_MSK); +} + +/** + * @brief Disable software interrupt on line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio6(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO6_MSK); +} + +/** + * @brief Check if software interrupt on line 6 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio6(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO6_MSK) == (EXTI_SWI_GPIO6_MSK)); +} + +/** + * @brief Enable software interrupt on line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio7(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO7_MSK); +} + +/** + * @brief Disable software interrupt on line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio7(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO7_MSK); +} + +/** + * @brief Check if software interrupt on line 7 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio7(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO7_MSK) == (EXTI_SWI_GPIO7_MSK)); +} + +/** + * @brief Enable software interrupt on line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio8(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO8_MSK); +} + +/** + * @brief Disable software interrupt on line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio8(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO8_MSK); +} + +/** + * @brief Check if software interrupt on line 8 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio8(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO8_MSK) == (EXTI_SWI_GPIO8_MSK)); +} + +/** + * @brief Enable software interrupt on line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio9(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO9_MSK); +} + +/** + * @brief Disable software interrupt on line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio9(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO9_MSK); +} + +/** + * @brief Check if software interrupt on line 9 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio9(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO9_MSK) == (EXTI_SWI_GPIO9_MSK)); +} + +/** + * @brief Enable software interrupt on line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio10(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO10_MSK); +} + +/** + * @brief Disable software interrupt on line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio10(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO10_MSK); +} + +/** + * @brief Check if software interrupt on line 10 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio10(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO10_MSK) == (EXTI_SWI_GPIO10_MSK)); +} + +/** + * @brief Enable software interrupt on line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio11(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO11_MSK); +} + +/** + * @brief Disable falling trigger event configuration bit of line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio11(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->FTS, EXTI_FTS_GPIO11_MSK); +} + +/** + * @brief Check if software interrupt on line 11 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio11(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO11_MSK) == (EXTI_SWI_GPIO11_MSK)); +} + +/** + * @brief Enable software interrupt on line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio12(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO12_MSK); +} + +/** + * @brief Disable software interrupt on line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio12(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO12_MSK); +} + +/** + * @brief Check if software interrupt on line 12 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio12(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO12_MSK) == (EXTI_SWI_GPIO12_MSK)); +} + +/** + * @brief Enable software interrupt on line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio13(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO13_MSK); +} + +/** + * @brief Disable software interrupt on line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio13(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO13_MSK); +} + +/** + * @brief Check if software interrupt on line 13 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio13(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO13_MSK) == (EXTI_SWI_GPIO13_MSK)); +} + +/** + * @brief Enable software interrupt on line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio14(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO14_MSK); +} + +/** + * @brief Disable software interrupt on line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio14(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO14_MSK); +} + +/** + * @brief Check if software interrupt on line 14 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio14(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO14_MSK) == (EXTI_SWI_GPIO14_MSK)); +} + +/** + * @brief Enable software interrupt on line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_gpio15(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_GPIO15_MSK); +} + +/** + * @brief Disable software interrupt on line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_gpio15(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_GPIO15_MSK); +} + +/** + * @brief Check if software interrupt on line is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_gpio15(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_GPIO15_MSK) == (EXTI_SWI_GPIO15_MSK)); +} + +/** + * @brief Enable software interrupt on line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_cmp1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_CMP1_MSK); +} + +/** + * @brief Disable software interrupt on line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_cmp1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_CMP1_MSK); +} + +/** + * @brief Check if software interrupt on line 16 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_cmp1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_CMP1_MSK) == (EXTI_SWI_CMP1_MSK)); +} + +/** + * @brief Enable software interrupt on line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_cmp2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_CMP2_MSK); +} + +/** + * @brief Disable software interrupt on line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_cmp2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_CMP2_MSK); +} + +/** + * @brief Check if software interrupt on line 17 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_cmp2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_CMP2_MSK) == (EXTI_SWI_CMP2_MSK)); +} + + +/** + * @brief Enable software interrupt on line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_pvd0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_PVD0_MSK); +} + +/** + * @brief Disable software interrupt on line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_pvd0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_PVD0_MSK); +} + +/** + * @brief Check if software interrupt on line 20 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_pvd0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_PVD0_MSK) == (EXTI_SWI_PVD0_MSK)); +} + +/** + * @brief Enable software interrupt on line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_swi_wakeup(EXTI_TypeDef *exti) +{ + SET_BIT(exti->SWI, EXTI_SWI_WAKEUP_MSK); +} + +/** + * @brief Disable software interrupt on line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_swi_wakeup(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->SWI, EXTI_SWI_WAKEUP_MSK); +} + +/** + * @brief Check if software interrupt on line 21 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_swi_wakeup(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->SWI, EXTI_SWI_WAKEUP_MSK) == (EXTI_SWI_WAKEUP_MSK)); +} + +/** + * @} MD_EXTI_PF_SWI + */ + + +/** @defgroup MD_EXTI_PF_ADTE EXTI ADC Trigger Enable Register + * @{ + */ +/** + * @brief Set ADC trigger enable on line + * @param exti EXTI Instance + * @param value The value write in EXTI->ADTE + * @retval None + */ +__STATIC_INLINE void md_exti_set_adte(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->ADTE, value); +} + +/** + * @brief Get ADC trigger enable on line + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_get_adte(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->ADTE)); +} + +/** + * @brief Enable ADC trigger on line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO0_MSK); +} + +/** + * @brief Disable ADC trigger on line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO0_MSK); +} + +/** + * @brief Check if ADC trigger on line 0 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO0_MSK) == (EXTI_ADTE_GPIO0_MSK)); +} + +/** + * @brief Enable ADC trigger on line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO1_MSK); +} + +/** + * @brief Disable ADC trigger on line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO1_MSK); +} + +/** + * @brief Check if ADC trigger on line 1 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO1_MSK) == (EXTI_ADTE_GPIO1_MSK)); +} + +/** + * @brief Enable ADC trigger on line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO2_MSK); +} + +/** + * @brief Disable ADC trigger on line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO2_MSK); +} + +/** + * @brief Check if ADC trigger on line 2 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO2_MSK) == (EXTI_ADTE_GPIO2_MSK)); +} + +/** + * @brief Enable ADC trigger on line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio3(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO3_MSK); +} + +/** + * @brief Disable ADC trigger on line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio3(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO3_MSK); +} + +/** + * @brief Check if ADC trigger on line 3 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio3(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO3_MSK) == (EXTI_ADTE_GPIO3_MSK)); +} + +/** + * @brief Enable ADC trigger on line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio4(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO4_MSK); +} + +/** + * @brief Disable ADC trigger on line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio4(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO4_MSK); +} + +/** + * @brief Check if ADC trigger on line 4 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio4(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO4_MSK) == (EXTI_ADTE_GPIO4_MSK)); +} + +/** + * @brief Enable ADC trigger on line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio5(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO5_MSK); +} + +/** + * @brief Disable ADC trigger on line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio5(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO5_MSK); +} + +/** + * @brief Check if ADC trigger on line 5 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio5(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO5_MSK) == (EXTI_ADTE_GPIO5_MSK)); +} + +/** + * @brief Enable ADC trigger on line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio6(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO6_MSK); +} + +/** + * @brief Disable ADC trigger on line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio6(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO6_MSK); +} + +/** + * @brief Check if ADC trigger on line 6 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio6(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO6_MSK) == (EXTI_ADTE_GPIO6_MSK)); +} + +/** + * @brief Enable ADC trigger on line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio7(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO7_MSK); +} + +/** + * @brief Disable ADC trigger on line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio7(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO7_MSK); +} + +/** + * @brief Check if ADC trigger on line 7 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio7(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO7_MSK) == (EXTI_ADTE_GPIO7_MSK)); +} + +/** + * @brief Enable ADC trigger on line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio8(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO8_MSK); +} + +/** + * @brief Disable ADC trigger on line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio8(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO8_MSK); +} + +/** + * @brief Check if ADC trigger on line 8 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio8(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO8_MSK) == (EXTI_ADTE_GPIO8_MSK)); +} + +/** + * @brief Enable ADC trigger on line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio9(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO9_MSK); +} + +/** + * @brief Disable ADC trigger on line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio9(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO9_MSK); +} + +/** + * @brief Check if ADC trigger on line 9 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio9(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO9_MSK) == (EXTI_ADTE_GPIO9_MSK)); +} + +/** + * @brief Enable ADC trigger on line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio10(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO10_MSK); +} + +/** + * @brief Disable ADC trigger on line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio10(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO10_MSK); +} + +/** + * @brief Check if ADC trigger on line 10 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio10(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO10_MSK) == (EXTI_ADTE_GPIO10_MSK)); +} + +/** + * @brief Enable ADC trigger on line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio11(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO11_MSK); +} + +/** + * @brief Disable ADC trigger on line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio11(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO11_MSK); +} + +/** + * @brief Check if ADC trigger on line 11 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio11(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO11_MSK) == (EXTI_ADTE_GPIO11_MSK)); +} + +/** + * @brief Enable ADC trigger on line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio12(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO12_MSK); +} + +/** + * @brief Disable ADC trigger on line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio12(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO12_MSK); +} + +/** + * @brief Check if ADC trigger on line 12 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio12(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO12_MSK) == (EXTI_ADTE_GPIO12_MSK)); +} + +/** + * @brief Enable ADC trigger on line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio13(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO13_MSK); +} + +/** + * @brief Disable ADC trigger on line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio13(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO13_MSK); +} + +/** + * @brief Check if ADC trigger on line 13 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio13(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO13_MSK) == (EXTI_ADTE_GPIO13_MSK)); +} + +/** + * @brief Enable ADC trigger on line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio14(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO14_MSK); +} + +/** + * @brief Disable ADC trigger on line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio14(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO14_MSK); +} + +/** + * @brief Check if ADC trigger on line 14 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio14(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO14_MSK) == (EXTI_ADTE_GPIO14_MSK)); +} + +/** + * @brief Enable ADC trigger on line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_gpio15(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_GPIO15_MSK); +} + +/** + * @brief Disable ADC trigger on line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_gpio15(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_GPIO15_MSK); +} + +/** + * @brief Check if ADC trigger on line is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_gpio15(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_GPIO15_MSK) == (EXTI_ADTE_GPIO15_MSK)); +} + +/** + * @brief Enable ADC trigger on line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_cmp1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_CMP1_MSK); +} + +/** + * @brief Disable ADC trigger on line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_cmp1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_CMP1_MSK); +} + +/** + * @brief Check if ADC trigger on line 16 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_cmp1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_CMP1_MSK) == (EXTI_ADTE_CMP1_MSK)); +} + +/** + * @brief Enable ADC trigger on line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_cmp2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_CMP2_MSK); +} + +/** + * @brief Disable ADC trigger on line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_cmp2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_CMP2_MSK); +} + +/** + * @brief Check if ADC trigger on line 17 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_cmp2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_CMP2_MSK) == (EXTI_ADTE_CMP2_MSK)); +} + +/** + * @brief Enable ADC trigger on line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_pvd0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_PVD0_MSK); +} + +/** + * @brief Disable ADC trigger on line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_pvd0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_PVD0_MSK); +} + +/** + * @brief Check if ADC trigger on line 20 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_pvd0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_PVD0_MSK) == (EXTI_ADTE_PVD0_MSK)); +} + +/** + * @brief Enable ADC trigger on line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_adte_wakeup(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ADTE, EXTI_ADTE_WAKEUP_MSK); +} + +/** + * @brief Disable ADC trigger on line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_adte_wakeup(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->ADTE, EXTI_ADTE_WAKEUP_MSK); +} + +/** + * @brief Check if ADC trigger on line 21 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_adte_wakeup(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->ADTE, EXTI_ADTE_WAKEUP_MSK) == (EXTI_ADTE_WAKEUP_MSK)); +} + + +/** + * @} MD_EXTI_PF_ADTE + */ + +/** @defgroup MD_EXTI_PF_INTERRUNPT_MANAGEMENT EXTI Interrupt Management + * @{ + */ + +/** @defgroup MD_EXTI_PF_IER EXTI Interrupt Enable Register + * @{ + */ + + +/** + * @brief Set interrupt enable on line + * @param exti EXTI Instance + * @param value The value write in EXTI->IER + * @retval None + */ +__STATIC_INLINE void md_spi_set_exti_ier(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->IER, value); +} + +/** + * @brief Enable interrupt on line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO0_MSK); +} + +/** + * @brief Enable interrupt on line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO1_MSK); +} + +/** + * @brief Enable interrupt on line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO2_MSK); +} + +/** + * @brief Enable interrupt on line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio3(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO3_MSK); +} + +/** + * @brief Enable interrupt on line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio4(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO4_MSK); +} + +/** + * @brief Enable interrupt on line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio5(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO5_MSK); +} + +/** + * @brief Enable interrupt on line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio6(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO6_MSK); +} + +/** + * @brief Enable interrupt on line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio7(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO7_MSK); +} + +/** + * @brief Enable interrupt on line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio8(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO8_MSK); +} + +/** + * @brief Enable interrupt on line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio9(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO9_MSK); +} + +/** + * @brief Enable interrupt on line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio10(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO10_MSK); +} + +/** + * @brief Enable interrupt on line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio11(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO11_MSK); +} + +/** + * @brief Enable interrupt on line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio12(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO12_MSK); +} + +/** + * @brief Enable interrupt on line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio13(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO13_MSK); +} + +/** + * @brief Enable interrupt on line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio14(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO14_MSK); +} + +/** + * @brief Enable interrupt on line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_gpio15(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_GPIO15_MSK); +} + + +/** + * @brief Enable interrupt on line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_cmp1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_CMP1_MSK); +} + +/** + * @brief Enable interrupt on line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_cmp2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_CMP2_MSK); +} + +/** + * @brief Enable interrupt on line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_pvd0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_PVD0_MSK); +} + +/** + * @brief Enable interrupt on line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_ier_wakeup(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IER, EXTI_IER_WAKEUP_MSK); +} + +/** + * @} MD_EXTI_PF_IER + */ + +/** @defgroup MD_EXTI_PF_IDR EXTI Interrupt Disable Register + * @{ + */ + +/** + * @brief Disable interrupt on line + * @param exti EXTI Instance + * @param value The value write in EXTI->IDR + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->IDR, value); +} + + +/** + * @brief Disable interrupt on line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO0_MSK); +} + +/** + * @brief Disable interrupt on line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO1_MSK); +} + +/** + * @brief Disable interrupt on line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO2_MSK); +} + +/** + * @brief Disable interrupt on line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio3(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO3_MSK); +} + +/** + * @brief Disable interrupt on line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio4(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO4_MSK); +} + +/** + * @brief Disable interrupt on line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio5(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO5_MSK); +} + +/** + * @brief Disable interrupt on line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio6(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO6_MSK); +} + +/** + * @brief Disable interrupt on line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio7(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO7_MSK); +} + +/** + * @brief Disable interrupt on line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio8(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO8_MSK); +} + +/** + * @brief Disable interrupt on line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio9(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO9_MSK); +} + +/** + * @brief Disable interrupt on line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio10(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO10_MSK); +} + +/** + * @brief Disable interrupt on line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio11(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO11_MSK); +} + +/** + * @brief Disable interrupt on line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio12(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO12_MSK); +} + +/** + * @brief Disable interrupt on line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio13(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO13_MSK); +} + +/** + * @brief Disable interrupt on line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio14(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->IDR, EXTI_IDR_GPIO14_MSK); +} + +/** + * @brief Disable interrupt on line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_gpio15(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_GPIO15_MSK); +} + +/** + * @brief Disable interrupt on line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_cmp1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->IDR, EXTI_IDR_CMP1_MSK); +} + +/** + * @brief Disable interrupt on line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_cmp2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_CMP2_MSK); +} + +/** + * @brief Disable interrupt on line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_pvd0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_PVD0_MSK); +} + +/** + * @brief Disable interrupt on line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_idr_wakeup(EXTI_TypeDef *exti) +{ + SET_BIT(exti->IDR, EXTI_IDR_WAKEUP_MSK); +} + + +/** + * @} MD_EXTI_PF_IDR + */ + +/** @defgroup MD_EXTI_PF_ICR EXTI Interrupt Clear Register + * @{ + */ + +/** + * @brief Interrupt Clear on line + * @param exti EXTI Instance + * @param value The value write in EXTI->ICR + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->ICR, value); +} + +/** + * @brief Interrupt Clear on line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO0_MSK); +} + +/** + * @brief Interrupt Clear on line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO1_MSK); +} + +/** + * @brief Interrupt Clear on line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO2_MSK); +} + +/** + * @brief Interrupt Clear on line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio3(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO3_MSK); +} + +/** + * @brief Interrupt Clear on line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio4(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO4_MSK); +} + +/** + * @brief Interrupt Clear on line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio5(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO5_MSK); +} + +/** + * @brief Interrupt Clear on line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio6(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO6_MSK); +} + +/** + * @brief Interrupt Clear on line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio7(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO7_MSK); +} + +/** + * @brief Interrupt Clear on line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio8(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO8_MSK); +} + +/** + * @brief Interrupt Clear on line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio9(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO9_MSK); +} + +/** + * @brief Interrupt Clear on line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio10(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO10_MSK); +} + +/** + * @brief Interrupt Clear on line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio11(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO11_MSK); +} + +/** + * @brief Interrupt Clear on line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio12(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO12_MSK); +} + +/** + * @brief Interrupt Clear on line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio13(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO13_MSK); +} + +/** + * @brief Interrupt Clear on line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio14(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO14_MSK); +} + +/** + * @brief Interrupt Clear on line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_gpio15(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_GPIO15_MSK); +} + + +/** + * @brief Interrupt Clear on line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_cmp1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_CMP1_MSK); +} + +/** + * @brief Interrupt Clear on line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_cmp2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_CMP2_MSK); +} + + +/** + * @brief Interrupt Clear on line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_pvd0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_PVD0_MSK); +} + +/** + * @brief Interrupt Clear on line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_clear_icr_wakeup(EXTI_TypeDef *exti) +{ + SET_BIT(exti->ICR, EXTI_ICR_WAKEUP_MSK); +} + +/** + * @} MD_EXTI_PF_ICR + */ + +/** @defgroup MD_EXTI_PF_IVS EXTI Interrupt Valid Status Register + * @{ + */ + +/** + * @brief Interrupt Valid Status on line + * @param exti EXTI Instance + * @param value The value write in EXTI->IVS + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs(EXTI_TypeDef *exti, uint32_t value) +{ + return (READ_REG(exti->IVS)); +} + +/** + * @brief Interrupt Valid Status on line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO0_MSK) == EXTI_IVS_GPIO0_POS); +} + +/** + * @brief Interrupt Valid Status on line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO1_MSK) == EXTI_IVS_GPIO1_POS); +} + +/** + * @brief Interrupt Valid Status on line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO2_MSK) == EXTI_IVS_GPIO2_POS); +} + +/** + * @brief Interrupt Valid Status on line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio3(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO3_MSK) == EXTI_IVS_GPIO3_POS); +} + +/** + * @brief Interrupt Valid Status on line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio4(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO4_MSK) == EXTI_IVS_GPIO4_POS); +} + +/** + * @brief Interrupt Valid Status on line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio5(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO5_MSK)>>EXTI_IVS_GPIO5_POS); +} + +/** + * @brief Interrupt Valid Status on line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio6(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO6_MSK) == EXTI_IVS_GPIO6_POS); +} + +/** + * @brief Interrupt Valid Status on line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio7(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO7_MSK) == EXTI_IVS_GPIO7_POS); +} + +/** + * @brief Interrupt Valid Status on line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio8(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO8_MSK) == EXTI_IVS_GPIO8_POS); +} + +/** + * @brief Interrupt Valid Status on line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio9(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO9_MSK) == EXTI_IVS_GPIO9_POS); +} + +/** + * @brief Interrupt Valid Status on line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio10(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO10_MSK) == EXTI_IVS_GPIO10_POS); +} + +/** + * @brief Interrupt Valid Status on line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio11(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO11_MSK) == EXTI_IVS_GPIO11_POS); +} + +/** + * @brief Interrupt Valid Status on line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio12(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO12_MSK) == EXTI_IVS_GPIO12_POS); +} + +/** + * @brief Interrupt Valid Status on line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio13(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO13_MSK) == EXTI_IVS_GPIO13_POS); +} + +/** + * @brief Interrupt Valid Status on line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio14(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO14_MSK) == EXTI_IVS_GPIO14_POS); +} + +/** + * @brief Interrupt Valid Status on line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_gpio15(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_GPIO15_MSK) == EXTI_IVS_GPIO15_POS); +} + +/** + * @brief Interrupt Valid Status on line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_cmp1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_CMP1_MSK) == EXTI_IVS_CMP1_POS); +} + +/** + * @brief Interrupt Valid Status on line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_cmp2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_CMP2_MSK) == EXTI_IVS_CMP2_POS); +} + + +/** + * @brief Interrupt Valid Status on line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_pvd0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_PVD0_MSK) == EXTI_IVS_PVD0_POS); +} + +/** + * @brief Interrupt Valid Status on line 21 + * @param exti EXTI Instance + * @retval None + */ + +__STATIC_INLINE uint32_t md_exti_is_enable_ivs_wakeup(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->IVS, EXTI_IVS_WAKEUP_MSK) == EXTI_IVS_WAKEUP_POS); +} + + +/** + * @} MD_EXTI_PF_IVS + */ + +/** @defgroup MD_EXTI_PF_IFM EXTI Interrupt Flag Masked Status Register + * @{ + */ + +/** + * @brief Check if Interrupt Flag Masked Status on line is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->IFM)); +} + + +/** + * @brief Check if Interrupt Flag Masked Status on line 0 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio0(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO0_MSK) == EXTI_IFM_GPIO0_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 1 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio1(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO1_MSK) == EXTI_IFM_GPIO1_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 2 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio2(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO2_MSK) == EXTI_IFM_GPIO2_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 3 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio3(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO3_MSK) == EXTI_IFM_GPIO3_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 4 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio4(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO4_MSK) == EXTI_IFM_GPIO4_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 5 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio5(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO5_MSK) == EXTI_IFM_GPIO5_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 6 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio6(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO6_MSK) == EXTI_IFM_GPIO6_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 7 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio7(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO7_MSK) == EXTI_IFM_GPIO7_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 8 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio8(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO8_MSK) == EXTI_IFM_GPIO8_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 9 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio9(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO9_MSK) == EXTI_IFM_GPIO9_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 10 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio10(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO10_MSK) == EXTI_IFM_GPIO10_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 11 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio11(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO11_MSK) == EXTI_IFM_GPIO11_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 12 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio12(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO12_MSK) == EXTI_IFM_GPIO12_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 13 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio13(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO13_MSK) == EXTI_IFM_GPIO13_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 14 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio14(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO14_MSK) == EXTI_IFM_GPIO14_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 15 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_gpio15(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_GPIO15_MSK) == EXTI_IFM_GPIO15_POS); +} + + +/** + * @brief Check if Interrupt Flag Masked Status on line 16 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_cmp1(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_CMP1_MSK) == EXTI_IFM_CMP1_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 17 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_cmp2(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_CMP2_MSK) == EXTI_IFM_CMP2_POS); +} + + +/** + * @brief Check if Interrupt Flag Masked Status on line 20 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_pvd0(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_PVD0_MSK) == EXTI_IFM_PVD0_POS); +} + +/** + * @brief Check if Interrupt Flag Masked Status on line 21 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_ifm_WAKEUP(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->IFM, EXTI_IFM_WAKEUP_MSK) == EXTI_IFM_WAKEUP_POS); +} + +/** + * @} MD_EXTI_PF_IFM + */ + +/** @defgroup MD_EXTI_PF_RIF EXTI Raw Interrupt Flag Status Register + * @{ + */ + + +/** + * @brief Check if Raw interrupt flag Status on line is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->RIF)); +} + + +/** + * @brief Check if Raw interrupt flag Status on line 0 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio0(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO0_MSK) == EXTI_RIF_GPIO0_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 1 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio1(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO1_MSK) == EXTI_RIF_GPIO1_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 2 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio2(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO2_MSK) == EXTI_RIF_GPIO2_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 3 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio3(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO3_MSK) == EXTI_RIF_GPIO3_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 4 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio4(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO4_MSK) == EXTI_RIF_GPIO4_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 5 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio5(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO5_MSK) == EXTI_RIF_GPIO5_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 6 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio6(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO6_MSK) == EXTI_RIF_GPIO6_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 7 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio7(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO7_MSK) == EXTI_RIF_GPIO7_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 8 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio8(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO8_MSK) == EXTI_RIF_GPIO8_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 9 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio9(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO9_MSK) == EXTI_RIF_GPIO9_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 10 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio10(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO10_MSK) == EXTI_RIF_GPIO10_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 11 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio11(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO11_MSK) == EXTI_RIF_GPIO11_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 12 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio12(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO12_MSK) == EXTI_RIF_GPIO12_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 13 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio13(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO13_MSK) == EXTI_RIF_GPIO13_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 14 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio14(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO14_MSK) == EXTI_RIF_GPIO14_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 15 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_gpio15(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_GPIO15_MSK) == EXTI_RIF_GPIO15_POS); +} + + +/** + * @brief Check if Raw interrupt flag Status on line 16 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_cmp1(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_CMP1_MSK) == EXTI_RIF_CMP1_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 17 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_cmp2(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_CMP2_MSK) == EXTI_RIF_CMP2_POS); +} + + +/** + * @brief Check if Raw interrupt flag Status on line 20 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_pvd0(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_PVD0_MSK) == EXTI_RIF_PVD0_POS); +} + +/** + * @brief Check if Raw interrupt flag Status on line 21 is actived + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_exti_is_active_flag_rif_WAKEUP(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_BIT(exti->RIF, EXTI_RIF_WAKEUP_MSK) == EXTI_RIF_WAKEUP_POS); +} + + +/** + * @} MD_EXTI_PF_RIF + */ + + + + +/** + * @} MD_EXTI_PF_INTERRUNPT_MANAGEMENT + */ + + + + + + +/** @defgroup MD_EXTI_PF_DEBOUNCE_SETTING EXTI Debounce Management + * @{ + */ +/** + * @brief Set debounce enable bit of line + * @param exti EXTI Instance + * @param value The value write in EXTI->DB + * @retval None + */ +__STATIC_INLINE void md_spi_set_exti_db(EXTI_TypeDef *exti, uint32_t value) +{ + WRITE_REG(exti->DB, value); +} + +/** + * @brief Get debounce enable bit of line + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_get_exti_db(EXTI_TypeDef *exti) +{ + return (uint32_t)(READ_REG(exti->DB)); +} + +/** + * @brief Enable debounce enable bit of line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO0_MSK); +} + +/** + * @brief Disable debounce enable bit of line 0 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO0_MSK); +} + +/** + * @brief Check if debounce enable bit of line 0 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO0_MSK) == (EXTI_DB_GPIO0_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO1_MSK); +} + +/** + * @brief Disable debounce enable bit of line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO1_MSK); +} + +/** + * @brief Check if debounce enable bit of line 1 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO1_MSK) == (EXTI_DB_GPIO1_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO2_MSK); +} + +/** + * @brief Disable debounce enable bit of line 2 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO2_MSK); +} + +/** + * @brief Check if debounce enable bit of line 2 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO2_MSK) == (EXTI_DB_GPIO2_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio3(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO3_MSK); +} + +/** + * @brief Disable debounce enable bit of line 3 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio3(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO3_MSK); +} + +/** + * @brief Check if debounce enable bit of line 3 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio3(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO3_MSK) == (EXTI_DB_GPIO3_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio4(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO4_MSK); +} + +/** + * @brief Disable debounce enable bit of line 4 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio4(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO4_MSK); +} + +/** + * @brief Check if debounce enable bit of line 4 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio4(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO4_MSK) == (EXTI_DB_GPIO4_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio5(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO5_MSK); +} + +/** + * @brief Disable debounce enable bit of line 5 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio5(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO5_MSK); +} + +/** + * @brief Check if debounce enable bit of line 5 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio5(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO5_MSK) == (EXTI_DB_GPIO5_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio6(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO6_MSK); +} + +/** + * @brief Disable debounce enable bit of line 6 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio6(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO6_MSK); +} + +/** + * @brief Check if debounce enable bit of line 6 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio6(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO6_MSK) == (EXTI_DB_GPIO6_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio7(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO7_MSK); +} + +/** + * @brief Disable debounce enable bit of line 7 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio7(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO7_MSK); +} + +/** + * @brief Check if debounce enable bit of line 7 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio7(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO7_MSK) == (EXTI_DB_GPIO7_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio8(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO8_MSK); +} + +/** + * @brief Disable debounce enable bit of line 8 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio8(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO1_MSK); +} + +/** + * @brief Check if debounce enable bit of line 8 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio8(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO8_MSK) == (EXTI_DB_GPIO8_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio9(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO9_MSK); +} + +/** + * @brief Disable debounce enable bit of line 9 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio9(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO9_MSK); +} + +/** + * @brief Check if debounce enable bit of line 9 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio9(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO9_MSK) == (EXTI_DB_GPIO9_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio10(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO10_MSK); +} + +/** + * @brief Disable debounce enable bit of line 10 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio10(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO10_MSK); +} + +/** + * @brief Check if debounce enable bit of line 10 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio10(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO10_MSK) == (EXTI_DB_GPIO10_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio11(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO11_MSK); +} + +/** + * @brief Disable debounce enable bit of line 11 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio11(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO11_MSK); +} + +/** + * @brief Check if debounce enable bit of line 11 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio11(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO11_MSK) == (EXTI_DB_GPIO11_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio12(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO12_MSK); +} + +/** + * @brief Disable debounce enable bit of line 12 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio12(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO12_MSK); +} + +/** + * @brief Check if debounce enable bit of line 12 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio12(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO12_MSK) == (EXTI_DB_GPIO12_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio13(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO13_MSK); +} + +/** + * @brief Disable debounce enable bit of line 13 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio13(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO13_MSK); +} + +/** + * @brief Check if debounce enable bit of line 13 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio13(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO13_MSK) == (EXTI_DB_GPIO13_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio14(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO14_MSK); +} + +/** + * @brief Disable debounce enable bit of line 14 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio14(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO14_MSK); +} + +/** + * @brief Check if debounce enable bit of line 14 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio14(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO14_MSK) == (EXTI_DB_GPIO14_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 1 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_gpio15(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_GPIO15_MSK); +} + +/** + * @brief Disable debounce enable bit of line 15 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_gpio15(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_GPIO15_MSK); +} + +/** + * @brief Check if debounce enable bit of line 15 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_gpio15(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_GPIO15_MSK) == (EXTI_DB_GPIO15_MSK)); +} + + +/** + * @brief Enable debounce enable bit of line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_cmp1(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_CMP1_MSK); +} + +/** + * @brief Disable debounce enable bit of line 16 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_cmp1(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_CMP1_MSK); +} + +/** + * @brief Check if debounce enable bit of line 16 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_cmp1(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_CMP1_MSK) == (EXTI_DB_CMP1_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_cmp2(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_CMP2_MSK); +} + +/** + * @brief Disable debounce enable bit of line 17 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_cmp2(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_CMP2_MSK); +} + +/** + * @brief Check if debounce enable bit of line 17 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_cmp2(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_CMP2_MSK) == (EXTI_DB_CMP2_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_pvd0(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_PVD0_MSK); +} + +/** + * @brief Disable debounce enable bit of line 20 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_pvd0(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_PVD0_MSK); +} + +/** + * @brief Check if debounce enable bit of line 20 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_pvd0(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_PVD0_MSK) == (EXTI_DB_PVD0_MSK)); +} + +/** + * @brief Enable debounce enable bit of line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_enable_db_wakeup(EXTI_TypeDef *exti) +{ + SET_BIT(exti->DB, EXTI_DB_WAKEUP_MSK); +} + +/** + * @brief Disable debounce enable bit of line 21 + * @param exti EXTI Instance + * @retval None + */ +__STATIC_INLINE void md_exti_disable_db_wakeup(EXTI_TypeDef *exti) +{ + CLEAR_BIT(exti->DB, EXTI_DB_WAKEUP_MSK); +} + +/** + * @brief Check if debounce enable bit of line 21 is enabled + * @param exti EXTI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_exti_is_enable_db_wakeup(EXTI_TypeDef *exti) +{ + return (READ_BIT(exti->DB, EXTI_DB_WAKEUP_MSK) == (EXTI_DB_WAKEUP_MSK)); +} + +/** + * @brief Set Debounce counter + * @param exti EXTI Port + * @param dbcnt This bit can be one of following valus: + * @arg Max Value 7 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_exti_set_dbcon_dbcnt(EXTI_TypeDef *exti, uint32_t dbcnt) +{ + MODIFY_REG(exti->DBCON, EXTI_DBCON_DBCNT_MSK, (dbcnt<DBCON, EXTI_DBCON_DBCNT_MSK)>>EXTI_DBCON_DBCNT_POSS); +} + +/** + * @brief Set Debounce prescale + * @param exti EXTI Port + * @param prescale This bit can be one of following valus: + * @arg Max Value 255 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_exti_set_dbcon_dbpre(EXTI_TypeDef *exti, uint32_t prescale) +{ + MODIFY_REG(exti->DBCON, EXTI_DBCON_DBPRE_MSK, (prescale<DBCON, EXTI_DBCON_DBPRE_MSK)>>EXTI_DBCON_DBPRE_POSS); +} + + +/** + * @} MD_EXTI_PF_DEBOUNCE_SETTING + */ + + + + + + +/** + * @} MD_EXTI_Public_Macros + */ + + + + +/* Public functions -----------------------------------------------------------*/ + + + +/** + * @} EXTI + */ + +#endif + + + +/** + * @} Micro_Driver + */ + +#endif + +#ifdef __cplusplus +} +#endif + + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_fc.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_fc.h new file mode 100644 index 0000000000..a7d85653bd --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_fc.h @@ -0,0 +1,832 @@ +/** + ****************************************************************************** + * @file md_FC.h + * @brief ES32F0271 FC HEAD File. + * + * @version V1.00.01 + * @date 11/20/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_FC_H__ +#define __MD_FC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_fc.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (FC) + +/** @defgroup FC FC + * @brief FC micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ +/** @defgroup MD_FC_Public_Types FC Public Types + * @{ + */ + +/** + * @brief MD FC Parameter Structure definition + */ +typedef struct +{ + uint32_t SAddr; /*!< Specifies the FC sector address to be erased. + This parameter should be aligned with 0x400*/ + + uint32_t SAddrC; /*!< Specifies the complement of FC sector address to be erased. + This parameter should be the complement of FC page address*/ + + uint16_t BCnt; /*!< Specifies the control byte count. + For program, this parameter should be aligned with 8 and smaller than 0x400 + For read, this parameter should be aligned with 4*/ + + uint32_t *pU32Buf; /*!< Specifies the uint32_t data buffer to program. + This parameter should be the pointer to uint32_t*/ + +} md_fc_ControlTypeDef; + +/** + * @brief MD FC Update Protect Level Structure definition + */ +typedef struct +{ + uint32_t UpdateL; /*!< Specifies the protect page bit mapping low byte (page 31~0) (0=protect, 1=unprotect). + This parameter can be any value between 0~65535*/ + + uint32_t UpdateH; /*!< Specifies the protect page bit mapping high byte (page 63~32) (0=protect, 1=unprotect). + This parameter can be any value between 0~65535*/ + + uint32_t ClearL; /*!< Specifies the reserve page bit mapping low byte (page 31~0) (0=reserve, 1=erase). + This parameter can be any value between 0~65535*/ + + uint32_t ClearH; /*!< Specifies the reserve page bit mapping high byte (page 63~32) (0=reserve, 1=erase). + This parameter can be any value between 0~65535*/ + +} md_fc_UpdProtTypeDef; + +/** + * @} MD_FC_Public_Types + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_FC_Public_Constants FC Public Constants + * @{ + */ + +#define MD_FC_PC_EF_MPAGESZ (0x00000400UL) /** @brief Select main page size */ +#define MD_FC_PC_EF_IPAGESZ (0x00000400UL) /** @brief Select information page size */ +#define MD_FC_PC_EF_MERASEID (0xA5A5AA55UL) /** @brief Select main erase ID */ + +#define MD_FC_PC_CMD_PROG_EFLASH (0xF0) /** @brief Program EFlash */ +#define MD_FC_PC_CMD_SECTOR_ERASE (0xF1) /** @brief Sector Erase */ +#define MD_FC_PC_CMD_MACRO_ERASE (0xF2) /** @brief Macro Erase */ +#define MD_FC_PC_CMD_UPDATE_LV1_PROTECT (0xF3) /** @brief Update Lv1 Protect */ +#define MD_FC_PC_CMD_UPDATE_LV2_PROTECT (0xF4) /** @brief Update Lv2 Protect */ +#define MD_FC_PC_CMD_OPTION_BYTE_ERASE (0xF5) /** @brief Option Byte Erase(Only for ISP) */ + +#define MD_FC_PC_SREMAP_MAIN (0x00) /** @brief Main Flash memory mapped at 0x0000 0000 */ +#define MD_FC_PC_SREMAP_SYSTEM (0x01) /** @brief System Flash memory mapped at 0x0000 0000 */ +#define MD_FC_PC_SREMAP_SRAM (0x02) /** @brief SRAM mapped at 0x0000 0000 */ + +/** + * @} MD_FC_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_FC_Public_Macros FC Public Macros + * @{ + */ + +/** @defgroup MD_FC_PM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in FC register + * @param __INSTANCE__ FC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define MD_FC_WRITEREG(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in FC register + * @param __INSTANCE__ FC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define MD_FC_READREG(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + +/** + * @brief Modify value in FC register + * @param __INSTANCE__ FC Instance + * @param __REG__ Register to be written + * @param __MASK__ Mask value to be written in the register + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define MD_FC_MODIFYREG(__INSTANCE__, __REG__, __MASK__, __VALUE__) MODIFY_REG(__INSTANCE__->__REG__, __MASK__, (__VALUE__)) + +/** + * @brief Set bit value in FC register + * @param __INSTANCE__ FC Instance + * @param __REG__ Register to be written + * @param __MASK__ Mask value to be set in the register + * @retval None + */ +#define MD_FC_SET_BIT(__INSTANCE__, __REG__, __MASK__) SET_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @brief Clear bit value in FC register + * @param __INSTANCE__ FC Instance + * @param __REG__ Register to be written + * @param __MASK__ Mask value to be cleared in the register + * @retval None + */ +#define MD_FC_CLEAR_BIT(__INSTANCE__, __REG__, __MASK__) CLEAR_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @brief Read bit value in FC register + * @param __INSTANCE__ FC Instance + * @param __REG__ Register to be read + * @param __MASK__ Mask value to be read in the register + * @retval Register bit value + */ +#define MD_FC_READBIT(__INSTANCE__, __REG__, __MASK__) READ_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @} MD_FC_PM_WRITE_READ + */ + +/** @defgroup MD_FC_Macro_Drivers FC Public Macro Drivers + * @{ + */ + +/** + * @brief Set FC CMD + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_cmd(uint32_t U32) +{ + MD_FC_WRITEREG(FC, CMD, U32); +} + +/** + * @brief Get FC CMD + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_cmd(void) +{ + return (MD_FC_READREG(FC, CMD)); +} + +/** + * @brief Set FC CMD Flash Command + * @note After procedure is finished, Flash command will be cleaned by itself + * @param @arg @ref MD_FC_PC_CMD_PROG_EFLASH(0xF0) : Program EFlash + * @arg @ref MD_FC_PC_CMD_SECTOR_ERASE(0xF1) : Sector Erase + * @arg @ref MD_FC_PC_CMD_MACRO_ERASE(0xF2) : Macro Erase + * @arg @ref MD_FC_PC_CMD_UPDATE_LV1_PROTECT(0xF3) : Update Lv1 Protect + * @arg @ref MD_FC_PC_CMD_UPDATE_LV2_PROTECT(0xF4) : Update Lv2 Protect + * @arg @ref MD_FC_PC_CMD_OPTION_BYTE_ERASE(0xF5) : Option Byte Erase(Only for ISP) + * @arg Else : Reserved + * @retval None + */ +__STATIC_INLINE void md_fc_set_fc_cmd(uint32_t Cmd) +{ + MD_FC_MODIFYREG(FC, CMD, FC_CMD_FC_CMD_MSK, (Cmd<>FC_CMD_FC_CMD_POSS); +} + +/** + * @brief Set FC PA + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_pa(uint32_t U32) +{ + MD_FC_WRITEREG(FC, PA, U32); +} + +/** + * @brief Get FC PA + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_pa(void) +{ + return (MD_FC_READREG(FC, PA)); +} + +/** + * @brief Set FC Program Counter + * @note Provide maximum 128 times continuous program + * @note Meanwhile user needs to fill out FC_PLD, FC_PHD and FC_CMD only + * @param @arg Max Value 0x7f + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_pa_pcnt(uint32_t PCnt) +{ + MD_FC_MODIFYREG(FC, PA, FC_PA_PCNT_MSK, (((PCnt>>3)-1)<>FC_PA_PCNT_POSS); +} + +/** + * @brief Enable FC Information Block + * @note User can program/erase Info. Block page 7 when Flash protect is disable + * @param None + * @retval None + */ +__STATIC_INLINE void md_fc_enable_pa_ifren(void) +{ + MD_FC_SET_BIT(FC, PA, FC_PA_IFREN_MSK); +} + +/** + * @brief Disable FC Information Block + * @param None + * @retval None + */ +__STATIC_INLINE void md_fc_disble_pa_ifren(void) +{ + MD_FC_CLEAR_BIT(FC, PA, FC_PA_IFREN_MSK); +} + +/** + * @brief Is FC Information Block Enabled + * @param None + * @retval The retval can be one of the following values: + * @arg 0x1 : Enable + * @arg 0x0 : Disable + */ +__STATIC_INLINE uint8_t md_fc_is_enabled_pa_ifren(void) +{ + return (MD_FC_READBIT(FC, PA, FC_PA_IFREN_MSK)>>FC_PA_IFREN_POS); +} + +/** + * @brief Set FC Program/Erase Address + * @note Program : PROG_ADDR[15:3] is double word address + * @note Sector Erase : PROG_ADDR[15:10] is page address, and PROG_ADDR[9:0] dont care + * @note Macro Erase : PROG_ADDR[15:0] dont care + * @param @arg Max Value 0xffc0 + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_pa_prog_addr(uint32_t PAddr) +{ + MD_FC_MODIFYREG(FC, PA, FC_PA_PROG_ADDR_MSK, (PAddr<>FC_PA_PROG_ADDR_POSS); +} + +/** + * @brief Set FC Program Low Data + * @note Eflash supports 64 bits data program, this register provides Low 32 bits data + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_pld(uint32_t U32) +{ + MD_FC_WRITEREG(FC, PLD, U32); +} + +/** + * @brief Get FC Program Low Data + * @note Eflash supports 64 bits data program, this register provides Low 32 bits data + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_pld(void) +{ + return (MD_FC_READREG(FC, PLD)); +} + +/** + * @brief Set FC Program High Data + * @note Eflash supports 64 bits data program, this register provides high 32 bits data + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_phd(uint32_t U32) +{ + MD_FC_WRITEREG(FC, PHD, U32); +} + +/** + * @brief Get FC Program High Data + * @note Eflash supports 64 bits data program, this register provides high 32 bits data + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_phd(void) +{ + return (MD_FC_READREG(FC, PHD)); +} + +/** + * @brief Set FC CON + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_con(uint32_t U32) +{ + MD_FC_WRITEREG(FC, CON, U32); +} + +/** + * @brief Get FC CON + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_con(void) +{ + return (MD_FC_READREG(FC, CON)); +} + +/** + * @brief Enable FC Control Sleep + * @note When receive sleep or deep sleep from CPU, controller will mask Eflash control signal when this option is selected. + * @param None + * @retval None + */ +__STATIC_INLINE void md_fc_enable_con_sleep(void) +{ + MD_FC_SET_BIT(FC, CON, FC_CON_SLEEP_MSK); +} + +/** + * @brief Disable FC Control Sleep + * @note When receive sleep or deep sleep from CPU, controller will mask Eflash control signal when this option is selected. + * @param None + * @retval None + */ +__STATIC_INLINE void md_fc_disable_con_sleep(void) +{ + MD_FC_CLEAR_BIT(FC, CON, FC_CON_SLEEP_MSK); +} + +/** + * @brief Is FC Control Sleep Enabled + * @note When receive sleep or deep sleep from CPU, controller will mask Eflash control signal when this option is selected. + * @param None + * @retval The retval can be one of the following values: + * 0x0:Disable Flash sleep mask function + * 0x1:Enable Flash sleep mask function + */ +__STATIC_INLINE uint8_t md_fc_is_enabled_con_sleep(void) +{ + return (MD_FC_READBIT(FC, CON, FC_CON_SLEEP_MSK)>>FC_CON_SLEEP_POS); +} + +/** + * @brief Enable FC Control PreFetch + * @note This function allow user to pre-fetch 64 bits data from Eflash when the last 32bits data in data buffer has been read + * @param None + * @retval None + */ +__STATIC_INLINE void md_fc_enable_con_pfen(void) +{ + MD_FC_SET_BIT(FC, CON, FC_CON_PFEN_MSK); +} + +/** + * @brief Disable FC Control PreFetch + * @note This function allow user to pre-fetch 64 bits data from Eflash when the last 32bits data in data buffer has been read + * @param None + * @retval None + */ +__STATIC_INLINE void md_fc_disable_con_pfen(void) +{ + MD_FC_CLEAR_BIT(FC, CON, FC_CON_PFEN_MSK); +} + +/** + * @brief Is FC Control PreFetch Enabled + * @note This function allow user to pre-fetch 64 bits data from Eflash when the last 32bits data in data buffer has been read + * @param None + * @retval The retval can be one of the following values: + * 0x0:Disable pre-fetch function + * 0x1:Enable pre-fetch function + */ +__STATIC_INLINE uint8_t md_fc_is_enabled_con_pfen(void) +{ + return (MD_FC_READBIT(FC, CON, FC_CON_PFEN_MSK)>>FC_CON_PFEN_POS); +} + +/** + * @brief Set FC Control Wait Cycle + * @note Eflash supports 64 bits data program, this register provides high 32 bits data + * @param @arg Max Value 0x3 + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_con_wait(uint32_t Wait) +{ + MD_FC_MODIFYREG(FC, CON, FC_CON_WAIT_MSK, (Wait<>FC_CON_WAIT_POSS); +} + +/** + * @brief Get FC STAT + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_sta(void) +{ + return (MD_FC_READREG(FC, STAT)); +} + +/** + * @brief Get FC Status Option Valid + * @note This bit is set when Option Byte Data is valid + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 : Option Byte Data is valid + * @arg Min Value 0x0 : Option Byte Data is invalid + */ +__STATIC_INLINE uint8_t md_fc_get_stat_opvd(void) +{ + return (MD_FC_READBIT(FC, STAT, FC_STAT_OPVD_MSK)>>FC_STAT_OPVD_POS); +} + +/** + * @brief Get FC Status Main Unprotect Level2 Status + * @note This bit is set when Flash main block is unprotect + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 : Lv2 Protect Function is disabled + * @arg Min Value 0x0 : Lv2 Protect Function is enabled + */ +__STATIC_INLINE uint8_t md_fc_get_stat_munp2(void) +{ + return (MD_FC_READBIT(FC, STAT, FC_STAT_MUNP2_MSK)>>FC_STAT_MUNP2_POS); +} + +/** + * @brief Get FC Status Main Unprotect Level1 Status + * @note This bit is set when Flash main block is unprotect + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 : Lv1 Protect Function is disabled + * @arg Min Value 0x0 : Lv1 Protect Function is enabled + */ +__STATIC_INLINE uint8_t md_fc_get_stat_munp1(void) +{ + return (MD_FC_READBIT(FC, STAT, FC_STAT_MUNP1_MSK)>>FC_STAT_MUNP1_POS); +} + +/** + * @brief Set FC Protect Update Low Data + * @note Update main block Lv2 Protect Page 0 ~ Page 31 + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_upl(uint32_t U32) +{ + MD_FC_WRITEREG(FC, UPL, U32); +} + +/** + * @brief Get FC Protect Update Low Data + * @note Update main block Lv2 Protect Page 0 ~ Page 31 + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_upl(void) +{ + return (MD_FC_READREG(FC, UPL)); +} + +/** + * @brief Set FC Protect Update High Data + * @note Update main block Lv2 Protect Page 63 ~ Page 32 + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_fc_set_uph(uint32_t U32) +{ + MD_FC_WRITEREG(FC, UPH, U32); +} + +/** + * @brief Get FC Protect Update High Data + * @note Update main block Lv2 Protect Page 63 ~ Page 32 + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_uph(void) +{ + return (MD_FC_READREG(FC, UPH)); +} + +/** + * @brief Get FC OP_TRIM + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_op_trim(void) +{ + return (MD_FC_READREG(FC, OP_TRIM)); +} + +/** + * @brief Get FC OP_TRIM BangGap trim valid + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xff + * @arg Min Value 0x0 + * @arg Value 0xa5 BG Trim is Valid + */ +__STATIC_INLINE uint32_t md_fc_get_op_trim_bgtrimvd(void) +{ + return (MD_FC_READBIT(FC, OP_TRIM, FC_OP_TRIM_BGTRIMVD_MSK)>>FC_OP_TRIM_BGTRIMVD_POSS); +} + +/** + * @brief Get FC Trim BangGap trim value + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_op_trim_bgtrim(void) +{ + return (MD_FC_READBIT(FC, OP_TRIM, FC_OP_TRIM_BGTRIM_MSK)>>FC_OP_TRIM_BGTRIM_POSS); +} + +/** + * @brief Get FC Trim HRC calibration value valid + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xff + * @arg Min Value 0x0 + * @arg Value 0xa5 BG Trim is Valid + */ +__STATIC_INLINE uint32_t md_fc_get_op_trim_hrctrimvd(void) +{ + return (MD_FC_READBIT(FC, OP_TRIM, FC_OP_TRIM_HRCTRIMVD_MSK)>>FC_OP_TRIM_HRCTRIMVD_POSS); +} + +/** + * @brief Get FC Trim HRC calibration value + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_op_trim_hrctrim(void) +{ + return (MD_FC_READBIT(FC, OP_TRIM, FC_OP_TRIM_HRCTRIM_MSK)>>FC_OP_TRIM_HRCTRIM_POSS); +} + +/** + * @brief Get FC Lv2 Protect Low 32 bits + * @note Lv2 Protect Page 0 ~ Page 31.The Bit is set to 0 when the page is protected + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_op_prt2l(void) +{ + return (MD_FC_READREG(FC, OP_PRT2L)); +} + +/** + * @brief Get FC Lv2 Protect High 32 bits + * @note Lv2 Protect Page 63 ~ Page 32.The Bit is set to 0 when the page is protected + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_op_prt2h(void) +{ + return (MD_FC_READREG(FC, OP_PRT2H)); +} + +/** + * @brief Get FC Lv1 Protect Low 32 bits + * @note Lv1 Protect Page 0 ~ Page 31.The Bit is set to 0 when the page is protected + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_op_prt1l(void) +{ + return (MD_FC_READREG(FC, OP_PRT1L)); +} + +/** + * @brief Get FC Lv1 Protect High 32 bits + * @note Lv1 Protect Page 63 ~ Page 32.The Bit is set to 0 when the page is protected + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_op_prt1h(void) +{ + return (MD_FC_READREG(FC, OP_PRT1H)); +} + +/** + * @brief Get FC OP_REMAP + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_fc_get_op_remap(void) +{ + return (MD_FC_READREG(FC, OP_REMAP)); +} + +/** + * @brief Get FC Hardware Remap Option + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xff + * @arg Min Value 0x0 + * @arg Value 0xa5 skip boot loader + */ +__STATIC_INLINE uint8_t md_fc_get_op_remap_hremap(void) +{ + return (MD_FC_READBIT(FC, OP_REMAP, FC_OP_REMAP_HREMAP_MSK)>>FC_OP_REMAP_HREMAP_POSS); +} + +/** + * @brief Get FC Software Remap Option + * @param None + * @retval The retval can be one of the following values: + * @arg @ref MD_FC_PC_SREMAP_MAIN(0x0) : Main Flash memory mapped at 0x0000 0000 + * @arg @ref MD_FC_PC_SREMAP_SYSTEM(0x1) : System Flash memory mapped at 0x0000 0000 + * @arg @ref MD_FC_PC_SREMAP_SRAM(0x2) : SRAM mapped at 0x0000 0000 + * @arg Else : Reserved + */ +__STATIC_INLINE uint8_t md_fc_get_op_remap_sremap(void) +{ + return (MD_FC_READBIT(FC, OP_REMAP, FC_OP_REMAP_SREMAP_MSK)>>FC_OP_REMAP_SREMAP_POSS); +} + +/** + * @brief Get FC Software Remap Base Address Settng Data + * @note If set 0x1, it means second 4k Byte, If set 0x2, it means third 4k Byte, and so on + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xf + * @arg Min Value 0x0 + * @note This value is invalid if the value in SREMAP field is 0x3 + */ +__STATIC_INLINE uint8_t md_fc_get_op_remap_sefbase(void) +{ + return (MD_FC_READBIT(FC, OP_REMAP, FC_OP_REMAP_SEFBASE_MSK)>>FC_OP_REMAP_SEFBASE_POSS); +} + +/** + * @} MD_FC_Macro_Drivers + */ + +/** + * @} MD_FC_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_FC_Public_Functions FC Public Functions + * @{ + */ +ErrorStatus md_fc_merase(uint32_t MEraseID); +ErrorStatus md_fc_serase(md_fc_ControlTypeDef *pSErasePara); +ErrorStatus md_fc_program(md_fc_ControlTypeDef *pProgramPara); +ErrorStatus md_fc_read(md_fc_ControlTypeDef *pReadPara); +ErrorStatus md_fc_updprotl1(md_fc_UpdProtTypeDef *pUpdPL1Para); +ErrorStatus md_fc_updprotl2(md_fc_UpdProtTypeDef *pUpdPL2Para); +ErrorStatus md_fc_updremap(uint8_t UpdRemap); +/** + * @} MD_FC_Public_Functions + */ + +#endif + +/** + * @} FC + */ + +/** + * @} Micro_Driver + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ + diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_gpio.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_gpio.h new file mode 100644 index 0000000000..a096fa7a01 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_gpio.h @@ -0,0 +1,2873 @@ +/** + ****************************************************************************** + * @file md_GPIO.h + * @brief ES32F0271 GPIO HEAD File. + * + * @version V1.00.02 + * @date 30/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_GPIO_H__ +#define __MD_GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_gpio.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) + +/** @defgroup GPIO GPIO + * @brief GPIO micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ +/** @defgroup MD_GPIO_PT_INIT GPIO Public Init structures + * @{ + */ + +/** + * @brief MD GPIO Init Structure definition + */ +typedef struct +{ + uint32_t Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref MD_GPIO_PC_PIN */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref MD_GPIO_PC_MODE. + + GPIO HW configuration can be modified afterwards using unitary function @ref md_gpio_set_mode().*/ + + uint32_t OutputType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref MD_GPIO_PC_OT. + + GPIO HW configuration can be modified afterwards using unitary function @ref md_gpio_set_output_type().*/ + + + uint32_t Pull; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref MD_GPIO_PC_PULL. + + GPIO HW configuration can be modified afterwards using unitary function @ref md_gpio_set_pull().*/ + + uint32_t OutDrive; /*!< Specifies the output driving current for the selected pins. + This parameter can be a value of @ref MD_GPIO_PC_DS. + + GPIO HW configuration can be modified afterwards using unitary function @ref md_gpio_get_ds().*/ + + uint32_t Function; /*!< Specifies the Peripheral to be connected to the selected pins. + This parameter can be a value of @ref MD_GPIO_PC_FUNCTION. + + GPIO HW configuration can be modified afterwards using unitary function @ref md_gpio_set_function0_7() and md_gpio_set_function8_15().*/ +} md_gpio_inittypedef; + +/** + * @} MD_GPIO_PT_INIT + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_GPIO_Public_Constants GPIO Public Constants + * @{ + */ + +/** @defgroup MD_GPIO_PC_PIN PIN + * @{ + */ +#define MD_GPIO_PIN_0 (0X1<<0) /*!< Select pin 0 */ +#define MD_GPIO_PIN_1 (0X1<<1) /*!< Select pin 1 */ +#define MD_GPIO_PIN_2 (0X1<<2) /*!< Select pin 2 */ +#define MD_GPIO_PIN_3 (0X1<<3) /*!< Select pin 3 */ +#define MD_GPIO_PIN_4 (0X1<<4) /*!< Select pin 4 */ +#define MD_GPIO_PIN_5 (0X1<<5) /*!< Select pin 5 */ +#define MD_GPIO_PIN_6 (0X1<<6) /*!< Select pin 6 */ +#define MD_GPIO_PIN_7 (0X1<<7) /*!< Select pin 7 */ +#define MD_GPIO_PIN_8 (0X1<<8) /*!< Select pin 8 */ +#define MD_GPIO_PIN_9 (0X1<<9) /*!< Select pin 9 */ +#define MD_GPIO_PIN_10 (0X1<<10) /*!< Select pin 10 */ +#define MD_GPIO_PIN_11 (0X1<<11) /*!< Select pin 11 */ +#define MD_GPIO_PIN_12 (0X1<<12) /*!< Select pin 12 */ +#define MD_GPIO_PIN_13 (0X1<<13) /*!< Select pin 13 */ +#define MD_GPIO_PIN_14 (0X1<<14) /*!< Select pin 14 */ +#define MD_GPIO_PIN_15 (0X1<<15) /*!< Select pin 15 */ +#define MD_GPIO_PIN_ALL (MD_GPIO_PIN_0 | MD_GPIO_PIN_1 | MD_GPIO_PIN_2 | \ + MD_GPIO_PIN_3 | MD_GPIO_PIN_4 | MD_GPIO_PIN_5 | \ + MD_GPIO_PIN_6 | MD_GPIO_PIN_7 | MD_GPIO_PIN_8 | \ + MD_GPIO_PIN_9 | MD_GPIO_PIN_10 | MD_GPIO_PIN_11 | \ + MD_GPIO_PIN_12 | MD_GPIO_PIN_13 | MD_GPIO_PIN_14 | \ + MD_GPIO_PIN_15) /*!< Select all pins */ +/** + * @} MD_GPIO_PC_PIN + */ + +/** @defgroup MD_GPIO_PC_MODE Mode + * @{ + */ +#define MD_GPIO_MODE_INPUT (0x00000000UL) /** @brief Select input mode */ +#define MD_GPIO_MODE_OUTPUT (0X00000001UL) /** @brief Select output mode */ +#define MD_GPIO_MODE_FUNCTION (0X00000002UL) /** @brief Select function mode */ +#define MD_GPIO_MODE_ANALOG (0x00000003UL) /** @brief Select analog mode */ +/** + * @} MD_GPIO_PC_MODE + */ + +/** @defgroup MD_GPIO_PC_OT Output Type + * @{ + */ +#define MD_GPIO_OUTPUT_PUSHPULL (0x00000000U) /** @brief Select push-pull as output type */ +#define MD_GPIO_OUTPUT_OPENDRAIN (0x00000001U) /** @brief Select open-drain as output type */ +/** + * @} MD_GPIO_PC_OT + */ + +/** @defgroup MD_GPIO_PC_PULL Pull Up Pull Down + * @{ + */ +#define MD_GPIO_PULL_FLOATING (0x00000000UL) /** @brief Select I/O no pull */ +#define MD_GPIO_PULL_UP (0x00000001UL) /** @brief Select I/O pull up */ +#define MD_GPIO_PULL_DOWN (0x00000002UL) /** @brief Select I/O pull down */ +/** + * @} MD_GPIO_PC_PULL + */ + +/** @defgroup MD_GPIO_PC_DS Output driving/sinking current + * @{ + */ +#define MD_GPIO_DS_16mA (0x00000001U) /** @brief Select I/O 16mA driving/sinking current */ +#define MD_GPIO_DS_8mA (0x00000000U) /** @brief Select I/O 8mA driving/sinking current */ +/** + * @} MD_GPIO_PC_DS + */ + +/** @defgroup MD_GPIO_PC_FUNCTION Alternate Function + * @{ + */ +#define MD_GPIO_AF0 (0x00000000UL) /** @brief Select alternate function 0 */ +#define MD_GPIO_AF1 (0x00000001UL) /** @brief Select alternate function 1 */ +#define MD_GPIO_AF2 (0x00000002UL) /** @brief Select alternate function 2 */ +#define MD_GPIO_AF3 (0x00000003UL) /** @brief Select alternate function 3 */ +#define MD_GPIO_AF4 (0x00000004UL) /** @brief Select alternate function 4 */ +#define MD_GPIO_AF5 (0x00000005UL) /** @brief Select alternate function 5 */ +#define MD_GPIO_AF6 (0x00000006UL) /** @brief Select alternate function 6 */ +#define MD_GPIO_AF7 (0x00000007UL) /** @brief Select alternate function 7 */ +#define MD_GPIO_AF8 (0x00000008UL) /** @brief Select alternate function 8 */ +/** + * @} MD_GPIO_PC_FUNCTION + */ + +/** @defgroup MD_GPIO_PC_FILTER Input Filter + * @{ + */ +#define MD_GPIO_FILTER_BYPASS (0x00000000UL) /** @brief Select bypass */ +#define MD_GPIO_FILTER_GLITCH (0x00000001UL) /** @brief Select glitch free for 20ns plus */ +/** + * @} MD_GPIO_PC_FILTER + */ + +/** @defgroup MD_GPIO_PC_IST Input Schmitt Trigger + * @{ + */ +#define MD_GPIO_IST_TTL (0x00000000UL) /** @brief Select TTL IO Level */ +#define MD_GPIO_IST_CMOS (0x00000001UL) /** @brief Select CMOS IO Level */ +/** + * @} MD_GPIO_PC_IST + */ + +/** @defgroup MD_GPIO_ODATA_SEL GPIO Output Select + * @{ + */ +#define MD_GPIO_OUTPUT_LOW (0x00000000UL) /** @brief Select GPIO Output Low*/ +#define MD_GPIO_OUTPUT_HIGH (0x00000001UL) /** @brief Select GPIO Output High*/ +/** + * @} MD_GPIO_ODATA_SEL + */ + +/** + * @} MD_GPIO_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_GPIO_Public_Macros GPIO Public Macros + * @{ + */ + +/** @defgroup MD_GPIO_MOD_MOD15 MOD15 + * @brief Set MOD15 configure I/O mode bit for md_gpio_set_mod() function used + * @param mod15 This parameter can be one of the following values: + * @arg @ref MD_GPIO_MODE_INPUT + * @arg @ref MD_GPIO_MODE_OUTPUT + * @arg @ref MD_GPIO_MODE_FUNCTION + * @arg @ref MD_GPIO_MODE_ANALOG + * @{ + */ +#define md_gpio_set_mod_mod15_fun(mod15) (mod15<MOD, (mod15|mod14|mod13|mod12|mod11|mod10|mod9|mod8|mod7|mod6|mod5|mod4|mod3|mod2|mod1|mod0)); +} + + + + +/** + * @brief Configure gpio mode for a dedicated pin on dedicated port. + * @note I/O mode can be Input mode, output mode, Alternate function mode, or Analog mode. + * @note Warning: only one pin can be passed as parameter. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @param Mode This parameter can be one of the following values: + * @arg @ref MD_GPIO_MODE_INPUT + * @arg @ref MD_GPIO_MODE_OUTPUT + * @arg @ref MD_GPIO_MODE_FUNCTION + * @arg @ref MD_GPIO_MODE_ANALOG + * @retval None + */ +__STATIC_INLINE void md_gpio_set_mode(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode) +{ + MODIFY_REG(GPIOx->MOD, (GPIO_MOD_MOD0_MSK << (POSITION_VAL(Pin) * 2U)), (Mode << (POSITION_VAL(Pin) * 2U))); +} + +/** + * @brief Return gpio mode for a dedicated pin on dedicated port. + * @note I/O mode can be Input mode, output mode, Alternate function mode, or Analog mode. + * @note Warning: only one pin can be passed as parameter. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @retval Returned value can be one of the following values: + * @arg @ref MD_GPIO_MODE_INPUT + * @arg @ref MD_GPIO_MODE_OUTPUT + * @arg @ref MD_GPIO_MODE_FUNCTION + * @arg @ref MD_GPIO_MODE_ANALOG + */ +__STATIC_INLINE uint32_t md_gpio_get_mode(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->MOD, + (GPIO_MOD_MOD0_MSK << (POSITION_VAL(Pin) * 2U))) >> (POSITION_VAL(Pin) * 2U)); +} + +/** @defgroup MD_GPIO_OT_OT15 OT15 + * @brief Set OT15 output data bit for md_gpio_set_ot() function used + * @param ot15 This parameter can be one of the following values: + * @arg @ref MD_GPIO_OUTPUT_PUSHPULL + * @arg @ref MD_GPIO_OUTPUT_OPENDRAIN + * @{ + */ +#define md_gpio_set_ot_ot15_fun(ot15) (ot15<OT, (ot15|ot14|ot13|ot12|ot11|ot10|ot9|ot8|ot7|ot6|ot5|ot4|ot3|ot2|ot1|ot0)); +} + + +/** + * @brief Configure gpio output type for several pins on dedicated port. + * @note Output type as to be set when gpio pin is in output or + * alternate modes. Possible type are Push-pull or Open-drain. + * @param GPIOx GPIO Port + * @param Pin This parameter can be a combination of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @param OutputType This parameter can be one of the following values: + * @arg @ref MD_GPIO_OUTPUT_PUSHPULL + * @arg @ref MD_GPIO_OUTPUT_OPENDRAIN + * @retval None + */ +__STATIC_INLINE void md_gpio_set_output_type(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t OutputType) +{ + MODIFY_REG(GPIOx->OT, (GPIO_OT_OT0_MSK << (POSITION_VAL(Pin))), (OutputType << (POSITION_VAL(Pin)))); +} + +/** + * @brief Return gpio output type for several pins on dedicated port. + * @note Output type as to be set when gpio pin is in output or + * alternate modes. Possible type are Push-pull or Open-drain. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref MD_GPIO_OUTPUT_PUSHPULL + * @arg @ref MD_GPIO_OUTPUT_OPENDRAIN + */ +__STATIC_INLINE uint32_t md_gpio_get_output_type(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)((READ_BIT(GPIOx->OT, + (GPIO_OT_OT_MSK << (POSITION_VAL(Pin)))) >> (POSITION_VAL(Pin))) & (0x1U)); +} + + +/** @defgroup MD_GPIO_PUD_PUD15 PUD15 + * @brief Set PUD15 I/O pull-up or pull-down bit for md_gpio_set_pud() function used + * @param pud15 This parameter can be one of the following values: + * @arg @ref MD_GPIO_PULL_FLOATING + * @arg @ref MD_GPIO_PULL_UP + * @arg @ref MD_GPIO_PULL_DOWN + * @{ + */ +#define md_gpio_set_pud_pud15_fun(pud15) (pud15<PUD, (pud15|pud14|pud13|pud12|pud11|pud10|pud9|pud8|pud7|pud6|pud5|pud4|pud3|pud2|pud1|pud0)); +} + +/** + * @brief Configure gpio pull-up or pull-down for a dedicated pin on a dedicated port. + * @note Warning: only one pin can be passed as parameter. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @param Pull This parameter can be one of the following values: + * @arg @ref MD_GPIO_PULL_FLOATING + * @arg @ref MD_GPIO_PULL_UP + * @arg @ref MD_GPIO_PULL_DOWN + * @retval None + */ +__STATIC_INLINE void md_gpio_set_pull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Pull) +{ + MODIFY_REG(GPIOx->PUD, (GPIO_PUD_PUD0_MSK << (POSITION_VAL(Pin) * 2U)), (Pull << (POSITION_VAL(Pin) * 2U))); +} + +/** + * @brief Return gpio pull-up or pull-down for a dedicated pin on a dedicated port + * @note Warning: only one pin can be passed as parameter. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref MD_GPIO_PULL_FLOATING + * @arg @ref MD_GPIO_PULL_UP + * @arg @ref MD_GPIO_PULL_DOWN + */ +__STATIC_INLINE uint32_t md_gpio_get_pull(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->PUD, + (GPIO_PUD_PUD0_MSK << (POSITION_VAL(Pin) * 2U))) >> (POSITION_VAL(Pin) * 2U)); +} + + +/** @defgroup MD_GPIO_DS_DS15 DS15 + * @brief Set DS15 I/O Driving/Sinking current bit for md_gpio_set_ds() function used + * @param ds15 This parameter can be one of the following values: + * @arg @ref MD_GPIO_DS_8mA + * @arg @ref MD_GPIO_DS_16mA + * @{ + */ +#define md_gpio_set_ds_ds15_fun(ds15) (ds15<DS, (ds15|ds14|ds13|ds12|ds11|ds10|ds9|ds8|ds7|ds6|ds5|ds4|ds3|ds2|ds1|ds0)); +} + + +/** + * @brief Configure gpio output driving/sinking current a dedicated pin on a dedicated port. + * @note Warning: only one pin can be passed as parameter. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @param Odrv This parameter can be one of the following values: + * @arg @ref MD_GPIO_DS_8mA + * @arg @ref MD_GPIO_DS_16mA + * @retval None + */ +__STATIC_INLINE void md_gpio_set_ds(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Odrv) +{ + MODIFY_REG(GPIOx->DS, (GPIO_DS_DS_MSK << (POSITION_VAL(Pin))), (Odrv << (POSITION_VAL(Pin)))); +} + +/** + * @brief Return gpio output driving/sinking current a dedicated pin on a dedicated port. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref MD_GPIO_DS_8mA + * @arg @ref MD_GPIO_DS_16mA + */ +__STATIC_INLINE uint32_t md_gpio_get_ds(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->DS, + (GPIO_DS_DS_MSK << (POSITION_VAL(Pin)))) >> (POSITION_VAL(Pin))); +} + +/** @defgroup MD_GPIO_AFL_AF0 AF0 + * @brief Set AF0 Alternate function selection bit for md_gpio_set_afl() function used + * @param af0 This parameter can be one of the following values: + * @arg @ref MD_GPIO_AF0 + * @arg @ref MD_GPIO_AF1 + * @arg @ref MD_GPIO_AF2 + * @arg @ref MD_GPIO_AF3 + * @arg @ref MD_GPIO_AF4 + * @arg @ref MD_GPIO_AF5 + * @arg @ref MD_GPIO_AF6 + * @arg @ref MD_GPIO_AF7 + * @{ + */ +#define md_gpio_set_afl_af0_fun(af0) (af0<AFL, (af7|af6|af5|af4|af3|af2|af1|af0)); +} + +/** + * @brief Configure gpio alternate function of a dedicated pin from 0 to 7 for a dedicated port. + * @note Possible values are from FUNCTION0 to FUNCTION7 depending on target. + * @note Warning: only one pin can be passed as parameter. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @param Function This parameter can be one of the following values: + * @arg @ref MD_GPIO_AF0 + * @arg @ref MD_GPIO_AF1 + * @arg @ref MD_GPIO_AF2 + * @arg @ref MD_GPIO_AF3 + * @arg @ref MD_GPIO_AF4 + * @arg @ref MD_GPIO_AF5 + * @arg @ref MD_GPIO_AF6 + * @arg @ref MD_GPIO_AF7 + * @retval None + */ +__STATIC_INLINE void md_gpio_set_function0_7(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Function) +{ + MODIFY_REG(GPIOx->AFL, (GPIO_AFL_AF0_MSK << (POSITION_VAL(Pin) * 4U)), + (Function << (POSITION_VAL(Pin) * 4U))); +} + +/** + * @brief Return gpio alternate function of a dedicated pin from 0 to 7 for a dedicated port. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @retval Returned value can be one of the following values: + * @arg @ref MD_GPIO_AF0 + * @arg @ref MD_GPIO_AF1 + * @arg @ref MD_GPIO_AF2 + * @arg @ref MD_GPIO_AF3 + * @arg @ref MD_GPIO_AF4 + * @arg @ref MD_GPIO_AF5 + * @arg @ref MD_GPIO_AF6 + * @arg @ref MD_GPIO_AF7 + */ +__STATIC_INLINE uint32_t md_gpio_get_function0_7(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->AFL, + (GPIO_AFL_AF0_MSK << (POSITION_VAL(Pin) * 4U))) >> (POSITION_VAL(Pin) * 4U)); +} + + +/** @defgroup MD_GPIO_AFH_AF8 AF8 + * @brief Set AF8 Alternate function selection bit for md_gpio_set_afh() function used + * @param af8 This parameter can be one of the following values: + * @arg @ref MD_GPIO_AF0 + * @arg @ref MD_GPIO_AF1 + * @arg @ref MD_GPIO_AF2 + * @arg @ref MD_GPIO_AF3 + * @arg @ref MD_GPIO_AF4 + * @arg @ref MD_GPIO_AF5 + * @arg @ref MD_GPIO_AF6 + * @arg @ref MD_GPIO_AF7 + * @{ + */ +#define md_gpio_set_afh_af8_fun(af8) (af8<AFH, (af15|af14|af13|af12|af11|af10|af9|af8)); +} + +/** + * @brief Configure gpio alternate function of a dedicated pin from 8 to 15 for a dedicated port. + * @note Possible values are from FUNCTION0 to FUNCTION7 depending on target. + * @note Warning: only one pin can be passed as parameter. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @param Function This parameter can be one of the following values: + * @arg @ref MD_GPIO_AF0 + * @arg @ref MD_GPIO_AF1 + * @arg @ref MD_GPIO_AF2 + * @arg @ref MD_GPIO_AF3 + * @arg @ref MD_GPIO_AF4 + * @arg @ref MD_GPIO_AF5 + * @arg @ref MD_GPIO_AF6 + * @arg @ref MD_GPIO_AF7 + * @retval None + */ +__STATIC_INLINE void md_gpio_set_function8_15(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Function) +{ + MODIFY_REG(GPIOx->AFH, (GPIO_AFH_AF8_MSK << (POSITION_VAL(Pin >> 8U) * 4U)), + (Function << (POSITION_VAL(Pin >> 8U) * 4U))); +} + +/** + * @brief Return gpio alternate function of a dedicated pin from 0 to 7 for a dedicated port. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref MD_GPIO_AF0 + * @arg @ref MD_GPIO_AF1 + * @arg @ref MD_GPIO_AF2 + * @arg @ref MD_GPIO_AF3 + * @arg @ref MD_GPIO_AF4 + * @arg @ref MD_GPIO_AF5 + * @arg @ref MD_GPIO_AF6 + * @arg @ref MD_GPIO_AF7 + */ +__STATIC_INLINE uint32_t md_gpio_get_function8_15(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->AFH, + (GPIO_AFH_AF8_MSK << (POSITION_VAL(Pin >> 8U) * 4U))) >> (POSITION_VAL(Pin >> 8U) * 4U)); +} + +/** + * @brief Lock configuration of several pins for a dedicated port. + * @note When the lock sequence has been applied on a port bit, the + * value of this port bit can no longer be modified until the + * next reset. + * @note LOCK key write sequence: + * WR GPIOx_LCK = (~LCK[15:0]<<16) + LCK[15:0] + * WR GPIOx_LCK = (~LCK[15:0]<<16) + LCK[15:0] + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @arg @ref MD_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void md_gpio_set_lock(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + SET_BIT(GPIOx->LCK, PinMask); +} + +/** + * @brief Return 1 if all pins passed as parameter, of a dedicated port, are locked. else Return 0. + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @arg @ref MD_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_gpio_get_lock(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + return (READ_BIT(GPIOx->LCK, PinMask) == (PinMask)); +} + + + +/** @defgroup MD_GPIO_IST_IST15 IST15 + * @brief Set IST15 configure the input schmitt trigger level bit for md_gpio_set_ist_fun() function used + * @param ist15 This parameter can be one of the following values: + * @arg @ref MD_GPIO_IST_TTL + * @arg @ref MD_GPIO_IST_CMOS + * @{ + */ +#define md_gpio_set_ist_ist15_fun(ist15) (ist15<IST, (ist15|ist14|ist13|ist12|ist11|ist10|ist9|ist8|ist7|ist6|ist5|ist4|ist3|ist2|ist1|ist0)); +} + +/** + * @brief Configure GPIOx port Input Schmitt Trigger Register. + * @note Warning: only one pin can be passed as parameter. + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @param Iolev This parameter can be one of the following values: + * @arg @ref MD_GPIO_IST_TTL + * @arg @ref MD_GPIO_IST_CMOS + * @retval None + */ +__STATIC_INLINE void md_gpio_set_ist(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Iolev) +{ + MODIFY_REG(GPIOx->IST, (GPIO_IST_IST_MSK << (POSITION_VAL(Pin))), (Iolev << (POSITION_VAL(Pin)))); +} + +/** + * @brief Return GPIOx port Input Schmitt Trigger Register + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @retval The retval can be one of the following values: + * @arg @ref MD_GPIO_IST_TTL + * @arg @ref MD_GPIO_IST_CMOS + */ +__STATIC_INLINE uint32_t md_gpio_get_ist(GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->IST, (GPIO_IST_IST_MSK << (POSITION_VAL(Pin)))) >> (POSITION_VAL(Pin))); +} + +/** + * @brief Return full input data register value for a dedicated port. + * @param GPIOx GPIO Port + * @retval Input data register value of port + */ +__STATIC_INLINE uint32_t md_gpio_get_input_port(GPIO_TypeDef *GPIOx) +{ + return (uint32_t)(READ_REG(GPIOx->IDATA)); +} + + + + +/** @defgroup MD_GPIO_ODATA_OD15 OD15 + * @brief Set OD15 set/reset bit for md_gpio_set_bsbr() function used + * @param od15 This parameter can be one of the following values: + * @arg @ref MD_GPIO_OUTPUT_LOW + * @arg @ref MD_GPIO_OUTPUT_HIGH + * @{ + */ +#define md_gpio_set_odata_od15_fun(od15) (od15<ODATA, (od15|od14|od13|od12|od11|od10|od9|od8|od7|od6|od5|od4|od3|od2|od1|od0)); +} + + + + + +/** + * @brief Write output data register for the port. + * @param GPIOx GPIO Port + * @param PortValue Level value for each pin of the port + * @retval None + */ +__STATIC_INLINE void md_gpio_set_output_port(GPIO_TypeDef *GPIOx, uint32_t PortValue) +{ + WRITE_REG(GPIOx->ODATA, PortValue); +} + +/** + * @brief Return full output data register value for a dedicated port. + * @param GPIOx GPIO Port + * @retval Output data register value of port + */ +__STATIC_INLINE uint32_t md_gpio_get_output_port(GPIO_TypeDef *GPIOx) +{ + return (uint32_t)(READ_REG(GPIOx->ODATA)); +} + +/** + * @brief Set several pins to high level on dedicated gpio port. + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @arg @ref MD_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void md_gpio_set_pin_high(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + WRITE_REG(GPIOx->BSBR, PinMask); +} + +/** + * @brief Reset several pins to low level on dedicated gpio port. + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @arg @ref MD_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void md_gpio_set_pin_low(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + WRITE_REG(GPIOx->BSBR, (PinMask << 16)); +} + + +/** @defgroup MD_GPIO_FIR_FIR15 FIR15 + * @brief Set FIR15 configure the input signal over thought a glitch filter bit for md_gpio_set_fir() function used + * @param fir15 This parameter can be one of the following values: + * @arg @ref MD_GPIO_FILTER_BYPASS + * @arg @ref MD_GPIO_FILTER_GLITCH + * @{ + */ +#define md_gpio_set_fir_fir15_fun(fir15) (fir15<FIR, (fir15|fir14|fir13|fir12|fir11|fir10|fir9|fir8|fir7|fir6|fir5|fir4|fir3|fir2|fir1|fir0)); +} + + +/** + * @brief Write input filter register for the port. + * @note These bits are written by software to configure + * the input signal over thought a glitch filter. + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @arg @ref MD_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void md_gpio_set_filter(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + WRITE_REG(GPIOx->FIR, PinMask); +} + +/** + * @brief Return full input filter data register value for a dedicated port. + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref MD_GPIO_PIN_0 + * @arg @ref MD_GPIO_PIN_1 + * @arg @ref MD_GPIO_PIN_2 + * @arg @ref MD_GPIO_PIN_3 + * @arg @ref MD_GPIO_PIN_4 + * @arg @ref MD_GPIO_PIN_5 + * @arg @ref MD_GPIO_PIN_6 + * @arg @ref MD_GPIO_PIN_7 + * @arg @ref MD_GPIO_PIN_8 + * @arg @ref MD_GPIO_PIN_9 + * @arg @ref MD_GPIO_PIN_10 + * @arg @ref MD_GPIO_PIN_11 + * @arg @ref MD_GPIO_PIN_12 + * @arg @ref MD_GPIO_PIN_13 + * @arg @ref MD_GPIO_PIN_14 + * @arg @ref MD_GPIO_PIN_15 + * @arg @ref MD_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_gpio_get_filter(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + return (READ_BIT(GPIOx->FIR, PinMask) == (PinMask)); +} + +/** + * @} MD_GPIO_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_GPIO_Public_Functions GPIO Public Functions + * @{ + */ + +/** @defgroup MD_GPIO_PF_Port_Configuration Port Configuration + * @{ + */ + +/** + * @} MD_GPIO_PF_Port_Configuration + */ + +/** @defgroup MD_GPIO_PF_Data_Access Data Access + * @{ + */ + +/** + * @} MD_GPIO_PF_Data_Access + */ + + +/** @defgroup MD_GPIO_PF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus md_gpio_deinit(GPIO_TypeDef *GPIOx); +ErrorStatus md_gpio_init(GPIO_TypeDef *GPIOx, md_gpio_inittypedef *GPIO_InitStruct); +void md_gpio_struct_init(md_gpio_inittypedef *GPIO_InitStruct); + +/** + * @} MD_GPIO_PF_Init + */ + +/** + * @} MD_GPIO_Public_Functions + */ + +#endif + +/** + * @} GPIO + */ + +/** + * @} Micro_Driver + */ + + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_hdiv.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_hdiv.h new file mode 100644 index 0000000000..5baf2d5d23 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_hdiv.h @@ -0,0 +1,292 @@ +/** + ****************************************************************************** + * @file md_HDIV.h + * @brief ES32F0271 HDIV HEAD File. + * + * @version V1.00.01 + * @date 11/20/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_HDIV_H__ +#define __MD_HDIV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_hdiv.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (HDIV) + +/** @defgroup HDIV HDIV + * @brief HDIV micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ + +/** + * @brief MD HDIV Parameter Structure definition + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_HDIV_Public_Constants HDIV Public Constants + * @{ + */ + +/** + * @} MD_HDIV_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_HDIV_Public_Macros HDIV Public Macros + * @{ + */ + +/** @defgroup MD_HDIV_PM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in HDIV register + * @param __INSTANCE__ HDIV Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define MD_HDIV_WRITEREG(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in HDIV register + * @param __INSTANCE__ HDIV Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define MD_HDIV_READREG(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + +/** + * @brief Modify value in HDIV register + * @param __INSTANCE__ HDIV Instance + * @param __REG__ Register to be written + * @param __MASK__ Mask value to be written in the register + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define MD_HDIV_MODIFYREG(__INSTANCE__, __REG__, __MASK__, __VALUE__) MODIFY_REG(__INSTANCE__->__REG__, __MASK__, (__VALUE__)) + +/** + * @brief Set bit value in HDIV register + * @param __INSTANCE__ HDIV Instance + * @param __REG__ Register to be read + * @param __MASK__ Mask value to be set in the register + * @retval None + */ +#define MD_HDIV_SET_BIT(__INSTANCE__, __REG__, __MASK__) SET_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @brief Clear bit value in HDIV register + * @param __INSTANCE__ HDIV Instance + * @param __REG__ Register to be read + * @param __MASK__ Mask value to be cleased in the register + * @retval None + */ +#define MD_HDIV_CLEAR_BIT(__INSTANCE__, __REG__, __MASK__) CLEAR_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @brief Read bit value in HDIV register + * @param __INSTANCE__ HDIV Instance + * @param __REG__ Register to be read + * @param __MASK__ Mask value to be read in the register + * @retval Register bit value + */ +#define MD_HDIV_READBIT(__INSTANCE__, __REG__, __MASK__) READ_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @} MD_HDIV_PM_WRITE_READ + */ + +/** @defgroup MD_HDIV_Macro_Drivers HDIV Public Macro Drivers + * @{ + */ + +/** + * @brief Set HDIV DIVDR + * @note This register is given the dividend of divider before calculation starting + * @note When this register is written, hardware divider will start calculate + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_hdiv_set_divdr(uint32_t U32) +{ + MD_HDIV_WRITEREG(HDIV, DIVDR, U32); +} + +/** + * @brief Get HDIV DIVIDEND + * @note This register is given the dividend of divider before calculation starting + * @note When this register is written, hardware divider will start calculate + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_hdiv_get_divdr(void) +{ + return (MD_HDIV_READREG(HDIV, DIVDR)); +} + +/** + * @brief Set HDIV DIVSR + * @note This register is given the divisor of divider before calculation starts + * @note When this register is written, hardware divider will start calculate + * @param @arg Max Value 0xffffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_hdiv_set_divsr(uint32_t U32) +{ + MD_HDIV_WRITEREG(HDIV, DIVSR, U32); +} + +/** + * @brief Get HDIV DIVSR + * @note This register is given the divisor of divider before calculation starts. + * @note When this register is written, hardware divider will start calculate + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_hdiv_get_divsr(void) +{ + return (MD_HDIV_READREG(HDIV, DIVSR)); +} + +/** + * @brief Get HDIV DIVQR + * @note This register holds the quotient result of divider after calculation complete + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_hdiv_get_divqr(void) +{ + return (MD_HDIV_READREG(HDIV, DIVQR)); +} + +/** + * @brief Get HDIV DIVRR + * @note This register holds the remainder result of divider after calculation complete + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_hdiv_get_divrr(void) +{ + return (MD_HDIV_READREG(HDIV, DIVRR)); +} + +/** + * @brief Get HDIV DIVSTAT + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x7 + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_hdiv_get_divstat(void) +{ + return (MD_HDIV_READREG(HDIV, DIVSTAT)); +} + +/** + * @brief Is HDIV DIVSTAT SIGN Active + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 : Signed + * @arg Min Value 0x0 : Unsigned + */ +__STATIC_INLINE uint8_t md_hdiv_get_divsts_sign(void) +{ + return (MD_HDIV_READBIT(HDIV, DIVSTAT, HDIV_DIVSTAT_SIGN_MSK)>>HDIV_DIVSTAT_SIGN_POS); +} + +/** + * @brief Is HDIV DIVSTAT DIV0 Active + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 : The divisor is 0 + * @arg Min Value 0x0 : The divisor is not 0 + */ +__STATIC_INLINE uint8_t md_hdiv_get_divsts_div0(void) +{ + return (MD_HDIV_READBIT(HDIV, DIVSTAT, HDIV_DIVSTAT_DIV0_MSK)>>HDIV_DIVSTAT_DIV0_POS); +} + +/** + * @brief Is HDIV DIVSTAT BUSY Active + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 : The divider is busy + * @arg Min Value 0x0 : The divider is not busy + */ +__STATIC_INLINE uint8_t md_hdiv_get_divsts_busy(void) +{ + return (MD_HDIV_READBIT(HDIV, DIVSTAT, HDIV_DIVSTAT_BUSY_MSK)>>HDIV_DIVSTAT_BUSY_POS); +} + +/** + * @} MD_HDIV_Macro_Drivers + */ + +/** + * @} MD_HDIV_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_HDIV_Public_Functions HDIV Public Functions + * @{ + */ + +/** + * @} MD_HDIV_Public_Functions + */ + +#endif + +/** + * @} HDIV + */ + +/** + * @} Micro_Driver + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_i2c.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_i2c.h new file mode 100644 index 0000000000..9f2e2ff964 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_i2c.h @@ -0,0 +1,3273 @@ +/** + ****************************************************************************** + * @file md_i2c.h + * @brief ES32F0271 I2C HEAD File. + * + * @version V0.01 + * @date 4/12/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_I2C_H__ +#define __MD_I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_i2c.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (I2C1) | defined (I2C2) + +/** @defgroup I2C I2C + * @brief I2C micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + + +/* Public Init Structure ------------------------------------------------------*/ +/** @defgroup MD_I2C_PT_INIT I2C Public Init structure + * @brief I2C Init structure. + * @{ + */ +typedef struct +{ + uint32_t Timing; /*!< Specifies the I2C_TIMINGR_register value. + This parameter calculated by referring to I2C initialization section in Reference manual */ + + uint32_t Address1; /*!< Specifies the first device address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t AddrSize; /*!< Specifies the device address 1 size (7-bit or 10-bit). + This parameter can be a value of @ref I2C_LL_EC_OWNADDRESS1 + + This feature can be modified afterwards using unitary function @ref LL_I2C_SetOwnAddress1(). */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref I2C_DUAL_ADDRESSING_MODE */ + + uint32_t Address2; /*!< Specifies the second device own address if dual addressing mode is selected + This parameter can be a 7-bit address. */ + + uint32_t Address2Masks; /*!< Specifies the acknowledge mask address second device own address if dual addressing mode is selected + This parameter can be a value of @ref I2C_OWN_ADDRESS2_MASKS */ +} md_i2c_inittypedef; +/** + * @} MD_I2C_PT_INIT + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_I2C_Public_Constants I2C Public Constants + * @{ + */ + +/** @defgroup MD_I2C_ADDRESSING_MODE I2C Addressing Mode + * @{ + */ +#define MD_I2C_ADDRESSINGMODE_7BIT (0x00000000U) /*!< DISABLE */ +#define MD_I2C_ADDRESSINGMODE_10BIT (I2C_CON2_ADD10_MSK) /*!< I2C_CON2_ADD10_MSK = 1<<11 */ +/** + * @} MD_I2C_ADDRESSING_MODE + */ + +/** @defgroup MD_I2C_DUAL_ADDRESSING_MODE I2C Dual Addressing Mode + * @{ + */ +#define MD_I2C_DUALADDRESS_DISABLE (0x00000000U) /*!< DISABLE */ +#define MD_I2C_DUALADDRESS_ENABLE (I2C_ADDR2_OA2EN_MSK) /*!< I2C_ADDR2_OA2EN_MSK = 1<<15 */ +/** + * @} MD_I2C_DUAL_ADDRESSING_MODE + */ + +/** @defgroup MD_I2C_TIMING_CONFIG I2C Timing Config + * @note pllmul<<28|presc<<24|scll<<16|sclh<<8|sdadel<<4|scldel + * @{ + */ +/* pllmul presc scll sclh sdadel scldel */ +#define CLK10kHz8M (1<<28) |(1<<24) |(0xC7<<16)|(0xC3<<8)|(2<<4)|(4) /*!< APB = 8MHz; CLK = 10kHz */ +#define CLK100kHz8M (1<<28) |(1<<24) |(0x13<<16)|(0xF<<8) |(2<<4)|(4) /*!< APB = 8MHz; CLK = 100kHz */ +#define CLK400kHz8M (1<<28) |(0<<24) |(9<<16) |(3<<8) |(1<<4)|(3) /*!< APB = 8MHz; CLK = 400kHz */ +#define CLK500kHz8M (1<<28) |(0<<24) |(6<<16) |(3<<8) |(0<<4)|(1) /*!< APB = 8MHz; CLK = 500kHz */ +#define CLK10kHz16M (3<<28) |(3<<24) |(0xC7<<16)|(0xC3<<8)|(2<<4)|(4) /*!< APB = 16MHz; CLK = 10kHz */ +#define CLK100kHz16M (3<<28) |(3<<24) |(0x13<<16)|(0xF<<8) |(2<<4)|(4) /*!< APB = 16MHz; CLK = 100kHz */ +#define CLK400kHz16M (3<<28) |(1<<24) |(9<<16) |(3<<8) |(2<<4)|(3) /*!< APB = 16MHz; CLK = 400kHz */ +#define CLK1000kHz16M (3<<28) |(0<<24) |(4<<16) |(2<<8) |(0<<4)|(2) /*!< APB = 16MHz; CLK = 1000kHz */ +#define CLK10kHz48M (11U<<28)|(0xB<<24)|(0xC7<<16)|(0xC3<<8)|(2<<4)|(4) /*!< APB = 48MHz; CLK = 10kHz */ +#define CLK100kHz48M (11U<<28)|(0xB<<24)|(0x13<<16)|(0xF<<8) |(2<<4)|(4) /*!< APB = 48MHz; CLK = 100kHz */ +#define CLK400kHz48M (11U<<28)|(5<<24) |(9<<16) |(3<<8) |(3<<4)|(3) /*!< APB = 48MHz; CLK = 400kHz */ +#define CLK1000kHz48M (11U<<28)|(5<<24) |(3<<16) |(1<<8) |(0<<4)|(1) /*!< APB = 48MHz; CLK = 1000kHz */ +/** + * @} MD_I2C_TIMING_CONFIG + */ + +/** @defgroup MD_I2C_ADDRESS2_MASKS I2C Address2 Masks + * @{ + */ +#define MD_I2C_ADDR2_NOMASK (0x0000U) /*!< NOMASK */ +#define MD_I2C_ADDR2_MASK01 (0x0100U) /*!< MASK01 */ +#define MD_I2C_ADDR2_MASK02 (0x0200U) /*!< MASK02 */ +#define MD_I2C_ADDR2_MASK03 (0x0300U) /*!< MASK03 */ +#define MD_I2C_ADDR2_MASK04 (0x0400U) /*!< MASK04 */ +#define MD_I2C_ADDR2_MASK05 (0x0500U) /*!< MASK05 */ +#define MD_I2C_ADDR2_MASK06 (0x0600U) /*!< MASK06 */ +#define MD_I2C_ADDR2_MASK07 (0x0700U) /*!< MASK07 */ +/** + * @} MD_I2C_ADDRESS2_MASKS + */ + +/** @defgroup MD_I2C_GENERAL_CALL_ADDRESSING_MODE I2C General Call Addressing Mode + * @{ + */ +#define MD_I2C_GENERALCALL_DISABLE (0x00000000U) /*!< DISABLE */ +#define MD_I2C_GENERALCALL_ENABLE (I2C_CON1_GCEN_MSK) /*!< I2C_CON1_GCEN_MSK = 1<<19 */ +/** + * @} MD_I2C_GENERAL_CALL_ADDRESSING_MODE + */ + +/** @defgroup MD_I2C_NOSTRETCH_MODE I2C No-Stretch Mode + * @{ + */ +#define MD_I2C_NOSTRETCH_DISABLE (0x00000000U) /*!< DISABLE */ +#define MD_I2C_NOSTRETCH_ENABLE (I2C_CON1_NOSTRETCH_MSK) /*!< I2C_CON1_NOSTRETCH_MSK = 1<<17 */ +/** + * @} MD_I2C_NOSTRETCH_MODE + */ + +/** @defgroup MD_I2C_MODE I2C Mode + * @{ + */ +#define MD_I2C_MODE_NONE ((uint8_t)0x00U /*!< None */ +#define MD_I2C_MODE_MASTER ((uint8_t)0x10U) /*!< Master */ +#define MD_I2C_MODE_SLAVE ((uint8_t)0x20U) /*!< Slave */ +#define MD_I2C_MODE_MEM ((uint8_t)0x40U) /*!< Mem */ +/** + * @} MD_I2C_MODE + */ + +/** @defgroup MD_I2C_PECBYTE_ENABLE Pecbyte Enable + * @{ + */ +#define MD_I2C_PECBYTE_ENABLE I2C_CON2_PECBYTE_MSK /*!< I2C_CON2_PECBYTE_MSK = 1<<26 */ +/** + * @} MD_I2C_PECBYTE_ENABLE + */ + +/** @defgroup MD_I2C_AUTOEND_ENABLE I2C Autoend Enable + * @{ + */ +#define MD_I2C_SOFTEND_MODE (0x00000000U) /*!< DISABLE */ +#define MD_I2C_AUTOEND_MODE (I2C_CON2_AUTOEND_MSK) /*!< I2C_CON2_AUTOEND_MSK = 1<<25 */ +/** + * @} MD_I2C_AUTOEND_ENABLE + */ + +/** @defgroup MD_I2C_RELOAD_MODE I2C Reload Mode + * @{ + */ +#define MD_I2C_NORELOAD_MODE (0x00000000U) /*!< DISABLE */ +#define MD_I2C_RELOAD_MODE (I2C_CON2_RELOAD_MSK) /*!< I2C_CON2_RELOAD_MSK = 1<<24 */ +/** + * @} MD_I2C_RELOAD_MODE + */ + +/** @defgroup MD_I2C_NACKNOWLEDGE Acknowledge Generation + * @{ + */ +#define MD_I2C_ACK 0x00000000U /*!< ACK is sent after current received byte. */ +#define MD_I2C_NACK I2C_CON2_NACK_MSK /*!< NACK is sent after current received byte, I2C_CON2_NACK_MSK = 1<<15 */ +/** + * @} MD_I2C_NACKNOWLEDGE + */ + +/** @defgroup MD_I2C_STOP_GENERATION Stop Generation + * @{ + */ +#define MD_I2C_STOP_GENERATION I2C_CON2_STOP_MSK /*!< I2C_CON2_STOP_MSK = 1<<14 */ +/** + * @} MD_I2C_STOP_GENERATION + */ + +/** @defgroup MD_I2C_START_GENERATION Start Generation + * @{ + */ +#define MD_I2C_START_GENERATION I2C_CON2_START_MSK /*!< I2C_CON2_PECBYTE_MSK = 1<<13 */ +/** + * @} MD_I2C_START_GENERATION + */ + +/** @defgroup MD_I2C_HEAD10R Acknowledge Generation + * @{ + */ +#define MD_I2C_GENERAL_10BIT_READ 0x00000000U /*!< DISABLE */ +#define MD_I2C_SIMPLIFIED_10BIT_READ I2C_CON2_HEAD10R_MSK /*!< I2C_CON2_HEAD10R_MSK = 1<<12 */ +/** + * @} MD_I2C_HEAD10R + */ + +/** @defgroup MD_I2C_TRANSFER_DIRECTION Transfer direction (master mode) + * @{ + */ +#define MD_I2C_MASTER_WRITE 0x00000000U /*!< Master Write */ +#define MD_I2C_MASTER_READ I2C_CON2_RD_WRN_MSK /*!< I2C_CON2_RD_WRN_MSK = 1<<10 */ +/** + * @} MD_I2C_TRANSFER_DIRECTION + */ + +/** @defgroup MD_I2C_OA1_MODE Own Address 1 mode + * @{ + */ +#define MD_I2C_OA1_7BIT 0x00000000U /*!< OA1 7-bit mode */ +#define MD_I2C_OA1_10BIT I2C_ADDR1_OA1MODE_MSK /*!< I2C_ADDR1_OA1MODE_MSK = 1<<10 */ +/** + * @} MD_I2C_OA1_MODE + */ + +/** @defgroup MD_I2C_TIDLE_MODE Tidle mode + * @{ + */ +#define MD_I2C_LOW_TIMEOUTA 0x00000000U /*!< TIMEOUTA is used to detect SCL low timeout */ +#define MD_I2C_IDLE_TIMEOUTA I2C_TIMEOUTR_TIDLE_MSK /*!< TIMEOUTA is used to detectbus idle condition, I2C_TIMEOUTR_TIDLE_MSK = 1<<12 */ +/** + * @} MD_I2C_TIDLE_MODE + */ + +/** @defgroup MD_I2C_RXFIFO_THRESHOLD FIFO Threshold + * @{ + */ +#define MD_I2C_RXFIFO_THRESHOLD_RX1 0U<CON1, Reg_Value); +} + +/** + * @brief I2C Get CON1 + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_con1(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->CON1)); +} + +/** + * @brief I2C PEC Enable + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to 0. + * This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_pecen(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_PECEN_MSK); +} + +/** + * @brief I2C PEC Disable + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to 0. + * This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_pecen(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_PECEN_MSK); +} + +/** + * @brief Indicate if I2C PEC is enabled + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to '0' + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_pecen(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_PECEN_MSK) == (I2C_CON1_PECEN_MSK)); +} + +/** + * @brief I2C Alert Enable + * @note When ALERTEN = 0, the SMBA pin can be used as a standard GPIO.If the SMBus feature is not supported, this bit is reserved and forced by hardware to 0. + * This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_alerten(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_ALERTEN_MSK); +} + +/** + * @brief I2C Alert Disable + * @note When ALERTEN = 0, the SMBA pin can be used as a standard GPIO.If the SMBus feature is not supported, this bit is reserved and forced by hardware to 0. + * This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_alerten(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_ALERTEN_MSK); +} + +/** + * @brief Indicate if I2C PEC is enabled + * @note When ALERTEN = 0, the SMBA pin can be used as a standard GPIO.If the SMBus feature is not supported, this bit is reserved and forced by hardware to 0. + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_alerten(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_ALERTEN_MSK) == (I2C_CON1_ALERTEN_MSK)); +} + +/** + * @brief I2C SMBus Device Default address Enable + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to 0. Device default address 0b1100 001. + * This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_smbden(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_SMBDEN_MSK); +} + +/** + * @brief I2C SMBus Device Default address Disable + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to 0. Device default address 0b1100 001. + * This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_smbden(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_SMBDEN_MSK); +} + +/** + * @brief Indicate if I2C SMBus Device Default address is enabled + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to 0. Device default address 0b1100 001. + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_smbden(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_SMBDEN_MSK) == (I2C_CON1_SMBDEN_MSK)); +} + +/** + * @brief I2C SMBus Host address Enable + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to 0. Host default address 0b0001 000. + * This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_smbhen(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_SMBHEN_MSK); +} + +/** + * @brief I2C SMBus Host address Disable + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to 0. Host default address 0b0001 000. + * This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_smbhen(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_SMBHEN_MSK); +} + +/** + * @brief Indicate if I2C SMBus Host address is enabled + * @note If the SMBus feature is not supported,this bit is reserved and forced by hardware to 0. Host default address 0b0001 000. + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_smbhen(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_SMBHEN_MSK) == (I2C_CON1_SMBHEN_MSK)); +} + +/** + * @brief I2C general call Enable + * @note This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_gcen(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_GCEN_MSK); +} + +/** + * @brief I2C general call Disable + * @note This register must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_gcen(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_GCEN_MSK); +} + +/** + * @brief Indicate if I2C general call is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_gcen(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_GCEN_MSK) == (I2C_CON1_GCEN_MSK)); +} + +/** + * @brief I2C clock stretching Disable + * @note Clock stretching disables. This bit can only be programmed when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_nostretch(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_NOSTRETCH_MSK); +} + +/** + * @brief I2C clock stretching Enable + * @note Clock stretching enables.This bit can only be programmed when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_nostretch(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_NOSTRETCH_MSK); +} + +/** + * @brief Indicate if I2C clock nostretching is enabled + * @note This bit can only be programmed when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_nostretch(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_NOSTRETCH_MSK) == (I2C_CON1_NOSTRETCH_MSK)); +} + +/** + * @brief I2C slave byte control Enable + * @note This bit can only be programmed when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_sbc(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_SBC_MSK); +} + +/** + * @brief I2C slave byte control Disable + * @note This bit can only be programmed when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_sbc(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_SBC_MSK); +} + +/** + * @brief Indicate if I2C slave byte control is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_sbc(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_SBC_MSK) == (I2C_CON1_SBC_MSK)); +} + +/** + * @brief I2C DMA reception requests Enable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_rxdmaen(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_RXDMAEN_MSK); +} + +/** + * @brief I2C DMA reception requests Disable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_rxdmaen(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_RXDMAEN_MSK); +} + +/** + * @brief Indicate if I2C DMA reception requests is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_rxdmaen(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_RXDMAEN_MSK) == (I2C_CON1_RXDMAEN_MSK)); +} + +/** + * @brief I2C DMA transmission requests Enable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_txdmaen(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_TXDMAEN_MSK); +} + +/** + * @brief I2C DMA transmission requests Disable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_txdmaen(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_TXDMAEN_MSK); +} + +/** + * @brief Indicate if I2C DMA transmission requests is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_txdmaen(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_TXDMAEN_MSK) == (I2C_CON1_TXDMAEN_MSK)); +} + +/** + * @brief Set I2C digital noise filter + * @note If the analog filter is also enabled,the digital filter is added to the analog filter. + * This filter can only be programmed when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @param filter_capability digital noise filter capability + * @arg Max Value 0xFF + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con1_dnf(I2C_TypeDef *I2Cx, uint32_t filter_capability) +{ + MODIFY_REG(I2Cx->CON1, I2C_CON1_DNF_MSK, filter_capability<CON1, I2C_CON1_DNF_MSK)>>I2C_CON1_DNF_POSS); +} + +/** + * @brief I2C Peripheral Enable + * @note When PE = 0, the I2C SCL and SDA lines are released. + * Internal state machines and status bits are put back to their reset value. + * When cleared, PE must be kept low for at least 3 APB clock cycles. + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con1_pe(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON1, I2C_CON1_PE_MSK); +} + +/** + * @brief I2C Peripheral Disable + * @note When PE = 0, the I2C SCL and SDA lines are released.Internal state machines and status bits are put back to their reset value.When cleared,PE must be kept low for at least 3 APB clock cycles + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con1_pe(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON1, I2C_CON1_PE_MSK); +} + +/** + * @brief Indicate if Peripheral is enabled + * @note When PE = 0, the I2C SCL and SDA lines are released.Internal state machines and status bits are put back to their reset value.When cleared,PE must be kept low for at least 3 APB clock cycles + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con1_pe(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON1, I2C_CON1_PE_MSK) == (I2C_CON1_PE_MSK)); +} + +/** + * @brief I2C Set CON2 + * @note None + * @param I2Cx I2C Instance + * @param Reg_Value is a 32-bit value + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2(I2C_TypeDef *I2Cx, uint32_t Reg_Value) +{ + WRITE_REG(I2Cx->CON2, Reg_Value); +} + +/** + * @brief I2C Get CON2 + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_con2(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->CON2)); +} + +/** + * @brief I2C Set ACK Update + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_ack_upd(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON2, I2C_CON2_ACK_UPD_MSK); +} + +/** + * @brief I2C Hold Ack Enable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_con2_holdack(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CON2, I2C_CON2_HOLDACK_MSK); +} + +/** + * @brief I2C Hold Ack Disable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_con2_holdack(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CON2, I2C_CON2_HOLDACK_MSK); +} + +/** + * @brief Indicate if I2C Hold Ack is enabled + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_con2_holdack(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CON2, I2C_CON2_HOLDACK_MSK) == (I2C_CON2_HOLDACK_MSK)); +} + +/** + * @brief Set I2C Packet error checking byte + * @note This bit is set by software, and cleared by hardware when the PEC is transferred, + * or when a STOP condition or an Address matched is received, also when PE=0. + * Writing 0 to this bit has no effet. This bit has no effect when RELOAD is set, + * and when SBC is 0 in the slave mode. + * If the SMBus feature is not supported, this bit is reserved and forced by hardware to 0. + * @param I2Cx I2C Instance + * @param setbit + * @arg @ref MD_I2C_PECBYTE_ENABLE + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_pecbyte(I2C_TypeDef *I2Cx, uint32_t setbit) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_PECBYTE_MSK, setbit); +} + +/** + * @brief Get I2C Packet error checking byte + * @note This bit is set by software, and cleared by hardware when the PEC is transferred, + * or when a STOP condition or an Address matched is received, also when PE=0. + * Writing 0 to this bit has no effet. This bit has no effect when RELOAD is set, + * and when SBC is 0 in the slave mode. + * If the SMBus feature is not supported, this bit is reserved and forced by hardware to 0. + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_pecbyte(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_PECBYTE_MSK)>>I2C_CON2_PECBYTE_POS); +} + +/** + * @brief Set I2C automatic end mode or software end mode(master mode) + * @note This bit has no effect in slave mode or when the RELOAD bit is set. + * Software end mode: TC flag is set when NBYTES data are transferred, stretching SCL low. + * Automatic end mode: a STOP condition is automatically sent when NBYTES data are transferred. + * @param I2Cx I2C Instance + * @param setbit + * @arg @ref MD_I2C_SOFTEND_MODE + * @arg @ref MD_I2C_AUTOEND_MODE + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_autoend(I2C_TypeDef *I2Cx, uint32_t setbit) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_AUTOEND_MSK, setbit); +} + +/** + * @brief Get I2C automatic or software end mode(master mode) + * @note This bit has no effect in slave mode or when the RELOAD bit is set. + * Software end mode: TC flag is set when NBYTES data are transferred, stretching SCL low. + * Automatic end mode: a STOP condition is automatically sent when NBYTES data are transferred. + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_autoend(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_AUTOEND_MSK)>>I2C_CON2_AUTOEND_POS); +} + +/** + * @brief Set I2C NBYTES reload mode or not + * @note RELOAD = 0: The transfer is completed after the NBYTES data transfer (STOP or RESTART will follow). + * RELOAD = 1: The transfer is not completed after the NBYTES data transfer (NBYTES will be reloaded). + * TCR flag is set when NBYTES data are transferred, stretching SCL low. + * @param I2Cx I2C Instance + * @param setbit + * @arg @ref MD_I2C_NORELOAD_MODE + * @arg @ref MD_I2C_RELOAD_MODE + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_reload(I2C_TypeDef *I2Cx, uint32_t setbit) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_RELOAD_MSK, setbit); +} + +/** + * @brief Get I2C RELOAD value + * @note RELOAD = 0: The transfer is completed after the NBYTES data transfer (STOP or RESTART will follow). + * RELOAD = 1: The transfer is not completed after the NBYTES data transfer (NBYTES will be reloaded). + * TCR flag is set when NBYTES data are transferred, stretching SCL low. + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_reload(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_RELOAD_MSK)>>I2C_CON2_RELOAD_POS); +} + +/** + * @brief Set I2C number of bytes + * @note The number of bytes to be transmitted/received is programmed there. + * This field is dont care in slave mode with SBC=0. + * Changing these bits when the START bit is set is not allowed. + * @param I2Cx I2C Instance + * @param nbytes number of bytes + * @arg Max Value 0xFF + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_nbytes(I2C_TypeDef *I2Cx, uint32_t nbytes) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_NBYTES_MSK, nbytes<CON2, I2C_CON2_NBYTES_MSK)>>I2C_CON2_NBYTES_POSS); +} + +/** + * @brief Set I2C NACK generation(slave mode) + * @note Writing 0 to this bit has no effect. This bit is used in slave mode only. + * When an overrun occurs in slave receiver NOSTRETCH mode,a NACK is automatically generated whatever the NACK bit value. + * When hardware PEC checking is enabled(PECBYTE = 1),the PEC acknowledge value does not depend on the NACK value. + * @param I2Cx I2C Instance + * @param nack nack generation + * @arg @ref MD_I2C_NACK + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_nack(I2C_TypeDef *I2Cx, uint32_t nack) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_NACK_MSK, nack); +} + +/** + * @brief Get I2C NACK bit state(slave mode) + * @note NACK=1: will generate NACK + * NACK=0: will generate ACK + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_nack(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_NACK_MSK)>>I2C_CON2_NACK_POS); +} + +/** + * @brief Set I2C Stop generation(master mode) + * @note Writing 0 to this bit has no effect. + * @param I2Cx I2C Instance + * @param stop_generate stop generate + * @arg MD_I2C_STOP_GENERATION + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_stop(I2C_TypeDef *I2Cx, uint32_t stop_generate) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_STOP_MSK, stop_generate); +} + +/** + * @brief Get I2C state of STOP bit(master mode) + * @note Writing 0 to this bit has no effect. + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_stop(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_STOP_MSK)>>I2C_CON2_STOP_POS); +} + +/** + * @brief Set I2C Start generation + * @note Writing 0 to this bit has no effect.The START bit can be set even if the bus is BUSY or I2C is in slave mode. + * In 10-bit addressing mode, if a NACK is received on the first part of the address, + * the START bit is not cleared by hardware and the master will resend the address sequence. + * @param I2Cx I2C Instance + * @param start_generate stop generate + * @arg MD_I2C_START_GENERATION + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_start(I2C_TypeDef *I2Cx, uint32_t start_generate) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_START_MSK, start_generate); +} + +/** + * @brief Get I2C state of START bit + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_start(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_START_MSK)>>I2C_CON2_START_POS); +} + +/** + * @brief Set the master operates in 10-bit addressing mode(master receiver mode) + * @note Changing this bit when the START bit is set is not allowed. + * It can be used when the 10-bit transmission was done before. + * @param I2Cx I2C Instance + * @param read_header format of read header + * @arg @ref MD_I2C_GENERAL_10BIT_READ + * @arg @ref MD_I2C_SIMPLIFIED_10BIT_READ + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_head10r(I2C_TypeDef *I2Cx, uint32_t read_header) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_HEAD10R_MSK, read_header); +} + +/** + * @brief Indicate if I2C 10-bit address header only read direction is enabled(master receiver mode) + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_head10r(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_HEAD10R_MSK)>>I2C_CON2_HEAD10R_POS); +} + +/** + * @brief I2C 10-bit addressing mode Enable(master mode) + * @note Changing this bit when the START bit is set is not allowed. + * @param I2Cx I2C Instance + * @param addrmode + @arg @ref MD_I2C_ADDRESSINGMODE_7BIT + @arg @ref MD_I2C_ADDRESSINGMODE_10BIT + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_add10(I2C_TypeDef *I2Cx, uint32_t addrmode) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_ADD10_MSK, addrmode); +} + +/** + * @brief Get I2C addressing mode is 10-bit or 7-bit mode(master mode) + * @note ADD10=1: 10-bit mode + * ADD10=0: 7-bit mode + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_add10(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_ADD10_MSK)>>I2C_CON2_ADD10_POS); +} + +/** + * @brief Set Master transfer direction(master mode) + * @note Changing this bit when the START bit is set is not allowed. + * @param I2Cx I2C Instance + * @param direction + * @arg @ref MD_I2C_MASTER_WRITE + * @arg @ref MD_I2C_MASTER_READ + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_rd_wrn(I2C_TypeDef *I2Cx, uint32_t direction) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_RD_WRN_MSK, direction); +} + +/** + * @brief Get Master transfer direction(master mode) + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_con2_rd_wrn(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_RD_WRN_MSK)>>I2C_CON2_RD_WRN_POS); +} + +/** + * @brief Set I2C slave address(master mode) + * @note Changing these bits when the START bit is set is not allowed + * For 7-bit mode, bit 7 to 1 are valid; for 10-bit mode, all 10 bits are valid. + * @param I2Cx I2C Instance + * @param slave_addr I2C slave address + * @arg Max Value 7-bit: 0xFF / 10-bit: 0x3FF + * @arg Min Value 7-bit: 0x2 / 10-bit: 0x1 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_con2_sadd(I2C_TypeDef *I2Cx, uint32_t slave_addr) +{ + MODIFY_REG(I2Cx->CON2, I2C_CON2_SADD_MSK, slave_addr); +} + +/** + * @brief Get I2C slave address(master mode) + * @note Changing these bits when the START bit is set is not allowed + * For 7-bit mode, bit 7 to 1 are valid; for 10-bit mode, all 10 bits are valid. + * @param I2Cx I2C Instance + * @retval I2C slave address + * @arg Max Value 7-bit: 0xFF / 10-bit: 0x3FF + * @arg Min Value 7-bit: 0x2 / 10-bit: 0x1 + */ +__STATIC_INLINE uint32_t md_i2c_get_sadd_7bit(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->CON2, I2C_CON2_SADD_MSK)); +} + +/** + * @brief Set I2C ADDR1 + * @note These bits can be written only when OA1EN=0 except OA1EN. + * @param I2Cx I2C Instance + * @param Reg_Value is a 32-bit value + * @retval None + */ +__STATIC_INLINE void md_i2c_set_addr1(I2C_TypeDef *I2Cx, uint32_t Reg_Value) +{ + WRITE_REG(I2Cx->ADDR1, Reg_Value); +} + +/** + * @brief Get I2C ADDR1 + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_addr1(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->ADDR1)); +} + +/** + * @brief I2C address register 1 Enable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_addr1_oa1en(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ADDR1, I2C_ADDR1_OA1EN_MSK); +} + +/** + * @brief I2C address register 1 Disable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_addr1_oa1en(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->ADDR1, I2C_ADDR1_OA1EN_MSK); +} + +/** + * @brief Indicate if address register 1 is enabled + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_addr1_oa1en(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->ADDR1, I2C_ADDR1_OA1EN_MSK) == (I2C_ADDR1_OA1EN_MSK)); +} + +/** + * @brief Set I2C OA1 bit mode + * @param I2Cx I2C Instance + * @param oa1mode + * @arg @ref MD_I2C_OA1_7BIT + * @arg @ref MD_I2C_OA1_10BIT + * @retval None + */ +__STATIC_INLINE void md_i2c_set_addr1_oa1mode(I2C_TypeDef *I2Cx, uint32_t oa1mode) +{ + MODIFY_REG(I2Cx->ADDR1, I2C_ADDR1_OA1MODE_MSK, oa1mode); +} + +/** + * @brief Get I2C own address 1 mode + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_addr1_oa1mode(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->ADDR1, I2C_ADDR1_OA1MODE_MSK)>>I2C_ADDR1_OA1MODE_POS); +} + +/** + * @brief Set I2C address1 + * @note For 7-bit mode, bit 7 to 1 are valid; for 10-bit mode, all 10 bits are valid. + * @param I2Cx I2C Instance + * @param own_addr I2C own address1 + * @arg Max Value 7-bit: 0xFF / 10-bit: 0x3FF + * @arg Min Value 7-bit: 0x2 / 10-bit: 0x1 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_addr1_oa1(I2C_TypeDef *I2Cx, uint32_t own_addr) +{ + MODIFY_REG(I2Cx->ADDR1, I2C_ADDR1_OA1_MSK, own_addr); +} + +/** + * @brief Get I2C address1 + * @note For 7-bit mode, bit 7 to 1 are valid; for 10-bit mode, all 10 bits are valid. + * @param I2Cx I2C Instance + * @retval I2C own address1 + * @arg Max Value 7-bit: 0xFF / 10-bit: 0x3FF + * @arg Min Value 7-bit: 0x2 / 10-bit: 0x1 + */ +__STATIC_INLINE uint32_t md_i2c_get_addr1_oa1(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->ADDR1, I2C_ADDR1_OA1_MSK)); +} + +/** + * @brief Set I2C ADDR2 + * @note These bits can be written only when OA2EN=0 except OA2EN. + * @param I2Cx I2C Instance + * @param Reg_Value is a 32-bit value + * @retval None + */ +__STATIC_INLINE void md_i2c_set_addr2(I2C_TypeDef *I2Cx, uint32_t Reg_Value) +{ + WRITE_REG(I2Cx->ADDR2, Reg_Value); +} + +/** + * @brief Get I2C ADDR2 + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_addr2(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->ADDR2)); +} + +/** + * @brief I2C own address register 2 Enable + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_addr2_oa2en(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ADDR2, I2C_ADDR2_OA2EN_MSK); +} + +/** + * @brief I2C own address register 2 Disable + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_addr2_oa2en(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->ADDR2, I2C_ADDR2_OA2EN_MSK); +} + +/** + * @brief Indicate if address register 2 is enabled + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_addr2_oa2en(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->ADDR2, I2C_ADDR2_OA2EN_MSK) == (I2C_ADDR2_OA2EN_MSK)); +} + +/** + * @brief Set I2C own address2 mask + * @note These bits can be written only when OA2EN=0. + * As soon as OA2MSK is not equal to 0,the reserved I2C addresses(0b0000xxx and 0b1111xxx) are not acknowledged even if the comparison matches. + * @param I2Cx I2C Instance + * @param oa2_mask I2C own address2 mask + * @arg @ref MD_I2C_ADDR2_NOMASK + * @arg @ref MD_I2C_ADDR2_MASK01 + * @arg @ref MD_I2C_ADDR2_MASK02 + * @arg @ref MD_I2C_ADDR2_MASK03 + * @arg @ref MD_I2C_ADDR2_MASK04 + * @arg @ref MD_I2C_ADDR2_MASK05 + * @arg @ref MD_I2C_ADDR2_MASK06 + * @arg @ref MD_I2C_ADDR2_MASK07 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_addr2_oa2mask(I2C_TypeDef *I2Cx, uint32_t oa2_mask) +{ + MODIFY_REG(I2Cx->ADDR2, I2C_ADDR2_OA2MSK_MSK, oa2_mask); +} + +/** + * @brief Get I2C address2 mask + * @note None + * As soon as OA2MSK is not equal to 0,the reserved I2C addresses(0b0000xxx and 0b1111xxx) are not acknowledged even if the comparison matches. + * @param I2Cx I2C Instance + * @retval I2C own address2 mask(value 0 to 7) + */ +__STATIC_INLINE uint32_t md_i2c_get_addr2_oa2mask(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->ADDR2, I2C_ADDR2_OA2MSK_MSK)>>I2C_ADDR2_OA2MSK_POSS); +} + +/** + * @brief Set I2C own address2 + * @note These bits can be written only when OA2EN=0. + * @param I2Cx I2C Instance + * @param own_addr I2C own address2 + * @arg Max Value 0x7F + * @arg Min Value 0x1 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_addr2_oa2(I2C_TypeDef *I2Cx, uint32_t own_addr) +{ + MODIFY_REG(I2Cx->ADDR2, I2C_ADDR2_OA2_MSK, own_addr <ADDR2, I2C_ADDR2_OA2_MSK)>>I2C_ADDR2_OA2_POSS); +} + +/** + * @brief Set I2C TIMINGR + * @note These bits must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @param Reg_Value is a 32-bit value + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timingr(I2C_TypeDef *I2Cx, uint32_t Reg_Value) +{ + WRITE_REG(I2Cx->TIMINGR, Reg_Value); +} + +/** + * @brief Get I2C TIMINGR + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_timingr(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->TIMINGR)); +} + +/** + * @brief Set I2C Timing prescaler + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @param timing_prescaler + * @arg Max Value 0xF + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timingr_presc(I2C_TypeDef *I2Cx, uint32_t timing_prescaler) +{ + MODIFY_REG(I2Cx->TIMINGR, I2C_TIMINGR_PRESC_MSK, timing_prescaler << I2C_TIMINGR_PRESC_POSS); +} + +/** + * @brief Get I2C Timing prescaler + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval timing_prescaler + * @arg Max Value 0xF + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_i2c_get_timingr_presc(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_PRESC_MSK)>>I2C_TIMINGR_PRESC_POSS); +} + +/** + * @brief Set I2C date setup time + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @param data_setup_time + * @arg Max Value 0xF + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timingr_scldel(I2C_TypeDef *I2Cx, uint32_t data_setup_time) +{ + MODIFY_REG(I2Cx->TIMINGR, I2C_TIMINGR_SCLDEL_MSK, data_setup_time <TIMINGR, I2C_TIMINGR_SCLDEL_MSK)>>I2C_TIMINGR_SCLDEL_POSS); +} + +/** + * @brief Set I2C date hold time + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @param data_hold_time + * @arg Max Value 0xF + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timingr_sdadel(I2C_TypeDef *I2Cx, uint32_t data_hold_time) +{ + MODIFY_REG(I2Cx->TIMINGR, I2C_TIMINGR_SDADEL_MSK, data_hold_time << I2C_TIMINGR_SDADEL_POSS); +} + +/** + * @brief Get I2C date hold time + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval data_hold_time + * @arg Max Value 0xF + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_i2c_get_timingr_sdadel(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SDADEL_MSK)>>I2C_TIMINGR_SDADEL_POSS); +} + +/** + * @brief Set I2C SCL high period(master mode) + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @param SCL_hperiod + * @arg Max Value 0xFF + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timingr_sclh(I2C_TypeDef *I2Cx, uint32_t SCL_hperiod) +{ + MODIFY_REG(I2Cx->TIMINGR, I2C_TIMINGR_SCLH_MSK, SCL_hperiod << I2C_TIMINGR_SCLH_POSS); +} + +/** + * @brief Get I2C SCL high period(master mode) + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval SCL_hperiod + * @arg Max Value 0xFF + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_i2c_get_timingr_sclh(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLH_MSK)>>I2C_TIMINGR_SCLH_POSS); +} + +/** + * @brief Set I2C SCL low period(master mode) + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @param SCL_lperiod + * @arg Max Value 0xFF + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timingr_scll(I2C_TypeDef *I2Cx, uint32_t SCL_lperiod) +{ + MODIFY_REG(I2Cx->TIMINGR, I2C_TIMINGR_SCLL_MSK, SCL_lperiod << I2C_TIMINGR_SCLL_POSS); +} + +/** + * @brief Get I2C SCL low period(master mode) + * @note This register must be configured when the I2C is disabled(PE = 0) + * @param I2Cx I2C Instance + * @retval SCL_lperiod + * @arg Max Value 0xFF + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_i2c_get_timingr_scll(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLL_MSK)); +} + +/** + * @brief Set I2C TIMEOUTR + * @note These bits can be written only when TEXTEN=0 and TIMEOUTEN=0 except TEXTEN and TIMEOUTEN. + * @param I2Cx I2C Instance + * @param Reg_Value is a 32-bit value + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timeoutr(I2C_TypeDef *I2Cx, uint32_t Reg_Value) +{ + WRITE_REG(I2Cx->TIMEOUTR, Reg_Value); +} + +/** + * @brief Get I2C TIMEOUTR + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_timeoutr(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->TIMEOUTR)); +} + +/** + * @brief I2C Extended clock timeout Enable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_timeoutr_texten(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TEXTEN_MSK); +} + +/** + * @brief I2C Extended clock timeout Disable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_timeoutr_texten(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TEXTEN_MSK); +} + +/** + * @brief Indicate if I2C Extended clock timeout is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_timeoutr_texten(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TEXTEN_MSK) == (I2C_TIMEOUTR_TEXTEN_MSK)); +} + +/** + * @brief Set I2C Bus timeout B + * @note These bits can be written only when TEXTEN = 0 + * @param I2Cx I2C Instance + * @param timeoutb Bus timeout B + * @arg Max Value 0xFFFFFF + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timeoutr_timeoutb(I2C_TypeDef *I2Cx, uint32_t timeoutb) +{ + MODIFY_REG(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTB_MSK, timeoutb << I2C_TIMEOUTR_TIMEOUTB_POSS); +} + +/** + * @brief Get I2C Bus timeout B + * @note These bits can be written only when TEXTEN = 0 + * @param I2Cx I2C Instance + * @retval Bus timeout B + * @arg Max Value 0xFFFFFF + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_i2c_get_timeoutr_timeoutb(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTB_MSK)>>I2C_TIMEOUTR_TIMEOUTB_POSS); +} + +/** + * @brief I2C clock timeout Enable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_timeoutr_timeouten(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTEN_MSK); +} + +/** + * @brief I2C clock timeout Disable + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_timeoutr_timeouten(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTEN_MSK); +} + +/** + * @brief Indicate if I2C clock timeout is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_timeoutr_timeouten(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTEN_MSK) == (I2C_TIMEOUTR_TIMEOUTEN_MSK)); +} + +/** + * @brief Set I2C Tidle to decide a timeouta mode + * @note This bit can be written only when TIMOUTEN = 0 + * @param I2Cx I2C Instance + * @param tidle_mode + * @arg @ref MD_I2C_LOW_TIMEOUTA + * @arg @ref MD_I2C_IDLE_TIMEOUTA + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timeoutr_tidle(I2C_TypeDef *I2Cx, uint32_t tidle_mode) +{ + MODIFY_REG(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIDLE_MSK, tidle_mode); +} + +/** + * @brief Get I2C Tidle to know a timeouta mode + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_timeoutr_tidle(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIDLE_MSK)>>I2C_TIMEOUTR_TIDLE_POS); +} + +/** + * @brief Set I2C Bus timeout A + * @note These bits can be written only when TIMOUTEN = 0 + * @param I2Cx I2C Instance + * @param timeouta Bus timeout A + * @arg Max Value 0xFFFFFF + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_timeoutr_timeouta(I2C_TypeDef *I2Cx, uint32_t timeouta) +{ + MODIFY_REG(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTA_MSK, timeouta << I2C_TIMEOUTR_TIMEOUTA_POSS); +} + +/** + * @brief Get I2C Bus timeout A + * @note These bits can be written only when TIMOUTEN = 0 + * @param I2Cx I2C Instance + * @retval Bus timeout A + * @arg Max Value 0xFFFFFF + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_i2c_get_timeoutr_timeouta(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTA_MSK)); +} + +/** + * @brief Get I2C STAT + * @note All bits are read-only + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_stat(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->STAT)); +} + +/** + * @brief Get address match code(slave mode) + * @note These bits are updated with the received address when an address match event occurs(ADDR=1). + * @param I2Cx I2C Instance + * @retval 7-bit received address value + */ +__STATIC_INLINE uint32_t md_i2c_get_stat_addcode(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->STAT, I2C_STAT_ADDCODE_MSK)>>I2C_STAT_ADDCODE_POSS); +} + +/** + * @brief Get transfer direction(slave mode) + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_get_stat_dir(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->STAT, I2C_STAT_DIR_MSK)>>I2C_STAT_DIR_POS); +} + +/** + * @brief Indicate if I2C busy flag is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_busy(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_BUSY_MSK) == (I2C_STAT_BUSY_MSK)); +} + +/** + * @brief Indicate if I2C transfer complete reload flag (TCR) is active + * @note This bit is cleared by hardware when PE = 0. + * This flag is only for master mode,or for slave mode when the SBC bit is set + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_tcr(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_TCR_MSK) == (I2C_STAT_TCR_MSK)); +} + +/** + * @brief Indicate if I2C transfer complete flag (TC) is active + * @note This bit is cleared by hardware when PE = 0. + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_tc(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_TC_MSK) == (I2C_STAT_TC_MSK)); +} + +/** + * @brief Indicate if I2C Rx FIFO level over threshold flag (RXTH) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_rxth(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_RXTH_MSK) == (I2C_STAT_RXTH_MSK)); +} + +/** + * @brief Indicate if I2C Rx buffer underflow flag (RXUD) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_rxud(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_RXUD_MSK) == (I2C_STAT_RXUD_MSK)); +} + +/** + * @brief Indicate if I2C Rx buffer overflow flag (RXOV) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_rxov(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_RXOV_MSK) == (I2C_STAT_RXOV_MSK)); +} + +/** + * @brief Indicate if I2C Rx buffer full flag (RXF) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_rxf(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_RXF_MSK) == (I2C_STAT_RXF_MSK)); +} + +/** + * @brief Indicate if I2C Rx buffer empty flag (RXE) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_rxe(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_RXE_MSK) == (I2C_STAT_RXE_MSK)); +} + +/** + * @brief Indicate if I2C Tx FIFO level over threshold flag (TXTH) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_txth(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_TXTH_MSK) == (I2C_STAT_TXTH_MSK)); +} + +/** + * @brief Indicate if I2C Tx buffer underflow flag (TXUD) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_is_active_stat_txud(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_TXUD_MSK) == (I2C_STAT_TXUD_MSK)); +} + +/** + * @brief Indicate if I2C Tx buffer overflow flag (TXOV) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_txov(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_TXOV_MSK) == (I2C_STAT_TXOV_MSK)); +} + +/** + * @brief Indicate if I2C Tx buffer full flag (TXF) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_txf(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_TXF_MSK) == (I2C_STAT_TXF_MSK)); +} + +/** + * @brief Indicate if I2C Tx buffer empty flag (TXE) is active + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_stat_txe(I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->STAT, I2C_STAT_TXE_MSK) == (I2C_STAT_TXE_MSK)); +} + +/** + * @brief Set I2C FCON + * @note FIFO trigger threshold must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @param Reg_Value is a 32-bit value + * @retval None + */ +__STATIC_INLINE void md_i2c_set_fcon(I2C_TypeDef *I2Cx, uint32_t Reg_Value) +{ + WRITE_REG(I2Cx->FCON, Reg_Value); +} + +/** + * @brief Get I2C FCON + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_fcon(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->FCON)); +} + +/** + * @brief Set RXFIFO trigger threshold + * @note Receive FIFO trigger threshold must be configured when the I2C is disabled (PE = 0). + * @param I2Cx I2C Instance + * @param rxfifo_trigger_threshold This parameter can be one of the following values: + * @arg @ref MD_I2C_RXFIFO_THRESHOLD_RX1 + * @arg @ref MD_I2C_RXFIFO_THRESHOLD_RX4 + * @arg @ref MD_I2C_RXFIFO_THRESHOLD_RX8 + * @arg @ref MD_I2C_RXFIFO_THRESHOLD_RX14 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_fcon_rxfth(I2C_TypeDef *I2Cx, uint32_t rxfifo_trigger_threshold) +{ + MODIFY_REG(I2Cx->FCON, I2C_FCON_RXFTH_MSK, rxfifo_trigger_threshold); +} + +/** + * @brief Get RXFIFO trigger threshold + * @note None + * @param I2Cx I2C Instance + * @retval The retval can be 0 to 3 + */ +__STATIC_INLINE uint32_t md_i2c_get_fcon_rxfth(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->FCON, I2C_FCON_RXFTH_MSK)>>I2C_FCON_RXFTH_POSS); +} + +/** + * @brief Set I2C RXFIFO reset + * @note None + * @param I2Cx I2C Instance + * @arg @ref MD_I2C_RXFIFO_RESET + * @retval None + */ +__STATIC_INLINE void md_i2c_set_fcon_rxfrst(I2C_TypeDef *I2Cx, uint32_t reset) +{ + MODIFY_REG(I2Cx->FCON, I2C_FCON_RXFRST_MSK, reset); +} + +/** + * @brief Get I2C RXFIFO level + * @note None + * @param I2Cx I2C Instance + * @retval It's from 0 to 16 + */ +__STATIC_INLINE uint32_t md_i2c_get_rxfifo_level(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->FCON, I2C_FCON_RXFLV_MSK)>>I2C_FCON_RXFLV_POSS); +} + +/** + * @brief Set TXFIFO trigger threshold + * @param I2Cx I2C Instance + * @param txfifo_trigger_threshold This parameter can be one of the following values: + * @arg @ref MD_I2C_TXFIFO_THRESHOLD_TX0 + * @arg @ref MD_I2C_TXFIFO_THRESHOLD_TX2 + * @arg @ref MD_I2C_TXFIFO_THRESHOLD_TX4 + * @arg @ref MD_I2C_TXFIFO_THRESHOLD_TX8 + * @retval None + */ +__STATIC_INLINE void md_i2c_set_fcon_txfth(I2C_TypeDef *I2Cx, uint32_t txfifo_trigger_threshold) +{ + MODIFY_REG(I2Cx->FCON, I2C_FCON_TXFTH_MSK, txfifo_trigger_threshold); +} + +/** + * @brief Get TXFIFO trigger threshold + * @param I2Cx I2C Instance + * @retval It's from 0 to 3 + */ +__STATIC_INLINE uint32_t md_i2c_get_txfifo_trigger_threshold(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->FCON, I2C_FCON_TXFTH_MSK)>>I2C_FCON_TXFTH_POSS); +} + +/** + * @brief I2C TXFIFO reset + * @note None + * @param I2Cx I2C Instance + * @arg @ref MD_I2C_TXFIFO_RESET + * @retval None + */ +__STATIC_INLINE void md_i2c_set_fcon_txfrst(I2C_TypeDef *I2Cx, uint32_t reset) +{ + MODIFY_REG(I2Cx->FCON, I2C_FCON_TXFRST_MSK, reset); +} + +/** + * @brief Get TXFIFO level + * @note None + * @param I2Cx I2C Instance + * @retval It's from 0 to 16 + */ +__STATIC_INLINE uint32_t md_i2c_get_txfifo_level(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->FCON, I2C_FCON_TXFLV_MSK)); +} + +/** + * @brief Get packet error checking register + * @note None + * @param I2Cx I2C Instance + * @retval 8-bit pec value + */ +__STATIC_INLINE uint32_t md_i2c_get_pecr_pec(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->PECR, I2C_PECR_PEC_MSK)); +} + +/** + * @brief 8-bit receive data + * @note None + * @param I2Cx I2C Instance + * @retval 8-bit receive data + */ +__STATIC_INLINE uint32_t md_i2c_recv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RXDATA, I2C_RXDATA_RXDATA_MSK)); +} + +/** + * @brief 8-bit transmit data + * @note These bits can be written only when TXE = 1. + * @param I2Cx I2C Instance + * @param txdata Transmit Data + * @arg Max value 0xFF + * @arg Min value 0 + * @retval None + */ +__STATIC_INLINE void md_i2c_send(I2C_TypeDef *I2Cx, uint32_t txdata) +{ + MODIFY_REG(I2Cx->TXDATA, I2C_TXDATA_TXDATA_MSK, txdata); +} + +/** + * @brief Set I2C IER + * @note None + * @param I2Cx I2C Instance + * @param ier + * @retval None + */ +__STATIC_INLINE void md_i2c_set_ier(I2C_TypeDef *I2Cx, uint32_t ier) +{ + WRITE_REG(I2Cx->IER, ier); +} + +/** + * @brief Enable SMBus alert interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_alertie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_ALERTIE_MSK); +} + +/** + * @brief Enable timeout interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_toutie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_TOUTIE_MSK); +} + +/** + * @brief Enable PEC error interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_peceie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_PECEIE_MSK); +} + +/** + * @brief Enable arbitration loss interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_arloie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_ARLOIE_MSK); +} + +/** + * @brief Enable bus error interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_berrie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_BERRIE_MSK); +} + +/** + * @brief Enable stop detection interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_stopie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_STOPIE_MSK); +} + +/** + * @brief Enable NACK reception interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_nackie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_NACKIE_MSK); +} + +/** + * @brief Enable address matched interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_addrie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_ADDRIE_MSK); +} + +/** + * @brief Enable transfer complete and reload interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_tcrie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_TCRIE_MSK); +} + +/** + * @brief Enable transfer complete interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_tcie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_TCIE_MSK); +} + +/** + * @brief Enable receive buffer over threshold interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_rxthie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_RXTHIE_MSK); +} + +/** + * @brief Enable receive buffer underrun interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_rxudie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_RXUDIE_MSK); +} + +/** + * @brief Enable receive buffer ovrun interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_rxovie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_RXOVIE_MSK); +} + +/** + * @brief Enable receive buffer full interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_rxfie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_RXFIE_MSK); +} + +/** + * @brief Enable transmit buffer under threshold interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_txthie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_TXTHIE_MSK); +} + +/** + * @brief Enable transmit buffer underrun interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_txudie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_TXUDIE_MSK); +} + +/** + * @brief Enable transmit buffer ovrun interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_txovie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_TXOVIE_MSK); +} + +/** + * @brief Enable transmit buffer empty interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_enable_ier_txeie(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->IER, I2C_IER_TXEIE_MSK); +} + +/** + * @brief Set I2C IDR + * @note None + * @param I2Cx I2C Instance + * @param ier + * @retval None + */ +__STATIC_INLINE void md_i2c_set_idr(I2C_TypeDef *I2Cx, uint32_t idr) +{ + WRITE_REG(I2Cx->IDR, idr); +} + +/** + * @brief Disable SMBus alert interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_alertid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_ALERTID_MSK); +} + +/** + * @brief Disable timeout interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_toutid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_TOUTID_MSK); +} + +/** + * @brief Disable PEC error interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_peceid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_PECEID_MSK); +} + +/** + * @brief Disable arbitration loss interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_arloid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_ARLOID_MSK); +} + +/** + * @brief Disable bus error interrupt. + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_berrid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_BERRID_MSK); +} + +/** + * @brief Disable stop detection interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_stopid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_STOPID_MSK); +} + +/** + * @brief Disable NACK reception interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_nackid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_NACKID_MSK); +} + +/** + * @brief Disable address matched interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_addrid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_ADDRID_MSK); +} + +/** + * @brief Disable transfer complete and reload interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_tcrid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_TCRID_MSK); +} + +/** + * @brief Disable transfer complete interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_tcid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_TCID_MSK); +} + +/** + * @brief Disable receive buffer over threshold interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_rxthid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_RXTHID_MSK); +} + +/** + * @brief Disable receive buffer underrun interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_rxudid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_RXUDID_MSK); +} + +/** + * @brief Disable receive buffer ovrun interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_rxovid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_RXOVID_MSK); +} + +/** + * @brief Disable receive buffer full interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_rxfid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_RXFID_MSK); +} + +/** + * @brief Disable transmit buffer under threshold interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_txthid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_TXTHID_MSK); +} + +/** + * @brief Disable transmit buffer underrun interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_txudid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_TXUDID_MSK); +} + +/** + * @brief Disable transmit buffer ovrun interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_txovid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_TXOVID_MSK); +} + +/** + * @brief Disable transmit buffer empty interrupt + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_disable_idr_txeid(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->IDR, I2C_IDR_TXEID_MSK); +} + +/** + * @brief Get I2C IVS + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_ivs(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->IVS)); +} + +/** + * @brief Check if SMBus alert interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_alertiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_ALERTIV_MSK) == (I2C_IVS_ALERTIV_MSK)); +} + +/** + * @brief Check if timeout interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_toutiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_TOUTIV_MSK) == (I2C_IVS_TOUTIV_MSK)); +} + +/** + * @brief Check if PEC error interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_peceiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_PECEIV_MSK) == (I2C_IVS_PECEIV_MSK)); +} + +/** + * @brief Check if arbitration loss interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_arloiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_ARLOIV_MSK) == (I2C_IVS_ARLOIV_MSK)); +} + +/** + * @brief Check if bus error interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_berriv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_BERRIV_MSK) == (I2C_IVS_BERRIV_MSK)); +} + +/** + * @brief Check if stop detection interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_stopiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_STOPIV_MSK) == (I2C_IVS_STOPIV_MSK)); +} + +/** + * @brief Check if NACK reception interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_nackiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_NACKIV_MSK) == (I2C_IVS_NACKIV_MSK)); +} + +/** + * @brief Check if address matched interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_addriv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_ADDRIV_MSK) == (I2C_IVS_ADDRIV_MSK)); +} + +/** + * @brief Check if transfer complete and reload interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_tcriv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_TCRIV_MSK) == (I2C_IVS_TCRIV_MSK)); +} + +/** + * @brief Check if transfer complete interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_tciv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_TCIV_MSK) == (I2C_IVS_TCIV_MSK)); +} + +/** + * @brief Check if receive buffer over threshold interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_rxthiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_RXTHIV_MSK) == (I2C_IVS_RXTHIV_MSK)); +} + +/** + * @brief Check if receive buffer underrun interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_rxudiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_RXUDIV_MSK) == (I2C_IVS_RXUDIV_MSK)); +} + +/** + * @brief Check if receive buffer ovrun interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_rxoviv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_RXOVIV_MSK) == (I2C_IVS_RXOVIV_MSK)); +} + +/** + * @brief Check if receive buffer full interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_rxfiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_RXFIV_MSK) == (I2C_IVS_RXFIV_MSK)); +} + +/** + * @brief Check if transmit buffer under threshold interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_txthiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_TXTHIV_MSK) == (I2C_IVS_TXTHIV_MSK)); +} + +/** + * @brief Check if transmit buffer underrun interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_txudiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_TXUDIV_MSK) == (I2C_IVS_TXUDIV_MSK)); +} + +/** + * @brief Check if transmit buffer ovrun interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_txoviv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_TXOVIV_MSK) == (I2C_IVS_TXOVIV_MSK)); +} + +/** + * @brief Check if transmit buffer empty interrupt is enabled + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_enabled_ivs_txeiv(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IVS, I2C_IVS_TXEIV_MSK) == (I2C_IVS_TXEIV_MSK)); +} + +/** + * @brief Get I2C RIF + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_rif(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->RIF)); +} + +/** + * @brief Get SMBus alert raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_alertri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_ALERTRI_MSK) == (I2C_RIF_ALERTRI_MSK)); +} + +/** + * @brief Get timeout raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_toutri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_TOUTRI_MSK) == (I2C_RIF_TOUTRI_MSK)); +} + +/** + * @brief Get PEC error raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_peceri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_PECERI_MSK) == (I2C_RIF_PECERI_MSK)); +} + +/** + * @brief Get arbitration loss raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_arlori(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_ARLORI_MSK) == (I2C_RIF_ARLORI_MSK)); +} + +/** + * @brief Get bus error raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_berrri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_BERRRI_MSK) == (I2C_RIF_BERRRI_MSK)); +} + +/** + * @brief Get stop detection raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_stopri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_STOPRI_MSK) == (I2C_RIF_STOPRI_MSK)); +} + +/** + * @brief Get NACK reception raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_nackri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_NACKRI_MSK) == (I2C_RIF_NACKRI_MSK)); +} + +/** + * @brief Get address matched raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_addrri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_ADDRRI_MSK) == (I2C_RIF_ADDRRI_MSK)); +} + +/** + * @brief Get transfer complete and reload raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_tcrri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_TCRRI_MSK) == (I2C_RIF_TCRRI_MSK)); +} + +/** + * @brief Get transfer complete raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_tcri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_TCRI_MSK) == (I2C_RIF_TCRI_MSK)); +} + +/** + * @brief Get receive buffer over threshold raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_rxthri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_RXTHRI_MSK) == (I2C_RIF_RXTHRI_MSK)); +} + +/** + * @brief Get receive buffer underrun raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_rxudri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_RXUDRI_MSK) == (I2C_RIF_RXUDRI_MSK)); +} + +/** + * @brief Get receive buffer ovrun raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_rxovri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_RXOVRI_MSK) == (I2C_RIF_RXOVRI_MSK)); +} + +/** + * @brief Get receive buffer full raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_rxfri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_RXFRI_MSK) == (I2C_RIF_RXFRI_MSK)); +} + +/** + * @brief Get transmit buffer under threshold raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_txthri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_TXTHRI_MSK) == (I2C_RIF_TXTHRI_MSK)); +} + +/** + * @brief Get transmit buffer underrun raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_txudri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_TXUDRI_MSK) == (I2C_RIF_TXUDRI_MSK)); +} + +/** + * @brief Get transmit buffer ovrun raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_txovri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_TXOVRI_MSK) == (I2C_RIF_TXOVRI_MSK)); +} + +/** + * @brief Get transmit buffer empty raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_rif_txeri(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->RIF, I2C_RIF_TXERI_MSK) == (I2C_RIF_TXERI_MSK)); +} + +/** + * @brief Set I2C ICR + * @note None + * @param I2Cx I2C Instance + * @param icr + * @retval None + */ +__STATIC_INLINE void md_i2c_set_icr(I2C_TypeDef *I2Cx, uint32_t icr) +{ + WRITE_REG(I2Cx->ICR, icr); +} + +/** + * @brief Clear SMBus alert raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_alertic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_ALERTIC_MSK); +} + +/** + * @brief Clear timeout raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_toutic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_TOUTIC_MSK); +} + +/** + * @brief Clear PEC error raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_peceic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_PECEIC_MSK); +} + +/** + * @brief Clear arbitration loss raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_arloic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_ARLOIC_MSK); +} + +/** + * @brief Clear bus error raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_berric(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_BERRIC_MSK); +} + +/** + * @brief Clear stop detection raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_stopic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_STOPIC_MSK); +} + +/** + * @brief Clear NACK reception raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_nackic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_NACKIC_MSK); +} + +/** + * @brief Clear address matched raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_addric(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_ADDRIC_MSK); +} + +/** + * @brief Clear transfer complete and reload raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_tcric(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_TCRIC_MSK); +} + +/** + * @brief Clear transfer complete raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_tcic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_TCIC_MSK); +} + +/** + * @brief Clear receive buffer over threshold raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_rxthic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_RXTHIC_MSK); +} + +/** + * @brief Clear receive buffer underrun raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_rxudic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_RXUDIC_MSK); +} + +/** + * @brief Clear receive buffer ovrun raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_rxovic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_RXOVIC_MSK); +} + +/** + * @brief Clear receive buffer full raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_rxfic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_RXFIC_MSK); +} + +/** + * @brief Clear transmit buffer under threshold raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_txthic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_TXTHIC_MSK); +} + +/** + * @brief Clear transmit buffer underrun raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_txudic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_TXUDIC_MSK); +} + +/** + * @brief Clear transmit buffer ovrun raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_txovic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_TXOVIC_MSK); +} + +/** + * @brief Clear transmit buffer empty raw interrupt flag + * @note None + * @param I2Cx I2C Instance + * @retval None + */ +__STATIC_INLINE void md_i2c_clear_icr_txeic(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_TXEIC_MSK); +} + +/** + * @brief Get I2C IFM + * @note None + * @param I2Cx I2C Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_i2c_get_ifm(I2C_TypeDef *I2Cx) +{ + return (uint32_t) (READ_REG(I2Cx->IFM)); +} + +/** + * @brief Get SMBus alert interrupt flag massked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_alertfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_ALERTFM_MSK) == (I2C_IFM_ALERTFM_MSK)); +} + +/** + * @brief Get timeout interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_toutfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_TOUTFM_MSK) == (I2C_IFM_TOUTFM_MSK)); +} + +/** + * @brief Get PEC error interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_pecefm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_PECEFM_MSK) == (I2C_IFM_PECEFM_MSK)); +} + +/** + * @brief Get arbitration loss interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_arlofm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_ARLOFM_MSK) == (I2C_IFM_ARLOFM_MSK)); +} + +/** + * @brief Get bus error interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_berrfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_BERRFM_MSK) == (I2C_IFM_BERRFM_MSK)); +} + +/** + * @brief Get stop detection interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_stopfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_STOPFM_MSK) == (I2C_IFM_STOPFM_MSK)); +} + +/** + * @brief Get NACK reception interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_nackfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_NACKFM_MSK) == (I2C_IFM_NACKFM_MSK)); +} + +/** + * @brief Get address matched interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_addrfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_ADDRFM_MSK) == (I2C_IFM_ADDRFM_MSK)); +} + +/** + * @brief Get transfer complete and reload interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_tcrfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_TCRFM_MSK) == (I2C_IFM_TCRFM_MSK)); +} + +/** + * @brief Get transfer complete interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_tcfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_TCFM_MSK) == (I2C_IFM_TCFM_MSK)); +} + +/** + * @brief Get receive buffer over threshold interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_rxthfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_RXTHFM_MSK) == (I2C_IFM_RXTHFM_MSK)); +} + +/** + * @brief Get receive buffer underrun interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_rxudfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_RXUDFM_MSK) == (I2C_IFM_RXUDFM_MSK)); +} + +/** + * @brief Get receive buffer ovrun interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_rxovfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_RXOVFM_MSK) == (I2C_IFM_RXOVFM_MSK)); +} + +/** + * @brief Get receive buffer full interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_rxffm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_RXFFM_MSK) == (I2C_IFM_RXFFM_MSK)); +} + +/** + * @brief Get transmit buffer under threshold interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_txthfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_TXTHFM_MSK) == (I2C_IFM_TXTHFM_MSK)); +} + +/** + * @brief Get transmit buffer underrun interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_txudfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_TXUDFM_MSK) == (I2C_IFM_TXUDFM_MSK)); +} + +/** + * @brief Get transmit buffer ovrun interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_txovfm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_TXOVFM_MSK) == (I2C_IFM_TXOVFM_MSK)); +} + +/** + * @brief Get transmit buffer empty interrupt flag masked status + * @note None + * @param I2Cx I2C Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_i2c_is_active_ifm_txefm(I2C_TypeDef *I2Cx) +{ + return (READ_BIT(I2Cx->IFM, I2C_IFM_TXEFM_MSK) == (I2C_IFM_TXEFM_MSK)); +} + +/** + * @} MD_I2C_Public_Macros + */ + + + + + + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_I2C_Public_Functions I2C Public Functions + * @{ + */ + +/** @defgroup MD_I2C_PF_Basic_Configuration I2C Configuration + * @{ + */ + +//ErrorStatus md_i2c_deinit(I2C_TypeDef *I2Cx); +ErrorStatus md_i2c_init(I2C_TypeDef *I2Cx, md_i2c_inittypedef *I2C_InitStruct); +void md_i2c_struct_init(md_i2c_inittypedef *I2C_InitStruct); +void md_i2c_master_send(I2C_TypeDef *I2Cx, uint8_t Nbyte, uint32_t addr10, uint16_t DevAddr, uint8_t *txbuf); +void md_i2c_master_rece(I2C_TypeDef *I2Cx, uint8_t Nbyte, uint32_t addr10, uint16_t DevAddr, uint8_t *rxbuf); +void md_i2c_slave_send(I2C_TypeDef *I2Cx, uint8_t Num, uint8_t *txbuf); +void md_i2c_slave_rece(I2C_TypeDef *I2Cx, uint8_t Num, uint8_t *rxbuf); + +/** + * @} MD_I2C_PF_Init + */ + +/** + * @} MD_I2C_Public_Functions + */ + +#endif + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup MD_I2C_Private_Macro I2C Private Macros + * @{ + */ +#define IS_MD_I2C_ALL_INSTANCE(__INSTANCE__) ((__INSTANCE__ == I2C1) \ + || (__INSTANCE__ == I2C2) \ + || (__INSTANCE__ == I2C3)) + +#define IS_MD_I2C_TIMING(__VALUE__) ((__VALUE__ == CLK10kHz8M) \ + || (__VALUE__ == CLK100kHz8M)) \ + || (__VALUE__ == CLK400kHz8M)) \ + || (__VALUE__ == CLK500kHz8M)) \ + || (__VALUE__ == CLK10kHz16M)) \ + || (__VALUE__ == CLK100kHz16M)) \ + || (__VALUE__ == CLK400kHz16M)) \ + || (__VALUE__ == CLK1000kHz16M)) \ + || (__VALUE__ == CLK10kHz48M)) \ + || (__VALUE__ == CLK100kHz48M)) \ + || (__VALUE__ == CLK400kHz48M)) \ + || (__VALUE__ == CLK1000kHz48M)) + +#define IS_MD_I2C_ADDRSIZE(__VALUE__) ((__VALUE__ == MD_I2C_ADDRESSINGMODE_7BIT) \ + || (__VALUE__ == MD_I2C_ADDRESSINGMODE_10BIT)) + +#define IS_MD_I2C_ADDRESS1(__VALUE__) (__VALUE__ <= 0x000003FFU) +#define IS_MD_I2C_ADDRESS2(__VALUE__) (__VALUE__ <= (uint16_t)0x00FFU) + +#define IS_MD_I2C_DUALADDRESSMODE(__VALUE__) ((__VALUE__ == MD_I2C_DUALADDRESS_DISABLE) \ + || (__VALUE__ == MD_I2C_DUALADDRESS_ENABLE)) +#define IS_MD_I2C_ADDRESS2MASKS(__VALUE__) ((__VALUE__ == MD_I2C_ADDR2_NOMASK) \ + || (__VALUE__ == MD_I2C_ADDR2_MASK01) \ + || (__VALUE__ == MD_I2C_ADDR2_MASK02) \ + || (__VALUE__ == MD_I2C_ADDR2_MASK03) \ + || (__VALUE__ == MD_I2C_ADDR2_MASK04) \ + || (__VALUE__ == MD_I2C_ADDR2_MASK05) \ + || (__VALUE__ == MD_I2C_ADDR2_MASK06) \ + || (__VALUE__ == MD_I2C_ADDR2_MASK07)) + +/** + * @} MD_I2C_Private_Macro + */ + +/** + * @} I2C + */ + +/** + * @} Micro_Driver + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_rcu.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_rcu.h new file mode 100644 index 0000000000..1b9b6ff09b --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_rcu.h @@ -0,0 +1,5804 @@ +/** + ****************************************************************************** + * @file md_RCU.h + * @brief ES32F0271 RCU HEAD File. + * + * @version V1.00.02 + * @date 30/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_RCU_H__ +#define __MD_RCU_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include +#include "es32f0271.h" +#include "reg_rcu.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (RCU) + +/** @defgroup RCU RCU + * @brief RCU micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/** @defgroup MD_RCU_Private_Constants RCU Private Constants + * @{ + */ + +#define __HOSC (8000000UL) +#define __HRC (4000000UL) +#define __LOSC ( 32768UL) +#define __LRC ( 32000UL) +#define __PLL1 (48000000UL) + +/** + * @} MD_RCU_Private_Constants + */ +/* Private macros -------------------------------------------------------------*/ +/* Public types ---------------------------------------------------------------*/ +/* Public types ---------------------------------------------------------------*/ +/** @defgroup MD_RCU_Public_Types RCU Public Init Type + * @{ + */ + +typedef struct +{ + uint32_t Mpre; /*! MCO clock prescaler */ + uint32_t Msw; /*! MCO clock output */ + uint32_t PllMul; /*! PLL multiplication factor */ + uint32_t PllSrc; /*! PLL clock source */ + uint32_t HoscDiv; /*! PLL base clock 4MHz HOSC clock prescale */ + uint32_t Ppre; /*! APB clock prescaler */ + uint32_t Hpre; /*! AHB clock prescaler */ + uint32_t Sw; /*! system clock */ + uint8_t SysClock;/*! system clock enable */ +} md_rcu_init_typedef; + +/** + * @} MD_RCU_Public_Types + */ +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_RCU_Public_Constants RCU Public Constants + * @{ + */ + +/** @defgroup MD_RCU_SWRDY_FLAG System clock switch ready flag + * @{ + */ +#define MD_RCU_SWRDY_NOT_READY (0x00000000UL) /** @brief System clock not ready */ +#define MD_RCU_SWRDY_READY (0x00000001UL) /** @brief System clock ready */ +/** + * @} MD_RCU_SWRDY_FLAG + */ + +/** @defgroup MD_RCU_CSSFLG_FLAG Clock Security System flag + * @{ + */ +#define MD_RCU_CSSFLG_NO_FAIL (0x00000000UL) /** @brief No clock security event caused by HOSC clock failure */ +#define MD_RCU_CSSFLG_FAIL (0x00000001UL) /** @brief Clock security event caused by HOSC clock failure */ +/** + * @} MD_RCU_CSSFLG_FLAG + */ + +/** @defgroup MD_RCU_PLL1_FLAG PLL1 clock ready flag + * @{ + */ +#define MD_RCU_PLL1_NOT_READY (0x00000000UL) /** @brief PLL1 not ready */ +#define MD_RCU_PLL1_READY (0x00000001UL) /** @brief PLL1 ready */ +/** + * @} MD_RCU_PLL1_FLAG + */ + +/** @defgroup MD_RCU_PLL0_FLAG PLL0 clock ready flag + * @{ + */ +#define MD_RCU_PLL0_NOT_READY (0x00000000UL) /** @brief PLL0 not ready */ +#define MD_RCU_PLL0_READY (0x00000001UL) /** @brief PLL0 ready */ +/** + * @} MD_RCU_PLL0_FLAG + */ + +/** @defgroup MD_RCU_LOSCRDY_FLAG LOSC clock ready flag + * @{ + */ +#define MD_RCU_LOSCRDY_NOT_READY (0x00000000UL) /** @brief LOSC oscillator not ready */ +#define MD_RCU_LOSCRDY_READY (0x00000001UL) /** @brief LOSC oscillator ready */ +/** + * @} MD_RCU_LOSCRDY_FLAG + */ + +/** @defgroup MD_RCU_LRCRDY_FLAG LRC clock ready flag + * @{ + */ +#define MD_RCU_LRCRDY_NOT_READY (0x00000000UL) /** @brief LRC oscillator not ready */ +#define MD_RCU_LRCRDY_READY (0x00000001UL) /** @brief LRC oscillator ready */ +/** + * @} MD_RCU_LRCRDY_FLAG + */ + +/** @defgroup MD_RCU_HOSCRDY_FLAG HOSC clock ready flag + * @{ + */ +#define MD_RCU_HOSCRDY_NOT_READY (0x00000000UL) /** @brief HOSC oscillator not ready */ +#define MD_RCU_HOSCRDY_READY (0x00000001UL) /** @brief HOSC oscillator ready */ +/** + * @} MD_RCU_HOSCRDY_FLAG + */ + +/** @defgroup MD_RCU_HRCRDY_FLAG HRC clock ready flag + * @{ + */ +#define MD_RCU_HRCRDY_NOT_READY (0x00000000UL) /** @brief HRC oscillator not ready */ +#define MD_RCU_HRCRDY_READY (0x00000001UL) /** @brief HRC oscillator ready */ +/** + * @} MD_RCU_HRCRDY_FLAG + */ + +/** @defgroup MD_RCU_MCO_OUTPUT Microcontroller clock output select + * @{ + */ +#define MD_RCU_MCO_DISABLE (0x00000000UL) /** @brief MCO output disabled, no clock on MCO */ +#define MD_RCU_MCO_LRC (0x00000001UL) /** @brief Internal low speed (LRC) oscillator clock selected */ +#define MD_RCU_MCO_LOSC (0x00000002UL) /** @brief External low speed (LOSC) oscillator clock selected */ +#define MD_RCU_MCO_HRC (0x00000003UL) /** @brief Internal high speed (HRC) oscillator clock selected */ +#define MD_RCU_MCO_HOSC (0x00000004UL) /** @brief External high speed (HOSC) oscillator clock selected */ +#define MD_RCU_MCO_PLL0 (0x00000005UL) /** @brief PLL0 clock selected */ +#define MD_RCU_MCO_PLL1 (0x00000006UL) /** @brief PLL1 clock selected */ +#define MD_RCU_MCO_SYSCLK (0x00000007UL) /** @brief System clock selected(SYSCLK) */ +#define MD_RCU_MCO_HCLK (0x00000008UL) /** @brief AHB clock selected(HCLK) */ +#define MD_RCU_MCO_PCLK (0x00000009UL) /** @brief APB clock selected(PCLK) */ +/** + * @} MD_RCU_MCO_OUTPUT + */ + +/** @defgroup MD_RCU_PLL_SRC PLL0/1 reference clock source + * @{ + */ +#define MD_RCU_PLL_SRC_HRC (0x00000000UL) /** @brief HRC selected as PLL0/1 reference clock */ +#define MD_RCU_PLL_SRC_HOSCDIV (0x00000001UL) /** @brief HOSC/HOSCDIV selected as PLL reference clock */ +/** + * @} MD_RCU_PLL_SRC + */ + +/** @defgroup MD_RCU_APB_CLK_DIV APB clock prescaler(PCLK) + * @{ + */ +#define MD_RCU_PPRE_HCLK_DIV_1 (0x00000000UL) /** @brief HCLK not divided */ +#define MD_RCU_PPRE_HCLK_DIV_2 (0x00000004UL) /** @brief HCLK divided by 2 */ +#define MD_RCU_PPRE_HCLK_DIV_4 (0x00000005UL) /** @brief HCLK divided by 4 */ +#define MD_RCU_PPRE_HCLK_DIV_8 (0x00000006UL) /** @brief HCLK divided by 8 */ +#define MD_RCU_PPRE_HCLK_DIV_16 (0x00000007UL) /** @brief HCLK divided by 16 */ +/** + * @} MD_RCU_APB_CLK_DIV + */ + +/** @defgroup MD_RCU_AHB_CLK_DIV AHB clock prescaler(HCLK) + * @{ + */ +#define MD_RCU_HPRE_SYSCLK_DIV_1 (0x00000000UL) /** @brief SYSCLK not divided */ +#define MD_RCU_HPRE_SYSCLK_DIV_2 (0x00000008UL) /** @brief SYSCLK divided by 2 */ +#define MD_RCU_HPRE_SYSCLK_DIV_4 (0x00000009UL) /** @brief SYSCLK divided by 4 */ +#define MD_RCU_HPRE_SYSCLK_DIV_8 (0x0000000AUL) /** @brief SYSCLK divided by 8 */ +#define MD_RCU_HPRE_SYSCLK_DIV_16 (0x0000000BUL) /** @brief SYSCLK divided by 16 */ +/** + * @} MD_RCU_AHB_CLK_DIV + */ + +/** @defgroup MD_RCU_SYS_CLK_SW System clock switch(SYSCLK) + * @{ + */ +#define MD_RCU_SYSCLK_HRC (0x00000000UL) /** @brief HRC selected as system clock */ +#define MD_RCU_SYSCLK_HOSC (0x00000001UL) /** @brief HOSC selected as system clock */ +#define MD_RCU_SYSCLK_LRC (0x00000002UL) /** @brief LRC selected as system clock */ +#define MD_RCU_SYSCLK_LOSC (0x00000003UL) /** @brief LOSC selected as system clock */ +#define MD_RCU_SYSCLK_PLL0 (0x00000004UL) /** @brief PLL0 selected as system clock */ +/** + * @} MD_RCU_SYS_CLK_SW + */ + +/** @defgroup MD_RCU_PSCK_I2S2CKSL SPI2/I2S2 External Clock Source Select + * @{ + */ +#define MD_RCU_PSCK_I2S2CKSL_DISABLE (0x00000000UL) /** @brief Disable External Clock (default value) */ +#define MD_RCU_PSCK_I2S2CKSL_I2SCLK1 (0x00000001UL) +#define MD_RCU_PSCK_I2S2CKSL_I2SCLK2 (0x00000002UL) +/** + * @} MD_RCU_PSCK_I2S2CKSL + */ + +/** @defgroup MD_RCU_PSCK_I2S1CKSL SPI1/I2S1 External Clock Source Select + * @{ + */ +#define MD_RCU_PSCK_I2S1CKSL_DISABLE (0x00000000UL) /** @brief Disable External Clock (default value) */ +#define MD_RCU_PSCK_I2S1CKSL_I2SCLK1 (0x00000001UL) +#define MD_RCU_PSCK_I2S1CKSL_I2SCLK2 (0x00000002UL) +/** + * @} MD_RCU_PSCK_I2S1CKSL + */ + + +/** + * @} MD_RCU_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_RCU_Public_Macros RCU Public Macros + * @{ + */ + +/** + * @brief Get System clock switch ready flag + * @note This bit is set by hardware to indicate that the system clock change is stable. + * When the CKCFG bit was set and finish configuartion process. + * @param rcu RCU Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RCU_SWRDY_NOT_READY + * @arg @ref MD_RCU_SWRDY_READY + */ +__STATIC_INLINE uint32_t md_rcu_get_con_swrdy(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_SWRDY_MSK)>>RCU_CON_SWRDY_POS); +} +/** + * @brief Get Clock Security System flag + * @note This bit is reset by software by writing the CSSON bit. + * It is set by hardware in case of HOSC clock failure. + * @param rcu RCU Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RCU_CSSFLG_NO_FAIL + * @arg @ref MD_RCU_CSSFLG_FAIL + */ +__STATIC_INLINE uint32_t md_rcu_get_con_cssflg(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_CSSFLG_MSK)>>RCU_CON_CSSFLG_POS); +} +/** + * @brief Get PLL1 clock ready flag + * @note This bit is set by hardware to indicate that the PLL1 oscillator is stable. + * @param rcu RCU Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RCU_PLL1_NOT_READY + * @arg @ref MD_RCU_PLL1_READY + */ +__STATIC_INLINE uint32_t md_rcu_get_con_pll1rdy(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_PLL1RDY_MSK)>>RCU_CON_PLL1RDY_POS); +} +/** + * @brief Get PLL0 clock ready flag + * @note This bit is set by hardware to indicate that the PLL0 oscillator is stable. + * @param rcu RCU Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RCU_PLL0_NOT_READY + * @arg @ref MD_RCU_PLL0_READY + */ +__STATIC_INLINE uint32_t md_rcu_get_con_pll0rdy(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_PLL0RDY_MSK)>>RCU_CON_PLL0RDY_POS); +} +/** + * @brief Get LOSCRDY clock ready flag + * @note This bit is set by hardware to indicate that the LOSC oscillator is stable. + * @param rcu RCU Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RCU_LOSCRDY_NOT_READY + * @arg @ref MD_RCU_LOSCRDY_READY + */ +__STATIC_INLINE uint32_t md_rcu_get_con_loscrdy(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_LOSCRDY_MSK)>>RCU_CON_LOSCRDY_POS); +} +/** + * @brief Get LRCRDY clock ready flag + * @note This bit is set by hardware to indicate that the LRC oscillator is stable. + * @param rcu RCU Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RCU_LRCRDY_NOT_READY + * @arg @ref MD_RCU_LRCRDY_READY + */ +__STATIC_INLINE uint32_t md_rcu_get_con_lrcrdy(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_LRCRDY_MSK)>>RCU_CON_LRCRDY_POS); +} +/** + * @brief Get HOSCRDY clock ready flag + * @note This bit is set by hardware to indicate that the HOSC oscillator is stable. + * @param rcu RCU Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RCU_HOSCRDY_NOT_READY + * @arg @ref MD_RCU_HOSCRDY_READY + */ +__STATIC_INLINE uint32_t md_rcu_get_con_hoscrdy(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_HOSCRDY_MSK)>>RCU_CON_HOSCRDY_POS); +} +/** + * @brief Get HRCRDY clock ready flag + * @note This bit is set by hardware to indicate that the HRC oscillator is stable. + * @param rcu RCU Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RCU_HRCRDY_NOT_READY + * @arg @ref MD_RCU_HRCRDY_READY + */ +__STATIC_INLINE uint32_t md_rcu_get_con_hrcrdy(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_HRCRDY_MSK)>>RCU_CON_HRCRDY_POS); +} +/** + * @brief Clock security system enable(CSS) + * @note Set and cleared by software to enable the clock security system. + * When CSSON is set, the clock detector is enabled by hardware when the HOSC oscillator is ready, + * and disabled by hardware if a HOSC clock failure is detected. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_con_csson(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->CON, RCU_CON_CSSON_MSK); +} +/** + * @brief Clock security system disable(CSS) + * @note Set and cleared by software to enable the clock security system. + * When CSSON is set, the clock detector is enabled by hardware when the HOSC oscillator is ready, + * and disabled by hardware if a HOSC clock failure is detected. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_con_csson(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->CON, RCU_CON_CSSON_MSK); +} +/** + * @brief Get Clock security system (CSS) + * @note Set and cleared by software to enable the clock security system. + * When CSSON is set, the clock detector is enabled by hardware when the HOSC oscillator is ready, + * and disabled by hardware if a HOSC clock failure is detected. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_con_csson(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_CSSON_MSK)>>RCU_CON_CSSON_POS); +} +/** + * @brief PLL1 enable bit(for USB PHY) + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_con_pll1on(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->CON, RCU_CON_PLL1ON_MSK); +} +/** + * @brief PLL1 disable bit(for USB PHY) + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_con_pll1on(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->CON, RCU_CON_PLL1ON_MSK); +} +/** + * @brief Get PLL1 bit(for USB PHY) + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_con_pll1on(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_PLL1ON_MSK)>>RCU_CON_PLL1ON_POS); +} +/** + * @brief PLL0 enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_con_pll0on(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->CON, RCU_CON_PLL0ON_MSK); +} +/** + * @brief PLL0 disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_con_pll0on(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->CON, RCU_CON_PLL0ON_MSK); +} +/** + * @brief Get PLL0 bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_con_pll0on(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_PLL0ON_MSK)>>RCU_CON_PLL0ON_POS); +} +/** + * @brief External low speed oscillator clock enbale bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_con_loscon(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->CON, RCU_CON_LOSCON_MSK); +} +/** + * @brief External low speed oscillator clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_con_loscon(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->CON, RCU_CON_LOSCON_MSK); +} +/** + * @brief Get External low speed oscillator clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_con_loscon(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_LOSCON_MSK)>>RCU_CON_LOSCON_POS); +} +/** + * @brief Internal low speed oscillator clock enbale bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_con_lrcon(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->CON, RCU_CON_LRCON_MSK); +} +/** + * @brief Internal low speed oscillator clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_con_lrcon(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->CON, RCU_CON_LRCON_MSK); +} +/** + * @brief Get Internal low speed oscillator clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_con_lrcon(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_LRCON_MSK)>>RCU_CON_LRCON_POS); +} +/** + * @brief External high speed oscillator clock enbale bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_con_hoscon(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->CON, RCU_CON_HOSCON_MSK); +} +/** + * @brief External high speed oscillator clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_con_hoscon(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->CON, RCU_CON_HOSCON_MSK); +} +/** + * @brief Get External high speed oscillator clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_con_hoscon(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_HOSCON_MSK)>>RCU_CON_HOSCON_POS); +} +/** + * @brief Internal high speed oscillator clock enbale bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_con_hrcon(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->CON, RCU_CON_HRCON_MSK); +} +/** + * @brief Internal high speed oscillator clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_con_hrcon(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->CON, RCU_CON_HRCON_MSK); +} +/** + * @brief Get Internal high speed oscillator clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_con_hrcon(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->CON, RCU_CON_HRCON_MSK)>>RCU_CON_HRCON_POS); +} + +/** @defgroup MD_RCU_CON_CSSON CSSON + * @brief Set Clock security system bit for md_rcu_set_con() function used + * @param csson This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_rcu_set_con_csson_fun(csson) (csson<CON, (csson|pll1on|pll0on|loscon|lrcon|hoscon|hrcon)); +} + +/** + * @brief Clock configuration set bit + * @note This bit is write-only. A read to this bit returns the value 0. + * If set is bit to high, start to configurate clock setting. + * When the clock configuration process was finished, this bit was clear to zero by self. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_ckcfg(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->CFG, RCU_CFG_CKCFG_MSK); +} +/** + * @brief Set Microcontroller clock output prescaler + * @note Output Frequency = MCO/(MPRE+1) + * @param rcu RCU Instance + * @param mpre This parameter can be one of the following values: + * @arg Max Value 7 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_mpre(RCU_TypeDef *rcu, uint32_t mpre) +{ + MODIFY_REG(rcu->CFG, RCU_CFG_MPRE_MSK, (mpre<CFG, RCU_CFG_MPRE_MSK)>>RCU_CFG_MPRE_POSS); +} +/** + * @brief Set Microcontroller clock output (MCO) + * @param rcu RCU Instance + * @param msw This parameter can be one of the following values: + * @arg @ref MD_RCU_MCO_DISABLE + * @arg @ref MD_RCU_MCO_LRC + * @arg @ref MD_RCU_MCO_LOSC + * @arg @ref MD_RCU_MCO_HRC + * @arg @ref MD_RCU_MCO_HOSC + * @arg @ref MD_RCU_MCO_PLL0 + * @arg @ref MD_RCU_MCO_PLL1 + * @arg @ref MD_RCU_MCO_SYSCLK + * @arg @ref MD_RCU_MCO_HCLK + * @arg @ref MD_RCU_MCO_PCLK + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_msw(RCU_TypeDef *rcu, uint32_t msw) +{ + MODIFY_REG(rcu->CFG, RCU_CFG_MSW_MSK, (msw<CFG, RCU_CFG_MSW_MSK)>>RCU_CFG_MSW_POSS); +} +/** + * @brief Set PLL0 multiplication factor + * @note PLL0 output clock frequency is 4*(PLL0MUL+1)MHz + * @param rcu RCU Instance + * @param pllmul can be one of the following values: + * @arg Max Value 31 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_pllmul(RCU_TypeDef *rcu, uint32_t pllmul) +{ + MODIFY_REG(rcu->CFG, RCU_CFG_PLLMUL_MSK, (pllmul<CFG, RCU_CFG_PLLMUL_MSK)>>RCU_CFG_PLLMUL_POSS); +} +/** + * @brief Set PLL0/1 reference clock source + * @param rcu RCU Instance + * @param pllsrc This parameter can be one of the following values: + * @arg @ref MD_RCU_PLL_SRC_HRC + * @arg @ref MD_RCU_PLL_SRC_HOSCDIV + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_pllsrc(RCU_TypeDef *rcu, uint32_t pllsrc) +{ + MODIFY_REG(rcu->CFG, RCU_CFG_PLLSRC_MSK, (pllsrc<CFG, RCU_CFG_PLLSRC_MSK)>>RCU_CFG_PLLSRC_POS); +} +/** + * @brief Set HOSC clock division factor for PLL0/1 reference clock 4 MHz + * @note These bits are set and cleared by software to select HOSCDIV division factor. + * @note PLL_reference_clock (4 MHz) = HOSC / (HOSCDIV+1) + * @param rcu RCU Instance + * @param hoscdiv can be one of the following values: + * @arg Max Value 7 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_hoscdiv(RCU_TypeDef *rcu, uint32_t hoscdiv) +{ + MODIFY_REG(rcu->CFG, RCU_CFG_HOSCDIV_MSK, (hoscdiv<CFG, RCU_CFG_HOSCDIV_MSK)>>RCU_CFG_HOSCDIV_POSS); +} +/** + * @brief Set APB clock prescaler(PCLK) + * @param rcu RCU Instance + * @param ppre The retval can be one of the following values: + * @arg @ref MD_RCU_PPRE_HCLK_DIV_1 + * @arg @ref MD_RCU_PPRE_HCLK_DIV_2 + * @arg @ref MD_RCU_PPRE_HCLK_DIV_4 + * @arg @ref MD_RCU_PPRE_HCLK_DIV_8 + * @arg @ref MD_RCU_PPRE_HCLK_DIV_16 + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_ppre(RCU_TypeDef *rcu, uint32_t ppre) +{ + MODIFY_REG(rcu->CFG, RCU_CFG_PPRE_MSK, (ppre<CFG, RCU_CFG_PPRE_MSK)>>RCU_CFG_PPRE_POSS); +} +/** + * @brief Set AHB clock prescaler(HCLK) + * @param rcu RCU Instance + * @param hpre can be one of the following values: + * @arg @ref MD_RCU_HPRE_SYSCLK_DIV_1 + * @arg @ref MD_RCU_HPRE_SYSCLK_DIV_2 + * @arg @ref MD_RCU_HPRE_SYSCLK_DIV_4 + * @arg @ref MD_RCU_HPRE_SYSCLK_DIV_8 + * @arg @ref MD_RCU_HPRE_SYSCLK_DIV_16 + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_hpre(RCU_TypeDef *rcu, uint32_t hpre) +{ + MODIFY_REG(rcu->CFG, RCU_CFG_HPRE_MSK, (hpre<CFG, RCU_CFG_HPRE_MSK)>>RCU_CFG_HPRE_POSS); +} +/** + * @brief Set System clock switch(SYSCLK) + * @param rcu RCU Instance + * @param sw can be one of the following values: + * @arg @ref MD_RCU_SYSCLK_HRC + * @arg @ref MD_RCU_SYSCLK_HOSC + * @arg @ref MD_RCU_SYSCLK_LRC + * @arg @ref MD_RCU_SYSCLK_LOSC + * @arg @ref MD_RCU_SYSCLK_PLL0 + * @retval None + */ +__STATIC_INLINE void md_rcu_set_cfg_sw(RCU_TypeDef *rcu, uint32_t sw) +{ + MODIFY_REG(rcu->CFG, RCU_CFG_SW_MSK, (sw<CFG, RCU_CFG_SW_MSK)>>RCU_CFG_SW_POSS); +} +/** @defgroup MD_RCU_CFG_MPRE MPRE + * @brief Set Microcontroller clock output prescaler bit for md_rcu_set_cfg() function used + * @param mpre This parameter can be one of the following values: + * @arg Max Value 7 + * @arg Min Value 0 + * @{ + */ +#define md_rcu_set_cfg_mpre_fun(mpre) (mpre<CFG, (mpre|msw|pllmul|pllsrc|hoscdiv|ppre|hpre|sw)); +} + +/** + * @brief Set SPI2/I2S2 External Clock Source Select + * @param rcu RCU Instance + * @param i2s2ckdl This parameter can be one of the following values: + * @arg @ref MD_RCU_PSCK_I2S2CKSL_DISABLE + * @arg @ref MD_RCU_PSCK_I2S2CKSL_I2SCLK1 + * @arg @ref MD_RCU_PSCK_I2S2CKSL_I2SCLK2 + * @retval None + */ +__STATIC_INLINE void md_rcu_set_psck_i2s2ckdl(RCU_TypeDef *rcu, uint32_t i2s2ckdl) +{ + MODIFY_REG(rcu->PSCK, RCU_PSCK_I2S2CKSL_MSK, (i2s2ckdl<PSCK, RCU_PSCK_I2S2CKSL_MSK)>>RCU_PSCK_I2S2CKSL_POSS); +} +/** + * @brief Set SPI1/I2S1 External Clock Source Select + * @param rcu RCU Instance + * @param i2s1ckdl This parameter can be one of the following values: + * @arg @ref MD_RCU_PSCK_I2S1CKSL_DISABLE + * @arg @ref MD_RCU_PSCK_I2S1CKSL_I2SCLK1 + * @arg @ref MD_RCU_PSCK_I2S1CKSL_I2SCLK2 + * @retval None + */ +__STATIC_INLINE void md_rcu_set_psck_i2s1ckdl(RCU_TypeDef *rcu, uint32_t i2s1ckdl) +{ + MODIFY_REG(rcu->PSCK, RCU_PSCK_I2S1CKSL_MSK, (i2s1ckdl<PSCK, RCU_PSCK_I2S1CKSL_MSK)>>RCU_PSCK_I2S1CKSL_POSS); +} + +/** @defgroup MD_RCU_PSCK_I2S2CKSL_ I2S2CKSL + * @brief Set SPI2/I2S2 External Clock Source Select bit for md_rcu_set_psck() function used + * @param i2s2ckdl This parameter can be one of the following values: + * @arg @ref MD_RCU_PSCK_I2S2CKSL_DISABLE + * @arg @ref MD_RCU_PSCK_I2S2CKSL_I2SCLK1 + * @arg @ref MD_RCU_PSCK_I2S2CKSL_I2SCLK2 + * @{ + */ +#define md_rcu_set_psck_i2s2ckdl_fun(i2s2ckdl) (i2s2ckdl<PSCK, (i2s2ckdl|i2s1ckdl)); +} + +/** + * @brief GPIOD reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_gpden(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_GPDEN_MSK); +} +/** + * @brief GPIOD reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_gpden(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_GPDEN_MSK); +} +/** + * @brief Get GPIOD reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_gpden(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_GPDEN_MSK)>>RCU_AHBRST_GPDEN_POS); +} +/** + * @brief GPIOC reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_gpcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_GPCEN_MSK); +} +/** + * @brief GPIOC reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_gpcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_GPCEN_MSK); +} +/** + * @brief Get GPIOC reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_gpcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_GPCEN_MSK)>>RCU_AHBRST_GPCEN_POS); +} +/** + * @brief GPIOB reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_gpben(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_GPBEN_MSK); +} +/** + * @brief GPIOB reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_gpben(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_GPBEN_MSK); +} +/** + * @brief Get GPIOB reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_gpben(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_GPBEN_MSK)>>RCU_AHBRST_GPBEN_POS); +} +/** + * @brief GPIOA reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_gpaen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_GPAEN_MSK); +} +/** + * @brief GPIOA reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_gpaen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_GPAEN_MSK); +} +/** + * @brief Get GPIOA reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_gpaen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_GPAEN_MSK)>>RCU_AHBRST_GPAEN_POS); +} +/** + * @brief HDIV reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_hdiven(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_HDIVEN_MSK); +} +/** + * @brief HDIV reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_hdiven(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_HDIVEN_MSK); +} +/** + * @brief Get HDIV reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_hdiven(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_HDIVEN_MSK)>>RCU_AHBRST_HDIVEN_POS); +} +/** + * @brief USB reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_usben(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_USBEN_MSK); +} +/** + * @brief USB reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_usben(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_USBEN_MSK); +} +/** + * @brief Get USB reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_usben(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_USBEN_MSK)>>RCU_AHBRST_USBEN_POS); +} +/** + * @brief AES reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_aesen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_AESEN_MSK); +} +/** + * @brief AES reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_aesen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_AESEN_MSK); +} +/** + * @brief Get AES reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_aesen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_AESEN_MSK)>>RCU_AHBRST_AESEN_POS); +} +/** + * @brief CRC reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_crcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_CRCEN_MSK); +} +/** + * @brief CRC reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_crcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_CRCEN_MSK); +} +/** + * @brief Get CRC reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_crcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_CRCEN_MSK)>>RCU_AHBRST_CRCEN_POS); +} +/** + * @brief RTC reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_rtcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_RTCEN_MSK); +} +/** + * @brief RTC reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_rtcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_RTCEN_MSK); +} +/** + * @brief Get RTC reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_rtcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_RTCEN_MSK)>>RCU_AHBRST_RTCEN_POS); +} +/** + * @brief DMA1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbrst_dma1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBRST, RCU_AHBRST_DMA1EN_MSK); +} +/** + * @brief DMA1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbrst_dma1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBRST, RCU_AHBRST_DMA1EN_MSK); +} +/** + * @brief Get DMA1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbrst_dma1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBRST, RCU_AHBRST_DMA1EN_MSK)>>RCU_AHBRST_DMA1EN_POS); +} + +/** @defgroup MD_RCU_AHBRST_GPDEN GPDEN + * @brief Set GPIOD reset request bit for md_rcu_set_ahbrst() function used + * @param gpden This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_rcu_set_ahbrst_gpden_fun(gpden) (gpden<AHBRST, (gpden|gpcen|gpben|gpaen|hdiven|usben|aesen|crcen|rtcen|dma1en)); +} + +/** + * @brief DAC reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_dacen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_DACEN_MSK); +} +/** + * @brief DAC reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_dacen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_DACEN_MSK); +} +/** + * @brief Get DAC reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_dacen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_DACEN_MSK)>>RCU_APB1RST_DACEN_POS); +} +/** + * @brief I2C2 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_i2c2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_I2C2EN_MSK); +} +/** + * @brief I2C2 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_i2c2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_I2C2EN_MSK); +} +/** + * @brief Get I2C2 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_i2c2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_I2C2EN_MSK)>>RCU_APB1RST_I2C2EN_POS); +} +/** + * @brief I2C1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_i2c1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_I2C1EN_MSK); +} +/** + * @brief I2C1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_i2c1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_I2C1EN_MSK); +} +/** + * @brief Get I2C1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_i2c1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_I2C1EN_MSK)>>RCU_APB1RST_I2C1EN_POS); +} +/** + * @brief SUART2 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_suart2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_SUART2EN_MSK); +} +/** + * @brief SUART2 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_suart2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_SUART2EN_MSK); +} +/** + * @brief Get SUART2 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_suart2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_SUART2EN_MSK)>>RCU_APB1RST_SUART2EN_POS); +} +/** + * @brief SUART1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_suart1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_SUART1EN_MSK); +} +/** + * @brief SUART1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_suart1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_SUART1EN_MSK); +} +/** + * @brief Get SUART1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_suart1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_SUART1EN_MSK)>>RCU_APB1RST_SUART1EN_POS); +} +/** + * @brief UART3 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_uart3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_UART3EN_MSK); +} +/** + * @brief UART3 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_uart3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_UART3EN_MSK); +} +/** + * @brief Get UART3 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_uart3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_UART3EN_MSK)>>RCU_APB1RST_UART3EN_POS); +} +/** + * @brief UART2 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_uart2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_UART2EN_MSK); +} +/** + * @brief UART2 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_uart2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_UART2EN_MSK); +} +/** + * @brief Get UART2 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_uart2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_UART2EN_MSK)>>RCU_APB1RST_UART2EN_POS); +} +/** + * @brief SPI2 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_spi2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_SPI2EN_MSK); +} +/** + * @brief SPI2 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_spi2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_SPI2EN_MSK); +} +/** + * @brief Get SPI2 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_spi2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_SPI2EN_MSK)>>RCU_APB1RST_SPI2EN_POS); +} +/** + * @brief IWDT reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_iwdten(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_IWDTEN_MSK); +} +/** + * @brief IWDT reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_iwdten(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_IWDTEN_MSK); +} +/** + * @brief Get IWDT reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_iwdten(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_IWDTEN_MSK)>>RCU_APB1RST_IWDTEN_POS); +} +/** + * @brief WWDT reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_wwdten(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_WWDTEN_MSK); +} +/** + * @brief WWDT reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_wwdten(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_WWDTEN_MSK); +} +/** + * @brief Get WWDT reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_wwdten(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_WWDTEN_MSK)>>RCU_APB1RST_WWDTEN_POS); +} +/** + * @brief BS16T1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_bs16t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_BS16T1EN_MSK); +} +/** + * @brief BS16T1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_bs16t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_BS16T1EN_MSK); +} +/** + * @brief Get BS16T1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_bs16t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_BS16T1EN_MSK)>>RCU_APB1RST_BS16T1EN_POS); +} +/** + * @brief GP16C4T3 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_gp16c4t3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T3EN_MSK); +} +/** + * @brief GP16C4T3 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_gp16c4t3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T3EN_MSK); +} +/** + * @brief Get GP16C4T3 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_gp16c4t3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T3EN_MSK)>>RCU_APB1RST_GP16C4T3EN_POS); +} +/** + * @brief GP16C4T2 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_gp16c4t2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T2EN_MSK); +} +/** + * @brief GP16C4T2 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_gp16c4t2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T2EN_MSK); +} +/** + * @brief Get GP16C4T2 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_gp16c4t2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T2EN_MSK)>>RCU_APB1RST_GP16C4T2EN_POS); +} +/** + * @brief GP16C4T1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_gp16c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T1EN_MSK); +} +/** + * @brief GP16C4T1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_gp16c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T1EN_MSK); +} +/** + * @brief Get GP16C4T1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_gp16c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_GP16C4T1EN_MSK)>>RCU_APB1RST_GP16C4T1EN_POS); +} +/** + * @brief GP32C4T1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1rst_gp32c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1RST, RCU_APB1RST_GP32C4T1EN_MSK); +} +/** + * @brief GP32C4T1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1rst_gp32c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1RST, RCU_APB1RST_GP32C4T1EN_MSK); +} +/** + * @brief Get GP32C4T1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1rst_gp32c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1RST, RCU_APB1RST_GP32C4T1EN_MSK)>>RCU_APB1RST_GP32C4T1EN_POS); +} + +/** @defgroup MD_RCU_APB1RST_DACEN DACEN + * @brief Set DAC reset request bit for md_rcu_set_apb1rst() function used + * @param dacen This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_rcu_set_apb1rst_dacen_fun(dacen) (dacen<APB1RST, (dacen|i2c2en|i2c1en|suart2en|suart1en|uart3en|uart2en|spi2en|iwdten|wwdten| + bs16t1en|gp16c4t3en|gp16c4t2en|gp16c4t1en|gp32c4t1en)); +} + +/** + * @brief CMP reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_cmpen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_CMPEN_MSK); +} +/** + * @brief CMP reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_cmpen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_CMPEN_MSK); +} +/** + * @brief Get CMP reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_cmpen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_CMPEN_MSK)>>RCU_APB2RST_CMPEN_POS); +} +/** + * @brief GP16C2T4 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_gp16c2t4en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T4EN_MSK); +} +/** + * @brief GP16C2T4 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_gp16c2t4en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T4EN_MSK); +} +/** + * @brief Get GP16C2T4 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_gp16c2t4en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T4EN_MSK)>>RCU_APB2RST_GP16C2T4EN_POS); +} +/** + * @brief GP16C2T3 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_gp16c2t3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T3EN_MSK); +} +/** + * @brief GP16C2T3 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_gp16c2t3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T3EN_MSK); +} +/** + * @brief Get GP16C2T3 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_gp16c2t3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T3EN_MSK)>>RCU_APB2RST_GP16C2T3EN_POS); +} +/** + * @brief GP16C2T2 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_gp16c2t2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T2EN_MSK); +} +/** + * @brief GP16C2T2 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_gp16c2t2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T2EN_MSK); +} +/** + * @brief Get GP16C2T2 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_gp16c2t2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T2EN_MSK)>>RCU_APB2RST_GP16C2T2EN_POS); +} +/** + * @brief GP16C2T1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_gp16c2t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T1EN_MSK); +} +/** + * @brief GP16C2T1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_gp16c2t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T1EN_MSK); +} +/** + * @brief Get GP16C2T1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_gp16c2t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_GP16C2T1EN_MSK)>>RCU_APB2RST_GP16C2T1EN_POS); +} +/** + * @brief UART1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_uart1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_UART1EN_MSK); +} +/** + * @brief UART1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_uart1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_UART1EN_MSK); +} +/** + * @brief Get UART1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_uart1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_UART1EN_MSK)>>RCU_APB2RST_UART1EN_POS); +} +/** + * @brief SPI1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_spi1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_SPI1EN_MSK); +} +/** + * @brief SPI1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_spi1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_SPI1EN_MSK); +} +/** + * @brief Get SPI1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_spi1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_SPI1EN_MSK)>>RCU_APB2RST_SPI1EN_POS); +} +/** + * @brief AD16C4T1 reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_ad16c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_AD16C4T1EN_MSK); +} +/** + * @brief AD16C4T1 reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_ad16c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_AD16C4T1EN_MSK); +} +/** + * @brief Get AD16C4T1 reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_ad16c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_AD16C4T1EN_MSK)>>RCU_APB2RST_AD16C4T1EN_POS); +} +/** + * @brief ADC reset request enable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2rst_adcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2RST, RCU_APB2RST_ADCEN_MSK); +} +/** + * @brief ADC reset request disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2rst_adcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2RST, RCU_APB2RST_ADCEN_MSK); +} +/** + * @brief Get ADC reset request bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2rst_adcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2RST, RCU_APB2RST_ADCEN_MSK)>>RCU_APB2RST_ADCEN_POS); +} + +/** @defgroup MD_RCU_APB2RST_CMPEN CMPEN + * @brief Set CMP reset request bit for md_rcu_set_apb2rst() function used + * @param cmpen This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_rcu_set_apb2rst_cmpen_fun(cmpen) (cmpen<APB2RST, (cmpen|gp16c2t4en|gp16c2t3en|gp16c2t2en|gp16c2t1en|uart1en|spi1en|ad16c4t1en|adcen)); +} + +/** + * @brief GPIOD clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_gpden(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_GPDEN_MSK); +} +/** + * @brief GPIOD Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_gpden(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_GPDEN_MSK); +} +/** + * @brief Get GPIOD Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_gpden(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_GPDEN_MSK)>>RCU_AHBEN_GPDEN_POS); +} +/** + * @brief GPIOC clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_gpcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_GPCEN_MSK); +} +/** + * @brief GPIOC Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_gpcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_GPCEN_MSK); +} +/** + * @brief Get GPIOC Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_gpcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_GPCEN_MSK)>>RCU_AHBEN_GPCEN_POS); +} +/** + * @brief GPIOB clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_gpben(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_GPBEN_MSK); +} +/** + * @brief GPIOB Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_gpben(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_GPBEN_MSK); +} +/** + * @brief Get GPIOB Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_gpben(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_GPBEN_MSK)>>RCU_AHBEN_GPBEN_POS); +} +/** + * @brief GPIOA clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_gpaen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_GPAEN_MSK); +} +/** + * @brief GPIOA Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_gpaen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_GPAEN_MSK); +} +/** + * @brief Get GPIOA Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_gpaen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_GPAEN_MSK)>>RCU_AHBEN_GPAEN_POS); +} +/** + * @brief HDIV clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_hdiven(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_HDIVEN_MSK); +} +/** + * @brief HDIV Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_hdiven(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_HDIVEN_MSK); +} +/** + * @brief Get HDIV Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_hdiven(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_HDIVEN_MSK)>>RCU_AHBEN_HDIVEN_POS); +} +/** + * @brief USB clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_usben(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_USBEN_MSK); +} +/** + * @brief USB Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_usben(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_USBEN_MSK); +} +/** + * @brief Get USB Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_usben(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_USBEN_MSK)>>RCU_AHBEN_USBEN_POS); +} +/** + * @brief AES clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_aesen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_AESEN_MSK); +} +/** + * @brief AES Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_aesen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_AESEN_MSK); +} +/** + * @brief Get AES Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_aesen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_AESEN_MSK)>>RCU_AHBEN_AESEN_POS); +} +/** + * @brief CRC clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_crcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_CRCEN_MSK); +} +/** + * @brief CRC Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_crcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_CRCEN_MSK); +} +/** + * @brief Get CRC Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_crcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_CRCEN_MSK)>>RCU_AHBEN_CRCEN_POS); +} +/** + * @brief RTC clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_rtcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_RTCEN_MSK); +} +/** + * @brief RTC Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_rtcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_RTCEN_MSK); +} +/** + * @brief Get RTC Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_rtcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_RTCEN_MSK)>>RCU_AHBEN_RTCEN_POS); +} +/** + * @brief DMA1 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahben_dma1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBEN, RCU_AHBEN_DMA1EN_MSK); +} +/** + * @brief DMA1 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahben_dma1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBEN, RCU_AHBEN_DMA1EN_MSK); +} +/** + * @brief Get DMA1 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahben_dma1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBEN, RCU_AHBEN_DMA1EN_MSK)>>RCU_AHBEN_DMA1EN_POS); +} + +/** @defgroup MD_RCU_AHBEN_GPDEN GPDEN + * @brief Set GPIOD clock bit for md_rcu_set_ahben() function used + * @param gpden This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_rcu_set_ahben_gpden_fun(gpden) (gpden<AHBEN, (gpden|gpcen|gpben|gpaen|hdiven|usben|aesen|crcen|rtcen|dma1en)); +} + +/** + * @brief DAC clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_dacen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_DACEN_MSK); +} +/** + * @brief DAC Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_dacen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_DACEN_MSK); +} +/** + * @brief Get DAC Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_dacen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_DACEN_MSK)>>RCU_APB1EN_DACEN_POS); +} +/** + * @brief I2C2 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_i2c2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_I2C2EN_MSK); +} +/** + * @brief I2C2 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_i2c2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_I2C2EN_MSK); +} +/** + * @brief Get I2C2 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_i2c2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_I2C2EN_MSK)>>RCU_APB1EN_I2C2EN_POS); +} +/** + * @brief I2C1 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_i2c1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_I2C1EN_MSK); +} +/** + * @brief I2C1 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_i2c1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_I2C1EN_MSK); +} +/** + * @brief Get I2C1 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_i2c1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_I2C1EN_MSK)>>RCU_APB1EN_I2C1EN_POS); +} +/** + * @brief SUART2 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_suart2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_SUART2EN_MSK); +} +/** + * @brief SUART2 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_suart2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_SUART2EN_MSK); +} +/** + * @brief Get SUART2 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_suart2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_SUART2EN_MSK)>>RCU_APB1EN_SUART2EN_POS); +} +/** + * @brief SUART1 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_suart1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_SUART1EN_MSK); +} +/** + * @brief SUART1 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_suart1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_SUART1EN_MSK); +} +/** + * @brief Get SUART1 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_suart1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_SUART1EN_MSK)>>RCU_APB1EN_SUART1EN_POS); +} +/** + * @brief UART3 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_uart3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_UART3EN_MSK); +} +/** + * @brief UART3 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_uart3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_UART3EN_MSK); +} +/** + * @brief Get UART3 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_uart3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_UART3EN_MSK)>>RCU_APB1EN_UART3EN_POS); +} +/** + * @brief UART2 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_uart2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_UART2EN_MSK); +} +/** + * @brief UART2 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_uart2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_UART2EN_MSK); +} +/** + * @brief Get UART2 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_uart2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_UART2EN_MSK)>>RCU_APB1EN_UART2EN_POS); +} +/** + * @brief SPI2 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_spi2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_SPI2EN_MSK); +} +/** + * @brief SPI2 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_spi2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_SPI2EN_MSK); +} +/** + * @brief Get SPI2 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_spi2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_SPI2EN_MSK)>>RCU_APB1EN_SPI2EN_POS); +} +/** + * @brief IWDT clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_iwdten(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_IWDTEN_MSK); +} +/** + * @brief IWDT Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_iwdten(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_IWDTEN_MSK); +} +/** + * @brief Get IWDT Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_iwdten(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_IWDTEN_MSK)>>RCU_APB1EN_IWDTEN_POS); +} +/** + * @brief WWDT clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_wwdten(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_WWDTEN_MSK); +} +/** + * @brief WWDT Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_wwdten(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_WWDTEN_MSK); +} +/** + * @brief Get WWDT Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_wwdten(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_WWDTEN_MSK)>>RCU_APB1EN_WWDTEN_POS); +} +/** + * @brief BS16T1 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_bs16t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_BS16T1EN_MSK); +} +/** + * @brief BS16T1 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_bs16t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_BS16T1EN_MSK); +} +/** + * @brief Get BS16T1 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_bs16t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_BS16T1EN_MSK)>>RCU_APB1EN_BS16T1EN_POS); +} +/** + * @brief GP16C4T3 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_gp16c4t3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T3EN_MSK); +} +/** + * @brief GP16C4T3 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_gp16c4t3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T3EN_MSK); +} +/** + * @brief Get GP16C4T3 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_gp16c4t3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T3EN_MSK)>>RCU_APB1EN_GP16C4T3EN_POS); +} +/** + * @brief GP16C4T2 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_gp16c4t2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T2EN_MSK); +} +/** + * @brief GP16C4T2 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_gp16c4t2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T2EN_MSK); +} +/** + * @brief Get GP16C4T2 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_gp16c4t2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T2EN_MSK)>>RCU_APB1EN_GP16C4T2EN_POS); +} +/** + * @brief GP16C4T1 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_gp16c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T1EN_MSK); +} +/** + * @brief GP16C4T1 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_gp16c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T1EN_MSK); +} +/** + * @brief Get GP16C4T1 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_gp16c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_GP16C4T1EN_MSK)>>RCU_APB1EN_GP16C4T1EN_POS); +} +/** + * @brief GP32C4T1 clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1en_gp32c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1EN, RCU_APB1EN_GP32C4T1EN_MSK); +} +/** + * @brief GP32C4T1 Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1en_gp32c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1EN, RCU_APB1EN_GP32C4T1EN_MSK); +} +/** + * @brief Get GP32C4T1 Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1en_gp32c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1EN, RCU_APB1EN_GP32C4T1EN_MSK)>>RCU_APB1EN_GP32C4T1EN_POS); +} + +/** @defgroup MD_RCU_APB1EN_DACEN DACEN + * @brief Set DAC clock bit for md_rcu_set_apb1en() function used + * @param dacen This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_rcu_set_apb1en_dacen_fun(dacen) (dacen<APB1EN, (dacen|i2c2en|i2c1en|suart2en|suart1en|uart3en|uart2en|spi2en|iwdten|wwdten| + bs16t1en|gp16c4t3en|gp16c4t2en|gp16c4t1en|gp32c4t1en)); +} + +/** + * @brief CMP clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_cmpen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_CMPEN_MSK); +} +/** + * @brief CMP Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_cmpen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_CMPEN_MSK); +} +/** + * @brief Get CMP Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_cmpen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_CMPEN_MSK)>>RCU_APB2EN_CMPEN_POS); +} +/** + * @brief GP16C2T4EN clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_gp16c2t4en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T4EN_MSK); +} +/** + * @brief GP16C2T4EN Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_gp16c2t4en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T4EN_MSK); +} +/** + * @brief Get GP16C2T4EN Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_gp16c2t4en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T4EN_MSK)>>RCU_APB2EN_GP16C2T4EN_POS); +} +/** + * @brief GP16C2T3EN clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_gp16c2t3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T3EN_MSK); +} +/** + * @brief GP16C2T3EN Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_gp16c2t3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T3EN_MSK); +} +/** + * @brief Get GP16C2T3EN Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_gp16c2t3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T3EN_MSK)>>RCU_APB2EN_GP16C2T3EN_POS); +} +/** + * @brief GP16C2T2EN clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_gp16c2t2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T2EN_MSK); +} +/** + * @brief GP16C2T2EN Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_gp16c2t2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T2EN_MSK); +} +/** + * @brief Get GP16C2T2EN Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_gp16c2t2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T2EN_MSK)>>RCU_APB2EN_GP16C2T2EN_POS); +} +/** + * @brief GP16C2T1EN clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_gp16c2t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T1EN_MSK); +} +/** + * @brief GP16C2T1EN Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_gp16c2t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T1EN_MSK); +} +/** + * @brief Get GP16C2T1EN Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_gp16c2t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_GP16C2T1EN_MSK)>>RCU_APB2EN_GP16C2T1EN_POS); +} +/** + * @brief UART1EN clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_uart1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_UART1EN_MSK); +} +/** + * @brief UART1EN Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_uart1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_UART1EN_MSK); +} +/** + * @brief Get UART1EN Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_uart1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_UART1EN_MSK)>>RCU_APB2EN_UART1EN_POS); +} +/** + * @brief SPI1EN clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_spi1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_SPI1EN_MSK); +} +/** + * @brief SPI1EN Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_spi1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_SPI1EN_MSK); +} +/** + * @brief Get SPI1EN Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_spi1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_SPI1EN_MSK)>>RCU_APB2EN_SPI1EN_POS); +} +/** + * @brief AD16C4T1EN clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_ad16c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_AD16C4T1EN_MSK); +} +/** + * @brief AD16C4T1EN Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_ad16c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_AD16C4T1EN_MSK); +} +/** + * @brief Get AD16C4T1EN Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_ad16c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_AD16C4T1EN_MSK)>>RCU_APB2EN_AD16C4T1EN_POS); +} +/** + * @brief ADCEN clock enable bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2en_adcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2EN, RCU_APB2EN_ADCEN_MSK); +} +/** + * @brief ADCEN Clock disable bit + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2en_adcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2EN, RCU_APB2EN_ADCEN_MSK); +} +/** + * @brief Get ADCEN Clock bit + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2en_adcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2EN, RCU_APB2EN_ADCEN_MSK)>>RCU_APB2EN_ADCEN_POS); +} + +/** @defgroup MD_RCU_APB2EN_CMPEN CMPEN + * @brief Set CMP clock bit for md_rcu_set_apb2en() function used + * @param cmpen This parameter can be one of the following values: + * @arg @ref DISABLE + * @arg @ref ENABLE + * @{ + */ +#define md_rcu_set_apb2en_cmpen_fun(cmpen) (cmpen<APB2EN, (cmpen|gp16c2t4en|gp16c2t3en|gp16c2t2en|gp16c2t1en|uart1en|spi1en|ad16c4t1en|adcen)); +} + + + + + + + + + + +/** + * @brief GPDEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_gpden(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_GPDEN_MSK); +} +/** + * @brief GPDEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_gpden(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_GPDEN_MSK); +} +/** + * @brief Get GPDEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_gpden(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_GPDEN_MSK)>>RCU_AHBSL_GPDEN_POS); +} +/** + * @brief GPCEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_gpcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_GPCEN_MSK); +} +/** + * @brief GPCEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_gpcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_GPCEN_MSK); +} +/** + * @brief Get GPCEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_gpcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_GPCEN_MSK)>>RCU_AHBSL_GPCEN_POS); +} +/** + * @brief GPBEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_gpben(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_GPBEN_MSK); +} +/** + * @brief GPBEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_gpben(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_GPBEN_MSK); +} +/** + * @brief Get GPBEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_gpben(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_GPBEN_MSK)>>RCU_AHBSL_GPBEN_POS); +} +/** + * @brief GPAEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_gpaen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_GPAEN_MSK); +} +/** + * @brief GPAEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_gpaen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_GPAEN_MSK); +} +/** + * @brief Get GPAEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_gpaen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_GPAEN_MSK)>>RCU_AHBSL_GPAEN_POS); +} +/** + * @brief HDIVEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_hdiven(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_HDIVEN_MSK); +} +/** + * @brief HDIVEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_hdiven(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_HDIVEN_MSK); +} +/** + * @brief Get HDIVEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_hdiven(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_HDIVEN_MSK)>>RCU_AHBSL_HDIVEN_POS); +} +/** + * @brief USBEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_usben(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_USBEN_MSK); +} +/** + * @brief USBEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_usben(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_USBEN_MSK); +} +/** + * @brief Get USBEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_usben(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_USBEN_MSK)>>RCU_AHBSL_USBEN_POS); +} +/** + * @brief AESEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_aesen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_AESEN_MSK); +} +/** + * @brief AESEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_aesen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_AESEN_MSK); +} +/** + * @brief Get AESEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_aesen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_AESEN_MSK)>>RCU_AHBSL_AESEN_POS); +} +/** + * @brief CRCEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_crcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_CRCEN_MSK); +} +/** + * @brief CRCEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_crcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_CRCEN_MSK); +} +/** + * @brief Get CRCEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_crcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_CRCEN_MSK)>>RCU_AHBSL_CRCEN_POS); +} +/** + * @brief RTCEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_rtcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_RTCEN_MSK); +} +/** + * @brief RTCEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_rtcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_RTCEN_MSK); +} +/** + * @brief Get RTCEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_rtcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_RTCEN_MSK)>>RCU_AHBSL_RTCEN_POS); +} +/** + * @brief DMA1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbsl_dma1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBSL, RCU_AHBSL_DMA1EN_MSK); +} +/** + * @brief DMA1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbsl_dma1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBSL, RCU_AHBSL_DMA1EN_MSK); +} +/** + * @brief Get DMA1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbsl_dma1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBSL, RCU_AHBSL_DMA1EN_MSK)>>RCU_AHBSL_DMA1EN_POS); +} + +/** + * @brief DAC clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_dacen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_DACEN_MSK); +} +/** + * @brief DAC clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_dacen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_DACEN_MSK); +} +/** + * @brief Get DAC clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_dacen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_DACEN_MSK)>>RCU_APB1SL_DACEN_POS); +} +/** + * @brief I2C2EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_i2c2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_I2C2EN_MSK); +} +/** + * @brief I2C2EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_i2c2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_I2C2EN_MSK); +} +/** + * @brief Get I2C2EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_i2c2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_I2C2EN_MSK)>>RCU_APB1SL_I2C2EN_POS); +} +/** + * @brief I2C1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_i2c1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_I2C1EN_MSK); +} +/** + * @brief I2C1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_i2c1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_I2C1EN_MSK); +} +/** + * @brief Get I2C1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_i2c1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_I2C1EN_MSK)>>RCU_APB1SL_I2C1EN_POS); +} +/** + * @brief SUART2EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_suart2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_SUART2EN_MSK); +} +/** + * @brief SUART2EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_suart2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_SUART2EN_MSK); +} +/** + * @brief Get SUART2EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_suart2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_SUART2EN_MSK)>>RCU_APB1SL_SUART2EN_POS); +} +/** + * @brief SUART1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_suart1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_SUART1EN_MSK); +} +/** + * @brief SUART1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_suart1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_SUART1EN_MSK); +} +/** + * @brief Get SUART1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_suart1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_SUART1EN_MSK)>>RCU_APB1SL_SUART1EN_POS); +} +/** + * @brief UART3EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_uart3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_UART3EN_MSK); +} +/** + * @brief UART3EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_uart3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_UART3EN_MSK); +} +/** + * @brief Get UART3EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_uart3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_UART3EN_MSK)>>RCU_APB1SL_UART3EN_POS); +} +/** + * @brief UART2EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_uart2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_UART2EN_MSK); +} +/** + * @brief UART2EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_uart2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_UART2EN_MSK); +} +/** + * @brief Get UART2EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_uart2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_UART2EN_MSK)>>RCU_APB1SL_UART2EN_POS); +} +/** + * @brief SPI2EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_spi2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_SPI2EN_MSK); +} +/** + * @brief SPI2EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_spi2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_SPI2EN_MSK); +} +/** + * @brief Get SPI2EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_spi2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_SPI2EN_MSK)>>RCU_APB1SL_SPI2EN_POS); +} +/** + * @brief IWDTEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_iwdten(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_IWDTEN_MSK); +} +/** + * @brief IWDTEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_iwdgen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_IWDTEN_MSK); +} +/** + * @brief Get IWDTEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_iwdten(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_IWDTEN_MSK)>>RCU_APB1SL_IWDTEN_POS); +} +/** + * @brief WWDTEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_wwdten(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_WWDTEN_MSK); +} +/** + * @brief WWDTEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_wwdten(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_WWDTEN_MSK); +} +/** + * @brief Get WWDTEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_wwdten(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_WWDTEN_MSK)>>RCU_APB1SL_WWDTEN_POS); +} +/** + * @brief BS16T1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_bs16t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_BS16T1EN_MSK); +} +/** + * @brief BS16T1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_bs16t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_BS16T1EN_MSK); +} +/** + * @brief Get BS16T1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_bs16t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_BS16T1EN_MSK)>>RCU_APB1SL_BS16T1EN_POS); +} +/** + * @brief GP16C4T3EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_gp16c4t3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T3EN_MSK); +} +/** + * @brief GP16C4T3EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_gp16c4t3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T3EN_MSK); +} +/** + * @brief Get GP16C4T3EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_gp16c4t3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T3EN_MSK)>>RCU_APB1SL_GP16C4T3EN_POS); +} +/** + * @brief GP16C4T2EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_gp16c4t2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T2EN_MSK); +} +/** + * @brief GP16C4T2EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_gp16c4t2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T2EN_MSK); +} +/** + * @brief Get GP16C4T2EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). +y*/ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_gp16c4t2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T2EN_MSK)>>RCU_APB1SL_GP16C4T2EN_POS); +} +/** + * @brief GP16C4T1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_gp16c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T1EN_MSK); +} +/** + * @brief GP16C4T1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_gp16c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T1EN_MSK); +} +/** + * @brief Get GP16C4T1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_gp16c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_GP16C4T1EN_MSK)>>RCU_APB1SL_GP16C4T1EN_POS); +} +/** + * @brief GP32C4T1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1sl_gp32c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1SL, RCU_APB1SL_GP32C4T1EN_MSK); +} +/** + * @brief GP32C4T1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1sl_gp32c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1SL, RCU_APB1SL_GP32C4T1EN_MSK); +} +/** + * @brief Get GP32C4T1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1sl_gp32c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1SL, RCU_APB1SL_GP32C4T1EN_MSK)>>RCU_APB1SL_GP32C4T1EN_POS); +} + +/** + * @brief CMP clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_cmpen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_CMPEN_MSK); +} +/** + * @brief CMP clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_cmpen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_CMPEN_MSK); +} +/** + * @brief Get CMP clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_cmpen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_CMPEN_MSK)>>RCU_APB2SL_CMPEN_POS); +} +/** + * @brief GP16C2T4EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_gp16c2t4en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T4EN_MSK); +} +/** + * @brief GP16C2T4EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_gp16c2t4en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T4EN_MSK); +} +/** + * @brief Get GP16C2T4EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_gp16c2t4en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T4EN_MSK)>>RCU_APB2SL_GP16C2T4EN_POS); +} +/** + * @brief GP16C2T3EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_gp16c2t3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T3EN_MSK); +} +/** + * @brief GP16C2T3EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_gp16c2t3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T3EN_MSK); +} +/** + * @brief Get GP16C2T3EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_gp16c2t3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T3EN_MSK)>>RCU_APB2SL_GP16C2T3EN_POS); +} +/** + * @brief GP16C2T2EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_gp16c2t2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T2EN_MSK); +} +/** + * @brief GP16C2T2EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_gp16c2t2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T2EN_MSK); +} +/** + * @brief Get GP16C2T2EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_gp16c2t2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T2EN_MSK)>>RCU_APB2SL_GP16C2T2EN_POS); +} +/** + * @brief GP16C2T1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_gp16c2t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T1EN_MSK); +} +/** + * @brief GP16C2T1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_gp16c2t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T1EN_MSK); +} +/** + * @brief Get GP16C2T1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_gp16c2t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_GP16C2T1EN_MSK)>>RCU_APB2SL_GP16C2T1EN_POS); +} +/** + * @brief UART1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_uart1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_UART1EN_MSK); +} +/** + * @brief UART1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_uart1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_UART1EN_MSK); +} +/** + * @brief Get UART1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_uart1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_UART1EN_MSK)>>RCU_APB2SL_UART1EN_POS); +} +/** + * @brief SPI1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_spi1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_SPI1EN_MSK); +} +/** + * @brief SPI1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_spi1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_SPI1EN_MSK); +} +/** + * @brief Get SPI1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_spi1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_SPI1EN_MSK)>>RCU_APB2SL_SPI1EN_POS); +} +/** + * @brief AD16C4T1EN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_ad16c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_AD16C4T1EN_MSK); +} +/** + * @brief AD16C4T1EN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_ad16c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_AD16C4T1EN_MSK); +} +/** + * @brief Get AD16C4T1EN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_ad16c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_AD16C4T1EN_MSK)>>RCU_APB2SL_AD16C4T1EN_POS); +} +/** + * @brief ADCEN clock enable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2sl_adcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2SL, RCU_APB2SL_ADCEN_MSK); +} +/** + * @brief ADCEN clock disable during Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2sl_adcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2SL, RCU_APB2SL_ADCEN_MSK); +} +/** + * @brief Get ADCEN clock during Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2sl_adcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2SL, RCU_APB2SL_ADCEN_MSK)>>RCU_APB2SL_ADCEN_POS); +} + +/** + * @brief GPIOD clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_gpden(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_GPDEN_MSK); +} +/** + * @brief GPIOD clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_gpden(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_GPDEN_MSK); +} +/** + * @brief Get GPIOD clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_gpden(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_GPDEN_MSK)>>RCU_AHBDSL_GPDEN_POS); +} +/** + * @brief GPIOC clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_gpcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_GPCEN_MSK); +} +/** + * @brief GPIOC clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_gpcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_GPCEN_MSK); +} +/** + * @brief Get GPIOC clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_gpcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_GPCEN_MSK)>>RCU_AHBDSL_GPCEN_POS); +} +/** + * @brief GPIOB clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_gpben(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_GPBEN_MSK); +} +/** + * @brief GPIOB clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_gpben(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_GPBEN_MSK); +} +/** + * @brief Get GPIOB clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_gpben(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_GPBEN_MSK)>>RCU_AHBDSL_GPBEN_POS); +} +/** + * @brief GPIOA clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_gpaen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_GPAEN_MSK); +} +/** + * @brief GPIOA clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_gpaen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_GPAEN_MSK); +} +/** + * @brief Get GPIOA clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_gpaen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_GPAEN_MSK)>>RCU_AHBDSL_GPAEN_POS); +} +/** + * @brief HDIV clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_hdiven(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_HDIVEN_MSK); +} +/** + * @brief HDIV clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_hdiven(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_HDIVEN_MSK); +} +/** + * @brief Get HDIV clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_hdiven(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_HDIVEN_MSK)>>RCU_AHBDSL_HDIVEN_POS); +} +/** + * @brief USB clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_usben(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_USBEN_MSK); +} +/** + * @brief USB clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_usben(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_USBEN_MSK); +} +/** + * @brief Get USB clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_usben(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_USBEN_MSK)>>RCU_AHBDSL_USBEN_POS); +} +/** + * @brief AES clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_aesen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_AESEN_MSK); +} +/** + * @brief AES clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_aesen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_AESEN_MSK); +} +/** + * @brief Get AES clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_aesen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_AESEN_MSK)>>RCU_AHBDSL_AESEN_POS); +} +/** + * @brief CRC clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_crcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_CRCEN_MSK); +} +/** + * @brief CRC clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_crcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_CRCEN_MSK); +} +/** + * @brief Get CRC clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_crcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_CRCEN_MSK)>>RCU_AHBDSL_CRCEN_POS); +} +/** + * @brief RTC clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_rtcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_RTCEN_MSK); +} +/** + * @brief RTC clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_rtcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_RTCEN_MSK); +} +/** + * @brief Get RTC clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_rtcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_RTCEN_MSK)>>RCU_AHBDSL_RTCEN_POS); +} +/** + * @brief DMA1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_ahbdsl_dma1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->AHBDSL, RCU_AHBDSL_DMA1EN_MSK); +} +/** + * @brief DMA1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_ahbdsl_dma1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->AHBDSL, RCU_AHBDSL_DMA1EN_MSK); +} +/** + * @brief Get DMA1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_ahbdsl_dma1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->AHBDSL, RCU_AHBDSL_DMA1EN_MSK)>>RCU_AHBDSL_DMA1EN_POS); +} + +/** + * @brief DAC clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_dacen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_DACEN_MSK); +} +/** + * @brief DAC clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_dacen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_DACEN_MSK); +} +/** + * @brief Get DAC clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_dacen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_DACEN_MSK)>>RCU_APB1DSL_DACEN_POS); +} +/** + * @brief I2C2 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_apb1dslen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_I2C2EN_MSK); +} +/** + * @brief I2C2 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_apb1dslen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_I2C2EN_MSK); +} +/** + * @brief Get I2C2 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_apb1dslen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_I2C2EN_MSK)>>RCU_APB1DSL_I2C2EN_POS); +} +/** + * @brief I2C1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_i2c1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_I2C1EN_MSK); +} +/** + * @brief I2C1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_i2c1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_I2C1EN_MSK); +} +/** + * @brief Get I2C1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_i2c1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_I2C1EN_MSK)>>RCU_APB1DSL_I2C1EN_POS); +} +/** + * @brief SUART2 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_suart2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_SUART2EN_MSK); +} +/** + * @brief SUART2 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_suart2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_SUART2EN_MSK); +} +/** + * @brief Get SUART2 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_suart2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_SUART2EN_MSK)>>RCU_APB1DSL_SUART2EN_POS); +} +/** + * @brief SUART1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_suart1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_SUART1EN_MSK); +} +/** + * @brief SUART1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_suart1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_SUART1EN_MSK); +} +/** + * @brief Get SUART1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_suart1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_SUART1EN_MSK)>>RCU_APB1DSL_SUART1EN_POS); +} +/** + * @brief UART3 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_uart3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_UART3EN_MSK); +} +/** + * @brief UART3 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_uart3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_UART3EN_MSK); +} +/** + * @brief Get UART3 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_uart3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_UART3EN_MSK)>>RCU_APB1DSL_UART3EN_POS); +} +/** + * @brief UART2 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_uart2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_UART2EN_MSK); +} +/** + * @brief UART2 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_uart2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_UART2EN_MSK); +} +/** + * @brief Get UART2 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_uart2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_UART2EN_MSK)>>RCU_APB1DSL_UART2EN_POS); +} +/** + * @brief SPI2 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_spi2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_SPI2EN_MSK); +} +/** + * @brief SPI2 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_spi2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_SPI2EN_MSK); +} +/** + * @brief Get SPI2 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_spi2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_SPI2EN_MSK)>>RCU_APB1DSL_SPI2EN_POS); +} +/** + * @brief IWDT clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_iwdten(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_IWDTEN_MSK); +} +/** + * @brief IWDT clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_iwdten(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_IWDTEN_MSK); +} +/** + * @brief Get IWDT clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_iwdten(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_IWDTEN_MSK)>>RCU_APB1DSL_IWDTEN_POS); +} +/** + * @brief WWDT clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_wwdten(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_WWDTEN_MSK); +} +/** + * @brief WWDT clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_wwdten(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_WWDTEN_MSK); +} +/** + * @brief Get WWDT clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_wwdten(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_WWDTEN_MSK)>>RCU_APB1DSL_WWDTEN_POS); +} +/** + * @brief BS16T1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_bs16t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_BS16T1EN_MSK); +} +/** + * @brief BS16T1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_bs16t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_BS16T1EN_MSK); +} +/** + * @brief Get BS16T1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_bs16t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_BS16T1EN_MSK)>>RCU_APB1DSL_BS16T1EN_POS); +} +/** + * @brief GP16C4T3 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_gp16c4t3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T3EN_MSK); +} +/** + * @brief GP16C4T3 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_gp16c4t3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T3EN_MSK); +} +/** + * @brief Get GP16C4T3 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_gp16c4t3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T3EN_MSK)>>RCU_APB1DSL_GP16C4T3EN_POS); +} +/** + * @brief GP16C4T2 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_gp16c4t2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T2EN_MSK); +} +/** + * @brief GP16C4T2 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_gp16c4t2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T2EN_MSK); +} +/** + * @brief Get GP16C4T2 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_gp16c4t2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T2EN_MSK)>>RCU_APB1DSL_GP16C4T2EN_POS); +} +/** + * @brief GP16C4T1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_gp16c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T1EN_MSK); +} +/** + * @brief GP16C4T1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_gp16c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T1EN_MSK); +} +/** + * @brief Get GP16C4T1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_gp16c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_GP16C4T1EN_MSK)>>RCU_APB1DSL_GP16C4T1EN_POS); +} +/** + * @brief GP32C4T1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb1dsl_gp32c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB1DSL, RCU_APB1DSL_GP32C4T1EN_MSK); +} +/** + * @brief GP32C4T1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb1dsl_gp32c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB1DSL, RCU_APB1DSL_GP32C4T1EN_MSK); +} +/** + * @brief Get GP32C4T1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb1dsl_gp32c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB1DSL, RCU_APB1DSL_GP32C4T1EN_MSK)>>RCU_APB1DSL_GP32C4T1EN_POS); +} + +/** + * @brief CMP clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_cmpen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_CMPEN_MSK); +} +/** + * @brief CMP clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_cmpen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_CMPEN_MSK); +} +/** + * @brief Get CMP clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_cmpen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_CMPEN_MSK)>>RCU_APB2DSL_CMPEN_POS); +} +/** + * @brief GP16C2T4 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_gp16c2t4en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T4EN_MSK); +} +/** + * @brief GP16C2T4 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_gp16c2t4en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T4EN_MSK); +} +/** + * @brief Get GP16C2T4 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_gp16c2t4en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T4EN_MSK)>>RCU_APB2DSL_GP16C2T4EN_POS); +} +/** + * @brief GP16C2T3 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_gp16c2t3en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T3EN_MSK); +} +/** + * @brief GP16C2T3 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_gp16c2t3en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T3EN_MSK); +} +/** + * @brief Get GP16C2T3 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_gp16c2t3en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T3EN_MSK)>>RCU_APB2DSL_GP16C2T3EN_POS); +} +/** + * @brief GP16C2T2 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_gp16c2t2en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T2EN_MSK); +} +/** + * @brief GP16C2T2 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_gp16c2t2en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T2EN_MSK); +} +/** + * @brief Get GP16C2T2 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_gp16c2t2en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T2EN_MSK)>>RCU_APB2DSL_GP16C2T2EN_POS); +} +/** + * @brief GP16C2T1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_gp16c2t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T1EN_MSK); +} +/** + * @brief GP16C2T1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_gp16c2t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T1EN_MSK); +} +/** + * @brief Get GP16C2T1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_gp16c2t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_GP16C2T1EN_MSK)>>RCU_APB2DSL_GP16C2T1EN_POS); +} +/** + * @brief UART1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_uart1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_UART1EN_MSK); +} +/** + * @brief UART1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_uart1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_UART1EN_MSK); +} +/** + * @brief Get UART1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_uart1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_UART1EN_MSK)>>RCU_APB2DSL_UART1EN_POS); +} +/** + * @brief SPI1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_spi1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_SPI1EN_MSK); +} +/** + * @brief SPI1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_spi1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_SPI1EN_MSK); +} +/** + * @brief Get SPI1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_spi1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_SPI1EN_MSK)>>RCU_APB2DSL_SPI1EN_POS); +} +/** + * @brief AD16C4T1 clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_ad16c4t1en(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_AD16C4T1EN_MSK); +} +/** + * @brief AD16C4T1 clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_ad16c4t1en(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_AD16C4T1EN_MSK); +} +/** + * @brief Get AD16C4T1 clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_ad16c4t1en(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_AD16C4T1EN_MSK)>>RCU_APB2DSL_AD16C4T1EN_POS); +} +/** + * @brief ADC clock enable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_enable_apb2dsl_adcen(RCU_TypeDef *rcu) +{ + SET_BIT(rcu->APB2DSL, RCU_APB2DSL_ADCEN_MSK); +} +/** + * @brief ADC clock disable during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval None + */ +__STATIC_INLINE void md_rcu_disable_apb2dsl_adcen(RCU_TypeDef *rcu) +{ + CLEAR_BIT(rcu->APB2DSL, RCU_APB2DSL_ADCEN_MSK); +} +/** + * @brief Get ADC clock during Deep Sleep mode bit. + * @param rcu RCU Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_rcu_get_apb2dsl_adcen(RCU_TypeDef *rcu) +{ + return (READ_BIT(rcu->APB2DSL, RCU_APB2DSL_ADCEN_MSK)>>RCU_APB2DSL_ADCEN_POS); +} + +/** + * @} MD_RCU_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_RCU_Public_Functions RCU Public Functions + * @{ + */ + +/** @defgroup MD_RCU_PF_Basic_Configuration Basic Configuration + * @{ + */ +void md_rcu_init(void); +void md_rcu_init_set(RCU_TypeDef *, md_rcu_init_typedef *); +void md_rcu_pllreinit(uint8_t); +/** + * @} MD_RCU_PF_Basic_Configuration + */ + +/** + * @} MD_RCU_Public_Functions + */ + +#endif + +/** + * @} RCU + */ + +/** + * @} Micro_Driver + */ +#ifdef __cplusplus +} + +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_rtc.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_rtc.h new file mode 100644 index 0000000000..4de23ae628 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_rtc.h @@ -0,0 +1,2785 @@ +/** + ****************************************************************************** + * @file md_RTC.h + * @brief ES32F0271 RTC HEAD File. + * + * @version V1.00.02 + * @date 30/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_RTC_H__ +#define __MD_RTC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include +#include "es32f0271.h" +#include "reg_rtc.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (RTC) + +/** @defgroup RTC RTC + * @brief RTC micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ +/** @defgroup MD_RTC_PT_INIT RTC Public Init structures + * @{ + */ + +/** + * @brief MD RTC Init Structure definition + */ + + +/** + * @} MD_RTC_PT_INIT + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_RTC_Public_Constants RTC Public Constants + * @{ + */ + +/** @defgroup MD_RTC_CON_MODE_ RTC Clock Calibration Mode + * @{ + */ +#define MD_RTC_CON_MODE_INCR (0x00000000UL) /** @brief Increase calibration value when match calibration cycle. */ +#define MD_RTC_CON_MODE_DECR (0X00000001UL) /** @brief DMA Decrease calibration value when match calibration cycle. */ +/** + * @} MD_RTC_CON_MODE_ + */ + +/** @defgroup MD_RTC_CON_CYCLE_ RTC Calibration Cycle Select + * @{ + */ +#define MD_RTC_CON_CYCLE_60S (0x00000000UL) /** @brief When enable Calibration Function, the calibrate cycle is 60s. */ +#define MD_RTC_CON_CYCLE_1S (0X00000001UL) /** @brief When enable Calibration Function, the calibrate cycle is 1s. */ +/** + * @} MD_RTC_CON_CYCLE_ + */ + +/** @defgroup MD_RTC_CON_CKSEL_ RTC Clock Source Selection + * @{ + */ +#define MD_RTC_CON_CKSEL_NO (0x00000000UL) /** @brief No clock */ +#define MD_RTC_CON_CKSEL_LOSC (0X00000001UL) /** @brief LOSC oscillator clock used as RTC clock */ +#define MD_RTC_CON_CKSEL_LRC (0x00000002UL) /** @brief LRC oscillator clock used as RTC clock */ +#define MD_RTC_CON_CKSEL_PLL (0X00000003UL) /** @brief PLL Reference clock source divided by 128 used as RTC clock */ +/** + * @} MD_RTC_CON_CKSEL_ + */ + +/** @defgroup MD_RTC_WKUP_WKSCAL RTC Wakeup Counter Scale Value + * @{ + */ +#define MD_RTC_WKUP_WKSCAL_DIV1 (0x00000000UL) /** @brief Divide 1, wakeup counter will count each second. */ +#define MD_RTC_WKUP_WKSCAL_DIV2 (0X00000001UL) /** @brief Divide 2, wakeup counter will count each 1/2 second. */ +#define MD_RTC_WKUP_WKSCAL_DIV4 (0x00000002UL) /** @brief Divide 4, wakeup counter will count each 1/4 second. */ +#define MD_RTC_WKUP_WKSCAL_DIV8 (0X00000003UL) /** @brief Divide 8, wakeup counter will count each 1/8 second. */ +#define MD_RTC_WKUP_WKSCAL_DIV16 (0X00000004UL) /** @brief Divide 16, wakeup counter will count each 1/16 second. */ +/** + * @} MD_RTC_WKUP_WKSCAL + */ + +/** @defgroup MD_RTC_WKUP_WKSEL RTC Wakeup Counter Events Select + * @{ + */ +#define MD_RTC_WKUP_WKSEL_OFF (0x00000000UL) /** @brief OFF */ +#define MD_RTC_WKUP_WKSEL_RTC (0X00000001UL) /** @brief Start counter when RTC start. */ +#define MD_RTC_WKUP_WKSEL_SLEEP (0x00000002UL) /** @brief Start counter when receive sleep flag. */ +/** + * @} MD_RTC_WKUP_WKSEL + */ + +/** @defgroup MD_RTC_STAT_SYNDONE RTC Calendar Synchronization status + * @{ + */ +#define MD_RTC_STAT_SYNDONE_UNDER (0x00000000UL) /** @brief RTC is under Synchronization procedure */ +#define MD_RTC_STAT_SYNDONE_CMP (0X00000001UL) /** @brief RTC Synchronization procedure is Completed */ +/** + * @} MD_RTC_STAT_SYNDONE + */ + +/** @defgroup MD_RTC_BKEN_BKEN Read RTC Backup Register Enable + * @{ + */ +#define MD_RTC_BKEN_BKEN_CONTROL (0x00000000UL) /** @brief Read RTCTIME & RTCCAL From control register. */ +#define MD_RTC_BKEN_BKEN_BACKUP (0X00000001UL) /** @brief Read RTCTIME & RTCCAL From backup register. */ +/** + * @} MD_RTC_BKEN_BKEN + */ + +/** + * @} MD_RTC_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_RTC_Public_Macros RTC Public Macros + * @{ + */ + +/** + * @brief Set RTC Clock Calibration Mode + * @param rtc RTC Instance + * @param mode can be one of the following values: + * @arg @ref MD_RTC_CON_MODE_INCR + * @arg @ref MD_RTC_CON_MODE_DECR + * @retval None + */ +__STATIC_INLINE void md_rtc_set_con_mode(RTC_TypeDef *rtc, uint32_t mode) +{ + MODIFY_REG(rtc->CON, RTC_CON_MODE_MSK, (mode<CON, RTC_CON_MODE_MSK)>>RTC_CON_MODE_POS); +} +/** + * @brief Set RTC Clock Calibration Value + * @param rtc RTC Instance + * @param calval Max calibration value is CALV. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_con_calval(RTC_TypeDef *rtc, uint32_t calval) +{ + MODIFY_REG(rtc->CON, RTC_CON_CALVAL_MSK, (calval<CON, RTC_CON_CALVAL_MSK)>>RTC_CON_CALVAL_POSS); +} +/** + * @brief Set RTC Clock Counter Scale + * @param rtc RTC Instance + * @param scale Max divider of This counter is (SCALE+1). + * @retval None + */ +__STATIC_INLINE void md_rtc_set_con_scale(RTC_TypeDef *rtc, uint32_t scale) +{ + MODIFY_REG(rtc->CON, RTC_CON_SCALE_MSK, (scale<CON, RTC_CON_SCALE_MSK)>>RTC_CON_SCALE_POSS); +} +/** + * @brief Set RTC Clock Counter Prescale + * @param rtc RTC Instance + * @param pscale Max divider of This counter is (PSCALE+1). + * @retval None + */ +__STATIC_INLINE void md_rtc_set_con_pscale(RTC_TypeDef *rtc, uint32_t pscale) +{ + MODIFY_REG(rtc->CON, RTC_CON_PSCALE_MSK, (pscale<CON, RTC_CON_PSCALE_MSK)>>RTC_CON_PSCALE_POSS); +} +/** + * @brief Set RTC Calibration Cycle Select + * @param rtc RTC Instance + * @param cycle This parameter can be one of the following values: + * @arg @ref MD_RTC_CON_CYCLE_60S + * @arg @ref MD_RTC_CON_CYCLE_1S + * @retval None + */ +__STATIC_INLINE void md_rtc_set_con_cycle(RTC_TypeDef *rtc, uint32_t cycle) +{ + MODIFY_REG(rtc->CON, RTC_CON_CYCLE_MSK, (cycle<CON, RTC_CON_CYCLE_MSK)>>RTC_CON_CYCLE_POS); +} +/** + * @brief Set RTC Calibration Function Enable + * @param rtc RTC Instance + * @param calib This parameter can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_con_calib(RTC_TypeDef *rtc, uint32_t calib) +{ + MODIFY_REG(rtc->CON, RTC_CON_CALIB_MSK, (calib<CON, RTC_CON_CALIB_MSK)>>RTC_CON_CALIB_POS); +} +/** + * @brief Set RTC Clock Source Selection + * @param rtc RTC Instance + * @param cksel This parameter can be one of the following values: + * @arg @ref MD_RTC_CON_CKSEL_NO + * @arg @ref MD_RTC_CON_CKSEL_LOSC + * @arg @ref MD_RTC_CON_CKSEL_LRC + * @arg @ref MD_RTC_CON_CKSEL_PLL + * @retval None + */ +__STATIC_INLINE void md_rtc_set_con_cksel(RTC_TypeDef *rtc, uint32_t cksel) +{ + MODIFY_REG(rtc->CON, RTC_CON_CKSEL_MSK, (cksel<CON, RTC_CON_CKSEL_MSK)>>RTC_CON_CKSEL_POSS); +} +/** + * @brief Set RTC Counter Enable bit + * @param rtc RTC Instance + * @param rtcen This parameter can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_con_rtcen(RTC_TypeDef *rtc, uint32_t rtcen) +{ + MODIFY_REG(rtc->CON, RTC_CON_RTCEN_MSK, (rtcen<CON, RTC_CON_RTCEN_MSK)>>RTC_CON_RTCEN_POS); +} + +/** @defgroup MD_RTC_CON_MODE MODE + * @brief Set RTC Clock Calibration Mode bit for md_rtc_set_con() function used + * @param mode This parameter can be one of the following values: + * @arg @ref MD_RTC_CON_MODE_INCR + * @arg @ref MD_RTC_CON_MODE_DECR + * @{ + */ +#define md_rtc_set_con_mode_fun(mode) (mode<CON, (mode|calval|scale|pscale|cycle|calib|cksel|rtcen)); +} + + +/** + * @brief Set RTC Wakeup Counter Scale Value + * @param rtc RTC Instance + * @param wkscal This parameter can be one of the following values: + * @arg @ref MD_RTC_WKUP_WKSCAL_DIV1 + * @arg @ref MD_RTC_WKUP_WKSCAL_DIV2 + * @arg @ref MD_RTC_WKUP_WKSCAL_DIV4 + * @arg @ref MD_RTC_WKUP_WKSCAL_DIV8 + * @arg @ref MD_RTC_WKUP_WKSCAL_DIV16 + * @retval None + */ +__STATIC_INLINE void md_rtc_set_wkup_wkscal(RTC_TypeDef *rtc, uint32_t wkscal) +{ + MODIFY_REG(rtc->WKUP, RTC_WKUP_WKSCAL_MSK, (wkscal<WKUP, RTC_WKUP_WKSCAL_MSK)>>RTC_WKUP_WKSCAL_POSS); +} +/** + * @brief Set RTC Wakeup Counter Events Select + * @param rtc RTC Instance + * @param wksel This parameter can be one of the following values: + * @arg @ref MD_RTC_WKUP_WKSEL_OFF + * @arg @ref MD_RTC_WKUP_WKSEL_RTC + * @arg @ref MD_RTC_WKUP_WKSEL_SLEEP + * @retval None + */ +__STATIC_INLINE void md_rtc_set_wkup_wksel(RTC_TypeDef *rtc, uint32_t wksel) +{ + MODIFY_REG(rtc->WKUP, RTC_WKUP_WKSEL_MSK, (wksel<WKUP, RTC_WKUP_WKSEL_MSK)>>RTC_WKUP_WKSEL_POSS); +} +/** + * @brief Set RTC Wakeup Counter setting value + * @param rtc RTC Instance + * @param wkcal Max value is WKCAL seconds + * @retval None + */ +__STATIC_INLINE void md_rtc_set_wkup_wkcal(RTC_TypeDef *rtc, uint32_t wkcal) +{ + MODIFY_REG(rtc->WKUP, RTC_WKUP_WKCAL_MSK, (wkcal<WKUP, RTC_WKUP_WKCAL_MSK)>>RTC_WKUP_WKCAL_POSS); +} + + +/** + * @brief Set Week Value + * @param rtc RTC Instance + * @param week value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_time_week(RTC_TypeDef *rtc, uint32_t week) +{ + MODIFY_REG(rtc->TIME, RTC_TIME_WEEK_MSK, (week<TIME, RTC_TIME_WEEK_MSK)>>RTC_TIME_WEEK_POSS); +} +/** + * @brief Set Hour Tens Value + * @param rtc RTC Instance + * @param hour_t Hour tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_time_hour_t(RTC_TypeDef *rtc, uint32_t hour_t) +{ + MODIFY_REG(rtc->TIME, RTC_TIME_HOUR_T_MSK, (hour_t<TIME, RTC_TIME_HOUR_T_MSK)>>RTC_TIME_HOUR_T_POSS); +} +/** + * @brief Set Hour Units Value + * @param rtc RTC Instance + * @param hour_u Hour units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_time_hour_u(RTC_TypeDef *rtc, uint32_t hour_u) +{ + MODIFY_REG(rtc->TIME, RTC_TIME_HOUR_U_MSK, (hour_u<TIME, RTC_TIME_HOUR_U_MSK)>>RTC_TIME_HOUR_U_POSS); +} +/** + * @brief Set Minute Tens Value + * @param rtc RTC Instance + * @param min_t Minute tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_time_min_t(RTC_TypeDef *rtc, uint32_t min_t) +{ + MODIFY_REG(rtc->TIME, RTC_TIME_MIN_T_MSK, (min_t<TIME, RTC_TIME_MIN_T_MSK)>>RTC_TIME_MIN_T_POSS); +} +/** + * @brief Set Minute Units Value + * @param rtc RTC Instance + * @param min_u Minute units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_time_min_u(RTC_TypeDef *rtc, uint32_t min_u) +{ + MODIFY_REG(rtc->TIME, RTC_TIME_MIN_U_MSK, (min_u<TIME, RTC_TIME_MIN_U_MSK)>>RTC_TIME_MIN_U_POSS); +} +/** + * @brief Set Second Tens Value + * @param rtc RTC Instance + * @param sec_t Second tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_time_sec_t(RTC_TypeDef *rtc, uint32_t sec_t) +{ + MODIFY_REG(rtc->TIME, RTC_TIME_SEC_T_MSK, (sec_t<TIME, RTC_TIME_SEC_T_MSK)>>RTC_TIME_SEC_T_POSS); +} +/** + * @brief Set Second Units Value + * @param rtc RTC Instance + * @param sec_u Second units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_time_sec_u(RTC_TypeDef *rtc, uint32_t sec_u) +{ + MODIFY_REG(rtc->TIME, RTC_TIME_SEC_U_MSK, (sec_u<TIME, RTC_TIME_SEC_U_MSK)>>RTC_TIME_SEC_U_POSS); +} + +/** @defgroup MD_RTC_TIME_WEEK WEEK + * @brief Set Week Value bit bit for md_rtc_set_time() function used + * @param week value in RTC timer, in BCD format. + * @{ + */ +#define md_rtc_set_time_week_fun(week) (week<TIME, (week|hour_t|hour_u|min_t|min_u|sec_t|sec_u)); +} + + + + + + + + + + +/** + * @brief Set Year Tens Value + * @param rtc RTC Instance + * @param year_t Year tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_cal_year_t(RTC_TypeDef *rtc, uint32_t year_t) +{ + MODIFY_REG(rtc->CAL, RTC_CAL_YEAR_T_MSK, (year_t<CAL, RTC_CAL_YEAR_T_MSK)>>RTC_CAL_YEAR_T_POSS); +} +/** + * @brief Set Year Units Value + * @param rtc RTC Instance + * @param year_u Year units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_cal_year_u(RTC_TypeDef *rtc, uint32_t year_u) +{ + MODIFY_REG(rtc->CAL, RTC_CAL_YEAR_U_MSK, (year_u<CAL, RTC_CAL_YEAR_U_MSK)>>RTC_CAL_YEAR_U_POSS); +} +/** + * @brief Set Month Tens Value + * @param rtc RTC Instance + * @param mon_t Month tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_cal_mon_t(RTC_TypeDef *rtc, uint32_t mon_t) +{ + MODIFY_REG(rtc->CAL, RTC_CAL_MON_T_MSK, (mon_t<CAL, RTC_CAL_MON_T_MSK)>>RTC_CAL_MON_T_POS); +} +/** + * @brief Set Month Units Value + * @param rtc RTC Instance + * @param mon_u Month units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_cal_mon_u(RTC_TypeDef *rtc, uint32_t mon_u) +{ + MODIFY_REG(rtc->CAL, RTC_CAL_MON_U_MSK, (mon_u<CAL, RTC_CAL_MON_U_MSK)>>RTC_CAL_MON_U_POSS); +} +/** + * @brief Set Date Tens Value + * @param rtc RTC Instance + * @param date_t Date tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_cal_date_t(RTC_TypeDef *rtc, uint32_t date_t) +{ + MODIFY_REG(rtc->CAL, RTC_CAL_DATE_T_MSK, (date_t<CAL, RTC_CAL_DATE_T_MSK)>>RTC_CAL_DATE_T_POSS); +} +/** + * @brief Set Date Units Value + * @param rtc RTC Instance + * @param date_u Date units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_cal_date_u(RTC_TypeDef *rtc, uint32_t date_u) +{ + MODIFY_REG(rtc->CAL, RTC_CAL_DATE_U_MSK, (date_u<CAL, RTC_CAL_DATE_U_MSK)>>RTC_CAL_DATE_U_POSS); +} + +/** + * @brief Set Alarm Week Value + * @param rtc RTC Instance + * @param week Alarm Week value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_altime_week(RTC_TypeDef *rtc, uint32_t week) +{ + MODIFY_REG(rtc->ALTIME, RTC_ALTIME_WEEK_MSK, (week<ALTIME, RTC_ALTIME_WEEK_MSK)>>RTC_ALTIME_WEEK_POSS); +} +/** + * @brief Set Alarm Hour Tens Value + * @param rtc RTC Instance + * @param hour_t Alarm Hour tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_altime_hour_t(RTC_TypeDef *rtc, uint32_t hour_t) +{ + MODIFY_REG(rtc->ALTIME, RTC_ALTIME_HOUR_T_MSK, (hour_t<ALTIME, RTC_ALTIME_HOUR_T_MSK)>>RTC_ALTIME_HOUR_T_POSS); +} +/** + * @brief Set Alarm Hour Units Value + * @param rtc RTC Instance + * @param hour_u Alarm Hour units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_altime_hour_u(RTC_TypeDef *rtc, uint32_t hour_u) +{ + MODIFY_REG(rtc->ALTIME, RTC_ALTIME_HOUR_U_MSK, (hour_u<ALTIME, RTC_ALTIME_HOUR_U_MSK)>>RTC_ALTIME_HOUR_U_POSS); +} +/** + * @brief Set Alarm Minute Tens Value + * @param rtc RTC Instance + * @param min_t Alarm Minute tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_altime_min_t(RTC_TypeDef *rtc, uint32_t min_t) +{ + MODIFY_REG(rtc->ALTIME, RTC_ALTIME_MIN_T_MSK, (min_t<ALTIME, RTC_ALTIME_MIN_T_MSK)>>RTC_ALTIME_MIN_T_POSS); +} +/** + * @brief Set Alarm Minute Units Value + * @param rtc RTC Instance + * @param min_u Alarm Minute units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_altime_min_u(RTC_TypeDef *rtc, uint32_t min_u) +{ + MODIFY_REG(rtc->ALTIME, RTC_ALTIME_MIN_U_MSK, (min_u<ALTIME, RTC_ALTIME_MIN_U_MSK)>>RTC_ALTIME_MIN_U_POSS); +} +/** + * @brief Set Alarm Second Tens Value + * @param rtc RTC Instance + * @param sec_t Alarm Second tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_altime_sec_t(RTC_TypeDef *rtc, uint32_t sec_t) +{ + MODIFY_REG(rtc->ALTIME, RTC_ALTIME_SEC_T_MSK, (sec_t<ALTIME, RTC_ALTIME_SEC_T_MSK)>>RTC_ALTIME_SEC_T_POSS); +} +/** + * @brief Set Alarm Second Units Value + * @param rtc RTC Instance + * @param sec_u Alarm Second units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_altime_sec_u(RTC_TypeDef *rtc, uint32_t sec_u) +{ + MODIFY_REG(rtc->ALTIME, RTC_ALTIME_SEC_U_MSK, (sec_u<ALTIME, RTC_ALTIME_SEC_U_MSK)>>RTC_ALTIME_SEC_U_POSS); +} + +/** + * @brief Set Alarm Year Tens Value + * @param rtc RTC Instance + * @param year_t Alarm Year tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alcal_year_t(RTC_TypeDef *rtc, uint32_t year_t) +{ + MODIFY_REG(rtc->ALCAL, RTC_ALCAL_YEAR_T_MSK, (year_t<ALCAL, RTC_ALCAL_YEAR_T_MSK)>>RTC_ALCAL_YEAR_T_POSS); +} +/** + * @brief Set Alarm Year Units Value + * @param rtc RTC Instance + * @param year_u Alarm Year units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alcal_year_u(RTC_TypeDef *rtc, uint32_t year_u) +{ + MODIFY_REG(rtc->ALCAL, RTC_ALCAL_YEAR_U_MSK, (year_u<ALCAL, RTC_ALCAL_YEAR_U_MSK)>>RTC_ALCAL_YEAR_U_POSS); +} +/** + * @brief Set Alarm Month Tens Value + * @param rtc RTC Instance + * @param mon_t Alarm Month tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alcal_mon_t(RTC_TypeDef *rtc, uint32_t mon_t) +{ + MODIFY_REG(rtc->ALCAL, RTC_ALCAL_MON_T_MSK, (mon_t<ALCAL, RTC_ALCAL_MON_T_MSK)>>RTC_ALCAL_MON_T_POS); +} +/** + * @brief Set Alarm Month Units Value + * @param rtc RTC Instance + * @param mon_u Alarm Month units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alcal_mon_u(RTC_TypeDef *rtc, uint32_t mon_u) +{ + MODIFY_REG(rtc->ALCAL, RTC_ALCAL_MON_U_MSK, (mon_u<ALCAL, RTC_ALCAL_MON_U_MSK)>>RTC_ALCAL_MON_U_POSS); +} +/** + * @brief Set Alarm Date Tens Value + * @param rtc RTC Instance + * @param date_t Alarm Date tens value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alcal_date_t(RTC_TypeDef *rtc, uint32_t date_t) +{ + MODIFY_REG(rtc->ALCAL, RTC_ALCAL_DATE_T_MSK, (date_t<ALCAL, RTC_ALCAL_DATE_T_MSK)>>RTC_ALCAL_DATE_T_POSS); +} +/** + * @brief Set Alarm Date Units Value + * @param rtc RTC Instance + * @param date_u Alarm Date units value in RTC timer, in BCD format. + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alcal_date_u(RTC_TypeDef *rtc, uint32_t date_u) +{ + MODIFY_REG(rtc->ALCAL, RTC_ALCAL_DATE_U_MSK, (date_u<ALCAL, RTC_ALCAL_DATE_U_MSK)>>RTC_ALCAL_DATE_U_POSS); +} + +/** + * @brief Set Year Alarm Function Enable + * @param rtc RTC Instance + * @param year can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alen_year(RTC_TypeDef *rtc, uint32_t year) +{ + MODIFY_REG(rtc->ALEN, RTC_ALEN_YEAR_MSK, (year<ALEN, RTC_ALEN_YEAR_MSK)>>RTC_ALEN_YEAR_POS); +} +/** + * @brief Set Month Alarm Function Enable + * @param rtc RTC Instance + * @param month can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alen_month(RTC_TypeDef *rtc, uint32_t month) +{ + MODIFY_REG(rtc->ALEN, RTC_ALEN_MONTH_MSK, (month<ALEN, RTC_ALEN_MONTH_MSK)>>RTC_ALEN_MONTH_POS); +} +/** + * @brief Set Date Alarm Function Enable + * @param rtc RTC Instance + * @param date can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alen_date(RTC_TypeDef *rtc, uint32_t date) +{ + MODIFY_REG(rtc->ALEN, RTC_ALEN_DATE_MSK, (date<ALEN, RTC_ALEN_DATE_MSK)>>RTC_ALEN_DATE_POS); +} +/** + * @brief Set Week Alarm Function Enable + * @param rtc RTC Instance + * @param week can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alen_week(RTC_TypeDef *rtc, uint32_t week) +{ + MODIFY_REG(rtc->ALEN, RTC_ALEN_WEEK_MSK, (week<ALEN, RTC_ALEN_WEEK_MSK)>>RTC_ALEN_WEEK_POS); +} +/** + * @brief Set Hour Alarm Function Enable + * @param rtc RTC Instance + * @param hour can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alen_hour(RTC_TypeDef *rtc, uint32_t hour) +{ + MODIFY_REG(rtc->ALEN, RTC_ALEN_HOUR_MSK, (hour<ALEN, RTC_ALEN_HOUR_MSK)>>RTC_ALEN_HOUR_POS); +} +/** + * @brief Set Minute Alarm Function Enable + * @param rtc RTC Instance + * @param min can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alen_min(RTC_TypeDef *rtc, uint32_t min) +{ + MODIFY_REG(rtc->ALEN, RTC_ALEN_MIN_MSK, (min<ALEN, RTC_ALEN_MIN_MSK)>>RTC_ALEN_MIN_POS); +} +/** + * @brief Set Second Alarm Function Enable + * @param rtc RTC Instance + * @param sec can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_alen_sec(RTC_TypeDef *rtc, uint32_t sec) +{ + MODIFY_REG(rtc->ALEN, RTC_ALEN_SEC_MSK, (sec<ALEN, RTC_ALEN_SEC_MSK)>>RTC_ALEN_SEC_POS); +} + +/** + * @brief Set RTC Wakeup Counter Match Trigger Enable + * @param rtc RTC Instance + * @param wktm can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_wktm(RTC_TypeDef *rtc, uint32_t wktm) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_WKTM_MSK, (wktm<TRIG, RTC_TRIG_WKTM_MSK)>>RTC_TRIG_WKTM_POS); +} +/** + * @brief Set RTC 1 Hz Trigger Enable + * @param rtc RTC Instance + * @param f1hz can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_f1hz(RTC_TypeDef *rtc, uint32_t f1hz) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_F1HZ_MSK, (f1hz<TRIG, RTC_TRIG_F1HZ_MSK)>>RTC_TRIG_F1HZ_POS); +} +/** + * @brief Set RTC Year Roll Alarm Trigger Enable + * @param rtc RTC Instance + * @param ryear can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_ryear(RTC_TypeDef *rtc, uint32_t ryear) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_RYEAR_MSK, (ryear<TRIG, RTC_TRIG_RYEAR_MSK)>>RTC_TRIG_RYEAR_POS); +} +/** + * @brief Set RTC Month Roll Alarm Trigger Enable + * @param rtc RTC Instance + * @param rmon can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_rmon(RTC_TypeDef *rtc, uint32_t rmon) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_RMON_MSK, (rmon<TRIG, RTC_TRIG_RMON_MSK)>>RTC_TRIG_RMON_POS); +} +/** + * @brief Set RTC Date Roll Alarm Trigger Enable + * @param rtc RTC Instance + * @param rdate can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_rdate(RTC_TypeDef *rtc, uint32_t rdate) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_RDATE_MSK, (rdate<TRIG, RTC_TRIG_RDATE_MSK)>>RTC_TRIG_RDATE_POS); +} +/** + * @brief Set RTC Week Roll Alarm Trigger Enable + * @param rtc RTC Instance + * @param rweek can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_rweek(RTC_TypeDef *rtc, uint32_t rweek) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_RWEEK_MSK, (rweek<TRIG, RTC_TRIG_RWEEK_MSK)>>RTC_TRIG_RWEEK_POS); +} +/** + * @brief Set RTC Hour Roll Alarm Trigger Enable + * @param rtc RTC Instance + * @param rhour can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_rhour(RTC_TypeDef *rtc, uint32_t rhour) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_RHOUR_MSK, (rhour<TRIG, RTC_TRIG_RHOUR_MSK)>>RTC_TRIG_RHOUR_POS); +} +/** + * @brief Set RTC Minute Roll Alarm Trigger Enable + * @param rtc RTC Instance + * @param rmin can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_rmin(RTC_TypeDef *rtc, uint32_t rmin) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_RMIN_MSK, (rmin<TRIG, RTC_TRIG_RMIN_MSK)>>RTC_TRIG_RMIN_POS); +} +/** + * @brief Set RTC Second Roll Alarm Trigger Enable + * @param rtc RTC Instance + * @param rsec can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_rsec(RTC_TypeDef *rtc, uint32_t rsec) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_RSEC_MSK, (rsec<TRIG, RTC_TRIG_RSEC_MSK)>>RTC_TRIG_RSEC_POS); +} +/** + * @brief Set RTC Match All Alarm Trigger Enable + * @param rtc RTC Instance + * @param amall can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_amall(RTC_TypeDef *rtc, uint32_t amall) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_AMALL_MSK, (amall<TRIG, RTC_TRIG_AMALL_MSK)>>RTC_TRIG_AMALL_POS); +} +/** + * @brief Set RTC Match Year Alarm Trigger Enable + * @param rtc RTC Instance + * @param ayear can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_ayear(RTC_TypeDef *rtc, uint32_t ayear) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_AYEAR_MSK, (ayear<TRIG, RTC_TRIG_AYEAR_MSK)>>RTC_TRIG_AYEAR_POS); +} +/** + * @brief Set RTC Match Month Alarm Trigger Enable + * @param rtc RTC Instance + * @param amon can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_amon(RTC_TypeDef *rtc, uint32_t amon) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_AMON_MSK, (amon<TRIG, RTC_TRIG_AMON_MSK)>>RTC_TRIG_AMON_POS); +} +/** + * @brief Set RTC Match Date Alarm Trigger Enable + * @param rtc RTC Instance + * @param adate can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_adate(RTC_TypeDef *rtc, uint32_t adate) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_ADTAE_MSK, (adate<TRIG, RTC_TRIG_ADTAE_MSK)>>RTC_TRIG_ADTAE_POS); +} +/** + * @brief Set RTC Match Week Alarm Trigger Enable + * @param rtc RTC Instance + * @param aweek can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_aweek(RTC_TypeDef *rtc, uint32_t aweek) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_AWEEK_MSK, (aweek<TRIG, RTC_TRIG_AWEEK_MSK)>>RTC_TRIG_AWEEK_POS); +} +/** + * @brief Set RTC Match Hour Alarm Trigger Enable + * @param rtc RTC Instance + * @param ahour can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_ahour(RTC_TypeDef *rtc, uint32_t ahour) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_AHOUR_MSK, (ahour<TRIG, RTC_TRIG_AHOUR_MSK)>>RTC_TRIG_AHOUR_POS); +} +/** + * @brief Set RTC Match Minute Alarm Trigger Enable + * @param rtc RTC Instance + * @param amin can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_amin(RTC_TypeDef *rtc, uint32_t amin) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_AMIN_MSK, (amin<TRIG, RTC_TRIG_AMIN_MSK)>>RTC_TRIG_AMIN_POS); +} +/** + * @brief Set RTC Match Second Alarm Trigger Enable + * @param rtc RTC Instance + * @param asec can be one of the following values: + * @arg DISABLE + * @arg ENABLE + * @retval None + */ +__STATIC_INLINE void md_rtc_set_trig_asec(RTC_TypeDef *rtc, uint32_t asec) +{ + MODIFY_REG(rtc->TRIG, RTC_TRIG_ASEC_MSK, (asec<TRIG, RTC_TRIG_ASEC_MSK)>>RTC_TRIG_ASEC_POS); +} + +/** + * @brief Set RTC Wakeup Counter Match Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_wktm(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_WKTM_MSK); +} +/** + * @brief Set RTC 1 Hz Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_f1hz(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_F1HZ_MSK); +} +/** + * @brief Set RTC Year Roll Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_ryear(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_RYEAR_MSK); +} +/** + * @brief Set RTC Month Roll Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_rmon(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_RMON_MSK); +} +/** + * @brief Set RTC Date Roll Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_rdate(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_RDATE_MSK); +} +/** + * @brief Set RTC Week Roll Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_rweek(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_RWEEK_MSK); +} +/** + * @brief Set RTC Hour Roll Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_rhour(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_RHOUR_MSK); +} +/** + * @brief Set RTC Minute Roll Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_rmin(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_RMIN_MSK); +} +/** + * @brief Set RTC Second Roll Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_rsec(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_RSEC_MSK); +} +/** + * @brief Set RTC Match All Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_amall(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_AMALL_MSK); +} +/** + * @brief Set RTC Match Year Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_ayear(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_AYEAR_MSK); +} +/** + * @brief Set RTC Match Month Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_amon(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_AMON_MSK); +} +/** + * @brief Set RTC Match Date Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_adate(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_ADTAE_MSK); +} +/** + * @brief Set RTC Match Week Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_aweek(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_AWEEK_MSK); +} +/** + * @brief Set RTC Match Hour Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_ahour(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_AHOUR_MSK); +} +/** + * @brief Set RTC Match Minute Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_amin(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_AMIN_MSK); +} +/** + * @brief Set RTC Match Second Alarm Interrupt Enable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_ier_asec(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IER, RTC_IER_ASEC_MSK); +} + +/** + * @brief Set RTC Wakeup Counter Match Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_wktm(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_WKTM_MSK); +} +/** + * @brief Set RTC 1 Hz Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_f1hz(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_F1HZ_MSK); +} +/** + * @brief Set RTC Year Roll Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_ryear(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_RYEAR_MSK); +} +/** + * @brief Set RTC Month Roll Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_rmon(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_RMON_MSK); +} +/** + * @brief Set RTC Date Roll Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_rdate(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_RDATE_MSK); +} +/** + * @brief Set RTC Week Roll Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_rweek(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_RWEEK_MSK); +} +/** + * @brief Set RTC Hour Roll Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_rhour(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_RHOUR_MSK); +} +/** + * @brief Set RTC Minute Roll Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_rmin(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_RMIN_MSK); +} +/** + * @brief Set RTC Second Roll Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_rsec(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_RSEC_MSK); +} +/** + * @brief Set RTC Match All Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_amall(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_AMALL_MSK); +} +/** + * @brief Set RTC Match Year Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_ayear(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_AYEAR_MSK); +} +/** + * @brief Set RTC Match Month Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_amon(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_AMON_MSK); +} +/** + * @brief Set RTC Match Date Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_adate(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_ADTAE_MSK); +} +/** + * @brief Set RTC Match Week Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_aweek(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_AWEEK_MSK); +} +/** + * @brief Set RTC Match Hour Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_ahour(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_AHOUR_MSK); +} +/** + * @brief Set RTC Match Minute Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_amin(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_AMIN_MSK); +} +/** + * @brief Set RTC Match Second Alarm Interrupt Disable bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_enable_idr_asec(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->IDR, RTC_IDR_ASEC_MSK); +} + +/** + * @brief Get RTC Wakeup Counter Match Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_wktm(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_WKTM_MSK)>>RTC_IVS_WKTM_POS); +} +/** + * @brief Get RTC 1 Hz Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_f1hz(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_F1HZ_MSK)>>RTC_IVS_F1HZ_POS); +} +/** + * @brief Get RTC Year Roll Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_ryear(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_RYEAR_MSK)>>RTC_IVS_RYEAR_POS); +} +/** + * @brief Get RTC Month Roll Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_rmon(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_RMON_MSK)>>RTC_IVS_RMON_POS); +} +/** + * @brief Get RTC Date Roll Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_rdate(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_RDATE_MSK)>>RTC_IVS_RDATE_POS); +} +/** + * @brief Get RTC Week Roll Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_rweek(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_RWEEK_MSK)>>RTC_IVS_RWEEK_POS); +} +/** + * @brief Get RTC Hour Roll Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_rhour(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_RHOUR_MSK)>>RTC_IVS_RHOUR_POS); +} +/** + * @brief Get RTC Minute Roll Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_rmin(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_RMIN_MSK)>>RTC_IVS_RMIN_POS); +} +/** + * @brief Get RTC Second Roll Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_rsec(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_RSEC_MSK)>>RTC_IVS_RSEC_POS); +} +/** + * @brief Get RTC Match All Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_amall(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_AMALL_MSK)>>RTC_IVS_AMALL_POS); +} +/** + * @brief Get RTC Match Year Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_ayear(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_AYEAR_MSK)>>RTC_IVS_AYEAR_POS); +} +/** + * @brief Get RTC Match Month Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_amon(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_AMON_MSK)>>RTC_IVS_AMON_POS); +} +/** + * @brief Get RTC Match Date Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_adate(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_ADTAE_MSK)>>RTC_IVS_ADTAE_POS); +} +/** + * @brief Get RTC Match Week Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_aweek(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_AWEEK_MSK)>>RTC_IVS_AWEEK_POS); +} +/** + * @brief Get RTC Match Hour Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_ahour(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_AHOUR_MSK)>>RTC_IVS_AHOUR_POS); +} +/** + * @brief Get RTC Match Minute Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_amin(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_AMIN_MSK)>>RTC_IVS_AMIN_POS); +} +/** + * @brief Get RTC Match Second Alarm Interrupt Valid Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ivs_asec(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IVS, RTC_IVS_ASEC_MSK)>>RTC_IVS_ASEC_POS); +} + +/** + * @brief Get RTC Wakeup Counter Match Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_wktm(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_WKTM_MSK)>>RTC_RIF_WKTM_POS); +} +/** + * @brief Get RTC 1 Hz Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_f1hz(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_F1HZ_MSK)>>RTC_RIF_F1HZ_POS); +} +/** + * @brief Get RTC Year Roll Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_ryear(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_RYEAR_MSK)>>RTC_RIF_RYEAR_POS); +} +/** + * @brief Get RTC Month Roll Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_rmon(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_RMON_MSK)>>RTC_RIF_RMON_POS); +} +/** + * @brief Get RTC Date Roll Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_rdate(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_RDATE_MSK)>>RTC_RIF_RDATE_POS); +} +/** + * @brief Get RTC Week Roll Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_rweek(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_RWEEK_MSK)>>RTC_RIF_RWEEK_POS); +} +/** + * @brief Get RTC Hour Roll Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_rhour(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_RHOUR_MSK)>>RTC_RIF_RHOUR_POS); +} +/** + * @brief Get RTC Minute Roll Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_rmin(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_RMIN_MSK)>>RTC_RIF_RMIN_POS); +} +/** + * @brief Get RTC Second Roll Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_rsec(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_RSEC_MSK)>>RTC_RIF_RSEC_POS); +} +/** + * @brief Get RTC Match All Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_amall(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_AMALL_MSK)>>RTC_RIF_AMALL_POS); +} +/** + * @brief Get RTC Match Year Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_ayear(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_AYEAR_MSK)>>RTC_RIF_AYEAR_POS); +} +/** + * @brief Get RTC Match Month Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_amon(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_AMON_MSK)>>RTC_RIF_AMON_POS); +} +/** + * @brief Get RTC Match Date Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_adate(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_ADTAE_MSK)>>RTC_RIF_ADTAE_POS); +} +/** + * @brief Get RTC Match Week Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_aweek(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_AWEEK_MSK)>>RTC_RIF_AWEEK_POS); +} +/** + * @brief Get RTC Match Hour Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_ahour(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_AHOUR_MSK)>>RTC_RIF_AHOUR_POS); +} +/** + * @brief Get RTC Match Minute Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_amin(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_AMIN_MSK)>>RTC_RIF_AMIN_POS); +} +/** + * @brief Get RTC Match Second Alarm Raw Interrupt Flag Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_rif_asec(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->RIF, RTC_RIF_ASEC_MSK)>>RTC_RIF_ASEC_POS); +} + +/** + * @brief Get RTC Wakeup Counter Match Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_wktm(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_WKTM_MSK)>>RTC_IFM_WKTM_POS); +} +/** + * @brief Get RTC 1 Hz Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_f1hz(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_F1HZ_MSK)>>RTC_IFM_F1HZ_POS); +} +/** + * @brief Get RTC Year Roll Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_ryear(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_RYEAR_MSK)>>RTC_IFM_RYEAR_POS); +} +/** + * @brief Get RTC Month Roll Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_rmon(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_RMON_MSK)>>RTC_IFM_RMON_POS); +} +/** + * @brief Get RTC Date Roll Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_rdate(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_RDATE_MSK)>>RTC_IFM_RDATE_POS); +} +/** + * @brief Get RTC Week Roll Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_rweek(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_RWEEK_MSK)>>RTC_IFM_RWEEK_POS); +} +/** + * @brief Get RTC Hour Roll Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_rhour(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_RHOUR_MSK)>>RTC_IFM_RHOUR_POS); +} +/** + * @brief Get RTC Minute Roll Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_rmin(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_RMIN_MSK)>>RTC_IFM_RMIN_POS); +} +/** + * @brief Get RTC Second Roll Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_rsec(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_RSEC_MSK)>>RTC_IFM_RSEC_POS); +} +/** + * @brief Get RTC Match All Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_amall(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_AMALL_MSK)>>RTC_IFM_AMALL_POS); +} +/** + * @brief Get RTC Match Year Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_ayear(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_AYEAR_MSK)>>RTC_IFM_AYEAR_POS); +} +/** + * @brief Get RTC Match Month Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_amon(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_AMON_MSK)>>RTC_IFM_AMON_POS); +} +/** + * @brief Get RTC Match Date Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_adate(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_ADTAE_MSK)>>RTC_IFM_ADTAE_POS); +} +/** + * @brief Get RTC Match Week Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_aweek(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_AWEEK_MSK)>>RTC_IFM_AWEEK_POS); +} +/** + * @brief Get RTC Match Hour Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_ahour(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_AHOUR_MSK)>>RTC_IFM_AHOUR_POS); +} +/** + * @brief Get RTC Match Minute Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_amin(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_AMIN_MSK)>>RTC_IFM_AMIN_POS); +} +/** + * @brief Get RTC Match Second Alarm Interrupt Flag Masked Status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg DISABLE + * @arg ENABLE + */ +__STATIC_INLINE uint32_t md_rtc_get_ifm_asec(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->IFM, RTC_IFM_ASEC_MSK)>>RTC_IFM_ASEC_POS); +} + +/** + * @brief Set RTC Wakeup Counter Match Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_wktm(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_WKTM_MSK); +} +/** + * @brief Set RTC 1 Hz Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_f1hz(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_F1HZ_MSK); +} +/** + * @brief Set RTC Year Roll Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_ryear(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_RYEAR_MSK); +} +/** + * @brief Set RTC Month Roll Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_rmon(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_RMON_MSK); +} +/** + * @brief Set RTC Date Roll Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_rdate(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_RDATE_MSK); +} +/** + * @brief Set RTC Week Roll Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_rweek(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_RWEEK_MSK); +} +/** + * @brief Set RTC Hour Roll Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_rhour(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_RHOUR_MSK); +} +/** + * @brief Set RTC Minute Roll Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_rmin(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_RMIN_MSK); +} +/** + * @brief Set RTC Second Roll Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_rsec(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_RSEC_MSK); +} +/** + * @brief Set RTC Match All Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_amall(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_AMALL_MSK); +} +/** + * @brief Set RTC Match Year Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_ayear(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_AYEAR_MSK); +} +/** + * @brief Set RTC Match Month Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_amon(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_AMON_MSK); +} +/** + * @brief Set RTC Match Date Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_adate(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_ADTAE_MSK); +} +/** + * @brief Set RTC Match Week Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_aweek(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_AWEEK_MSK); +} +/** + * @brief Set RTC Match Hour Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_ahour(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_AHOUR_MSK); +} +/** + * @brief Set RTC Match Minute Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_amin(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_AMIN_MSK); +} +/** + * @brief Set RTC Match Second Alarm Interrupt Clear bit + * @param rtc RTC Instance + * @retval None + */ +__STATIC_INLINE void md_rtc_clear_icr_asec(RTC_TypeDef *rtc) +{ + SET_BIT(rtc->ICR, RTC_ICR_ASEC_MSK); +} + +/** + * @brief Get RTC Calendar Synchronization status bit + * @param rtc RTC Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_RTC_STAT_SYNDONE_UNDER + * @arg @ref MD_RTC_STAT_SYNDONE_CMP + */ +__STATIC_INLINE uint32_t md_rtc_get_stat_syndone(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->STAT, RTC_STAT_SYNDONE_MSK)>>RTC_STAT_SYNDONE_POS); +} +/** + * @brief Get RTC Calendar Status bit + * @param rtc RTC Instance + * @retval State of bit (1 or 0). + * @note 0 = RTC calendar is not empty + * 1 = RTC calendar is empty + */ +__STATIC_INLINE uint32_t md_rtc_get_stat_empty(RTC_TypeDef *rtc) +{ + return (READ_BIT(rtc->STAT, RTC_STAT_EMPTY_MSK)>>RTC_STAT_EMPTY_POS); +} + +/** + * @brief Set Read RTC Backup Register Enable bit + * @param rtc RTC Instance + * @param bken can be one of the following values: + * @arg @ref MD_RTC_BKEN_BKEN_CONTROL + * @arg @ref MD_RTC_BKEN_BKEN_BACKUP + * @retval None + */ +__STATIC_INLINE void md_rtc_set_bken_bken(RTC_TypeDef *rtc, uint32_t bken) +{ + MODIFY_REG(rtc->BKEN, RTC_BKEN_BKEN_MSK, (bken<BKEN, RTC_BKEN_BKEN_MSK)>>RTC_BKEN_BKEN_POS); +} + +/** + * @} MD_RTC_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_RTC_Public_Functions RTC Public Functions + * @{ + */ + +/** @defgroup MD_RTC_PF_Basic_Configuration Basic Configuration + * @{ + */ + +/** + * @} MD_RTC_PF_Basic_Configuration + */ + +/** @defgroup MD_RTC_PF_Data_Access Data Access + * @{ + */ + +/** + * @} MD_RTC_PF_Data_Access + */ + +/** @defgroup MD_RTC_PF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @} MD_RTC_PF_Init + */ + +/** + * @} MD_RTC_Public_Functions + */ + +#endif + +/** + * @} RTC + */ + +/** + * @} Micro_Driver + */ + + +#ifdef __cplusplus +} + +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_spi.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_spi.h new file mode 100644 index 0000000000..74f01e6312 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_spi.h @@ -0,0 +1,2523 @@ +/** + ****************************************************************************** + * @file md_spi.h + * @brief ES32F0271 SPI Head File. + * + * @version V1.00.01 + * @date 06/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_SPI_H__ +#define __MD_SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_spi.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (SPI1) || defined (SPI2) + +/** @defgroup SPI SPI + * @brief SPI micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ +/** @defgroup MD_SPI_Public_Types SPI Public Types + * @{ + */ + +/** @defgroup MD_SPI_PT_INIT SPI Public Init structure + * @{ + */ + +/** + * @brief SPI Init structure. + */ +typedef struct +{ + uint32_t Mode; /*!< Specifies the SPI mode (Master/Slave). + This parameter can be a value of @ref MD_SPI_PC_MODE. + + This feature can be modified afterwards using unitary function @ref md_spi_set_con1_mstren().*/ + + uint32_t ClockPhase; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref MD_SPI_PC_PHASE. + + This feature can be modified afterwards using unitary function @ref md_spi_set_con1_cpha().*/ + + uint32_t ClockPolarity; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref MD_SPI_PC_POLARITY. + + This feature can be modified afterwards using unitary function @ref md_spi_get_con1_cpol().*/ + + uint32_t BaudRate; /*!< Specifies the BaudRate prescaler value which will be used to configure the transmit and receive SCK clock. + This parameter can be a value of @ref MD_SPI_PC_BAUDRATEPRESCALER. + @note The communication clock is derived from the master clock. The slave clock does not need to be set. + + This feature can be modified afterwards using unitary function @ref md_spi_set_con1_baud().*/ + + uint32_t BitOrder; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref MD_SPI_PC_BIT_ORDER. + + This feature can be modified afterwards using unitary function @ref md_spi_set_con1_lsbfirst().*/ + + uint32_t TransferDirection; /*!< Specifies the SPI unidirectional or bidirectional data mode. + This parameter can be a value of @ref MD_SPI_PC_TRANSFER_DIRECTION. + + This feature can be modified afterwards using unitary function @ref md_spi_set_con1_bidimode().*/ + + uint32_t DataWidth; /*!< Specifies the SPI data width. + This parameter can be a value of @ref MD_SPI_PC_FRAME_FORMAT. + + This feature can be modified afterwards using unitary function @ref md_spi_set_con1_dlen().*/ + + uint32_t NSS; /*!< Specifies whether the NSS signal is managed by hardware (NSS pin) or by software using the SSI bit. + This parameter can be a value of @ref MD_SPI_PC_NSS_MODE. + + This feature can be modified afterwards using unitary function @ref md_spi_set_con1_ssout().*/ + + uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not. + This parameter can be a value of @ref MD_SPI_EC_CRC_CALCULATION. + + This feature can be modified afterwards using unitary functions @ref md_spi_enable_con1_crcen() and @ref md_spi_disable_con1_crcen().*/ + + uint32_t CRCPoly; /*!< Specifies the polynomial used for the CRC calculation. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary function.*/ + +} md_spi_inittypedef; + + + + +/** + * @} MD_SPI_PT_INIT + */ + +/** + * @} MD_SPI_Public_Types + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_SPI_Public_Constants SPI Public Constants + * @{ + */ + +/** @defgroup MD_SPI_PC_MODE SPI Operation Mode + * @{ + */ +#define MD_SPI_MODE_SLAVE 0x00000000U /*!< Slave configuration */ +#define MD_SPI_MODE_MASTER (SPI_CON1_MSTREN_MSK) /*!< Master configuration */ +/** + * @} MD_SPI_PC_MODE + */ + +/** @defgroup MD_SPI_PC_PROTOCOL SPI Serial Protocol + * @{ + */ +#define MD_SPI_PROTOCOL_MOTOROLA 0x00000000U /*!< Motorola mode. Used as default value */ +#define MD_SPI_PROTOCOL_TI (SPI_CON2_FRF_MSK) /*!< TI mode */ +/** + * @} MD_SPI_PC_PROTOCOL + */ + +/** @defgroup MD_SPI_PC_PHASE SPI Clock Phase + * @{ + */ +#define MD_SPI_PHASE_1EDGE 0x00000000U /*!< First clock transition is the first data capture edge */ +#define MD_SPI_PHASE_2EDGE (SPI_CON1_CPHA_MSK) /*!< Second clock transition is the first data capture edge */ +/** + * @} MD_SPI_PC_PHASE + */ + +/** @defgroup MD_SPI_PC_POLARITY SPI Clock Polarity + * @{ + */ +#define MD_SPI_POLARITY_LOW 0x00000000U /*!< Clock to 0 when idle */ +#define MD_SPI_POLARITY_HIGH (SPI_CON1_CPOL_MSK) /*!< Clock to 1 when idle */ +/** + * @} MD_SPI_PC_POLARITY + */ + +/** @defgroup MD_SPI_PC_BAUDRATEPRESCALER SPI Baud Rate Prescaler + * @{ + */ +#define MD_SPI_BAUDRATEPRESCALER_DIV2 0x00000000U /*!< BaudRate control equal to fPCLK/2 */ +#define MD_SPI_BAUDRATEPRESCALER_DIV4 (0x1U<CON1, value); +} + +/** + * @brief Get SPI control register (SPIx_CON1) + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_get_con1(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->CON1)); +} + +/** + + * @brief Set SPI clock phase + * @note This bit should not be changed when communication is ongoing. \n + This bit is not used in SPI TI mode. + * @param SPIx SPI Instance + * @param ClockPhase This parameter can be one of the following values: + * @arg @ref MD_SPI_PHASE_1EDGE + * @arg @ref MD_SPI_PHASE_2EDGE + * @retval None + + */ +__STATIC_INLINE void md_spi_set_con1_cpha(SPI_TypeDef *SPIx, uint32_t ClockPhase) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_CPHA_MSK, ClockPhase); +} + +/** + * @brief Get SPI clock phase + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_SPI_PHASE_1EDGE + * @arg @ref MD_SPI_PHASE_2EDGE + */ +__STATIC_INLINE uint32_t md_spi_get_con1_cpha(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_CPHA_MSK)>>SPI_CON1_CPHA_POS); +} + +/** + * @brief Set SPI clock polarity + * @note This bit should not be changed when communication is ongoing. + * This bit is not used in SPI TI mode. + * @param SPIx SPI Instance + * @param ClockPolarity This parameter can be one of the following values: + * @arg @ref MD_SPI_POLARITY_LOW + * @arg @ref MD_SPI_POLARITY_HIGH + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_cpol(SPI_TypeDef *SPIx, uint32_t ClockPolarity) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_CPOL_MSK, ClockPolarity); +} + +/** + * @brief Get SPI clock polarity + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_SPI_POLARITY_LOW + * @arg @ref MD_SPI_POLARITY_HIGH + */ +__STATIC_INLINE uint32_t md_spi_get_con1_cpol(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_CPOL_MSK)>>SPI_CON1_CPOL_POS); +} + +/** + * @brief Set SPI master selection + * @note This bit should not be changed when communication is ongoing. + * @param SPIx SPI Instance + * @param Mode This parameter can be one of the following values: + * @arg @ref MD_SPI_MODE_MASTER + * @arg @ref MD_SPI_MODE_SLAVE + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_mstren(SPI_TypeDef *SPIx, uint32_t Mode) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_MSTREN_MSK, Mode); +} + +/** + * @brief Get SPI SPI operation mode (Master or Slave) + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_SPI_MODE_MASTER + * @arg @ref MD_SPI_MODE_SLAVE + */ +__STATIC_INLINE uint32_t md_spi_get_con1_mstren(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_MSTREN_MSK )>>SPI_CON1_MSTREN_POS); +} + +/** + * @brief Set SPI baud rate control + * @note These bits should not be changed when communication is ongoing. SPI BaudRate = fPCLK/Prescaler. + * @param SPIx SPI Instance + * @param BaudRate This parameter can be one of the following values: + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV2 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV4 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV8 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV16 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV32 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV64 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV128 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV256 + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_baud(SPI_TypeDef *SPIx, uint32_t BaudRate) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_BAUD_MSK, BaudRate); +} + +/** + * @brief Get SPI baud rate prescaler + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV2 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV4 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV8 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV16 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV32 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV64 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV128 + * @arg @ref MD_SPI_BAUDRATEPRESCALER_DIV256 + */ +__STATIC_INLINE uint32_t md_spi_get_con1_baud(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_BAUD_MSK)>>SPI_CON1_BAUD_POSS); +} + +/** + * @brief Enable SPI peripheral + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_con1_spien(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CON1, SPI_CON1_SPIEN_MSK); +} + +/** + * @brief Disable SPI peripheral + * @note When disabling the SPI, follow the procedure described in the Reference Manual. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_con1_spien(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CON1, SPI_CON1_SPIEN_MSK); +} + +/** + * @brief Check if SPI peripheral is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enable_con1_spien(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->CON1, SPI_CON1_SPIEN_MSK) == (SPI_CON1_SPIEN_MSK)); +} + +/** + * @brief Set SPI frame format + * @note This bit should not be changed when communication is ongoing. This bit is not used in SPI TI mode. + * @param SPIx SPI Instance + * @param BitOrder This parameter can be one of the following values: + * @arg @ref MD_SPI_LSB_FIRST + * @arg @ref MD_SPI_MSB_FIRST + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_lsbfirst(SPI_TypeDef *SPIx, uint32_t BitOrder) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_LSBFST_MSK, BitOrder); +} + +/** + * @brief Get SPI transfer bit order + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_SPI_LSB_FIRST + * @arg @ref MD_SPI_MSB_FIRST + */ +__STATIC_INLINE uint32_t md_spi_get_con1_lsbfirst(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_LSBFST_MSK)>>SPI_CON1_LSBFST_POS); +} + +/** + * @brief Set SPI Internal slave select + * @note This bit has an effect only when the SSEN bit is set. The value of this bit is forced onto the NSS pin. + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg BIT_SET + * @arg BIT_RESET + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_ssout(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_SSOUT_MSK , value); +} + +/** + * @brief Get SPI Internal slave select + * @param SPIx SPI Instance + * @retval State of 1 or 0 + */ +__STATIC_INLINE uint32_t md_spi_get_con1_ssout(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_SSOUT_MSK)>>SPI_CON1_SSOUT_POS); +} + +/** + * @brief Enable SPI software slave management + * @note When the SSEN bit is set, the NSS pin input is replaced with the value from the SSOUT bit. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_con1_ssen(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CON1, SPI_CON1_SSEN_MSK); +} + +/** + * @brief Disable SPI software slave management + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_con1_ssen(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CON1, SPI_CON1_SSEN_MSK); +} + +/** + * @brief Check if SPI peripheral is software slave management + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enable_con1_ssen(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->CON1, SPI_CON1_SSEN_MSK) == (SPI_CON1_SSEN_MSK)); +} + +/** + * @brief Set SPI receive only mode enable + * @note This bit enables simplex communication using a single unidirectional line to receive data exclusively. \n + Keep BIDEN bit clear when receive only mode is active.This bit is also useful in a multislave system \n + in which this particular slave is not accessed, the output from the accessed slave is not corrupted. + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg BIT_SET + * @arg BIT_RESET + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_rxo(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_RXO_MSK , value); +} + +/** + * @brief Set SPI receive only mode enable + * @param SPIx SPI Instance + * @retval State of 1 or 0 + */ +__STATIC_INLINE uint32_t md_spi_get_con1_rxo(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_RXO_MSK)>>SPI_CON1_RXO_POS); +} + +/** + * @brief Set data frame format + * @param SPIx SPI Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref MD_SPI_FRAME_FORMAT_8BIT + * @arg @ref MD_SPI_FRAME_FORMAT_16BIT + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_flen(SPI_TypeDef *SPIx, uint32_t DataWidth) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_FLEN_MSK, DataWidth); +} + +/** + * @brief Get data frame format + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_SPI_FRAME_FORMAT_8BIT + * @arg @ref MD_SPI_FRAME_FORMAT_16BIT + */ +__STATIC_INLINE uint32_t md_spi_get_con1_flen(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_FLEN_MSK)>>SPI_CON1_FLEN_POS); +} + +/** + * @brief Set CRCNext to transfer CRC on the line + * @note This bit has to be written as soon as the last data is written in the SPIx_DATA register. + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg BIT_SET + * @arg BIT_RESET + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_crcnext(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_NXTCRC_MSK, value); +} + +/** + * @brief Get CRCNext to transfer CRC on the line + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval State of 1 or 0 + */ +__STATIC_INLINE uint32_t md_spi_get_con1_crcnext(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_NXTCRC_MSK)>>SPI_CON1_NXTCRC_POS); +} + +/** + * @brief Enable SPI hardware CRC calculation + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_con1_crcen(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CON1, SPI_CON1_CRCEN_MSK); +} + +/** + * @brief Disable SPI hardware CRC calculation + * @note When disabling the SPI, follow the procedure described in the Reference Manual. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_con1_crcen(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CON1, SPI_CON1_CRCEN_MSK); +} + +/** + * @brief Check if hardware CRC calculation is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enable_con1_crcen(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->CON1, SPI_CON1_CRCEN_MSK) == (SPI_CON1_CRCEN_MSK)); +} + +/** + * @brief Enable SPI Output enable in bidirectional mode + * @note Output enable in bidirectional mode. This bit combined with the BIDEN bit selects the direction of \n + transfer in bidirectional mode + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_con1_bidoen(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CON1, SPI_CON1_BIDOEN_MSK); +} + +/** + * @brief Disable Output enable in bidirectional mode + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_con1_bidoen(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CON1, SPI_CON1_BIDOEN_MSK); +} + +/** + * @brief Check if Output enable in bidirectional mode is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enable_con1_bidoen(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->CON1, SPI_CON1_BIDOEN_MSK) == (SPI_CON1_BIDOEN_MSK)); +} + +/** + * @brief Set Bidirectional data mode enable + * @note Bidirectional data mode enable. This bit enables half-duplex communication using common single bidirectional \n + data line. Keep RXO bit clear when bidirectional mode is active. + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg @ref MD_SPI_FULL_DUPLEX + * @arg @ref MD_SPI_HALF_DUPLEX + * @retval None + */ +__STATIC_INLINE void md_spi_set_con1_bidimode(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->CON1, SPI_CON1_BIDEN_MSK, value); +} + +/** + * @brief Get Bidirectional data mode enable + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow: + * @arg @ref MD_SPI_FULL_DUPLEX + * @arg @ref MD_SPI_HALF_DUPLEX + */ +__STATIC_INLINE uint32_t md_spi_get_con1_bidimode(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON1, SPI_CON1_BIDEN_MSK)>>SPI_CON1_BIDEN_POS); +} + + +/** + * @} MD_SPI_CON1 + */ + + + +/** @defgroup MD_SPI_CON2 SPI Control Register 2 + * @{ + */ + +/** + * @brief Set SPI control register 2 (SPIx_CON2) + * @param SPIx SPI Instance + * @param value The value write in SPIx_CON2 + * @retval None + */ +__STATIC_INLINE void md_spi_set_con2(SPI_TypeDef *SPIx, uint32_t value) +{ + WRITE_REG(SPIx->CON2, value); +} + +/** + * @brief Get SPI control register 2(SPIx_CON2) + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_get_con2(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->CON2)); +} + + +/** + * @brief Enable Rx buffer DMA + * @note When this bit is set, a DMA request is generated whenever the RXTH flag is set. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_con2_rxdmaen(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CON2, SPI_CON2_RXDMA_MSK); +} + +/** + * @brief Disable Rx buffer DMA + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_con2_rxdmaen(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CON2, SPI_CON2_RXDMA_MSK); +} + +/** + * @brief Check if Rx buffer DMA is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_con2_rxdmaen(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->CON2, SPI_CON2_RXDMA_MSK) == (SPI_CON2_RXDMA_MSK)); +} + +/** + * @brief Enable Tx buffer DMA enable + * @note When this bit is set, a DMA request is generated whenever the TXTH flag is set. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_con2_txdmaen(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CON2, SPI_CON2_TXDMA_MSK); +} + +/** + * @brief Disable Tx buffer DMA enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_con2_txdmaen(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CON2, SPI_CON2_TXDMA_MSK); +} + +/** + * @brief Check if Tx buffer DMA enable is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_con2_txdmaen(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->CON2, SPI_CON2_TXDMA_MSK) == (SPI_CON2_TXDMA_MSK)); +} + +/** + * @brief Enable SS output enable + * @note SS output is enabled in master mode and when the SPI interface is enabled. The SPI interface cannot \n + work in a multimaster environment. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_con2_ssoe(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CON2, SPI_CON2_NSSOE_MSK); +} + +/** + * @brief Disable SS output enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_con2_ssoe(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CON2, SPI_CON2_NSSOE_MSK); +} + +/** + * @brief Check if SS output enable is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_con2_ssoe(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->CON2, SPI_CON2_NSSOE_MSK) == (SPI_CON2_NSSOE_MSK)); +} + +/** + * @brief Enable NSS pulse management + * @note This bit is used in master mode only. It allow the SPI to generate an NSS pulse between two consecutive \n + data when doing continuous transfers. In the case of a single data transfer, it forces the NSS pin high \n + level after the transfer. It has no meaning if CPHA = ’1’, or FRF = ’1’.This bit should not be changed \n + when communication is ongoing. This bit is not used in SPI TI mode. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_con2_nssp(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CON2, SPI_CON2_NSSP_MSK); +} + +/** + * @brief Disable NSS pulse management + * @note This bit should not be changed when communication is ongoing. This bit is not used in SPI TI mode. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_con2_nssp(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CON2, SPI_CON2_NSSP_MSK); +} + +/** + * @brief Check if NSS pulse is enabled + * @note This bit should not be changed when communication is ongoing. This bit is not used in SPI TI mode. + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_con2_nssp(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->CON2, SPI_CON2_NSSP_MSK) == (SPI_CON2_NSSP_MSK)); +} + +/** + * @brief Set frame format + * @note This bit should be written only when SPI is disabled (SPE = 0) for correct operation. + * @param SPIx SPI Instance + * @param Standard This parameter can be one of the following values: + * @arg @ref MD_SPI_PROTOCOL_MOTOROLA + * @arg @ref MD_SPI_PROTOCOL_TI + * @retval None + */ +__STATIC_INLINE void md_spi_set_con2_frf(SPI_TypeDef *SPIx, uint32_t Standard) +{ + MODIFY_REG(SPIx->CON2, SPI_CON2_FRF_MSK, Standard); +} + +/** + * @brief Get frame format + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_SPI_PROTOCOL_MOTOROLA + * @arg @ref MD_SPI_PROTOCOL_TI + */ +__STATIC_INLINE uint32_t md_spi_get_con2_frf(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON2, SPI_CON2_FRF_MSK)>>SPI_CON2_FRF_POS); +} + + +/** + * @brief Set transmit FIFO trigger threshold + * @note This is used to select the threshold level in the transmit FIFO at which the Transmit FIFO \n + trigger threshold flag is generated. + * @param SPIx SPI Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref MD_SPI_TX_FIFO_TH_0BIT + * @arg @ref MD_SPI_TX_FIFO_TH_2BIT + * @arg @ref MD_SPI_TX_FIFO_TH_4BIT + * @arg @ref MD_SPI_TX_FIFO_TH_8BIT + * @retval None + */ +__STATIC_INLINE void md_spi_set_con2_txfth(SPI_TypeDef *SPIx, uint32_t Threshold) +{ + MODIFY_REG(SPIx->CON2, SPI_CON2_TXFTH_MSK, Threshold<CON2, SPI_CON2_TXFTH_MSK)>>SPI_CON2_TXFTH_POSS); +} + +/** + * @brief Set receive FIFO trigger threshold + * @note This is used to select the threshold level in the receiver FIFO at which the Receive FIFO \n + trigger threshold flag is generated. + * @param SPIx SPI Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref MD_SPI_RX_FIFO_TH_1BIT + * @arg @ref MD_SPI_RX_FIFO_TH_4BIT + * @arg @ref MD_SPI_RX_FIFO_TH_8BIT + * @arg @ref MD_SPI_RX_FIFO_TH_14BIT + * @retval None + */ +__STATIC_INLINE void md_spi_set_con2_rxfth(SPI_TypeDef *SPIx, uint32_t Threshold) +{ + MODIFY_REG(SPIx->CON2, SPI_CON2_RXFTH_MSK, Threshold<CON2, SPI_CON2_RXFTH_MSK)>>SPI_CON2_RXFTH_POSS); +} + + +/** + * @} MD_SPI_CON2 + */ + +/** + * @defgroup MD_SPI_STAT SPI Status Register + * @{ + */ + + +/** + * @brief Get SPI status register(SPIx_STAT) + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_get_stat(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->STAT)); +} + +/** + * @brief Check if SPI transmit buffer empty is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_txe(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_TXE_MSK)== (SPI_STAT_TXE_MSK)); +} + +/** + * @brief Check if SPI transmit buffer full is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_txf(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_TXF_MSK)== (SPI_STAT_TXF_MSK)); +} + +/** + * @brief Check if SPI transmit buffer overflow is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_txov(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_TXOV_MSK)== (SPI_STAT_TXOV_MSK)); +} + +/** + * @brief Check if SPI transmit buffer underflow is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_txud(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_TXUD_MSK) == (SPI_STAT_TXUD_MSK)); +} + +/** + * @brief Check if SPI Tx FIFO level under threshold is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_txth(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_TXTH_MSK) == (SPI_STAT_TXTH_MSK)); +} + +/** + * @brief Check if SPI receive buffer empty is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_rxe(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_RXE_MSK) == (SPI_STAT_RXE_MSK)); +} + +/** + * @brief Check if SPI receive buffer full is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_rxf(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_RXF_MSK)== (SPI_STAT_RXF_MSK)); +} + +/** + * @brief Get SPI receive buffer overflow + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_rxov(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CON2, SPI_STAT_RXOV_MSK)== (SPI_STAT_RXOV_MSK)); +} + +/** + * @brief Check if SPI receive buffer underflow is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_rxud(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_RXUD_MSK)== (SPI_STAT_RXUD_MSK)); +} + +/** + * @brief Check if SPI Rx FIFO level over threshold is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_rxth(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_RXTH_MSK)== (SPI_STAT_RXTH_MSK)); +} + +/** + * @brief Check if SPI channel side is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_chside(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_CHSIDE_MSK)== (SPI_STAT_CHSIDE_MSK)); +} + +/** + * @brief Check if SPI busy flag is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_stat_busy(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_BUSY_MSK)== (SPI_STAT_BUSY_MSK)); +} + +/** + * @brief Get SPI Tx FIFO level + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_get_stat_txflv(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_TXFLV_MSK) >> SPI_STAT_TXFLV_POSS); +} + +/** + * @brief Get SPI Rx FIFO level + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_get_stat_rxflv(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->STAT, SPI_STAT_RXFLV_MSK) >> SPI_STAT_RXFLV_POSS); +} + +/** + * @} MD_SPI_STAT + */ + + +/** @defgroup MD_SPI_DATA SPI Data Register + * @{ + */ + +/** + * @brief Read 8-Bits in the data register + * @param SPIx SPI Instance + * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t md_spi_recv_data8(SPI_TypeDef *SPIx) +{ + return (uint8_t)(READ_REG(SPIx->DATA)); +} + +/** + * @brief Read 16-Bits in the data register + * @param SPIx SPI Instance + * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint16_t md_spi_recv_data16(SPI_TypeDef *SPIx) +{ + return (uint16_t)(READ_REG(SPIx->DATA)); +} + +/** + * @brief Write 8-Bits in the data register + * @param SPIx SPI Instance + * @param TxData Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void md_spi_send_data8(SPI_TypeDef *SPIx, uint8_t TxData) +{ + SPIx->DATA = (uint8_t)TxData; +} + +/** + * @brief Write 16-Bits in the data register + * @param SPIx SPI Instance + * @param TxData Value between Min_Data=0x0000 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void md_spi_send_data16(SPI_TypeDef *SPIx, uint16_t TxData) +{ + SPIx->DATA = (uint16_t)TxData; +} + +/** + * @} MD_SPI_DATA + */ + +/** @defgroup MD_SPI_CRC SPI CRC Manangement + * @{ MD_SPI_CRC + */ + +/** + * @brief Set CRC polynmomial register (SPIx_CRCPLOY) + * @note When CRC calculation is enabled, the RxCRC[15:0] bits contain the computed CRC value of the subsequently \n + received bytes. This register is reset when the CRCEN bit in SPIx_CR1 register is written to 1. The CRC is \n + calculated serially using the polynomial programmed in the SPIx_CRCPLOY register. Only the 8 LSB bits are \n + considered when the CRC frame format is set to be 8-bit length (CRCL bit in the SPIx_CON1 is cleared). CRC \n + calculation is done based on any CRC8 standard. The entire 16-bits of this register are considered when a \n + 16-bit CRC frame format is selected (CRCL bit in the SPIx_CR1 register is set). CRC calculation is done based \n + on any CRC16 standard. + Note: A read to this register when the BSY Flag is set could return an incorrect value. These bits are not \n + used in I2S mode. + * @param SPIx SPI Instance + * @param CRCPoly This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFFFF + * @retval None + */ +__STATIC_INLINE void md_spi_set_crcploy(SPI_TypeDef *SPIx, uint32_t CRCPoly) +{ + WRITE_REG(SPIx->CRCPOLY, (uint16_t)CRCPoly); +} + +/** + * @brief Get CRC polynmomial register (SPIx_CRCPLOY) + * @param SPIx SPI Instance + * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF + */ +__STATIC_INLINE uint32_t md_spi_get_crcploy(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->CRCPOLY)); +} + +/** + * @brief Get Rx CRC register + * @note When CRC calculation is enabled, the RxCRC[7:0] bits contain the computed CRC value of the subsequently \n + transmitted bytes. This register is reset when the CRCEN bit of SPIx_CON1 is written to 1. The CRC is calculated \n + serially using the polynomial programmed in the SPIx_CRCPLOY register. Only the 8 LSB bits are considered \n + when the CRC frame format is set to be 8-bit length (FLEN bit in the SPIx_CON1 is cleared). CRC calculation is \n + done based on any CRC8 standard. The entire 16-bits of this register are considered when a 16-bit CRC frame \n + format is selected (CRCL bit in the SPIx_CR1 register is set). CRC calculation is done based on any CRC16 standard. \n + Note: A read to this register when the BSY flag is set could return an incorrect value. These bits are not used \n + in I2S mode. + * @param SPIx SPI Instance + * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF + */ +__STATIC_INLINE uint32_t md_spi_get_rxcrc(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->RXCRC)); +} + +/** + * @brief Get Tx CRC register + * @note When CRC calculation is enabled, the TxCRC[7:0] bits contain the computed CRC value of the subsequently \n + transmitted bytes. This register is reset when the CRCEN bit of SPIx_CON1 is written to 1. The CRC is calculated \n + serially using the polynomial programmed in the SPIx_CRCPLOY register. Only the 8 LSB bits are considered \n + when the CRC frame format is set to be 8-bit length (FLEN bit in the SPIx_CR1 is cleared). CRC calculation is \n + done based on any CRC8 standard. The entire 16-bits of this register are considered when a 16-bit CRC frame \n + format is selected (CRCL bit in the SPIx_CR1 register is set). CRC calculation is done based on any CRC16 standard. \n + Note: A read to this register when the BSY flag is set could return an incorrect value. These bits are not used \n + in I2S mode. + * @param SPIx SPI Instance + * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF + */ +__STATIC_INLINE uint32_t md_spi_get_txcrc(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->TXCRC)); +} + +/** + * @} MD_SPI_CRC + */ + + + +/** @defgroup MD_SPI_I2S I2S Configuration Management + * @{ + */ + + +/** @defgroup MD_SPI_I2SCFG I2S Configuration register + * @{ + */ + +/** + * @brief Set SPI I2S configuration register(SPIx_I2SCFG) + * @param SPIx SPI Instance + * @param value The value write in SPIx_I2SCFG + * @retval None + */ +__STATIC_INLINE void md_spi_set_I2SCFG(SPI_TypeDef *SPIx, uint32_t value) +{ + WRITE_REG(SPIx->I2SCFG, value); +} + +/** + * @brief Get SPI I2S configuration register (SPIx_I2SCFG) + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_get_I2SCFG(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->I2SCFG)); +} + +/** + * @brief Set channel legth(number of bits per audio channel) + * @note The bit write operation has a meaning only if DATLEN = 00 otherwise the channel length is fixed to 32-bit by \n + hardware whatever the value filled in. + Note: For correct operation, this bit should be configured when the I2S is disabled. It is not used in SPI mode. + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg @ref MD_I2S_CHANNEL_LENGTH_16BIT + * @arg @ref MD_I2S_CHANNEL_LENGTH_32BIT + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2scfg_chlen(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SCFG, SPI_I2SCFG_CHLEN_MSK, value); +} + +/** + * @brief Get channel legth(number of bits per audio channel) + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return: + * @arg @ref MD_I2S_CHANNEL_LENGTH_16BIT + * @arg @ref MD_I2S_CHANNEL_LENGTH_32BIT + */ +__STATIC_INLINE uint32_t md_spi_get_i2scfg_chlen(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFG, SPI_I2SCFG_CHLEN_MSK)); +} + +/** + * @brief Set Data length to be transferred + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg @ref MD_I2S_DATA_LENGTH_16BIT + * @arg @ref MD_I2S_DATA_LENGTH_24BIT + * @arg @ref MD_I2S_DATA_LENGTH_32BIT + * @arg @ref MD_I2S_DATA_LENGTH_NOT_ALLOWED + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2scfg_datlen(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SCFG, SPI_I2SCFG_DATLEN_MSK, value); +} + +/** + * @brief Get Data length to be transferred + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref MD_I2S_DATA_LENGTH_16BIT + * @arg @ref MD_I2S_DATA_LENGTH_24BIT + * @arg @ref MD_I2S_DATA_LENGTH_32BIT + * @arg @ref MD_I2S_DATA_LENGTH_NOT_ALLOWED + */ +__STATIC_INLINE uint32_t md_spi_get_i2scfg_datlen(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFG, SPI_I2SCFG_DATLEN_MSK)>>SPI_I2SCFG_DATLEN_POSS); +} + +/** + * @brief Set Inactive state clock polarity + * @note Note: For correct operation, this bit should be configured when the I2S is disabled. It is not used \n + in SPI mode. The bit CKPOL does not affect the CK edge sensitivity used to receive or transmit the SD \n + and WS signals. + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg @ref MD_I2S_POLARITY_LOW + * @arg @ref MD_I2S_POLARITY_HIGH + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2scfg_ckpol(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SCFG, SPI_I2SCFG_CKPOL_MSK, value); +} + +/** + * @brief Get Inactive state clock polarity + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow : + * @arg @ref MD_I2S_POLARITY_LOW + * @arg @ref MD_I2S_POLARITY_HIGH + */ +__STATIC_INLINE uint32_t md_spi_get_i2scfg_ckpol(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFG, SPI_I2SCFG_CKPOL_MSK)>>SPI_I2SCFG_CKPOL_POS); +} + +/** + * @brief Set I2S standard selection + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg @ref MD_I2S_PHILIPS_STANDARD + * @arg @ref MD_I2S_MSB_STANDARD + * @arg @ref MD_I2S_LSB_STANDARD + * @arg @ref MD_I2S_PCM_STANDARD + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2scfg_i2sstd(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SCFG, SPI_I2SCFG_I2SSTD_MSK, value); +} + +/** + * @brief Get I2S standard selection + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow : + * @arg @ref MD_I2S_PHILIPS_STANDARD + * @arg @ref MD_I2S_MSB_STANDARD + * @arg @ref MD_I2S_LSB_STANDARD + * @arg @ref MD_I2S_PCM_STANDARD + */ +__STATIC_INLINE uint32_t md_spi_get_i2scfg_i2sstd(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFG, SPI_I2SCFG_I2SSTD_MSK)>>SPI_I2SCFG_I2SSTD_POSS); +} + +/** + * @brief Set PCM frame synchronization + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg @ref MD_I2S_FRAME_SYN_SHORT + * @arg @ref MD_I2S_FRAME_SYN_LONG + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2scfg_pcmsync(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SCFG, SPI_I2SCFG_PCMSYNC_MSK, value); +} + +/** + * @brief Get PCM frame synchronization + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow : + * @arg @ref MD_I2S_FRAME_SYN_SHORT + * @arg @ref MD_I2S_FRAME_SYN_LONG + */ +__STATIC_INLINE uint32_t md_spi_get_i2scfg_pcmsync(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFG, SPI_I2SCFG_PCMSYNC_MSK)>>SPI_I2SCFG_PCMSYNC_POS); +} + +/** + * @brief Set I2S configuration mode + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg @ref MD_I2S_SLAVE_TX + * @arg @ref MD_I2S_SLAVE_RX + * @arg @ref MD_I2S_MASTER_TX + * @arg @ref MD_I2S_MASTER_RX + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2scfg_i2scfg(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SCFG, SPI_I2SCFG_I2SCFG_MSK, value); +} + +/** + * @brief Get I2S configuration mode + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow : + * @arg @ref MD_I2S_SLAVE_TX + * @arg @ref MD_I2S_SLAVE_RX + * @arg @ref MD_I2S_MASTER_TX + * @arg @ref MD_I2S_MASTER_RX + */ +__STATIC_INLINE uint32_t md_spi_get_i2scfg_i2scfg(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFG, SPI_I2SCFG_I2SCFG_MSK)>>SPI_I2SCFG_I2SCFG_POSS); +} + +/** + * @brief Enable I2S enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_i2scfg_i2se(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->I2SCFG, SPI_I2SCFG_I2SE_MSK); +} + +/** + * @brief Disable I2S enable + * @note When disabling the I2S, follow the procedure described in the Reference Manual. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_i2scfg_i2se(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->I2SCFG, SPI_I2SCFG_I2SE_MSK); +} + +/** + * @brief Check if I2S enable is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enable_i2scfg_i2se(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->I2SCFG, SPI_I2SCFG_I2SE_MSK) == (SPI_I2SCFG_I2SE_MSK)); +} + +/** + * @brief Set I2S mode selection + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg @ref MD_I2S_MODE_SPI + * @arg @ref MD_I2S_MODE_I2S + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2scfg_i2smod(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SCFG, SPI_I2SCFG_I2SMOD_MSK, value); +} + +/** + * @brief Get I2S mode selection + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow : + * @arg @ref MD_I2S_MODE_SPI + * @arg @ref MD_I2S_MODE_I2S + */ +__STATIC_INLINE uint32_t md_spi_get_i2scfg_i2smod(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFG, SPI_I2SCFG_I2SMOD_MSK)>>SPI_I2SCFG_I2SMOD_POS); +} + + +/** + * @} MD_SPI_I2SCFG + */ + +/**@defgroup MD_SPI_I2SPR I2S Prescaler register + * @{ + */ + + + +/** + * @brief Set SPI I2S configuration register(SPIx_I2SPR) + * @param SPIx SPI Instance + * @param value The value write in SPIx_I2SPR + * @retval None + */ +__STATIC_INLINE void md_spi_set_I2SPR(SPI_TypeDef *SPIx, uint32_t value) +{ + WRITE_REG(SPIx->I2SPR, value); +} + +/** + * @brief Get SPI I2S configuration register (SPIx_I2SPR) + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_get_I2SPR(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->I2SPR)); +} + +/** + * @brief Set I2S linear prescaler + * @note I2SDIV [7:0] = 0 or I2SDIV [7:0] = 1 are forbidden values. \n + Note: These bits should be configured when the I2S is disabled. \n + They are used only when the I2S is in master mode. They are not used in SPI mode. + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg Max:255 + * @arg Min:2 + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2spr_i2sdiv(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV_MSK, value); +} + +/** + * @brief Get I2S linear prescaler + * @note 0 or 1 are forbidden values + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow : + * @arg Max:255 + * @arg Min:2 + */ +__STATIC_INLINE uint32_t md_spi_get_i2spr_i2sdiv(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_I2SDIV_MSK)>>SPI_I2SPR_I2SDIV_POSS); +} + +/** + * @brief Set Odd factor for the prescaler + * @note 0 or 1 are forbidden values + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg MD_I2S_EVEN + * @arg MD_I2S_ODD + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2spr_odd(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_ODD_MSK, value); +} + +/** + * @brief Get Odd factor for the prescaler + * @note 0 or 1 are forbidden values + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow : + * @arg MD_I2S_EVEN + * @arg MD_I2S_ODD + */ +__STATIC_INLINE uint32_t md_spi_get_i2spr_odd(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_ODD_MSK)>>SPI_I2SPR_ODD_POS); +} + +/** + * @brief Master clock output enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_i2spr_mckoe(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE_MSK); +} + +/** + * @brief Master clock output disable + * @note When disabling the I2S, follow the procedure described in the Reference Manual. + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_i2spr_mckoe(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->I2SCFG, SPI_I2SPR_MCKOE_MSK); +} + +/** + * @brief Check if Master clock output enable is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enable_i2spr_mckoe(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE_MSK) == (SPI_I2SPR_MCKOE_MSK)); +} + +/** + * @brief Set External I2S Clock Enable + * @note 0 or 1 are forbidden values + * @param SPIx SPI Instance + * @param value This bit can be set to: + * @arg MD_I2S_APB_CLOCK + * @arg MD_I2S_EXTERNAL_CLOCK + * @retval None + */ +__STATIC_INLINE void md_spi_set_i2spr_extcken(SPI_TypeDef *SPIx, uint32_t value) +{ + MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_EXTCKEN_MSK, value); +} + +/** + * @brief Get External I2S Clock Enable + * @note 0 or 1 are forbidden values + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @retval Return follow : + * @arg MD_I2S_APB_CLOCK + * @arg MD_I2S_EXTERNAL_CLOCK + */ +__STATIC_INLINE uint32_t md_spi_get_i2spr_extcken(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_EXTCKEN_MSK)>>SPI_I2SPR_EXTCKEN_POS); +} + + + + + + +/** + * @} MD_SPI_I2SPR + */ + + + +/** + * @} MD_SPI_I2S + */ + + +/** @defgroup MD_SPI_PF_Interrupt_Management SPI Interrupt Management + * @{ + */ + +/** @defgroup MD_SPI_IER SPI Interrupt Enable Register + * @{ + */ + + +/** + * @brief Frame format error interrupt enable + * @note This bit controls the generation of an interrupt when an error condition occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode). + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_freie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_FREIE_MSK); +} + +/** + * @brief Mode fault interrupt enable + * @note This bit controls the generation of an interrupt when an error condition occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode). + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_modfie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_MODFIE_MSK); +} + +/** + * @brief CRC error interrupt enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_crcerrie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_CRCERRIE_MSK); +} + +/** + * @brief Receive buffer over threshold interrupt enable + * @note This bit controls the generation of an interrupt when an error condition occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode). + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_rxthie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_RXTHIE_MSK); +} + +/** + * @brief Transmit buffer over threshold interrupt enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_txthie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_TXTHIE_MSK); +} + +/** + * @brief Receive buffer underrun interrupt enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_rxudie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_RXUDIE_MSK); +} + +/** + * @brief Transmit buffer underrun interrupt enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_txudie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_TXUDIE_MSK); +} + +/** + * @brief Receive buffer overrun interrupt enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_rxovie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_RXOVIE_MSK); +} + +/** + * @brief Transmit buffer overrun interrupt enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_txovie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_TXOVIE_MSK); +} + +/** + * @brief Receive buffer full interrupt enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_rxfie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_RXFIE_MSK); +} + +/** + * @brief Transmit buffer empty interrupt enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_enable_ier_txeie(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_TXEIE_MSK); +} + +/** + * @} MD_SPI_IER + */ + + +/** @defgroup MD_SPI_IDR SPI Interrupt Disable Register + * @{ + */ + +/** + * @brief Frame format error interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_freid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_FREID_MSK); +} + +/** + * @brief Mode fault interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_modfid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_MODFID_MSK); +} + +/** + * @brief CRC error interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_crcerrid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_CRCERRID_MSK); +} + +/** + * @brief Receive buffer under threshold interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_rxthid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_RXTHID_MSK); +} + +/** + * @brief Transmit buffer under threshold interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_txthid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_TXTHID_MSK); +} + +/** + * @brief Receive buffer underrun interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_rxudid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_RXUDID_MSK); +} + +/** + * @brief Transmit buffer underrun interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_txudid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_TXUDID_MSK); +} + +/** + * @brief Receive buffer overrun interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_rxovid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_RXOVID_MSK); +} + +/** + * @brief Transmit buffer overrun interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_txovid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_TXOVID_MSK); +} + +/** + * @brief Receive buffer full interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_rxfid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_RXFID_MSK); +} + +/** + * @brief Transmit buffer empty interrupt disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void md_spi_disable_idr_txeid(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IDR, SPI_IDR_TXEID_MSK); +} + +/** + * @} MD_SPI_IDR + */ + +/** @defgroup MD_SPI_ICR SPI Interrupt Clear Status Register + * @{ + */ + +/** + * @brief Frame format error interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_freic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_FREIC_MSK); +} + +/** + * @brief Mode fault interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_modfic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_MODFIC_MSK); +} + +/** + * @brief CRC error interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_crcerric(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_CRCERRIC_MSK); +} + +/** + * @brief Receive buffer over threshold interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_rxthic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_RXTHIC_MSK); +} + +/** + * @brief Transmit buffer over threshold interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_txthic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_TXTHIC_MSK); +} + +/** + * @brief Receive buffer underrun interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_rxudic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_RXUDIC_MSK); +} + +/** + * @brief Transmit buffer underrun interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_txudic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_TXUDIC_MSK); +} + +/** + * @brief Receive buffer overrun interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_rxovic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_RXOVIC_MSK); +} + +/** + * @brief Transmit buffer overrun interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_txovic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_TXOVIC_MSK); +} + +/** + * @brief Receive buffer full interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_rxfic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_RXFIC_MSK); +} + +/** + * @brief Transmit buffer empty interrupt clear + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_spi_clear_icr_txeic(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->ICR, SPI_ICR_TXEIC_MSK); +} + +/** + * @} MD_SPI_ICR + */ + +/** @defgroup MD_SPI_IVS SPI Interrupt Valid Status Register + * @{ + */ + + +/** + * @brief Check if Frame format error interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_freiv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_FREIV_MSK) == (SPI_IVS_FREIV_MSK)); +} + +/** + * @brief Check if Mode fault interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_modfiv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_MODFIV_MSK) == (SPI_IVS_MODFIV_MSK)); +} + +/** + * @brief Check if CRC error interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_crcerriv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_CRCERRIV_MSK) == (SPI_IVS_CRCERRIV_MSK)); +} + +/** + * @brief Check if Receive buffer under threshold interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_rxthiv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_RXTHIV_MSK) == (SPI_IVS_RXTHIV_MSK)); +} + +/** + * @brief Check if Transmit buffer under threshold interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_it_txthiv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_TXTHIV_MSK) == (SPI_IVS_TXTHIV_MSK)); +} + +/** + * @brief Check if Receive buffer under underrun interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_rxudiv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_RXUDIV_MSK) == (SPI_IVS_RXUDIV_MSK)); +} + +/** + * @brief Check if Transmit buffer underrun interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_it_txudiv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_TXUDIV_MSK) == (SPI_IVS_TXUDIV_MSK)); +} + +/** + * @brief Check if Receive buffer overrun interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_rxoviv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_RXOVIV_MSK) == (SPI_IVS_RXOVIV_MSK)); +} + +/** + * @brief Check if Transmit buffer overrun interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_txoviv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_TXOVIV_MSK) == (SPI_IVS_TXOVIV_MSK)); +} + +/** + * @brief Check if Receive buffer full interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_rxfiv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_RXFIV_MSK) == (SPI_IVS_RXFIV_MSK)); +} + +/** + * @brief Check if Transmit buffer empty interrupt valid is enabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_spi_is_enabled_ivs_txeiv(SPI_TypeDef *SPIx) +{ + return (READ_BIT(SPIx->IVS, SPI_IVS_TXEIV_MSK) == (SPI_IVS_TXEIV_MSK)); +} + + +/** + * @} MD_SPI_IVS + */ + + +/** @defgroup MD_SPI_RIF SPI Raw Interrupt Flag Status Register + * @{ + */ + +/** + * @brief Check if Transmit buffer empty interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_txeri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_TXERI_MSK)==(SPI_RIF_TXERI_MSK)); +} + +/** + * @brief Check if Transmit buffer overrun interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_txovri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_TXOVRI_MSK)==(SPI_RIF_TXOVRI_MSK)); +} + +/** + * @brief Check if Transmit buffer underrun interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_txudri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_TXUDRI_MSK)==(SPI_RIF_TXUDRI_MSK)); +} + +/** + * @brief Check if Transmit buffer under threshold interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_txthri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_TXTHRI_MSK)==(SPI_RIF_TXTHRI_MSK)); +} + +/** + * @brief Check if Receive buffer full interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_rxfri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_RXFRI_MSK)==(SPI_RIF_RXFRI_MSK)); +} + +/** + * @brief Check if Receive buffer overrun interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_rxovri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_RXOVRI_MSK)==(SPI_RIF_RXOVRI_MSK)); +} + +/** + * @brief Check if Receive buffer underrun interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_rxudri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_RXUDRI_MSK)==(SPI_RIF_RXUDRI_MSK)); +} + +/** + * @brief Check if Receive buffer over threshold interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_rxthri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_RXTHRI_MSK)==(SPI_RIF_RXTHRI_MSK)); +} + +/** + * @brief Check if CRC error interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_crcerrri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_CRCERRRI_MSK)==(SPI_RIF_CRCERRRI_MSK)); +} + +/** + * @brief Check if Mode fault interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_modfri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_MODFRI_MSK)==(SPI_RIF_MODFRI_MSK)); +} + +/** + * @brief Check if Frame format error interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_rif_freri(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->RIF, SPI_RIF_FRERI_MSK)==(SPI_RIF_FRERI_MSK)); +} + +/** + * @} MD_SPI_RIF + */ + +/** @defgroup MD_SPI_IFM SPI Interrupt Masked Flag Status Register + * @{ + */ + +/** + * @brief Check if Transmit buffer empty interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_txefm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_TXEFM_MSK)==(SPI_IFM_TXEFM_MSK)); +} + +/** + * @brief Check if Transmit buffer overrun interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_txovfm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_TXOVFM_MSK)==(SPI_IFM_TXOVFM_MSK)); +} + +/** + * @brief Check if Transmit buffer underrun interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_txudfm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_TXUDFM_MSK)==(SPI_IFM_TXUDFM_MSK)); +} + +/** + * @brief Check if Transmit buffer under threshold interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_txthfm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_TXTHFM_MSK)==(SPI_IFM_TXTHFM_MSK)); +} + +/** + * @brief Check if Receive buffer full interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_rxffm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_RXFFM_MSK)==(SPI_IFM_RXFFM_MSK)); +} + +/** + * @brief Check if Receive buffer overrun interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_rxovfm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_RXOVFM_MSK)==(SPI_IFM_RXOVFM_MSK)); +} + +/** + * @brief Check if Receive buffer underrun interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_rxudfm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_RXUDFM_MSK)==(SPI_IFM_RXUDFM_MSK)); +} + +/** + * @brief Check if Receive buffer over threshold interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_rxthfm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_RXTHFM_MSK)==(SPI_IFM_RXTHFM_MSK)); +} + +/** + * @brief Check if CRC error interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_crcerrfm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_CRCERRFM_MSK)==(SPI_IFM_CRCERRFM_MSK)); +} + +/** + * @brief Check if Mode fault interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_modffm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_MODFFM_MSK)==(SPI_IFM_MODFFM_MSK)); +} + +/** + * @brief Check if Frame format error interrupt flag status is actived + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE uint32_t md_spi_is_active_flag_ifm_frefm(SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->IFM, SPI_IFM_FREFM_MSK)==(SPI_IFM_FREFM_MSK)); +} + +/** + * @} MD_SPI_IFM + */ + + + +/** + * @} MD_SPI_PF_Interrupt_Management + */ + + + +/** + * @} MD_SPI_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_SPI_Public_Functions SPI Public Functions + * @{ + */ + + + + +/** @defgroup MD_SPI_PF_Init SPI Initialization and De-Initialization functions + * @{ + */ + +ErrorStatus md_spi_init(SPI_TypeDef *SPIx, md_spi_inittypedef *SPI_InitStruct); +void md_spi_struct_init(md_spi_inittypedef *SPI_InitStruct); +void SPISingleWr(SPI_TypeDef *SPIx, uint8_t data); +uint8_t SPISSingleRd(SPI_TypeDef *SPIx); +/** + * @} MD_SPI_PF_Init + */ + +/** + * @} MD_SPI_Public_Functions + */ + +/** + * @} SPI + */ + +#endif + +/** + * @} Micro_Driver + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_syscfg.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_syscfg.h new file mode 100644 index 0000000000..0da1bfc14d --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_syscfg.h @@ -0,0 +1,1249 @@ +/** + ****************************************************************************** + * @file md_SYSCFG.h + * @brief ES32F0271 SYSCFG HEAD File. + * + * @version V1.00.02 + * @date 30/11/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_SYSCFG_H__ +#define __MD_SYSCFG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include +#include "es32f0271.h" +#include "reg_syscfg.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (SYSCFG) + +/** @defgroup SYSCFG SYSCFG + * @brief SYSCFG micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ +/** @defgroup MD_SYSCFG_PT_INIT RCC Public Init structures + * @{ + */ + +/** + * @brief MD SYSCFG Init Structure definition + */ + + +/** + * @} MD_SYSCFG_PT_INIT + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_SYSCFG_Public_Constants SYSCFG Public Constants + * @{ + */ + +/** @defgroup MD_SYSCFG_REMAP_REALMOD_FLAG Current Memory mapping Status + * @{ + */ +#define MD_SYSCFG_REALMOD_MAIN (0x00000000UL) /** @brief Main Flash memory mapped at 0x00000000 */ +#define MD_SYSCFG_REALMOD_SYSTEM (0x00000001UL) /** @brief System Flash memory mapped at 0x00000000 */ +#define MD_SYSCFG_REALMOD_SRAM (0x00000002UL) /** @brief SRAM mapped at 0x00000000 */ +/** + * @} MD_SYSCFG_REMAP_REALMOD_FLAG + */ + +/** @defgroup MD_SYSCFG_REMAP_MEMMOD_FLAG Memory mapping selection bits + * @{ + */ +#define MD_SYSCFG_MEMMOD_MAIN (0x00000000UL) /** @brief Main Flash memory mapped at 0x00000000 */ +#define MD_SYSCFG_MEMMOD_SYSTEM (0x00000001UL) /** @brief System Flash memory mapped at 0x00000000 */ +#define MD_SYSCFG_MEMMOD_SRAM (0x00000002UL) /** @brief SRAM mapped at 0x00000000 */ +/** + * @} MD_SYSCFG_REMAP_MEMMOD_FLAG + */ + +/** @defgroup MD_SYSCFG_IRSEL_PLR_FLAG IR Polarity + * @{ + */ +#define MD_SYSCFG_PLR_INV_SEL1_AND_SEL2 (0x00000000UL) /** @brief IR out = ~(SEL1 & SEL2) */ +#define MD_SYSCFG_PLR_SEL1_AND_SEL2 (0x00000001UL) /** @brief IR out = SEL1 & SEL2 */ +/** + * @} MD_SYSCFG_IRSEL_PLR_FLAG + */ + +/** @defgroup MD_SYSCFG_IRSEL_SEL2 IR Select 2 + * @{ + */ +#define MD_SYSCFG_SEL2_OFF (0x00000000UL) /** @brief 0000: OFF */ +#define MD_SYSCFG_SEL2_GP16C2T4_CH1 (0x00000001UL) /** @brief 0001: GP16C2T4_CH1 */ +#define MD_SYSCFG_SEL2_GP16C2T4_CH2 (0x00000002UL) /** @brief 0010: GP16C2T4_CH2 */ +#define MD_SYSCFG_SEL2_UART3_TX (0x00000003UL) /** @brief 0100: UART3_TX */ +#define MD_SYSCFG_SEL2_SUART2_TX (0x00000004UL) /** @brief 1000: SUART2_TX */ +/** + * @} MD_SYSCFG_IRSEL_SEL2 + */ + +/** @defgroup MD_SYSCFG_IRSEL_SEL1 IR Select 1 + * @{ + */ +#define MD_SYSCFG_SEL1_OFF (0x00000000UL) /** @brief 0000: OFF */ +#define MD_SYSCFG_SEL1_GP16C2T2_CH1 (0x00000001UL) /** @brief 0001: GP16C2T2_CH1 */ +#define MD_SYSCFG_SEL1_GP16C2T2_CH2 (0x00000002UL) /** @brief 0010: GP16C2T2_CH2 */ +#define MD_SYSCFG_SEL1_GP16C2T3_CH1 (0x00000003UL) /** @brief 0100: GP16C2T3_CH1 */ +#define MD_SYSCFG_SEL1_GP16C2T3_CH2 (0x00000004UL) /** @brief 1000: GP16C2T3_CH2 */ +/** + * @} MD_SYSCFG_IRSEL_SEL1 + */ + +/** @defgroup MD_SYSCFG_CFG_DBGH_EN DBG Halt enable bit + * @{ + */ +#define MD_SYSCFG_DBGH_EN_IWDT (0x00002000UL) +#define MD_SYSCFG_DBGH_EN_WWDT (0x00001000UL) +#define MD_SYSCFG_DBGH_EN_BS16T1 (0x00000200UL) +#define MD_SYSCFG_DBGH_EN_GP16C4T3 (0x00000100UL) +#define MD_SYSCFG_DBGH_EN_GP16C4T2 (0x00000080UL) +#define MD_SYSCFG_DBGH_EN_GP16C4T1 (0x00000040UL) +#define MD_SYSCFG_DBGH_EN_GP32C4T1 (0x00000020UL) +#define MD_SYSCFG_DBGH_EN_GP16C2T4 (0x00000010UL) +#define MD_SYSCFG_DBGH_EN_GP16C2T3 (0x00000008UL) +#define MD_SYSCFG_DBGH_EN_GP16C2T2 (0x00000004UL) +#define MD_SYSCFG_DBGH_EN_GP16C2T1 (0x00000002UL) +#define MD_SYSCFG_DBGH_EN_AD16C4T1 (0x00000001UL) +/** + * @} MD_SYSCFG_CFG_DBGH_EN + */ + +/** @defgroup MD_SYSCFG_CFG_VTST Voltage testing + * @{ + */ +#define MD_SYSCFG_VTST_LDO (0x00000000UL) /** @brief 00: LDO Buffer Voltage */ +#define MD_SYSCFG_VTST_BANDGAP_REF (0x00000001UL) /** @brief 01: BandGap Reference Voltage */ +#define MD_SYSCFG_VTST_LDO1V2 (0x00000002UL) /** @brief 10: LDO1V2 Voltage */ +#define MD_SYSCFG_VTST_LDO1V5 (0x00000003UL) /** @brief 11: LDO1V5 Voltage */ +/** + * @} MD_SYSCFG_CFG_VTST + */ + +/** @defgroup MD_SYSCFG_CFG_VRLS These bits are written by software to select the voltage reference level by the ADC/DAC + * @{ + */ +#define MD_SYSCFG_VRLS_1V5 (0x00000000UL) /** @brief 000: 1.5V */ +#define MD_SYSCFG_VRLS_2V (0x00000001UL) /** @brief 001: 2.0V */ +#define MD_SYSCFG_VRLS_2V5 (0x00000002UL) /** @brief 010: 2.5V */ +#define MD_SYSCFG_VRLS_3V (0x00000003UL) /** @brief 011: 3.0V */ +#define MD_SYSCFG_VRLS_3V5 (0x00000004UL) /** @brief 100: 3.5V */ +#define MD_SYSCFG_VRLS_4V (0x00000005UL) /** @brief 101: 4.0V */ +#define MD_SYSCFG_VRLS_4V5 (0x00000006UL) /** @brief 110: 4.5V */ +#define MD_SYSCFG_VRLS_5V (0x00000007UL) /** @brief 111: 5.0V(VDD5) */ +/** + * @} MD_SYSCFG_CFG_VRLS + */ + +/** @defgroup MD_SYSCFG_PWCON_PVLS These bits are written by software to select the voltage reference level by the ADC/DAC + * @{ + */ +#define MD_SYSCFG_PVLS_R1V9_F2V (0x00000000UL) /** @brief 0000: R-1.9V, F-2.0V */ +#define MD_SYSCFG_PVLS_R2V1_F2V2 (0x00000001UL) /** @brief 0001: R-2.1V, F-2.2V */ +#define MD_SYSCFG_PVLS_R2V3_F2V4 (0x00000002UL) /** @brief 0010: R-2.3V, F-2.4V */ +#define MD_SYSCFG_PVLS_R2V5_F2V6 (0x00000003UL) /** @brief 0011: R-2.5V, F-2.6V */ +#define MD_SYSCFG_PVLS_R2V7_F2V8 (0x00000004UL) /** @brief 0100: R-2.7V, F-2.8V */ +#define MD_SYSCFG_PVLS_R2V9_F3V (0x00000005UL) /** @brief 0101: R-2.9V, F-3.0V */ +#define MD_SYSCFG_PVLS_R3V1_F3V2 (0x00000006UL) /** @brief 0110: R-3.1V, F-3.2V */ +#define MD_SYSCFG_PVLS_R3V3_F3V4 (0x00000007UL) /** @brief 0111: R-3.3V, F-3.4V */ +#define MD_SYSCFG_PVLS_R3V5_F3V6 (0x00000008UL) /** @brief 1000: R-3.5V, F-3.6V */ +#define MD_SYSCFG_PVLS_R3V7_F3V8 (0x00000009UL) /** @brief 1001: R-3.7V, F-3.8V */ +#define MD_SYSCFG_PVLS_R3V9_F4V (0x0000000AUL) /** @brief 1010: R-3.9V, F-4.0V */ +#define MD_SYSCFG_PVLS_R4V1_F4V2 (0x0000000BUL) /** @brief 1011: R-4.1V, F-4.2V */ +#define MD_SYSCFG_PVLS_R4V3_F4V4 (0x0000000CUL) /** @brief 1100: R-4.3V, F-4.4V */ +#define MD_SYSCFG_PVLS_R4V5_F4V6 (0x0000000DUL) /** @brief 1101: R-4.5V, F-4.6V */ +#define MD_SYSCFG_PVLS_R4V7_F4V8 (0x0000000EUL) /** @brief 1110: R-4.7V, F-4.8V */ +#define MD_SYSCFG_PVLS_R4V9_F5V (0x0000000FUL) /** @brief 1111: R-4.9V, F-5.0V */ +/** + * @} MD_SYSCFG_PWCON_PVLS + */ + +/** @defgroup MD_SYSCFG_WKCON_LPLS Low Power Level Select + * @{ + */ +#define MD_SYSCFG_LPLS_LV0 (0x00000000UL) /** @brief 0 : Level 0, Sleep Mode (Normal) */ +#define MD_SYSCFG_LPLS_LV1 (0x00000001UL) /** @brief 1 : Level 1, Stop Mode (All Clock OFF) */ +#define MD_SYSCFG_LPLS_LV2 (0x00000002UL) /** @brief 2 : Level 2, Standby Mode (SRAM retention) */ +#define MD_SYSCFG_LPLS_LV3 (0x00000003UL) /** @brief 3 : Level 3, Low Power Mode (LDO off) */ +#define MD_SYSCFG_LPLS_LV4 (0x00000004UL) /** @brief 4 : Level 3, Ultra Low Power Mode(LDO off/BandGap off) */ +/** + * @} MD_SYSCFG_WKCON_LPLS + */ + +/** @defgroup MD_SYSCFG_WKCON_WKEG WKEGx:WKUPx pin edge sensitive type select + * @{ + */ +#define MD_SYSCFG_WKCON_WKEG_NRST (0x00000800UL) +#define MD_SYSCFG_WKCON_WKEG_PVD (0x00000400UL) +#define MD_SYSCFG_WKCON_WKEG_CMP0 (0x00000200UL) +#define MD_SYSCFG_WKCON_WKEG_RTC (0x00000100UL) +#define MD_SYSCFG_WKCON_WKEG_PIN7 (0x00000080UL) +#define MD_SYSCFG_WKCON_WKEG_PIN6 (0x00000040UL) +#define MD_SYSCFG_WKCON_WKEG_PIN5 (0x00000020UL) +#define MD_SYSCFG_WKCON_WKEG_PIN4 (0x00000010UL) +#define MD_SYSCFG_WKCON_WKEG_PIN3 (0x00000008UL) +#define MD_SYSCFG_WKCON_WKEG_PIN2 (0x00000004UL) +#define MD_SYSCFG_WKCON_WKEG_PIN1 (0x00000002UL) +#define MD_SYSCFG_WKCON_WKEG_PIN0 (0x00000001UL) +/** + * @} MD_SYSCFG_WKCON_WKEG + */ + +/** @defgroup MD_SYSCFG_WKCON_WKEN WKENx: Enable WKUPx pin or wakeup event + * @{ + */ +#define MD_SYSCFG_WKCON_WKEN_NRST (0x00000800UL) +#define MD_SYSCFG_WKCON_WKEN_PVD (0x00000400UL) +#define MD_SYSCFG_WKCON_WKEN_CMP0 (0x00000200UL) +#define MD_SYSCFG_WKCON_WKEN_RTC (0x00000100UL) +#define MD_SYSCFG_WKCON_WKEN_PIN7 (0x00000080UL) +#define MD_SYSCFG_WKCON_WKEN_PIN6 (0x00000040UL) +#define MD_SYSCFG_WKCON_WKEN_PIN5 (0x00000020UL) +#define MD_SYSCFG_WKCON_WKEN_PIN4 (0x00000010UL) +#define MD_SYSCFG_WKCON_WKEN_PIN3 (0x00000008UL) +#define MD_SYSCFG_WKCON_WKEN_PIN2 (0x00000004UL) +#define MD_SYSCFG_WKCON_WKEN_PIN1 (0x00000002UL) +#define MD_SYSCFG_WKCON_WKEN_PIN0 (0x00000001UL) +/** + * @} MD_SYSCFG_WKCON_WKEN + */ + +/** @defgroup MD_SYSCFG_WKSTAT_FG FGx: WKUPx pin or wakeup event flag + * @{ + */ +#define MD_SYSCFG_WKSTAT_FG_NRST (0x00000800UL) +#define MD_SYSCFG_WKSTAT_FG_PVD (0x00000400UL) +#define MD_SYSCFG_WKSTAT_FG_CMP0 (0x00000200UL) +#define MD_SYSCFG_WKSTAT_FG_RTC (0x00000100UL) +#define MD_SYSCFG_WKSTAT_FG_PIN7 (0x00000080UL) +#define MD_SYSCFG_WKSTAT_FG_PIN6 (0x00000040UL) +#define MD_SYSCFG_WKSTAT_FG_PIN5 (0x00000020UL) +#define MD_SYSCFG_WKSTAT_FG_PIN4 (0x00000010UL) +#define MD_SYSCFG_WKSTAT_FG_PIN3 (0x00000008UL) +#define MD_SYSCFG_WKSTAT_FG_PIN2 (0x00000004UL) +#define MD_SYSCFG_WKSTAT_FG_PIN1 (0x00000002UL) +#define MD_SYSCFG_WKSTAT_FG_PIN0 (0x00000001UL) +/** + * @} MD_SYSCFG_WKSTAT_FG + */ + +/** + * @} MD_SYSCFG_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_SYSCFG_Public_Macros SYSCFG Public Macros + * @{ + */ + +/** + * @brief Get Current Memory mapping Status + * @param syscfg SYSCFG Instance + * @retval The retval can be one of the following values: + * @arg @ref MD_SYSCFG_REALMOD_MAIN + * @arg @ref MD_SYSCFG_REALMOD_SYSTEM + * @arg @ref MD_SYSCFG_REALMOD_SRAM + */ +__STATIC_INLINE uint32_t md_syscfg_get_remap_REALMOD(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->REMAP, SYSCFG_REMAP_REALMOD_MSK)>>SYSCFG_REMAP_REALMOD_POSS); +} +/** + * @brief Set Remap Main Flash Base Address Selection + * @note If set 0x1, it means second 4k Byte, If set 0x2, it means third 4k Byte, and so on. + * @param syscfg SYSCFG Instance + * @param efbase This parameter can be one of the following values: + * @arg Max Value 15 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_remap_efbase(SYSCFG_TypeDef *syscfg, uint32_t efbase) +{ + MODIFY_REG(syscfg->REMAP, SYSCFG_REMAP_EFBASE_MSK, (efbase<REMAP, SYSCFG_REMAP_EFBASE_MSK)>>SYSCFG_REMAP_EFBASE_POSS); +} +/** + * @brief Set Memory mapping selection bits + * @param syscfg SYSCFG Instance + * @param memmod This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_MEMMOD_MAIN + * @arg @ref MD_SYSCFG_MEMMOD_SYSTEM + * @arg @ref MD_SYSCFG_MEMMOD_SRAM + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_remap_memmod(SYSCFG_TypeDef *syscfg, uint32_t memmod) +{ + MODIFY_REG(syscfg->REMAP, SYSCFG_REMAP_MEMMOD_MSK, (memmod<REMAP, SYSCFG_REMAP_MEMMOD_MSK)>>SYSCFG_REMAP_MEMMOD_POSS); +} +/** + * @brief Set Start Remap bit + * @note This bit set High to start remapping process, that will be auto clear when process was finish. + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_remap_remap(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->REMAP, SYSCFG_REMAP_REMAP_MSK); +} +/** + * @brief Get Start Remap bit + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_remap_remap(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->REMAP, SYSCFG_REMAP_REMAP_MSK)>>SYSCFG_REMAP_REMAP_POS); +} + +/** + * @brief Set IR Polarity + * @param syscfg SYSCFG Instance + * @param plr This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_PLR_INV_SEL1_AND_SEL2 + * @arg @ref MD_SYSCFG_PLR_SEL1_AND_SEL2 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_irsel_plr(SYSCFG_TypeDef *syscfg, uint32_t plr) +{ + MODIFY_REG(syscfg->IRSEL, SYSCFG_IRSEL_PLR_MSK, (plr<IRSEL, SYSCFG_IRSEL_PLR_MSK)>>SYSCFG_IRSEL_PLR_POS); +} +/** + * @brief Set IR Select 2 + * @param syscfg SYSCFG Instance + * @param sel2 This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_SEL2_OFF + * @arg @ref MD_SYSCFG_SEL2_GP16C2T4_CH1 + * @arg @ref MD_SYSCFG_SEL2_GP16C2T4_CH2 + * @arg @ref MD_SYSCFG_SEL2_UART3_TX + * @arg @ref MD_SYSCFG_SEL2_SUART2_TX + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_irsel_sel2(SYSCFG_TypeDef *syscfg, uint32_t sel2) +{ + MODIFY_REG(syscfg->IRSEL, SYSCFG_IRSEL_SEL2_MSK, (sel2<IRSEL, SYSCFG_IRSEL_SEL2_MSK)>>SYSCFG_IRSEL_SEL2_POSS); +} +/** + * @brief Set IR Select 1 + * @param syscfg SYSCFG Instance + * @param sel1 This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_SEL1_OFF + * @arg @ref MD_SYSCFG_SEL1_GP16C2T2_CH1 + * @arg @ref MD_SYSCFG_SEL1_GP16C2T2_CH2 + * @arg @ref MD_SYSCFG_SEL1_GP16C2T3_CH1 + * @arg @ref MD_SYSCFG_SEL1_GP16C2T3_CH2 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_irsel_sel1(SYSCFG_TypeDef *syscfg, uint32_t sel1) +{ + MODIFY_REG(syscfg->IRSEL, SYSCFG_IRSEL_SEL1_MSK, (sel1<IRSEL, SYSCFG_IRSEL_SEL1_MSK)>>SYSCFG_IRSEL_SEL1_POSS); +} + +/** + * @brief Set DBG Halt enable bit + * @note 0: The counter clock is fed even if the core is halted + * 1: The counter clock is stopped when the core is halted + * @param syscfg SYSCFG Instance + * @param sel1 This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_DBGH_EN_IWDT + * @arg @ref MD_SYSCFG_DBGH_EN_WWDT + * @arg @ref MD_SYSCFG_DBGH_EN_BS16T1 + * @arg @ref MD_SYSCFG_DBGH_EN_GP16C4T3 + * @arg @ref MD_SYSCFG_DBGH_EN_GP16C4T2 + * @arg @ref MD_SYSCFG_DBGH_EN_GP16C4T1 + * @arg @ref MD_SYSCFG_DBGH_EN_GP32C4T1 + * @arg @ref MD_SYSCFG_DBGH_EN_GP16C2T4 + * @arg @ref MD_SYSCFG_DBGH_EN_GP16C2T3 + * @arg @ref MD_SYSCFG_DBGH_EN_GP16C2T2 + * @arg @ref MD_SYSCFG_DBGH_EN_GP16C2T1 + * @arg @ref MD_SYSCFG_DBGH_EN_AD16C4T1 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_cfg_dbgh_en(SYSCFG_TypeDef *syscfg, uint32_t sel1) +{ + MODIFY_REG(syscfg->CFG, SYSCFG_CFG_DBGH_EN_MSK, (sel1<CFG, SYSCFG_CFG_DBGH_EN_MSK)>>SYSCFG_CFG_DBGH_EN_POSS); +} +/** + * @brief PVD lock enable bit + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_cfg_pvdlck(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->CFG, SYSCFG_CFG_PVD_LCK_MSK); +} +/** + * @brief PVD lock disable bit + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_cfg_pvdlck(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->CFG, SYSCFG_CFG_PVD_LCK_MSK); +} +/** + * @brief Get PVD lock bit + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_cfg_pvdlck(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->CFG, SYSCFG_CFG_PVD_LCK_MSK)>>SYSCFG_CFG_PVD_LCK_POS); +} +/** + * @brief Clock security system lock enable bit + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_cfg_csslck(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->CFG, SYSCFG_CFG_CSS_LCK_MSK); +} +/** + * @brief Clock security system lock enable bit + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_cfg_csslck(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->CFG, SYSCFG_CFG_CSS_LCK_MSK); +} +/** + * @brief Clock security system lock enable bit + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_cfg_csslck(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->CFG, SYSCFG_CFG_CSS_LCK_MSK)>>SYSCFG_CFG_CSS_LCK_POS); +} +/** + * @brief Cortex-M0 LOCKUP bit enable bit + * @note This bit is set by software and cleared by a system reset. + * It can be use to enable and lock the connection of Cortex-M0 LOCKUP (Hardfault) output to AD16C4T/GP16C2T1-4 Break input. + * @note 1: Cortex-M0 LOCKUP output connected to AD16C4T/GP16C2T1/GP16C2T2/GP16C2T3/GP16C2T4 Break input + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_cfg_cpulck(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->CFG, SYSCFG_CFG_CPU_LCK_MSK); +} +/** + * @brief Cortex-M0 LOCKUP bit disable bit + * @note 0: Cortex-M0 LOCKUP output disconnected from AD16C4T / GP16C2T1-4 Break input + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_cfg_cpulck(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->CFG, SYSCFG_CFG_CPU_LCK_MSK); +} +/** + * @brief Get Cortex-M0 LOCKUP bit + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_cfg_cpulck(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->CFG, SYSCFG_CFG_CPU_LCK_MSK)>>SYSCFG_CFG_CPU_LCK_POS); +} +/** + * @brief Set Voltage testing, This bit is set and cleared by software. + * @param syscfg SYSCFG Instance + * @param vtst This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_VTST_LDO + * @arg @ref MD_SYSCFG_VTST_BANDGAP_REF + * @arg @ref MD_SYSCFG_VTST_LDO1V2 + * @arg @ref MD_SYSCFG_VTST_LDO1V5 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_cfg_vtst(SYSCFG_TypeDef *syscfg, uint32_t vtst) +{ + MODIFY_REG(syscfg->CFG, SYSCFG_CFG_VTST_MSK, (vtst<CFG, SYSCFG_CFG_VTST_MSK)>>SYSCFG_CFG_VTST_POSS); +} +/** + * @brief Enable External NRST Pin reset request + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_cfg_nrstreq(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->CFG, SYSCFG_CFG_NRSTREQ_MSK); +} +/** + * @brief Disable External NRST Pin reset request + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_cfg_nrstreq(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->CFG, SYSCFG_CFG_NRSTREQ_MSK); +} +/** + * @brief External NRST Pin reset request + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_cfg_nrstreq(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->CFG, SYSCFG_CFG_NRSTREQ_MSK)>>SYSCFG_CFG_NRSTREQ_POS); +} +/** + * @brief ADC/DAC current generator enabled + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_cfg_currgen(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->CFG, SYSCFG_CFG_CURRGEN_MSK); +} +/** + * @brief ADC/DAC current generator disabled + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_cfg_currgen(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->CFG, SYSCFG_CFG_CURRGEN_MSK); +} +/** + * @brief ADC/DAC current generator status + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_cfg_currgen(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->CFG, SYSCFG_CFG_CURRGEN_MSK)>>SYSCFG_CFG_CURRGEN_POS); +} +/** + * @brief Temperature sensor enabled + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_cfg_tempen(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->CFG, SYSCFG_CFG_TEMPEN_MSK); +} +/** + * @brief Temperature sensor disabled + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_cfg_tempen(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->CFG, SYSCFG_CFG_TEMPEN_MSK); +} +/** + * @brief Get Temperature sensor status + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_cfg_tempen(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->CFG, SYSCFG_CFG_TEMPEN_MSK)>>SYSCFG_CFG_TEMPEN_POS); +} +/** + * @brief Voltage reference enabled + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_cfg_vrefen(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->CFG, SYSCFG_CFG_VREFEN_MSK); +} +/** + * @brief Voltage reference disabled + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_cfg_vrefen(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->CFG, SYSCFG_CFG_VREFEN_MSK); +} +/** + * @brief Get Voltage reference status + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_cfg_vrefen(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->CFG, SYSCFG_CFG_VREFEN_MSK)>>SYSCFG_CFG_VREFEN_POS); +} +/** + * @brief Set These bits are written by software to select the voltage reference level by the ADC/DAC: + * @param syscfg SYSCFG Instance + * @param vlrs This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_VRLS_1V5 + * @arg @ref MD_SYSCFG_VRLS_2V + * @arg @ref MD_SYSCFG_VRLS_2V5 + * @arg @ref MD_SYSCFG_VRLS_3V + * @arg @ref MD_SYSCFG_VRLS_3V5 + * @arg @ref MD_SYSCFG_VRLS_4V + * @arg @ref MD_SYSCFG_VRLS_4V5 + * @arg @ref MD_SYSCFG_VRLS_5V + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_cfg_vlrs(SYSCFG_TypeDef *syscfg, uint32_t vlrs) +{ + MODIFY_REG(syscfg->CFG, SYSCFG_CFG_VRLS_MSK, (vlrs<CFG, SYSCFG_CFG_VRLS_MSK)>>SYSCFG_CFG_VRLS_POSS); +} + +/** + * @brief WKCON0-7 IO Setting Value LOCKED enabled + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_pwcon_iolock(SYSCFG_TypeDef *syscfg) +{ + MODIFY_REG(syscfg->PWCON, SYSCFG_PWCON_IOLOCK_MSK, (ENABLE<PWCON, SYSCFG_PWCON_IOLOCK_MSK, (DISABLE<PWCON, SYSCFG_PWCON_IOLOCK_MSK)>>SYSCFG_PWCON_IOLOCK_POS); +} +/** + * @brief Set BandGap Trimming Value + * @param syscfg SYSCFG Instance + * @param bgtrim This parameter can be one of the following values: + * @arg Max Value 15 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_pwcon_bgtrim(SYSCFG_TypeDef *syscfg, uint32_t bgtrim) +{ + MODIFY_REG(syscfg->PWCON, SYSCFG_PWCON_BGTRIM_MSK, (bgtrim<PWCON, SYSCFG_PWCON_BGTRIM_MSK)>>SYSCFG_PWCON_BGTRIM_POSS); +} +/** + * @brief HSI auto calibration result value LOCK + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_pwcon_hrclock(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->PWCON, SYSCFG_PWCON_HRCLOCK_MSK); +} +/** + * @brief HSI auto calibration result value unLOCK + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_pwcon_hrclock(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->PWCON, SYSCFG_PWCON_HRCLOCK_MSK); +} +/** + * @brief Get HSI auto calibration result value + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_pwcon_hrclock(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->PWCON, SYSCFG_PWCON_HRCLOCK_MSK)>>SYSCFG_PWCON_HRCLOCK_POS); +} +/** + * @brief Set HSI auto calibration result value + * @param syscfg SYSCFG Instance + * @param hsitrim This parameter can be one of the following values: + * @arg Max Value 255 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_pwcon_hrctrim(SYSCFG_TypeDef *syscfg, uint32_t hsitrim) +{ + MODIFY_REG(syscfg->PWCON, SYSCFG_PWCON_HRCTRIM_MSK, (hsitrim<PWCON, SYSCFG_PWCON_HRCTRIM_MSK)>>SYSCFG_PWCON_HRCTRIM_POSS); +} +/** + * @brief Set LSI Driver Select + * @param syscfg SYSCFG Instance + * @param loscdrv This parameter can be one of the following values: + * @arg Max Value 7 + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_pwcon_loscdrv(SYSCFG_TypeDef *syscfg, uint32_t loscdrv) +{ + MODIFY_REG(syscfg->PWCON, SYSCFG_PWCON_LOSCDRV_MSK, (loscdrv<PWCON, SYSCFG_PWCON_LOSCDRV_MSK)>>SYSCFG_PWCON_LOSCDRV_POSS); +} +/** + * @brief Power voltage detector(PVD) enable + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_pwcon_pvden(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->PWCON, SYSCFG_PWCON_PVDEN_MSK); +} +/** + * @brief Power voltage detector(PVD) disable + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_disable_pwcon_pvden(SYSCFG_TypeDef *syscfg) +{ + CLEAR_BIT(syscfg->PWCON, SYSCFG_PWCON_PVDEN_MSK); +} +/** + * @brief Get Power voltage detector(PVD) status + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_pwcon_pvden(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->PWCON, SYSCFG_PWCON_PVDEN_MSK)>>SYSCFG_PWCON_PVDEN_POS); +} +/** + * @brief Set power voltage detector + * @note These bits are written by software to select the voltage threshold detected by the power voltage detector + * @param syscfg SYSCFG Instance + * @param pvls This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_PVLS_R1V9_F2V + * @arg @ref MD_SYSCFG_PVLS_R2V1_F2V2 + * @arg @ref MD_SYSCFG_PVLS_R2V3_F2V4 + * @arg @ref MD_SYSCFG_PVLS_R2V5_F2V6 + * @arg @ref MD_SYSCFG_PVLS_R2V7_F2V8 + * @arg @ref MD_SYSCFG_PVLS_R2V9_F3V + * @arg @ref MD_SYSCFG_PVLS_R3V1_F3V2 + * @arg @ref MD_SYSCFG_PVLS_R3V3_F3V4 + * @arg @ref MD_SYSCFG_PVLS_R3V5_F3V6 + * @arg @ref MD_SYSCFG_PVLS_R3V7_F3V8 + * @arg @ref MD_SYSCFG_PVLS_R3V9_F4V + * @arg @ref MD_SYSCFG_PVLS_R4V1_F4V2 + * @arg @ref MD_SYSCFG_PVLS_R4V3_F4V4 + * @arg @ref MD_SYSCFG_PVLS_R4V5_F4V6 + * @arg @ref MD_SYSCFG_PVLS_R4V7_F4V8 + * @arg @ref MD_SYSCFG_PVLS_R4V9_F5V + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_pwcon_pvls(SYSCFG_TypeDef *syscfg, uint32_t pvls) +{ + MODIFY_REG(syscfg->PWCON, SYSCFG_PWCON_PVLS_MSK, (pvls<PWCON, SYSCFG_PWCON_PVLS_MSK)>>SYSCFG_PWCON_PVLS_POSS); +} + +/** + * @brief Clear Wake Flag enable + * @param syscfg SYSCFG Instance + * @retval None + */ +__STATIC_INLINE void md_syscfg_enable_wkcon_wkclr(SYSCFG_TypeDef *syscfg) +{ + SET_BIT(syscfg->WKCON, SYSCFG_WKCON_WKCLR_MSK); +} +/** + * @brief Set Low Power Level Select + * @param syscfg SYSCFG Instance + * @param lpls The parameter can be one of the following values: + * @arg @ref MD_SYSCFG_LPLS_LV0 + * @arg @ref MD_SYSCFG_LPLS_LV1 + * @arg @ref MD_SYSCFG_LPLS_LV2 + * @arg @ref MD_SYSCFG_LPLS_LV3 + * @arg @ref MD_SYSCFG_LPLS_LV4 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_wkcon_lpls(SYSCFG_TypeDef *syscfg, uint32_t lpls) +{ + MODIFY_REG(syscfg->WKCON, SYSCFG_WKCON_LPLS_MSK, (lpls<WKCON, SYSCFG_WKCON_LPLS_MSK)>>SYSCFG_WKCON_LPLS_POSS); +} +/** + * @brief Set WKUPx pin edge sensitive type select + * @note 0 : Falling Edge-sensitive (default) + * 1 : Rising Edge-sensitive + * @param syscfg SYSCFG Instance + * @param wkeg This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_WKCON_WKEG_NRST + * @arg @ref MD_SYSCFG_WKCON_WKEG_PVD + * @arg @ref MD_SYSCFG_WKCON_WKEG_CMP0 + * @arg @ref MD_SYSCFG_WKCON_WKEG_RTC + * @arg @ref MD_SYSCFG_WKCON_WKEG_PIN7 + * @arg @ref MD_SYSCFG_WKCON_WKEG_PIN6 + * @arg @ref MD_SYSCFG_WKCON_WKEG_PIN5 + * @arg @ref MD_SYSCFG_WKCON_WKEG_PIN4 + * @arg @ref MD_SYSCFG_WKCON_WKEG_PIN3 + * @arg @ref MD_SYSCFG_WKCON_WKEG_PIN2 + * @arg @ref MD_SYSCFG_WKCON_WKEG_PIN1 + * @arg @ref MD_SYSCFG_WKCON_WKEG_PIN0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_wkcon_wkeg(SYSCFG_TypeDef *syscfg, uint32_t wkeg) +{ + MODIFY_REG(syscfg->WKCON, SYSCFG_WKCON_WKEG_MSK, (wkeg<WKCON, SYSCFG_WKCON_WKEG_MSK)>>SYSCFG_WKCON_WKEG_POSS); +} + +/** + * @brief Set Enable WKUPx pin or wakeup event + * @note 0: WKUPx pin is used for general purpose I/Os. An event on the WKUPx pin does not wakeup the device from Standby mode. + * 1: WKUPx pin is used for wakeup from Standby mode. + * @param syscfg SYSCFG Instance + * @param wken This parameter can be one of the following values: + * @arg @ref MD_SYSCFG_WKCON_WKEN_NRST + * @arg @ref MD_SYSCFG_WKCON_WKEN_PVD + * @arg @ref MD_SYSCFG_WKCON_WKEN_CMP0 + * @arg @ref MD_SYSCFG_WKCON_WKEN_RTC + * @arg @ref MD_SYSCFG_WKCON_WKEN_PIN7 + * @arg @ref MD_SYSCFG_WKCON_WKEN_PIN6 + * @arg @ref MD_SYSCFG_WKCON_WKEN_PIN5 + * @arg @ref MD_SYSCFG_WKCON_WKEN_PIN4 + * @arg @ref MD_SYSCFG_WKCON_WKEN_PIN3 + * @arg @ref MD_SYSCFG_WKCON_WKEN_PIN2 + * @arg @ref MD_SYSCFG_WKCON_WKEN_PIN1 + * @arg @ref MD_SYSCFG_WKCON_WKEN_PIN0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_wkcon_wken(SYSCFG_TypeDef *syscfg, uint32_t wken) +{ + MODIFY_REG(syscfg->WKCON, SYSCFG_WKCON_WKEN_MSK, (wken<WKCON, SYSCFG_WKCON_WKEN_MSK)>>SYSCFG_WKCON_WKEN_POSS); +} +/** + * @brief Set SYSCFG WCON register + * @param syscfg SYSCFG Instance + * @param uint32_t wcon + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_wkcon(SYSCFG_TypeDef *syscfg, uint32_t wcon) +{ + WRITE_REG(syscfg->WKCON, wcon); +} + +/** + * @brief Get Wakeup Flag + * @param syscfg SYSCFG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_syscfg_get_wkstat_flag(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->WKSTAT, SYSCFG_WKSTAT_FLAG_MSK)>>SYSCFG_WKSTAT_FLAG_POS); +} +/** + * @brief Get WKCON pin0 or wakeup event flag. + * @note When this bit was set to 1, a wakeup event occurs. + * @param syscfg SYSCFG Instance + * @retval State of bit. + * @arg @ref MD_SYSCFG_WKSTAT_FG_NRST + * @arg @ref MD_SYSCFG_WKSTAT_FG_PVD + * @arg @ref MD_SYSCFG_WKSTAT_FG_CMP0 + * @arg @ref MD_SYSCFG_WKSTAT_FG_RTC + * @arg @ref MD_SYSCFG_WKSTAT_FG_PIN7 + * @arg @ref MD_SYSCFG_WKSTAT_FG_PIN6 + * @arg @ref MD_SYSCFG_WKSTAT_FG_PIN5 + * @arg @ref MD_SYSCFG_WKSTAT_FG_PIN4 + * @arg @ref MD_SYSCFG_WKSTAT_FG_PIN3 + * @arg @ref MD_SYSCFG_WKSTAT_FG_PIN2 + * @arg @ref MD_SYSCFG_WKSTAT_FG_PIN1 + * @arg @ref MD_SYSCFG_WKSTAT_FG_PIN0 + */ +__STATIC_INLINE uint32_t md_syscfg_get_wkstat_fg(SYSCFG_TypeDef *syscfg) +{ + return (READ_BIT(syscfg->WKSTAT, SYSCFG_WKSTAT_FG_MSK)>>SYSCFG_WKSTAT_FG_POSS); +} + + +/** + * @brief Set Backup Register 0. + * @note This field was saved in the always on block, reset by power reset. + * @param syscfg SYSCFG Instance + * @param bkreg0 This parameter can be one of the following values: + * @arg Max Value 0xFFFFFFFF + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_bkreg0(SYSCFG_TypeDef *syscfg, uint32_t bkreg0) +{ + MODIFY_REG(syscfg->BKREG0, SYSCFG_BKREG0_BKREG0_MSK, (bkreg0<BKREG0, SYSCFG_BKREG0_BKREG0_MSK)>>SYSCFG_BKREG0_BKREG0_POSS); +} + +/** + * @brief Set Backup Register 1. + * @note This field was saved in the always on block, reset by power reset. + * @param syscfg SYSCFG Instance + * @param bkreg1 This parameter can be one of the following values: + * @arg Max Value 0xFFFFFFFF + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_bkreg1(SYSCFG_TypeDef *syscfg, uint32_t bkreg1) +{ + MODIFY_REG(syscfg->BKREG1, SYSCFG_BKREG1_BKREG1_MSK, (bkreg1<BKREG1, SYSCFG_BKREG1_BKREG1_MSK)>>SYSCFG_BKREG1_BKREG1_POSS); +} + +/** + * @brief Set Backup Register 2. + * @note This field was saved in the always on block, reset by power reset. + * @param syscfg SYSCFG Instance + * @param bkreg2 This parameter can be one of the following values: + * @arg Max Value 0xFFFFFFFF + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_bkreg2(SYSCFG_TypeDef *syscfg, uint32_t bkreg2) +{ + MODIFY_REG(syscfg->BKREG2, SYSCFG_BKREG2_BKREG2_MSK, (bkreg2<BKREG2, SYSCFG_BKREG2_BKREG2_MSK)>>SYSCFG_BKREG2_BKREG2_POSS); +} + +/** + * @brief Set Backup Register 3. + * @note This field was saved in the always on block, reset by power reset. + * @param syscfg SYSCFG Instance + * @param bkreg3 This parameter can be one of the following values: + * @arg Max Value 0xFFFFFFFF + * @arg Min Value 0 + * @retval None + */ +__STATIC_INLINE void md_syscfg_set_bkreg3(SYSCFG_TypeDef *syscfg, uint32_t bkreg3) +{ + MODIFY_REG(syscfg->BKREG3, SYSCFG_BKREG3_BKREG3_MSK, (bkreg3<BKREG3, SYSCFG_BKREG3_BKREG3_MSK)>>SYSCFG_BKREG3_BKREG3_POSS); +} + +/** + * @} MD_SYSCFG_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_SYSCFG_Public_Functions SYSCFG Public Functions + * @{ + */ + +/** @defgroup MD_SYSCFG_PF_Basic_Configuration Basic Configuration + * @{ + */ + +/** + * @} MD_SYSCFG_PF_Basic_Configuration + */ + +/** @defgroup MD_SYSCFG_PF_Data_Access Data Access + * @{ + */ + +/** + * @} MD_SYSCFG_PF_Data_Access + */ + +/** @defgroup MD_SYSCFG_PF_Init Initialization and de-initialization functions + * @{ + */ + +/** + * @} MD_SYSCFG_PF_Init + */ + +/** + * @} MD_SYSCFG_Public_Functions + */ + +#endif + +/** + * @} SYSCFG + */ + +/** + * @} Micro_Driver + */ + + +#ifdef __cplusplus +} + +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_tick.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_tick.h new file mode 100644 index 0000000000..f8570471e9 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_tick.h @@ -0,0 +1,433 @@ +/** + ****************************************************************************** + * @file md_TICK.h + * @brief ES32F0271 TICK HEAD File. + * + * @version V1.00.01 + * @date 11/20/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_TICK_H__ +#define __MD_TICK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_tick.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (TICK) + +/** @defgroup TICK TICK + * @brief TICK micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ + +/** + * @brief MD TICK Parameter Structure definition + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_TICK_Public_Constants TICK Public Constants + * @{ + */ + +/** + * @} MD_TICK_Public_Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_TICK_Public_Macros TICK Public Macros + * @{ + */ + +/** @defgroup MD_TICK_PM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in TICK register + * @param __INSTANCE__ TICK Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define MD_TICK_WRITEREG(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in TICK register + * @param __INSTANCE__ TICK Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define MD_TICK_READREG(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + +/** + * @brief Modify value in TICK register + * @param __INSTANCE__ TICK Instance + * @param __REG__ Register to be written + * @param __MASK__ Mask value to be written in the register + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define MD_TICK_MODIFYREG(__INSTANCE__, __REG__, __MASK__, __VALUE__) MODIFY_REG(__INSTANCE__->__REG__, __MASK__, (__VALUE__)) + +/** + * @brief Set bit value in TICK register + * @param __INSTANCE__ TICK Instance + * @param __REG__ Register to be read + * @param __MASK__ Mask value to be set in the register + * @retval None + */ +#define MD_TICK_SET_BIT(__INSTANCE__, __REG__, __MASK__) SET_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @brief Clear bit value in TICK register + * @param __INSTANCE__ TICK Instance + * @param __REG__ Register to be read + * @param __MASK__ Mask value to be cleased in the register + * @retval None + */ +#define MD_TICK_CLEAR_BIT(__INSTANCE__, __REG__, __MASK__) CLEAR_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @brief Read bit value in TICK register + * @param __INSTANCE__ TICK Instance + * @param __REG__ Register to be read + * @param __MASK__ Mask value to be read in the register + * @retval Register bit value + */ +#define MD_TICK_READBIT(__INSTANCE__, __REG__, __MASK__) READ_BIT(__INSTANCE__->__REG__, __MASK__) + +/** + * @} MD_TICK_PM_WRITE_READ + */ + +/** @defgroup MD_TICK_Macro_Drivers TICK Public Macro Drivers + * @{ + */ + +/** + * @brief Set TICK CSR + * @param @arg Max Value 0x7 + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_tick_set_csr(uint32_t U32) +{ + MD_TICK_WRITEREG(TICK, CSR, U32); +} + +/** + * @brief Get TICK CSR + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x10007 + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_tick_get_csr(void) +{ + return (MD_TICK_READREG(TICK, CSR)); +} + +/** + * @brief Get TICK CSR Count Flag + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint8_t md_tick_is_active_csr_countflag(void) +{ + return (MD_TICK_READBIT(TICK, CSR, TICK_CSR_COUNTFLAG_MSK)>>TICK_CSR_COUNTFLAG_POS); +} + +/** + * @brief Set TICK CSR Clock Source + * @param @arg Max Value 0x1 + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_tick_set_csr_clksource(uint32_t ClkSource) +{ + MD_TICK_MODIFYREG(TICK, CSR, TICK_CSR_CLKSOURCE_MSK, (ClkSource<>TICK_CSR_CLKSOURCE_POS); +} + +/** + * @brief Enable TICK CSR Tick Interrupt + * @param None + * @retval None + */ +__STATIC_INLINE void md_tick_enable_csr_tickint(void) +{ + MD_TICK_SET_BIT(TICK, CSR, TICK_CSR_TICKINT_MSK); +} + +/** + * @brief Disable TICK CSR Tick Interrupt + * @param None + * @retval None + */ +__STATIC_INLINE void md_tick_disable_csr_tickint(void) +{ + MD_TICK_CLEAR_BIT(TICK, CSR, TICK_CSR_TICKINT_MSK); +} + +/** + * @brief is TICK CSR Tick Interrupt Enabled + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint8_t md_tick_is_enabled_csr_tickint(void) +{ + return (MD_TICK_READBIT(TICK, CSR, TICK_CSR_TICKINT_MSK)>>TICK_CSR_TICKINT_POS); +} + +/** + * @brief Enable TICK CSR Enable + * @param None + * @retval None + */ +__STATIC_INLINE void md_tick_enable_csr_enable(void) +{ + MD_TICK_SET_BIT(TICK, CSR, TICK_CSR_ENABLE_MSK); +} + +/** + * @brief Disable TICK CSR Enable + * @param None + * @retval None + */ +__STATIC_INLINE void md_tick_disable_csr_enable(void) +{ + MD_TICK_CLEAR_BIT(TICK, CSR, TICK_CSR_ENABLE_MSK); +} + +/** + * @brief is TICK CSR Enable Enabled + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint8_t md_tick_is_enabled_csr_enable(void) +{ + return (MD_TICK_READBIT(TICK, CSR, TICK_CSR_ENABLE_MSK)>>TICK_CSR_ENABLE_POS); +} + +/** + * @brief Set TICK RVR + * @param @arg Max Value 0xffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_tick_set_rvr(uint32_t U32) +{ + MD_TICK_WRITEREG(TICK, RVR, U32); +} + +/** + * @brief Get TICK RVR + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_tick_get_rvr(void) +{ + return (MD_TICK_READREG(TICK, RVR)); +} + +/** + * @brief Set TICK RVR Reload + * @param @arg Max Value 0xfffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_tick_set_rvr_reload(uint32_t Reload) +{ + MD_TICK_MODIFYREG(TICK, RVR, TICK_RVR_RELOAD_MSK, (Reload<>TICK_RVR_RELOAD_POSS); +} + +/** + * @brief Set TICK CVR + * @param @arg Max Value 0xffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_tick_set_cvr(uint32_t U32) +{ + MD_TICK_WRITEREG(TICK, CVR, U32); +} + +/** + * @brief Get TICK CVR + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_tick_get_cvr(void) +{ + return (MD_TICK_READREG(TICK, CVR)); +} + +/** + * @brief Set TICK CVR Current + * @param @arg Max Value 0xfffffff + * @arg Min Value 0x0 + * @retval None + */ +__STATIC_INLINE void md_tick_set_cvr_current(uint32_t Current) +{ + MD_TICK_MODIFYREG(TICK, CVR, TICK_CVR_CURRENT_MSK, (Current<>TICK_CVR_CURRENT_POSS); +} + +/** + * @brief Get TICK CALIB + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xffffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_tick_get_calib(void) +{ + return (MD_TICK_READREG(TICK, CALIB)); +} + +/** + * @brief Get TICK CALIB NOREF + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint8_t md_tick_get_calib_noref(void) +{ + return (MD_TICK_READBIT(TICK, CALIB, TICK_CALIB_NOREF_MSK)>>TICK_CALIB_NOREF_POS); +} + +/** + * @brief Get TICK CALIB SKEW + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0x1 + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint8_t md_tick_get_calib_skew(void) +{ + return (MD_TICK_READBIT(TICK, CALIB, TICK_CALIB_SKEW_MSK)>>TICK_CALIB_SKEW_POS); +} + +/** + * @brief Get TICK CALIB 10ms Value + * @param None + * @retval The retval can be one of the following values: + * @arg Max Value 0xfffffff + * @arg Min Value 0x0 + */ +__STATIC_INLINE uint32_t md_tick_get_calib_tenms(void) +{ + return (MD_TICK_READBIT(TICK, CALIB, TICK_CALIB_TENMS_MSK)>>TICK_CALIB_TENMS_POSS); +} + + +/** + * @} MD_TICK_Macro_Drivers + */ + +/** + * @} MD_TICK_Public_Macros + */ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_TICK_Public_Functions TICK Public Functions + * @{ + */ +void md_tick_init(void); +uint32_t md_tick_get_mscnt(void); +uint32_t md_tick_get_100uscnt(void); +uint32_t md_tick_get_10uscnt(void); +void md_tick_waitms(uint8_t Unit, uint16_t msCnt); +void md_tick_wait100us(uint16_t Unit, uint16_t usCnt); +void md_tick_wait10us(uint16_t Unit, uint16_t usCnt); +/** + * @} MD_TICK_Public_Functions + */ + +#endif + +/** + * @} TICK + */ + +/** + * @} Micro_Driver + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_uart.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_uart.h new file mode 100644 index 0000000000..e638ab0a7a --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_uart.h @@ -0,0 +1,2874 @@ +/** + ****************************************************************************** + * @file md_UART.h + * @brief ES32F0271 UART Header File. + * + * @version V1.00.01 + * @date 04/12/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_UART_H__ +#define __MD_UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include +#include "es32f0271.h" +#include "reg_uart.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (UART1) | defined (UART2) | defined (UART3) | defined (SUART1) | defined (SUART2) + +/** @defgroup UART UART + * @brief UART micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public types ---------------------------------------------------------------*/ +/** @defgroup MD_UART_Public_Types UART Public Init Type + * @{ + */ + +typedef struct +{ + uint32_t BaudRate; /*!< This field defines expected Usart communication baud rate.*/ + + uint32_t BitOrder; /*!< Specifies the MSB of data bits will be transmitted or received first. + This parameter can be a value of @ref MD_UART_LCON_MSB_FIRST.*/ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref MD_UART_LCON_PS_EVEN.*/ + + uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref MD_UART_LCON_STOP_1.*/ + + uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref MD_UART_LCON_DLS_8.*/ + +} md_uart_init_typedef; + +/** + * @} MD_UART_Public_Types + */ + +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +/* Public functions -----------------------------------------------------------*/ +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_UART_Public_Constants UART Public Constants + * @{ + */ + +/** @defgroup UART_BAUDRATE UART Baudrate Definitation + * @{ + */ +#define MD_UART_BAUDRATE_1200 (1200U) /* baud rate=1200 bps */ +#define MD_UART_BAUDRATE_2400 (2400U) /* baud rate=2400 bps */ +#define MD_UART_BAUDRATE_4800 (4800U) /* baud rate=4800 bps */ +#define MD_UART_BAUDRATE_9600 (9600U) /* baud rate=9600 bps */ +#define MD_UART_BAUDRATE_19200 (19200U) /* baud rate=19200 bps */ +#define MD_UART_BAUDRATE_38400 (38400U) /* baud rate=38400 bps */ +#define MD_UART_BAUDRATE_57600 (57600U) /* baud rate=57600 bps */ +#define MD_UART_BAUDRATE_115200 (115200U) /* baud rate=115200 bps */ +#define MD_UART_BAUDRATE_230400 (230400U) /* baud rate=230400 bps */ +#define MD_UART_BAUDRATE_460800 (460800U) /* baud rate=460800 bps */ +#define MD_UART_BAUDRATE_512000 (512000U) /* baud rate=512000 bps */ +#define MD_UART_BAUDRATE_921600 (921600U) /* baud rate=921600 bps */ +/** + * @} UART_BAUDRATE UART Baudrate Definitation + */ + +/** @defgroup UART_LCON UART_LCON Register + * @{ + */ +#define MD_UART_LCON_MSB_FIRST (1U) /** @brief data Most significant bit first */ +#define MD_UART_LCON_LSB_FIRST (0U) /** @brief data Least significant bit first */ +#define MD_UART_LCON_PS_EVEN (1U) /** @brief data Even parity bit selection */ +#define MD_UART_LCON_PS_ODD (0U) /** @brief data Odd parity bit selection */ +#define MD_UART_LCON_STOP_2 (1U) /** @brief data 2(1.5) Stop bit */ +#define MD_UART_LCON_STOP_1 (0U) /** @brief data 2(1.5) Stop bit */ +#define MD_UART_LCON_DLS_8 (0U) /** @brief data Date length 8 */ +#define MD_UART_LCON_DLS_7 (1U) /** @brief data Date length 7 */ +#define MD_UART_LCON_DLS_6 (2U) /** @brief data Date length 6 */ +#define MD_UART_LCON_DLS_5 (3U) /** @brief data Date length 5 */ +/** + * @} UART_LCON UART_LCON Register + */ + +/** @defgroup UART_MCON UART_MCON Register + * @{ + */ +#define MD_UART_MCON_ABRMOD_0 (0U) /** @brief data Receiver DMA disable */ +#define MD_UART_MCON_ABRMOD_1 (1U) /** @brief data Repeat auto-baud rate detection after timeout enable */ +#define MD_UART_MCON_ABRMOD_2 (2U) /** @brief data Repeat auto-baud rate detection after timeout disable */ +#define MD_UART_MCON_RTSSET_LOW (1U) /** @brief data RTSn set control bit RTSn level is 0 */ +#define MD_UART_MCON_RTSSET_HIGH (0U) /** @brief data RTSn set control bit RTSn level is 1 */ +/** + * @} UART_MCON UART_MCON Register + */ + +/** @defgroup UART_MCON UART_MCON Register + * @{ + */ +#define MD_UART_RS485_AADINV_LOW (0U) /** @brief data Low : Transfering data, High: Idle */ +#define MD_UART_RS485_AADINV_HIGH (1U) /** @brief data High: Transfering data, Low : Idle */ +/** + * @} UART_MCON UART_MCON Register + */ + +/** @defgroup UART_FCON UART_FCON Register + * @{ + */ +#define MD_UART_FCON_TXTH_0 (0U) /** @brief data Transmit FIFO trigger threshold: FIFO empty */ +#define MD_UART_FCON_TXTH_2 (1U) /** @brief data Transmit FIFO trigger threshold: 2 characters in the FIFO */ +#define MD_UART_FCON_TXTH_4 (2U) /** @brief data Transmit FIFO trigger threshold: 4 characters in the FIFO */ +#define MD_UART_FCON_TXTH_8 (3U) /** @brief data Transmit FIFO trigger threshold: 8 characters in the FIFO */ +#define MD_UART_FCON_TFRST (1U) /** @brief data Transmitter FIFO reset */ +#define MD_UART_FCON_RXTH_1 (0U) /** @brief data Receive FIFO trigger threshold: 1 character in the FIFO */ +#define MD_UART_FCON_RXTH_4 (1U) /** @brief data Receive FIFO trigger threshold: 4 characters in the FIFO */ +#define MD_UART_FCON_RXTH_8 (2U) /** @brief data Receive FIFO trigger threshold: 8 characters in the FIFO */ +#define MD_UART_FCON_RXTH_14 (3U) /** @brief data Receive FIFO trigger threshold: 14 characters in the FIFO */ +#define MD_UART_FCON_RFRST (1U) /** @brief data Receive FIFO reset */ +/** + * @} UART_FCON UART_FCON Register + */ + +/** + * @} MD_UART_Public_Constants UART Public Constants + */ + +/* Public macro ---------------------------------------------------------------*/ +/** @defgroup MD_UART_Public_Macros UART Public Macros + * @{ + */ + +/** + * @brief Read Receiver Buffer Register + * @note Contains the received data character. + * The RXBR register provides the parallel interface between the + * input shift register and the internal bus. + * When receiving with the parity enabled, the value read in the + * MSB bit is the received parity bit. + * @param UARTx UART Instance + * @retval RxData Value between Min_Data=0x00 and Max_Data=0x1FF + */ +__STATIC_INLINE uint16_t md_uart_get_rxbuf(UART_TypeDef *UARTx) +{ + return (uint16_t) ((READ_REG(UARTx->RXBUF))>>UART_RXBUF_RXBUF_POSS); +} + +/** + * @brief Write Transmit buffer register + * @note Contains the data character to be transmitted. + * The TXBR register provides the parallel interface between the + * internal bus and the output shift register. + * When transmitting with the parity enabled the value written in + * the MSB (bit 7 or bit 8 depending on the data length) has no + * effect because it is replaced by the parity. + * @param UARTx UART Instance + * @param TxData Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void md_uart_send_txbuf(UART_TypeDef *UARTx, uint8_t TxData) +{ + WRITE_REG (UARTx->TXBUF, (uint8_t)TxData); +} + +/** + * @brief Set UARTx Baud rate register. + * @note This bits can only be written when the UART is disabled. + * (RXEN and TXEN=0 in the LCR register). + * @param UARTx UART Instance. + * @param UART buad rate value. + * @retval None + */ +__STATIC_INLINE void md_uart_set_brr(UART_TypeDef *UARTx, uint32_t baudrate) +{ + WRITE_REG(UARTx->BRR, baudrate); +} + +/** + * @brief Get UARTx baud rate. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * @param UARTx UART Instance. + * @retval UARTx Baudrate. + */ +__STATIC_INLINE uint32_t md_uart_get_brr(UART_TypeDef *UARTx) +{ + return (uint32_t) (READ_REG(UARTx->BRR)>>UART_BRR_BRR_POSS); +} + +/** + * @brief UARTx Transmitter enable. + * @note This bit enables the transmitter. It is set and cleared by + * software. + * @param UARTx UART Instance + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_lcon_txen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_TXEN_MSK); +} + +/** + * @brief UARTx Transmitter disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_lcon_txen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_TXEN_MSK); +} + +/** + * @brief Check if UART Transmitter is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_tx(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_TXEN_MSK) == (UART_LCON_TXEN_MSK)); +} + +/** + * @brief UARTx Receiver enable + * @note This bit enables the receiver. It is set and cleared by software. + * @param UARTx UART Instance + * @retval None + */ +__STATIC_INLINE void md_uart_enable_lcon_rxen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_RXEN_MSK); +} + +/** + * @brief UARTx Receiver Disable + * @param UARTx UART Instance + * @retval None + */ +__STATIC_INLINE void md_uart_disable_lcon_rxen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_RXEN_MSK); +} + +/** + * @brief Check if UARTx Receiver is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_rxen(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_RXEN_MSK) == (UART_LCON_RXEN_MSK)); +} + +/** + * @brief UARTx Debounce Enable. + * @note This bit enables the debounce. It is set and cleared by software. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_lcon_decen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_DBCEN_MSK); +} + +/** + * @brief UART Debounce Disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_lcon_dbcen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_DBCEN_MSK); +} + +/** + * @brief Check if UART Debounce is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_dbcen(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_DBCEN_MSK) == (UART_LCON_DBCEN_MSK)); +} + +/** + * @brief Enable UARTx Break control bit. + * @note This is used to cause a break condition to be transmitted to the + * receiving device. The serial data output (Tx) is forced to the + * Spacing State (logic 0). + * This bit can only be written when the UART is disabled. + * (RXENand TXEN=0). + * @param UARTx UART Instance + * @retval None + */ +__STATIC_INLINE void md_uart_enable_lcon_break(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_BREAK_MSK); +} + +/** + * @brief Disable UARTx Break control bit. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_lcon_break(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_BREAK_MSK); +} + +/** + * @brief Check if UARTx Break control bit is enabled. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_break(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_BREAK_MSK) == (UART_LCON_BREAK_MSK)); +} + +/** + * @brief UARTx Swap TX/RX pins. + * @note This allows to work in the case of a cross-wired connection to another UART. + * This bit can only be written when the UART is disabled (RXEN and TXEN=0). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_lcon_swap(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_SWAP_MSK); +} + +/** + * @brief UARTx Swap TX/RX pins disabl. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_disable_lcon_swap(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_SWAP_MSK); +} + +/** + * @brief Check if UART Swap TX/RX pins is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_swap(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_SWAP_MSK) == (UART_LCON_SWAP_MSK)); +} + +/** + * @brief UARTx TX pin active level inversion. + * @note This allows the use of an external inverter on the TX line. + * This bit can only be written when the UART is disabled (RXEN and TXEN=0). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_lcon_txinv(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_TXINV_MSK); +} + +/** + * @brief UARTx TX pin active level inversion disable. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_lcon_txinv(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_TXINV_MSK); +} + +/** + * @brief Check if UARTx TX pin active level is inverted. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_txinv(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_TXINV_MSK) == (UART_LCON_TXINV_MSK)); +} + +/** + * @brief UARTx RX pin active level inversion. + * @note This allows the use of an external inverter on the RX line. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_lcon_rxinv(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_RXINV_MSK); +} + +/** + * @brief UARTx RX pin active level inversion disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_lcon_rxinv(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_RXINV_MSK); +} + +/** + * @brief Check if UART RX pin active level is inverted. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_rxinv(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_RXINV_MSK) == (UART_LCON_RXINV_MSK)); +} + +/** + * @brief UARTx Binary data inversion. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * The parity bit is also inverted. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_lcon_datainv(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_RXINV_MSK); +} + +/** + * @brief UARTx Binary data inverted disable. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_lcon_datainv(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_RXINV_MSK); +} + +/** + * @brief Check if UARTx Binary data is inverted. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_datainv(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_DATAINV_MSK) == (UART_LCON_DATAINV_MSK)); +} + +/** + * @brief Set UARTx Most significant bit first. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * @param UARTx UART Instance. + * @param msb This parameter can be one of the following values: + * @arg @ref MD_UART_LCON_LSB_FIRST + * @arg @ref MD_UART_LCON_MSB_FIRST + * @retval None + */ +__STATIC_INLINE void md_uart_set_lcon_msb(UART_TypeDef *UARTx, uint32_t msb) +{ + MODIFY_REG(UARTx->LCON, UART_LCON_MSB_MSK, msb<LCON, UART_LCON_MSB_MSK))>>UART_LCON_MSB_POS); +} + +/** + * @brief UARTx Parity bit selection. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * @param UARTx UART Instance. + * @param parity This parameter can be one of the following values: + * @arg @ref MD_UART_LCON_PS_ODD + * @arg @ref MD_UART_LCON_PS_EVEN + * @retval None + */ +__STATIC_INLINE void md_uart_set_lcon_ps(UART_TypeDef *UARTx, uint32_t parity) +{ + MODIFY_REG(UARTx->LCON, UART_LCON_PS_MSK, parity<LCON, UART_LCON_PS_MSK))>>UART_LCON_PS_POS); +} + +/** + * @brief UARTx Parity enable. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_lcon_pe(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_LCON_PE_MSK); +} + +/** + * @brief UARTx Parity disable. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_lcon_pe(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_LCON_PE_MSK); +} + +/** + * @brief Check if UARTx Parity is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lcon_pe(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LCON, UART_LCON_PE_MSK) == (UART_LCON_PE_MSK)); +} + +/** + * @brief Set UARTx Stop bit. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0) + * @param UARTx UART Instance. + * @param stop This parameter can be one of the following values: + * @arg @ref MD_UART_LCON_STOP_1 + * @arg @ref MD_UART_LCON_STOP_2 + * @retval None + */ +__STATIC_INLINE void md_uart_set_lcon_stop(UART_TypeDef *UARTx, uint32_t stop) +{ + MODIFY_REG(UARTx->LCON, UART_LCON_STOP_MSK, stop<LCON, UART_LCON_STOP_MSK))>>UART_LCON_STOP_POS); +} + +/** + * @brief UARTx Date length selection. + * @note This bit can only be written when UART is disabled(TXEN and RXEN=0). + * @param UARTx UART Instance. + * @param width This parameter can be one of the following values: + * @arg @ref MD_UART_LCON_DLS_8 + * @arg @ref MD_UART_LCON_DLS_7 + * @arg @ref MD_UART_LCON_DLS_6 + * @arg @ref MD_UART_LCON_DLS_5 + * @retval None + */ +__STATIC_INLINE void md_uart_set_lcon_dls(UART_TypeDef *UARTx, uint32_t width) +{ + MODIFY_REG(UARTx->LCON, UART_LCON_DLS_MSK, width<LCON, UART_LCON_DLS_MSK))>>UART_LCON_DLS_POSS); +} + +/** + * @brief UARTx Transmitter DMA enable. + * @note This bit is set and cleared by software. This bit enables the DMA transmitter. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_mcon_txdmaen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->MCON, UART_MCON_TXDMAEN_MSK); +} + +/** + * @brief UARTx Transmitter DMA enable disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_mcon_txdmaen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->MCON, UART_MCON_TXDMAEN_MSK); +} + +/** + * @brief Check if UARTx Transmitter DMA is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_mcon_txdmaen(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->MCON, UART_MCON_TXDMAEN_MSK) == (UART_MCON_TXDMAEN_MSK)); +} + +/** + * @brief UARTx Receiver DMA enable. + * @note This bit is set and cleared by software. This bit enables the DMA Receiver. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_mcon_rxdmaen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->MCON, UART_MCON_RXDMAEN_MSK); +} + +/** + * @brief UARTx Receiver DMA disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_mcon_rxdmaen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->MCON, UART_MCON_RXDMAEN_MSK); +} + +/** + * @brief Check if UARTx UARTx Receiver DMA is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_mcon_rxdmaen(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->MCON, UART_MCON_RXDMAEN_MSK) == (UART_MCON_RXDMAEN_MSK)); +} + +/** + * @brief UARTx Auto baud rate detection repeat enable. + * @note This bit is set to enable baud rate detection repeat one more time + * after the first failure of auto-baud rate detection. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_mcon_abrrept(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_MCON_ABRREPT_MSK); +} + +/** + * @brief UARTx Auto baud rate detection repeat disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_mcon_abrrept(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_MCON_ABRREPT_MSK); +} + +/** + * @brief Check if UARTx Auto baud rate detection repeat is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_mcon_abrrept(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->MCON, UART_MCON_ABRREPT_MSK) == (UART_MCON_ABRREPT_MSK)); +} + +/** + * @brief Set UARTx Auto baud rate mode. + * @note MD_UART_MCON_ABRMOD_0: Mode 0 detect falling edge to second falling edge (detect 2 Bps). + * MD_UART_MCON_ABRMOD_1: Mode 1 detect falling edge to first rising edge (detect 1 Bps). + * MD_UART_MCON_ABRMOD_2: Mode 2 detect falling edge to first rising edge (detect 2 Bps). + * @param UARTx UART Instance. + * @param mode This parameter can be one of the following values: + * @arg @ref MD_UART_MCON_ABRMOD_0 + * @arg @ref MD_UART_MCON_ABRMOD_1 + * @arg @ref MD_UART_MCON_ABRMOD_2 + * @retval None + */ +__STATIC_INLINE void md_uart_set_mcon_abrmod(UART_TypeDef *UARTx, uint32_t mode) +{ + MODIFY_REG(UARTx->MCON, UART_MCON_ABRMOD_MSK, mode<MCON, UART_MCON_ABRMOD_MSK))>>UART_MCON_ABRMOD_POSS); +} + +/** + * @brief UARTx Auto baud rate enable. + * @note This bit is set by software and cleared by hardware after the + * auto-baud rate finish. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_mcon_abren(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LCON, UART_MCON_ABREN_MSK); +} + +/** + * @brief UARTx Auto baud rate disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_mcon_abren(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LCON, UART_MCON_ABREN_MSK); +} + +/** + * @brief Check if UARTx Auto baud rate is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_mcon_abren(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->MCON, UART_MCON_ABREN_MSK) == (UART_MCON_ABREN_MSK)); +} + +/** + * @brief UARTx break request enable. + * @note This bit is set by software and automatically cleared by + * hardware in the next clock cycle. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_mcon_bkreq(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->MCON, UART_MCON_BKREQ_MSK); +} + +/** + * @brief UARTx break request disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_mcon_bkreq(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->MCON, UART_MCON_BKREQ_MSK); +} + +/** + * @brief Check if UARTx break request is enabled + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_mcon_bkreq(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->MCON, UART_MCON_BKREQ_MSK) == (UART_MCON_BKREQ_MSK)); +} + +/** + * @brief UARTx Half-duplex enable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_mcon_hden(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->MCON, UART_MCON_HDEN_MSK); +} + +/** + * @brief UARTx Half-duplex disable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_mcon_hden(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->MCON, UART_MCON_HDEN_MSK); +} + +/** + * @brief Check if UARTx Half-duplex is enabled. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_mcon_hden(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->MCON, UART_MCON_HDEN_MSK) == (UART_MCON_HDEN_MSK)); +} + +/** + * @brief UARTx IrDA mode enable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_mcon_iren(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->MCON, UART_MCON_IREN_MSK); +} + +/** + * @brief UARTx IrDA mode disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_mcon_iren(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->MCON, UART_MCON_IREN_MSK); +} + +/** + * @brief Check if UARTx IrDA mode is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_mcon_iren(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->MCON, UART_MCON_IREN_MSK) == (UART_MCON_IREN_MSK)); +} + +/** + * @brief UARTx Auto flow control enable. + * @param UARTx UART Instance + * @retval None + */ +__STATIC_INLINE void md_uart_enable_mcon_afcen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->MCON, UART_MCON_AFCEN_MSK); +} + +/** + * @brief UARTx Auto flow control disable. + * @param UARTx UART Instance + * @retval None + */ +__STATIC_INLINE void md_uart_disable_mcon_afcen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->MCON, UART_MCON_AFCEN_MSK); +} + +/** + * @brief Check if Auto flow control is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_mcon_afcen(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->MCON, UART_MCON_AFCEN_MSK) == (UART_MCON_AFCEN_MSK)); +} + +/** + * @brief Set UARTx RTSn set control bit. + * @note If Auto flow control disable, user can control RTSn output level by this bit. + * MD_UART_MCON_RTSSET_LOW : RTSn level is 0 + * MD_UART_MCON_RTSSET_HIGH: RTSn level is 1 + * @param UARTx UART Instance. + * @param This parameter can be one of the following values: + * @arg @ref MD_UART_MCON_RTSSET_LOW + * @arg @ref MD_UART_MCON_RTSSET_HIGH + * @retval None + */ +__STATIC_INLINE void md_uart_set_mcon_rtsset(UART_TypeDef *UARTx, uint32_t level) +{ + MODIFY_REG(UARTx->MCON, UART_MCON_RTSSET_MSK, level<MCON, UART_MCON_RTSSET_MSK))>>UART_MCON_RTSSET_POS); +} + +/** + * @brief UARTx LoopBack enable. + * @note This is used to put the UART into a diagnostic mode for test purpose. + * If operating in UART mode, data on the TXD line is held high, + * while serial data output is looped back to the RXD line, internally. + * In this mode, all the interrupts are fully functional. + * If operating in infrared mode, data on the TXD with IrDA line is held low, + * while serial data output is inverted and looped back to the RXD line. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_mcon_lpbken(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->MCON, UART_MCON_LPBKEN_MSK); +} + +/** + * @brief UARTx LoopBack disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_mcon_lpbken(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->MCON, UART_MCON_LPBKEN_MSK); +} + +/** + * @brief Check if UARTx LoopBack is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lpbken(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->MCON, UART_MCON_LPBKEN_MSK) == (UART_MCON_LPBKEN_MSK)); +} + +/** + * @brief Set UARTx Delay value. + * @note Contains a direction control RTSn Delay value. This register + * works in conjunction with an 8-bit counter in terms of number of + * DIVISOR bit duration. + * @param UARTx UART Instance. + * @param UARTx Delay value. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_rs485_dly(UART_TypeDef *UARTx, uint32_t delay) +{ + MODIFY_REG(UARTx->RS485, UART_RS485_DLY_MSK, delay<RS485, UART_RS485_DLY_MSK))>>UART_RS485_DLY_POSS); +} + +/** + * @brief Set UARTx Address match value. + * @param UARTx UART Instance. + * @param UARTx Address match value. + * @retval None + */ +__STATIC_INLINE void md_uart_set_rs485_addr(UART_TypeDef *UARTx, uint32_t address) +{ + MODIFY_REG(UARTx->RS485, UART_RS485_ADDR_MSK, address<RS485, UART_RS485_ADDR_MSK))>>UART_RS485_ADDR_POSS); +} + +/** + * @brief Set UARTx Automatic address detection invert. + * @note This bit retains the DE(RTSn) polarity direction control signal on pin. + * @param UARTx UART Instance. + * @param aadinv can be one of the following value: + * @arg @ref MD_UART_RS485_AADINV_LOW (Low : Transfering data, High: Idle) + * @arg @ref MD_UART_RS485_AADINV_HIGH (High: Transfering data, Low : Idle) + * @retval None + */ +__STATIC_INLINE void md_uart_set_rs485_aadinv(UART_TypeDef *UARTx, uint32_t aadinv) +{ + MODIFY_REG(UARTx->RS485, UART_RS485_AADINV_MSK, aadinv<RS485, UART_RS485_AADINV_MSK))>>UART_RS485_AADINV_POS); +} + +/** + * @brief UARTx Automatic address detection auto-control enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_rs485_aadacen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->RS485, UART_RS485_AADACEN_MSK); +} + +/** + * @brief UARTx Automatic address detection auto-control disable + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_rs485_aadacen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->RS485, UART_RS485_AADACEN_MSK); +} + +/** + * @brief Check if UARTx Automatic address detection auto-control is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_rs485_aadacen(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->RS485, UART_RS485_AADACEN_MSK) == (UART_RS485_AADACEN_MSK)); +} + +/** + * @brief UARTx Automatic address detection normal mode enable. + * @note Note that it can be active with RS-485 AAD operation mode. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_rs485_aadnen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->RS485, UART_RS485_AADNEN_MSK); +} + +/** + * @brief UARTx Automatic address detection normal mode disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_rs485_aadnen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->RS485, UART_RS485_AADNEN_MSK); +} + +/** + * @brief Check if Automatic address detection normal mode is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_rs485_aadnen(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->RS485, UART_RS485_AADNEN_MSK) == (UART_RS485_AADNEN_MSK)); +} + +/** + * @brief UARTx Automatic address detection operation mode enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_rs485_aaden(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->RS485, UART_RS485_AADEN_MSK); +} + +/** + * @brief UARTx Automatic address detection operation mode disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_rs485_aaden(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->RS485, UART_RS485_AADEN_MSK); +} + +/** + * @brief Check if UARTx Automatic address detection operation mode is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_rs485_aaden(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->RS485, UART_RS485_AADEN_MSK) == (UART_RS485_AADEN_MSK)); +} + +/** + * @brief Set UARTx Block Length (Only UART). + * @note This bit-field gives the Block length in Smartcard T=1 + * Reception. Its value equals the number of information + * characters + the length of the Epilogue Field (1-LEC/2-CRC) - 1. + * This bit-field can be used also in other modes. In this case, the + * Block length counter is reset when RXEN=0 (receiver disabled). + * @param UARTx UART Instance. + * @param Block Length. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_scard_blen(UART_TypeDef *UARTx, uint32_t blocklength) +{ + MODIFY_REG(UARTx->SCARD, UART_SCARD_BLEN_MSK, blocklength<SCARD, UART_SCARD_BLEN_MSK))>>UART_SCARD_BLEN_POSS); +} + +/** + * @brief Set UARTx Guard time value(Only UART). + * @param UARTx UART Instance. + * @param Guard time value. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_scard_gt(UART_TypeDef *UARTx, uint32_t guardtime) +{ + MODIFY_REG(UARTx->SCARD, UART_SCARD_GT_MSK, guardtime<SCARD, UART_SCARD_GT_MSK))>>UART_SCARD_GT_POSS); +} + +/** + * @brief Set UARTx Prescaler value (Only UART). + * @note In IrDA Low-power and normal IrDA mode: + * Used for programming the prescaler for dividing the UART + * source clock to achieve the low-power frequency. + * The source clock is divided by the value given in the register (8 + * significant bits) + * In Smartcard mode: + * Used for programming the prescaler for dividing the UART + * source clock to provide the Smartcard clock. + * The value given in the register (5 significant bits) is multiplied by + * 2 to give the division factor of the source clock frequency. + * @param UARTx UART Instance. + * @param Prescaler value. + * @retval None + */ +__STATIC_INLINE void md_uart_set_scard_psc(UART_TypeDef *UARTx, uint32_t prescaler) +{ + MODIFY_REG(UARTx->SCARD, UART_SCARD_PSC_MSK, prescaler<SCARD, UART_SCARD_PSC_MSK))>>UART_SCARD_PSC_POSS); +} + +/** + * @brief Set UARTx Smartcard auto-retry count (Only UART). + * @note This bit-field specifies the number of retries in transmit and + * receive, in Smartcard mode. + * In transmission mode, it specifies the number of automatic + * retransmission retries, before generating a transmission error + * (FE bit set). + * In reception mode, it specifies the number or erroneous + * reception trials, before generating a reception error (RXNE and + * PE bits set). + * @param UARTx UART Instance. + * @param smartcard auto-retry count Min_Value=0x00 Max_Value=0x07. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_scard_sccnt(UART_TypeDef *UARTx, uint32_t count) +{ + MODIFY_REG(UARTx->SCARD, UART_SCARD_SCCNT_MSK, count<SCARD, UART_SCARD_SCCNT_MSK))>>UART_SCARD_SCCNT_POSS); +} + +/** + * @brief Smartcard clock enable(Only UART). + * @note This bit allows the user to enable the SCK pin. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_scard_sclken(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->SCARD, UART_SCARD_SCLKEN_MSK); +} + +/** + * @brief Smartcard clock disable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_scard_sclken(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->SCARD, UART_SCARD_SCLKEN_MSK); +} + +/** + * @brief Check if Smartcard clock is enable. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_scard_sclken(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->SCARD, UART_SCARD_SCLKEN_MSK) == (UART_SCARD_SCLKEN_MSK)); +} + +/** + * @brief Smartcard NACK enable(Only UART). + * @note This bit allows the user to enable nack detection. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_scard_scnack(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->SCARD, UART_SCARD_SCNACK_MSK); +} + +/** + * @brief Smartcard NACK disable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_scard_scnack(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->SCARD, UART_SCARD_SCNACK_MSK); +} + +/** + * @brief Check if Smartcard NACK is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_scard_scnack(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->SCARD, UART_SCARD_SCNACK_MSK) == (UART_SCARD_SCNACK_MSK)); +} + +/** + * @brief Smartcard mode enable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_scard_scen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->SCARD, UART_SCARD_SCEN_MSK); +} + +/** + * @brief Smartcard mode disable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_scard_scen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->SCARD, UART_SCARD_SCEN_MSK); +} + +/** + * @brief Check if Smartcard mode is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_scard_scen(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->SCARD, UART_SCARD_SCEN_MSK) == (UART_SCARD_SCEN_MSK)); +} + +/** + * @brief Enable LIN mode break request. + * @note This bit is set by software and automatically cleared by + * hardware in the next clock cycle. + * Writing 1 to this bit sets request to send a BREAK on the line, as + * soon as the transmit machine is available. + * It generates 13 bits rate low pulse in Lin mode. + * @param UARTx UART Instance + * @retval None + */ +__STATIC_INLINE void md_uart_enable_lin_linbkreq(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LIN, UART_LIN_LINBKREQ_MSK); +} + +/** + * @brief Disable LIN mode break request. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_linbkreq(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LIN, UART_LIN_LINBKREQ_MSK); +} + +/** + * @brief Check if LIN break is enabled + * @param None + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enable_linbkreq(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->LIN, UART_LIN_LINBKREQ_MSK) == (UART_LIN_LINBKREQ_MSK)); +} + +/** + * @brief UARTx LIN mode enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_lin_linen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->LIN, UART_LIN_LINEN_MSK); +} + +/** + * @brief UART LIN mode disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_lin_linen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->LIN, UART_LIN_LINEN_MSK); +} + +/** + * @brief Check if UARTx LIN mode is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_lin_linen(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->LIN, UART_LIN_LINEN_MSK) == (UART_LIN_LINEN_MSK)); +} + +/** + * @brief UARTx receive timeout enable. + * @note When this feature is enabled, the RTOIF flag in the UART_RIF + * register is set if the RX line is idle (no reception) for the duration + * programmed in the RTOR (receiver timeout register). + * @param UARTx UART Instance + * @retval None + */ +__STATIC_INLINE void md_uart_enable_rtor_rtoen(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->RTOR, UART_RTOR_RTOEN_MSK); +} + +/** + * @brief UARTx receive timeout disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_rtor_rtoen(UART_TypeDef *UARTx) +{ + CLEAR_BIT(UARTx->RTOR, UART_RTOR_RTOEN_MSK); +} + +/** + * @brief Check if UARTx receive timeout is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_rtor_rtoen(UART_TypeDef *UARTx) +{ + return (uint32_t)(READ_BIT(UARTx->RTOR, UART_RTOR_RTOEN_MSK) == (UART_RTOR_RTOEN_MSK)); +} + +/** + * @brief Set UARTx receiver timeout value. + * @note This bit-field gives the Receiver timeout value in terms of number of bit duration. + * In standard mode: + * the RTOF flag is set if, after the last received character, + * no new start bit is detected for more than the RTO value. + * In Smartcard mode: + * this value is used to implement the CWT and BWT. See Smartcard section for more details. + * In this case, the timeout measurement is done starting from the Stop Bit of the last + * received character. + * @param UARTx UART Instance. + * @param timeout UART timeout value. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_rtor_rto(UART_TypeDef *UARTx, uint32_t timeout) +{ + MODIFY_REG(UARTx->RTOR, UART_RTOR_RTO_MSK, timeout<RTOR, UART_RTOR_RTO_MSK))>>UART_RTOR_RTO_POSS); +} + +/** + * @brief Set UARTx Transmit FIFO level. + * @note This is used to indicate the number of data entries in the Transmit FIFO. + * It's value from 0 to 16. + * @param UARTx UART Instance. + * @param Value between Min_Data=0x00 and Max_Data=0x010. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_fcon_txfl(UART_TypeDef *UARTx, uint32_t level) +{ + MODIFY_REG(UARTx->FCON, UART_FCON_TXFL_MSK, level<FCON, UART_FCON_TXFL_MSK))>>UART_FCON_TXFL_POSS); +} + +/** + * @brief Set UARTx Transmit FIFO trigger threshold. + * @note This is used to select the threshold level in the transmit FIFO at + * which the Transmit FIFO trigger threshold flag is generated. + * @param UARTx UART Instance + * @param level This parameter can be one of the following values: + * @arg @ref MD_UART_FCON_TXTH_0 + * @arg @ref MD_UART_FCON_TXTH_2 + * @arg @ref MD_UART_FCON_TXTH_4 + * @arg @ref MD_UART_FCON_TXTH_8 + * @retval None + */ +__STATIC_INLINE void md_uart_set_fcon_txth(UART_TypeDef *UARTx, uint32_t level) +{ + MODIFY_REG(UARTx->FCON, UART_FCON_TXTH_MSK, level<FCON, UART_FCON_TXTH_MSK))>>UART_FCON_TXTH_POSS); +} + +/** + * @brief Transmit FIFO reset. + * @note When FIFO is set, all the byte in the transmit FIFO are cleared + * and treats the FIFO as empty. Note that this bit will return to 0 in + * the next clock cycle. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_fcon_tfrst(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->FCON, UART_FCON_TFRST_MSK); +} + +/** + * @brief Set UARTx Receive FIFO level. + * @note This bit is set by hardware. This is used to indicate the number + * of data entries in the Receive FIFO. It's value from 0 to 16. + * @param UARTx UART Instance. + * @param Value between Min_Data=0x00 and Max_Data=0x010. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_fcon_rxfl(UART_TypeDef *UARTx, uint32_t level) +{ + MODIFY_REG(UARTx->FCON, UART_FCON_RXFL_MSK, level<FCON, UART_FCON_RXFL_MSK))>>UART_FCON_TXFL_POSS); +} + +/** + * @brief Set UARTx Receive FIFO trigger threshold. + * @note This is used to select the threshold level in the receiver FIFO at + * which the Receive FIFO trigger threshold flag is generated. + * @param UARTx UART Instance. + * @param level This parameter can be one of the following values: + * @arg @ref MD_UART_FCON_RXTH_1 + * @arg @ref MD_UART_FCON_RXTH_4 + * @arg @ref MD_UART_FCON_RXTH_8 + * @arg @ref MD_UART_FCON_RXTH_14 + * @retval None + */ +__STATIC_INLINE void md_uart_set_fcon_rxth(UART_TypeDef *UARTx, uint32_t level) +{ + MODIFY_REG(UARTx->FCON, UART_FCON_RXTH_MSK, level<FCON, UART_FCON_RXTH_MSK))>>UART_FCON_RXTH_POSS); +} + +/** + * @brief Receive FIFO reset + * @note When FIFO is set, all the byte in the receiver FIFO are cleared + * and treats the FIFO as empty. Note that this bit will return to 0 in + * the next clock cycle. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_set_fcon_rfrst(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->FCON, UART_FCON_RFRST_MSK); +} + +/** + * @brief Check if Transmit FIFO overrun error. + * @note This bit is set and cleared by hardware Tx line start transmit + * data. An overrun error occurs when the FIFO is full and a new + * character write at the Transmit. The data in the FIFO is retained + * and the data in the TXBR register is lost. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_tfoerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_TFOERR_MSK) == (UART_STAT_TFOERR_MSK)); +} + +/** + * @brief Check if Transmit FIFO full. + * @note This bit is set and cleared by hardware when the TX FIFO is no + * longer full. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_tffull(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_TFFULL_MSK) == (UART_STAT_TFFULL_MSK)); +} + +/** + * @brief Check if Transmit FIFO empty. + * @note This bit is set and cleared by hardware when the TX FIFO is no + * longer empty. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_tfempty(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_TFEMPTY_MSK) == (UART_STAT_TFEMPTY_MSK)); +} + +/** + * @brief Check if Transmit FIFO trigger threshold flag. + * @note This bit is set and cleared by hardware when transmit FIFO + * arrived threshold level in the FCR register. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_tfth(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_TFTH_MSK) == (UART_STAT_TFTH_MSK)); +} + +/** + * @brief Check if Transmit shift register busy. + * @note This bit is cleared by hardware. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_tsbsy(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_TSBUSY_MSK) == (UART_STAT_TSBUSY_MSK)); +} + +/** + * @brief Check if Receive FIFO underrun error. + * @note This bit is set and cleared by hardware when receive a new + * data. An underrun error occurs when the FIFO is empty at the + * receive. The data in the FIFO is read 0 in the RXBR register. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_rfuerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_RFUERR_MSK) == (UART_STAT_RFUERR_MSK)); +} + +/** + * @brief Check if Receive FIFO overrun error. + * @note This bit is set and cleared by hardware when read data in the + * RXBR register. An overrun error occurs when the FIFO is full + * and a new character arrives at the receiver. The data in the + * FIFO is retained and the data in the RXBR register is lost. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_rfoerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_RFOERR_MSK) == (UART_STAT_RFOERR_MSK)); +} + +/** + * @brief Check if Receive FIFO full. + * @note This bit is set and cleared by hardware when the RX FIFO is no + * longer full. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_rffull(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_RFFULL_MSK) == (UART_STAT_RFFULL_MSK)); +} + +/** + * @brief Check if Receive FIFO empty. + * @note This bit is cleared when the RX FIFO is no longer empty. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_rfempty(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_RFEMPTY_MSK) == (UART_STAT_RFEMPTY_MSK)); +} + +/** + * @brief Check if Receive FIFO trigger threshold flag. + * @note This bit is set and cleared by hardware when receive FIFO + * arrived threshold level in the FCR register. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_rfth(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_RFTH_MSK) == (UART_STAT_RFTH_MSK)); +} + +/** + * @brief Check if Receive shiftregister busy. + * @note This bit is set and cleared by hardware. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_rsbsy(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_RSBUSY_MSK) == (UART_STAT_RSBUSY_MSK)); +} + +/** + * @brief Get UARTx Clear to send status. + * @note This bit is the complement of CTSn. When CTSn is asserted, it + * is an indication that the modem or data set is ready to exchange + * data with UART. + * @param ADCx ADC Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_get_stat_ctssta(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_CTSSTA_MSK)>>UART_STAT_CTSSTA_POS); +} + +/** + * @brief Check if Break error. + * @note This bit is used to indicate the detection of a break sequence on + * the serial input data. + * This error is associated with the character at the top of the FIFO. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_bkerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_BKERR_MSK) == (UART_STAT_BKERR_MSK)); +} + +/** + * @brief Check if Framing Error. + * @note When the received characters stop bit is a logic 0(i.e. the + * receiver did not have a valid stop bit), a framing error occurs. + * This error is associated with the character at the top of the FIFO. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_ferr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_FERR_MSK) == (UART_STAT_FERR_MSK)); +} + +/** + * @brief Check if Parity Error. + * @note When the receive character does not have correct parity + * information and is suspect, a parity error occurs. + * This error is associated with the character at the top of the FIFO. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_stat_perr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->STAT, UART_STAT_PERR_MSK) == (UART_STAT_PERR_MSK)); +} + +/** + * @brief Transmit FIFO overrun interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_tfover(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_TFOVER_MSK); +} + +/** + * @brief Transmit FIFO empty interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_tfempty(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_TFEMPTY_MSK); +} + +/** + * @brief Transmit FIFO trigger threshold interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_tfth(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_TFTH_MSK); +} + +/** + * @brief Transmission byte complete enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_tbc(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_TBC_MSK); +} + +/** + * @brief Receive FIFO underrun interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_rfuerr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_RFUERR_MSK); +} + +/** + * @brief Receive FIFO overrun interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_rfoerr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_RFOERR_MSK); +} + +/** + * @brief Receive FIFO full interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_rffull(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_RFFULL_MSK); +} + +/** + * @brief Receive FIFO trigger threshold interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_rfth(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_RFTH_MSK); +} + +/** + * @brief Bit Noise detection enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_noise(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_NOISE_MSK); +} + +/** + * @brief End of block interrupt enable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_eob(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_EOB_MSK); +} + +/** + * @brief LINBK: LIN break detection interrupt enable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_linbk(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_LINBK_MSK); +} + +/** + * @brief Address match interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_addrm(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_ADDRM_MSK); +} + +/** + * @brief Receiver Timeout interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_rxto(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_RXTO_MSK); +} + +/** + * @brief Delta CTS status interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_dcts(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_DCTS_MSK); +} + +/** + * @brief Auto-Baud rate detection Timeout interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_abto(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_ABTO_MSK); +} + +/** + * @brief Auto-Baud rate detection End interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_abend(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_ABEND_MSK); +} + +/** + * @brief Receiver byte error interrupt enable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_enable_ier_rxberr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IER, UART_IER_RXBERR_MSK); +} + +/** + * @brief Transmit FIFO overrun interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_tfover(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_TFOVER_MSK); +} + +/** + * @brief Transmit FIFO empty interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_tfempty(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_TFEMPTY_MSK); +} + +/** + * @brief Transmit FIFO trigger threshold interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_tfth(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_TFTH_MSK); +} + +/** + * @brief Transmission byte complete interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_tbc(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_TBC_MSK); +} + +/** + * @brief Receive FIFO underrun interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_rfuerr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_RFUERR_MSK); +} + +/** + * @brief Receive FIFO overrun interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_rfoerr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_RFOERR_MSK); +} + +/** + * @brief Receive FIFO full interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_rffull(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_RFFULL_MSK); +} + +/** + * @brief Receive FIFO trigger threshold interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_rfth(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_RFTH_MSK); +} + +/** + * @brief Bit Noise detection disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_noise(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_NOISE_MSK); +} + +/** + * @brief End of block interrupt disable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_eob(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_EOB_MSK); +} + +/** + * @brief LIN break detection interrupt disable(Only UART). + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_linbk(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_LINBK_MSK); +} + +/** + * @brief Address match interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_addrm(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_ADDRM_MSK); +} + +/** + * @brief Receiver Timeout interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_rxto(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_RXTO_MSK); +} + +/** + * @brief Delta CTS status interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_dcts(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_DCTS_MSK); +} + +/** + * @brief Auto-Baud rate detection Timeout interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_abto(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_ABTO_MSK); +} + +/** + * @brief Auto-Baud rate detection End interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_abend(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_ABEND_MSK); +} + +/** + * @brief Receiver byte error interrupt disable. + * @param UARTx UART Instance. + * @retval None. + */ +__STATIC_INLINE void md_uart_disable_idr_rxberr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->IDR, UART_IDR_RXBERR_MSK); +} + +/** + * @brief Check if Tx FIFO overrun interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_tfover(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_TFOVER_MSK) == (UART_IVS_TFOVER_MSK)); +} + +/** + * @brief Check if Tx FIFO empty interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_tfempty(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_TFEMPTY_MSK) == (UART_IVS_TFEMPTY_MSK)); +} + +/** + * @brief Check if Tx FIFO trigger threshold interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_tfth(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_TFTH_MSK) == (UART_IVS_TFTH_MSK)); +} + +/** + * @brief Check if Tx complete interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_tbc(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_TBC_MSK) == (UART_IVS_TBC_MSK)); +} + +/** + * @brief Check if Rx FIFO underrun interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_rfuerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_RFUERR_MSK) == (UART_IVS_RFUERR_MSK)); +} + +/** + * @brief Check if Rx FIFO overrun interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_rfoerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_RFOERR_MSK) == (UART_IVS_RFOERR_MSK)); +} + +/** + * @brief Check if Rx FIFO full interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_rffull(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_RFFULL_MSK) == (UART_IVS_RFFULL_MSK)); +} + +/** + * @brief Check if Rx FIFO trigger threshold interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_rfth(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_RFTH_MSK) == (UART_IVS_RFTH_MSK)); +} + +/** + * @brief Check if noise detection interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_noise(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_NOISE_MSK) == (UART_IVS_NOISE_MSK)); +} + +/** + * @brief Check if end of block detection interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_eob(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_EOB_MSK) == (UART_IVS_EOB_MSK)); +} + +/** + * @brief Check if LIN break detection interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_linbk(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_LINBK_MSK) == (UART_IVS_LINBK_MSK)); +} + +/** + * @brief Check if address match interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_addrm(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_ADDRM_MSK) == (UART_IVS_ADDRM_MSK)); +} + +/** + * @brief Check if RX timeout interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_rxto(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_RXTO_MSK) == (UART_IVS_RXTO_MSK)); +} + +/** + * @brief Check if delta CTS status interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_dcts(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_DCTS_MSK) == (UART_IVS_DCTS_MSK)); +} + +/** + * @brief Check if auto-baud rate detection interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_abto(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_ABTO_MSK) == (UART_IVS_ABTO_MSK)); +} + +/** + * @brief Check if auto-baud rate detection end interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_abend(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_ABEND_MSK) == (UART_IVS_ABEND_MSK)); +} + +/** + * @brief Check if RX byte error interrupt is enabled. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_enabled_ivs_rxberr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IVS, UART_IVS_RXBERR_MSK) == (UART_IVS_RXBERR_MSK)); +} + +/** + * @brief Get Transmit FIFO overrun interrupt flag. + * @note This bit is set by hardware when an overrun error occurs that + * the FIFO is full and a new character write at the Transmit. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_tfover(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_TFOVER_MSK) == (UART_RIF_TFOVER_MSK)); +} + +/** + * @brief Get Transmit FIFO empty interrupt flag. + * @note This bit is set by hardware when transmit FIFO is empty from + * have data to empty. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_txempty(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_TFEMPTY_MSK) == (UART_RIF_TFEMPTY_MSK)); +} + +/** + * @brief Get Transmit FIFO trigger threshold interrupt flag + * @note This bit is set by hardware when transmit FIFO arrived + * threshold level in the FCR register. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_tfth(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_TFTH_MSK) == (UART_RIF_TFTH_MSK)); +} + +/** + * @brief Get Transmission byte complete interrupt flag. + * @note This bit is set by hardware when transmission byte complete. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_tbc(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_TBC_MSK) == (UART_RIF_TBC_MSK)); +} + +/** + * @brief Get Receive FIFO underrun interrupt flag + * @note This bit is set by hardware when an underrun error occurs that + * the FIFO is empty and a new character read at the Receive. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_rfuerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_RFUERR_MSK) == (UART_RIF_RFUERR_MSK)); +} + +/** + * @brief Get Receive FIFO overrun interrupt flag. + * @note This bit is set by hardware when an overrun error occurs that + * the FIFO is full and a new character arrive at the Receive. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_rfoerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_RFOERR_MSK) == (UART_RIF_RFOERR_MSK)); +} + +/** + * @brief Get Receive FIFO full interrupt flag. + * @note This bit is set by hardware when receive FIFO is full. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_rffull(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_RFFULL_MSK) == (UART_RIF_RFFULL_MSK)); +} + +/** + * @brief Get Receive FIFO trigger threshold interrupt flag. + * @note This bit is set by hardware when receive FIFO arrived threshold + * level in the FCR register. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_rfth(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_RFTH_MSK) == (UART_RIF_RFTH_MSK)); +} + +/** + * @brief Get Bit Noise detection interrupt flag. + * @note This bit is set by hardware when START bit Noise is detected. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_noise(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_NOISE_MSK) == (UART_RIF_NOISE_MSK)); +} + +/** + * @brief Get End of block interrupt flag(Only UART). + * @note This bit is set by hardware when blcok length value equals the + * number of data byte. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_eob(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_EOB_MSK) == (UART_RIF_EOB_MSK)); +} + +/** + * @brief Get LIN break detection interrupt flag(Only UART). + * @note This bit is set by hardware when lin break is detected. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_linbk(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_LINBK_MSK) == (UART_RIF_LINBK_MSK)); +} + +/** + * @brief Get Address match interrupt flag. + * @note This bit is set by hardware when the data in the RXBR register + * defined by ADD[7:0] in the RS485 register is received. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_addrm(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_ADDRM_MSK) == (UART_RIF_ADDRM_MSK)); +} + +/** + * @brief Get Receiver Timeout interrupt flag. + * @note This bit is set by hardware when the timeout value, + * programmed in the RTOR register has lapsed, without any + * communication. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_rxto(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_RXTO_MSK) == (UART_RIF_RXTO_MSK)); +} + +/** + * @brief Get Delta CTS status interrupt flag. + * @note This bit is set by hardware when the CTS input toggles. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_dcts(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_DCTS_MSK) == (UART_RIF_DCTS_MSK)); +} + +/** + * @brief Get Auto-Baud rate detection timeout interrupt flag. + * @note This bit is set by hardware when the baud rate detection timeout. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_abto(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_ABTO_MSK) == (UART_RIF_ABTO_MSK)); +} + +/** + * @brief Get Auto-Baud rate detection end interrupt flag. + * @note This bit is set by hardware when the baud rate detection end. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_abend(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_ABEND_MSK) == (UART_RIF_ABEND_MSK)); +} + +/** + * @brief Get Receiver byte error flag. + * @note This bit is set by hardware when a parity error or frame error + * occurs in receiver. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_rif_rxberr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_RIF_RXBERR_MSK) == (UART_RIF_RXBERR_MSK)); +} + +/** + * @brief Get Transmit FIFO overrun interrupt flag masked. + * @note This bit is set by hardware when an overrun error occurs that + * the FIFO is full and a new character write at the Transmit. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_tfover(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_TFOVER_MSK) == (UART_IFM_TFOVER_MSK)); +} + +/** + * @brief Get Transmit FIFO empty interrupt flag masked. + * @note This bit is set by hardware when transmit FIFO is empty from + * have data to empty. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_txempty(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_TFEMPTY_MSK) == (UART_IFM_TFEMPTY_MSK)); +} + +/** + * @brief Get Transmit FIFO trigger threshold interrupt flag masked. + * @note This bit is set by hardware when transmit FIFO arrived + * threshold level in the FCR register. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_tfth(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_TFTH_MSK) == (UART_IFM_TFTH_MSK)); +} + +/** + * @brief Get Transmission byte complete interrupt flag masked. + * @note This bit is set by hardware when transmission byte complete. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_tbc(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_TBC_MSK) == (UART_IFM_TBC_MSK)); +} + +/** + * @brief Get Receive FIFO underrun interrupt flag masked. + * @note This bit is set by hardware when an underrun error occurs that + * the FIFO is empty and a new character read at the Receive. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_rfuerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_RFUERR_MSK) == (UART_IFM_RFUERR_MSK)); +} + +/** + * @brief Get Receive FIFO overrun interrupt flag masked. + * @note This bit is set by hardware when an overrun error occurs that + * the FIFO is full and a new character arrive at the Receive. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_rfoerr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_RFOERR_MSK) == (UART_IFM_RFOERR_MSK)); +} + +/** + * @brief Get Receive FIFO full interrupt flag masked. + * @note This bit is set by hardware when receive FIFO is full. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_rffull(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_RFFULL_MSK) == (UART_IFM_RFFULL_MSK)); +} + +/** + * @brief Get Receive FIFO trigger threshold interrupt flag masked. + * @note This bit is set by hardware when receive FIFO arrived threshold + * level in the FCR register. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_rfth(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_RFTH_MSK) == (UART_IFM_RFTH_MSK)); +} + +/** + * @brief Get Bit Noise detection interrupt flag masked. + * @note This bit is set by hardware when START bit Noise is detected. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_noise(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_NOISE_MSK) == (UART_IFM_NOISE_MSK)); +} + +/** + * @brief Get End of block interrupt flag masked(Only UART). + * @note This bit is set by hardware when block length value equals the + * number of data byte. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_eob(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_EOB_MSK) == (UART_IFM_EOB_MSK)); +} + +/** + * @brief Get LIN break detection interrupt flag masked(Only UART). + * @note This bit is set by hardware when lin break is detected. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_linbk(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_LINBK_MSK) == (UART_IFM_LINBK_MSK)); +} + +/** + * @brief Get Address match interrupt flag masked. + * @note This bit is set by hardware when the data in the RXBR register + * defined by ADD[7:0] in the RS485 register is received. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_addrm(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_ADDRM_MSK) == (UART_IFM_ADDRM_MSK)); +} + +/** + * @brief Get Receiver Timeout interrupt flag masked. + * @note This bit is set by hardware when the timeout value, + * programmed in the RTOR register has lapsed, without any + * communication. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_rxto(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_RXTO_MSK) == (UART_IFM_RXTO_MSK)); +} + +/** + * @brief Get Delta CTS status interrupt flag masked. + * @note This bit is set by hardware when the CTS input toggles. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_dcts(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->IFM, UART_RIF_DCTS_MSK) == (UART_IFM_DCTS_MSK)); +} + +/** + * @brief Get Auto-Baud rate detection timeout interrupt flag masked. + * @note This bit is set by hardware when the baud rate detection timeout. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_abto(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_ABTO_MSK) == (UART_IFM_ABTO_MSK)); +} + +/** + * @brief Get Auto-Baud rate detection end interrupt flag masked. + * @note This bit is set by hardware when the baud rate detection end. + * @param UARTx UART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_abend(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_ABEND_MSK) == (UART_IFM_ABEND_MSK)); +} + +/** + * @brief Get Receiver byte error interrupt flag masked. + * @note This bit is set by hardware when a parity error, frame error or + * break error occurs in receiver. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_uart_is_active_flag_ifm_rxberr(UART_TypeDef *UARTx) +{ + return (READ_BIT(UARTx->RIF, UART_IFM_RXBERR_MSK) == (UART_IFM_RXBERR_MSK)); +} + +/** + * @brief Transmit FIFO overrun interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_txover(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_TFOVER_MSK); +} + +/** + * @brief Transmit FIFO empty interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_txempty(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_TFEMPTY_MSK); +} + +/** + * @brief Transmit FIFO trigger threshold interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_tfth(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_TFTH_MSK); +} + +/** + * @brief Transmission byte complete interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_tbc(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_TBC_MSK); +} + +/** + * @brief Receive FIFO underrun interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_rfuerr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_RFUERR_MSK); +} + +/** + * @brief Receive FIFO overrun interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_rfoerr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_RFOERR_MSK); +} + +/** + * @brief Receive FIFO full interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_rffull(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_RFFULL_MSK); +} + +/** + * @brief Receive FIFO trigger threshold interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_rfth(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_RFTH_MSK); +} + +/** + * @brief Bit Noise detection interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_noise(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_NOISE_MSK); +} + +/** + * @brief End of block interrupt flag clear(Only UART). + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_eob(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_EOB_MSK); +} + +/** + * @brief LIN break detection interrupt flag clear(Only UART). + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_linbk(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_LINBK_MSK); +} + +/** + * @brief Address match interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_addrm(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_ADDRM_MSK); +} + +/** + * @brief Receiver Timeout interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_rxto(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_RXTO_MSK); +} + +/** + * @brief Delta CTS status interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_dcts(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_DCTS_MSK); +} + +/** + * @brief Auto-Baud rate detection timeout interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_abto(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_ABTO_MSK); +} + +/** + * @brief Auto-Baud rate detection end interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_abend(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_ABEND_MSK); +} + +/** + * @brief Receiver byte error interrupt flag clear. + * @param UARTx UART Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE void md_uart_clear_flag_rxberr(UART_TypeDef *UARTx) +{ + SET_BIT(UARTx->ICR, UART_ICR_RXBERR_MSK); +} + +/** + * @} MD_UART_Public_Macros UART Public Macros + */ + +/* Public functions -----------------------------------------------------------*/ +void md_uart_set_baudrate (UART_TypeDef *UARTx, uint32_t baudrate); +void md_uart_init(UART_TypeDef *UARTx, md_uart_init_typedef *UART_InitStruct); +void md_uart_send (UART_TypeDef *UARTx, uint8_t ch); +uint8_t md_uart_recv (UART_TypeDef *UARTx); +uint32_t md_uart_get_baudrate (UART_TypeDef *UARTx); + +/** + * @} UART + */ + +#endif + +/** + * @} Micro_Driver + */ + + +#ifdef __cplusplus +} + +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_wwdt.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_wwdt.h new file mode 100644 index 0000000000..f2f1a86a29 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/md_wwdt.h @@ -0,0 +1,382 @@ +/** + ****************************************************************************** + * @file md_wwdt.h + * @brief ES32F0271 WWDT HEAD File. + * + * @version V0.01 + * @date 4/12/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MD_WWDT_H__ +#define __MD_WWDT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "reg_wwdt.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (WWDT) +/** @defgroup WWDT WWDT + * @brief WWDT micro driver + * @{ + */ + +/* Public Init Structure ------------------------------------------------------*/ +/** @defgroup MD_WWDT_PT_INIT WWDT Public Init Structure + * @brief WWDT Init Structure. + * @{ + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the prescaler value of the WWDT. + This parameter can be a value of @ref WWDT_Prescaler */ + + uint32_t Window; /*!< Specifies the WWDT window value to be compared to the downcounter. + This parameter must be a number a minimum, 0x40 and a maximum, 0x7F */ + + uint32_t Counter; /*!< Specifies the WWDT free-running downcounter value. + This parameter must be a number between a minimum, 0x40 and a maximum, 0x7F */ + + uint32_t EWIMode ; /*!< Specifies if WWDT Early Wakeup Interupt is enable or not. + This parameter can be a value of @ref WWDT_EWI_Mode */ + +} md_wwdt_inittypedef; +/** + * @} MD_WWDT_PT_INIT + */ + +/* Public constants -----------------------------------------------------------*/ +/** @defgroup MD_WWDT_PUBLIC_CONSTANTS WWDT Public Constants + * @{ + */ + +/** @defgroup MD_WWDT_Prescaler WWDT Prescaler + * @{ + */ +#define WWDT_PRESCALER_1 0x00000000U /*!< WWDT counter clock = (PCLK1/4096)/1 */ +#define WWDT_PRESCALER_2 1U<CON, Reg_Value); +} + +/** + * @brief Get the WWDT_CON value + * @note None. + * @param WWD WWDT Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_wwdt_get_con(WWDT_TypeDef *WWD) +{ + return (uint32_t) (READ_REG(WWD->CON)); +} + +/** + * @brief WWDT WDG Enable + * @note This bit is set by software and only cleared by hardware after a reset. + * A write of 0 has no effect. When WDGA=1, the watchdog can generate a reset. + * @param WWD WWDT Instance + * @retval None + */ +__STATIC_INLINE void md_wwdt_enable_con_wdga(WWDT_TypeDef *WWD) +{ + SET_BIT(WWD->CON, WWDT_CON_WDGA_MSK); +} + +/** + * @brief Indicate if WWDT WDG is enabled + * @note This bit is set by software and only cleared by hardware after a reset. + * A write of 0 has no effect. When WDGA=1, the watchdog can generate a reset. + * @param WWD WWDT Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_wwdt_is_enabled_wdga(WWDT_TypeDef *WWD) +{ + return (uint32_t)(READ_BIT(WWD->CON, WWDT_CON_WDGA_MSK) == (WWDT_CON_WDGA_MSK)); +} + +/** + * @brief Set WWDT T 7-bit counter + * @note These bits contain the value of the watchdog counter. + * It is decremented every (4096 x 2^WDGTB[1:0]) PCLK cycles. + * A reset is produced when it is decremented from 0x40 to 0x3F(T6 becomes cleared), + * and when it is renewed on the condition the value is more than the window value and the WDGA bit is enabled. + * @param WWD WWDT Instance + * @param counter is a 7-bit number + * @arg Max Value 0x7F + * @arg Min Value 0x40 + * @retval None + */ +__STATIC_INLINE void md_wwdt_set_con_t(WWDT_TypeDef *WWD, uint32_t counter) +{ + MODIFY_REG(WWD->CON, WWDT_CON_T_MSK, counter); +} + +/** + * @brief Get WWDT T 7-bit counter + * @note These bits contain the value of the watchdog counter. + * It is decremented every (4096 x 2^WDGTB[1:0]) PCLK cycles. + * A reset is produced when it is decremented from 0x40 to 0x3F(T6 becomes cleared), + * and when it is renewed on the condition the value is more than the window value and the WDGA bit is enabled. + * @param WWD WWDT Instance + * @retval The retval can be a value of the area: + * @arg Max Value 0x7F + * @arg Min Value 0x40 + */ +__STATIC_INLINE uint32_t md_wwdt_get_con_t(WWDT_TypeDef *WWD) +{ + return (READ_BIT(WWD->CON, WWDT_CON_T_MSK)>>WWDT_CON_T_POSS); +} + +/** + * @brief Set the WWDT_CFG value + * @note None. + * @param WWD WWDT Instance + * @param Reg_Value is a 32-bit value + * @retval None + */ +__STATIC_INLINE void md_wwdt_set_cfg(WWDT_TypeDef *WWD, uint32_t Reg_Value) +{ + WRITE_REG(WWD->CFG, Reg_Value); +} + +/** + * @brief Get the WWDT_CFG value + * @note None. + * @param WWD WWDT Instance + * @retval a 32-bit value + */ +__STATIC_INLINE uint32_t md_wwdt_get_cfg(WWDT_TypeDef *WWD) +{ + return (uint32_t) (READ_REG(WWD->CFG)); +} + +/** + * @brief Set WWDT WDGTB 2-bit prescaler value + * @note The time base of the prescaler can be modified as follows: + * 00: CK Counter Clock (PCLK div 4096) div 1 + * 01: CK Counter Clock (PCLK div 4096) div 2 + * 10: CK Counter Clock (PCLK div 4096) div 4 + * 11: CK Counter Clock (PCLK div 4096) div 8 + * @param WWD WWDT Instance + * @param prescaler is a 2-bit number + * @arg @ref WWDT_PRESCALER_1 + * @arg @ref WWDT_PRESCALER_2 + * @arg @ref WWDT_PRESCALER_4 + * @arg @ref WWDT_PRESCALER_8 + * @retval None + */ +__STATIC_INLINE void md_wwdt_set_cfg_wdgtb(WWDT_TypeDef *WWD, uint32_t prescaler) +{ + MODIFY_REG(WWD->CFG, WWDT_CFG_WDGTB_MSK, prescaler); +} + +/** + * @brief Get WWDT WDGTB 2-bit prescaler value + * @note The time base of the prescaler can be modified as follows: + 00: CK Counter Clock (PCLK div 4096) div 1 + 01: CK Counter Clock (PCLK div 4096) div 2 + 10: CK Counter Clock (PCLK div 4096) div 4 + 11: CK Counter Clock (PCLK div 4096) div 8 + * @param WWD WWDT Instance + * @retval The retval can be one of the following values: + * @arg @ref WWDT_PRESCALER_1 + * @arg @ref WWDT_PRESCALER_2 + * @arg @ref WWDT_PRESCALER_4 + * @arg @ref WWDT_PRESCALER_8 + */ +__STATIC_INLINE uint32_t md_wwdt_get_cfg_wdgtb(WWDT_TypeDef *WWD) +{ + return (READ_BIT(WWD->CFG, WWDT_CFG_WDGTB_MSK)>>WWDT_CFG_WDGTB_POSS); +} + +/** + * @brief Set WWDT W 7-bit window + * @note These bits contain the window value to be compared to the downcounter. + * @param WWD WWDT Instance + * @param window is a 7-bit number + * @arg Max Value 0x7F + * @arg Min Value 0x40 + * @retval None + */ +__STATIC_INLINE void md_wwdt_set_cfg_w(WWDT_TypeDef *WWD, uint32_t window) +{ + MODIFY_REG(WWD->CFG, WWDT_CFG_W_MSK, window); +} + +/** + * @brief Get WWDT W 7-bit window + * @note These bits contain the window value to be compared to the downcounter. + * @param WWD WWDT Instance + * @retval The retval can be a value of the area: + * @arg Max Value 0x7F + * @arg Min Value 0x40 + */ +__STATIC_INLINE uint32_t md_wwdt_get_cfg_w(WWDT_TypeDef *WWD) +{ + return (READ_BIT(WWD->CFG, WWDT_CFG_W_MSK)>>WWDT_CFG_W_POSS); +} + +/** + * @brief WWDT Early wakeup interrupt Enable + * @note A write of 1 in IER to enable this interrupt. + * @param WWD WWDT Instance + * @retval None + */ +__STATIC_INLINE void md_wwdt_enable_ier_ewis(WWDT_TypeDef *WWD) +{ + SET_BIT(WWD->IER, WWDT_IER_EWIS_MSK); +} + +/** + * @brief WWDT Early wakeup interrupt Disable + * @note A write of 1 in IDR to disable this interrupt. + * @param WWD WWDT Instance + * @retval None + */ +__STATIC_INLINE void md_wwdt_disable_idr_ewis(WWDT_TypeDef *WWD) +{ + SET_BIT(WWD->IDR, WWDT_IDR_EWIS_MSK); +} + +/** + * @brief Indicate if WWDT EWI is enabled + * @note To check EWI enable or not. + * @param WWD WWDT Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_wwdt_is_enabled_ivs_ewis(WWDT_TypeDef *WWD) +{ + return (uint32_t) (READ_BIT(WWD->IVS, WWDT_IVS_EWIS_MSK) == (WWDT_IVS_EWIS_MSK)); +} + +/** + * @brief Get the early wakeup interrupt flag status + * @note This bit is set by hardware when the counter has reached the value 0x40. + It can be cleared by software by writing 1 in WWDT_ICR. This bit is + also set if the interrupt is not enabled. + * @param WWD WWDT Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_wwdt_is_active_rif_ewif(WWDT_TypeDef *WWD) +{ + return (uint32_t) (READ_BIT(WWD->RIF, WWDT_RIF_EWIF_MSK) == (WWDT_RIF_EWIF_MSK)); +} + +/** + * @brief Get the early wakeup interrupt flag masked status + * @note This bit is set by hardware when the counter has reached the value 0x40 + and the interrupt is enabled. + * @param WWD WWDT Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t md_wwdt_is_active_ifm_ewim(WWDT_TypeDef *WWD) +{ + return (uint32_t) (READ_BIT(WWD->IFM, WWDT_IFM_EWIM_MSK) == (WWDT_IFM_EWIM_MSK)); +} + +/** + * @brief Clear the early wakeup interrupt flag + * @param WWD WWDT Instance + * @retval None + */ +__STATIC_INLINE void md_wwdt_clear_icr_ewic(WWDT_TypeDef *WWD) +{ + SET_BIT(WWD->ICR, WWDT_ICR_EWIC_MSK); +} + +/** + * @} MD_WWDT_Public_Macros + */ + +/** @defgroup MD_WWDT_PF_Init WWDT Init Function + * @{ + */ +void md_wwdt_init(WWDT_TypeDef *WWD, md_wwdt_inittypedef *WWDT_InitStruct); +/** + * @} MD_WWDT_PF_Init + */ + +#endif + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup MD_WWDT_Private_Macros WWDG Private Macros + * @{ + */ +#define IS_MD_WWDT_ALL_INSTANCE(__INSTANCE__) (__INSTANCE__ == WWDT) + +#define IS_MD_WWDT_PRESCALER(__VALUE__) (((__VALUE__) == WWDT_PRESCALER_1) \ + || ((__VALUE__) == WWDT_PRESCALER_2) \ + || ((__VALUE__) == WWDT_PRESCALER_4) \ + || ((__VALUE__) == WWDT_PRESCALER_8)) + +#define IS_MD_WWDT_WINDOW(__VALUE__) (((__VALUE__) >= 0x40) && ((__VALUE__) <= 0x7F)) + +#define IS_MD_WWDT_COUNTER(__VALUE__) (((__VALUE__) >= 0x40) && ((__VALUE__) <= 0x7F)) + +#define IS_MD_WWDT_EWI_MODE(__VALUE__) (((__VALUE__) == WWDT_EWI_ENABLE) \ + || ((__VALUE__) == WWDT_EWI_DISABLE)) +/** + * @} MD_WWDT_Private_Macros + */ + +/** + * @} WWDT + */ +/** + * @} Micro_Driver + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/usb_lowlayer_api.h b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/usb_lowlayer_api.h new file mode 100644 index 0000000000..5fee2e973e --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Include/usb_lowlayer_api.h @@ -0,0 +1,728 @@ +/** + ************************************************************************************** + * @file usb_lowlayer_api.h + * @brief USB library lower layer api + * @data 11/9/2018 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ************************************************************************************** + */ + +/* Includes-------------------------------------------------------------------*/ +#include "stdint.h" +#include + +#ifndef __USB_LOWLAYER_API_H__ +#define __USB_LOWLAYER_API_H__ + + +/** + * If building with a C++ compiler, make all of the definitions in this header + * have a C binding. + */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public constants -----------------------------------------------------------*/ + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hosdev_int_enable() and +// md_usb_hosdev_int_disable() as the ui32Flags parameter, and are returned from +// md_usb_hosdev_int_status(). +// +//***************************************************************************** +#define USB_INTCTRL_ALL 0x000003FF // All control interrupt sources +#define USB_INTCTRL_STATUS 0x000000FF // Status Interrupts +#define USB_INTCTRL_VBUS_ERR 0x00000080 // VBUS Error +#define USB_INTCTRL_SESSION 0x00000040 // Session Start Detected +#define USB_INTCTRL_SESSION_END 0x00000040 // Session End Detected +#define USB_INTCTRL_DISCONNECT 0x00000020 // Disconnect Detected +#define USB_INTCTRL_CONNECT 0x00000010 // Device Connect Detected +#define USB_INTCTRL_SOF 0x00000008 // Start of Frame Detected +#define USB_INTCTRL_BABBLE 0x00000004 // Babble signaled +#define USB_INTCTRL_RESET 0x00000004 // Reset signaled +#define USB_INTCTRL_RESUME 0x00000002 // Resume detected +#define USB_INTCTRL_SUSPEND 0x00000001 // Suspend detected +#define USB_INTCTRL_MODE_DETECT 0x00000200 // Mode value valid +#define USB_INTCTRL_POWER_FAULT 0x00000100 // Power Fault detected + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hosdev_endpoint_int_enable() +// and md_usb_hosdev_endpoint_int_disable() as the ui32Flags parameter, and +// are returned from md_usb_hosdev_endpoint_int_status(). +// +//***************************************************************************** +#define USB_INTEP_ALL 0xFFFFFFFF // Host IN Interrupts +#define USB_INTEP_HOST_IN 0xFFFE0000 // Host IN Interrupts +#define USB_INTEP_HOST_IN_15 0x80000000 // Endpoint 15 Host IN Interrupt +#define USB_INTEP_HOST_IN_14 0x40000000 // Endpoint 14 Host IN Interrupt +#define USB_INTEP_HOST_IN_13 0x20000000 // Endpoint 13 Host IN Interrupt +#define USB_INTEP_HOST_IN_12 0x10000000 // Endpoint 12 Host IN Interrupt +#define USB_INTEP_HOST_IN_11 0x08000000 // Endpoint 11 Host IN Interrupt +#define USB_INTEP_HOST_IN_10 0x04000000 // Endpoint 10 Host IN Interrupt +#define USB_INTEP_HOST_IN_9 0x02000000 // Endpoint 9 Host IN Interrupt +#define USB_INTEP_HOST_IN_8 0x01000000 // Endpoint 8 Host IN Interrupt +#define USB_INTEP_HOST_IN_7 0x00800000 // Endpoint 7 Host IN Interrupt +#define USB_INTEP_HOST_IN_6 0x00400000 // Endpoint 6 Host IN Interrupt +#define USB_INTEP_HOST_IN_5 0x00200000 // Endpoint 5 Host IN Interrupt +#define USB_INTEP_HOST_IN_4 0x00100000 // Endpoint 4 Host IN Interrupt +#define USB_INTEP_HOST_IN_3 0x00080000 // Endpoint 3 Host IN Interrupt +#define USB_INTEP_HOST_IN_2 0x00040000 // Endpoint 2 Host IN Interrupt +#define USB_INTEP_HOST_IN_1 0x00020000 // Endpoint 1 Host IN Interrupt + +#define USB_INTEP_DEV_OUT 0xFFFE0000 // Device OUT Interrupts +#define USB_INTEP_DEV_OUT_15 0x80000000 // Endpoint 15 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_14 0x40000000 // Endpoint 14 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_13 0x20000000 // Endpoint 13 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_12 0x10000000 // Endpoint 12 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_11 0x08000000 // Endpoint 11 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_10 0x04000000 // Endpoint 10 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_9 0x02000000 // Endpoint 9 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_8 0x01000000 // Endpoint 8 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_7 0x00800000 // Endpoint 7 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_6 0x00400000 // Endpoint 6 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_5 0x00200000 // Endpoint 5 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_4 0x00100000 // Endpoint 4 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_3 0x00080000 // Endpoint 3 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_2 0x00040000 // Endpoint 2 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_1 0x00020000 // Endpoint 1 Device OUT Interrupt + +#define USB_INTEP_HOST_OUT 0x0000FFFE // Host OUT Interrupts +#define USB_INTEP_HOST_OUT_15 0x00008000 // Endpoint 15 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_14 0x00004000 // Endpoint 14 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_13 0x00002000 // Endpoint 13 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_12 0x00001000 // Endpoint 12 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_11 0x00000800 // Endpoint 11 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_10 0x00000400 // Endpoint 10 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_9 0x00000200 // Endpoint 9 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_8 0x00000100 // Endpoint 8 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_7 0x00000080 // Endpoint 7 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_6 0x00000040 // Endpoint 6 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_5 0x00000020 // Endpoint 5 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_4 0x00000010 // Endpoint 4 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_3 0x00000008 // Endpoint 3 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_2 0x00000004 // Endpoint 2 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_1 0x00000002 // Endpoint 1 Host OUT Interrupt + +#define USB_INTEP_DEV_IN 0x0000FFFE // Device IN Interrupts +#define USB_INTEP_DEV_IN_15 0x00008000 // Endpoint 15 Device IN Interrupt +#define USB_INTEP_DEV_IN_14 0x00004000 // Endpoint 14 Device IN Interrupt +#define USB_INTEP_DEV_IN_13 0x00002000 // Endpoint 13 Device IN Interrupt +#define USB_INTEP_DEV_IN_12 0x00001000 // Endpoint 12 Device IN Interrupt +#define USB_INTEP_DEV_IN_11 0x00000800 // Endpoint 11 Device IN Interrupt +#define USB_INTEP_DEV_IN_10 0x00000400 // Endpoint 10 Device IN Interrupt +#define USB_INTEP_DEV_IN_9 0x00000200 // Endpoint 9 Device IN Interrupt +#define USB_INTEP_DEV_IN_8 0x00000100 // Endpoint 8 Device IN Interrupt +#define USB_INTEP_DEV_IN_7 0x00000080 // Endpoint 7 Device IN Interrupt +#define USB_INTEP_DEV_IN_6 0x00000040 // Endpoint 6 Device IN Interrupt +#define USB_INTEP_DEV_IN_5 0x00000020 // Endpoint 5 Device IN Interrupt +#define USB_INTEP_DEV_IN_4 0x00000010 // Endpoint 4 Device IN Interrupt +#define USB_INTEP_DEV_IN_3 0x00000008 // Endpoint 3 Device IN Interrupt +#define USB_INTEP_DEV_IN_2 0x00000004 // Endpoint 2 Device IN Interrupt +#define USB_INTEP_DEV_IN_1 0x00000002 // Endpoint 1 Device IN Interrupt + +#define USB_INTEP_0 0x00000001 // Endpoint 0 Interrupt + +//***************************************************************************** +// +// The following are values that are returned from md_usb_hos_speed_get() 0r +// md_usb_dev_speed_get(). +// +//***************************************************************************** +#define USB_UNDEF_SPEED 0x80000000 // Current speed is undefined +#define USB_HIGH_SPEED 0x00000002 // Current speed is High Speed +#define USB_FULL_SPEED 0x00000001 // Current speed is Full Speed +#define USB_LOW_SPEED 0x00000000 // Current speed is Low Speed + +//***************************************************************************** +// +// The following are values that are returned from md_usb_hosdev_endpoint_status(). The +// USB_HOST_* values are used when the USB controller is in host mode and the +// USB_DEV_* values are used when the USB controller is in device mode. +// +//***************************************************************************** +#define USB_HOST_IN_STATUS 0x114F0000 // Mask of all host IN interrupts +#define USB_HOST_IN_PID_ERROR 0x10000000 // Stall on this endpoint received +#define USB_HOST_IN_NOT_COMP 0x01000000 // Device failed to respond +#define USB_HOST_IN_STALL 0x00400000 // Stall on this endpoint received +#define USB_HOST_IN_DATA_ERROR 0x00080000 // CRC or bit-stuff error +// (ISOC Mode) +#define USB_HOST_IN_NAK_TO 0x00080000 // NAK received for more than the +// specified timeout period +#define USB_HOST_IN_ERROR 0x00040000 // Failed to communicate with a +// device +#define USB_HOST_IN_FIFO_FULL 0x00020000 // RX FIFO full +#define USB_HOST_IN_PKTRDY 0x00010000 // Data packet ready +#define USB_HOST_OUT_STATUS 0x000000A7 // Mask of all host OUT interrupts +#define USB_HOST_OUT_NAK_TO 0x00000080 // NAK received for more than the +// specified timeout period +#define USB_HOST_OUT_NOT_COMP 0x00000080 // No response from device +// (ISOC mode) +#define USB_HOST_OUT_STALL 0x00000020 // Stall on this endpoint received +#define USB_HOST_OUT_ERROR 0x00000004 // Failed to communicate with a +// device +#define USB_HOST_OUT_FIFO_NE 0x00000002 // TX FIFO is not empty +#define USB_HOST_OUT_PKTPEND 0x00000001 // Transmit still being transmitted +#define USB_HOST_EP0_NAK_TO 0x00000080 // NAK received for more than the +// specified timeout period +#define USB_HOST_EP0_STATUS 0x00000040 // This was a status packet +#define USB_HOST_EP0_ERROR 0x00000010 // Failed to communicate with a +// device +#define USB_HOST_EP0_RX_STALL 0x00000004 // Stall on this endpoint received +#define USB_HOST_EP0_RXPKTRDY 0x00000001 // Receive data packet ready +#define USB_DEV_RX_PID_ERROR 0x01000000 // PID error in isochronous +// transfer +#define USB_DEV_RX_SENT_STALL 0x00400000 // Stall was sent on this endpoint +#define USB_DEV_RX_DATA_ERROR 0x00080000 // CRC error on the data +#define USB_DEV_RX_OVERRUN 0x00040000 // OUT packet was not loaded due to +// a full FIFO +#define USB_DEV_RX_FIFO_FULL 0x00020000 // RX FIFO full +#define USB_DEV_RX_PKT_RDY 0x00010000 // Data packet ready +#define USB_DEV_TX_NOT_COMP 0x00000080 // Large packet split up, more data +// to come +#define USB_DEV_TX_SENT_STALL 0x00000020 // Stall was sent on this endpoint +#define USB_DEV_TX_UNDERRUN 0x00000004 // IN received with no data ready +#define USB_DEV_TX_FIFO_NE 0x00000002 // The TX FIFO is not empty +#define USB_DEV_TX_TXPKTRDY 0x00000001 // Transmit still being transmitted +#define USB_DEV_EP0_SETUP_END 0x00000010 // Control transaction ended before +// Data End seen +#define USB_DEV_EP0_SENT_STALL 0x00000004 // Stall was sent on this endpoint +#define USB_DEV_EP0_IN_PKTPEND 0x00000002 // Transmit data packet pending +#define USB_DEV_EP0_OUT_PKTRDY 0x00000001 // Receive data packet ready + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hos_endpoint_config_set() and +// md_usb_dev_endpoint_config_set() as the ui32Flags parameter. +// +//***************************************************************************** +#define USB_EP_AUTO_SET 0x00000001 // Auto set feature enabled +#define USB_EP_AUTO_REQUEST 0x00000002 // Auto request feature enabled +#define USB_EP_AUTO_CLEAR 0x00000004 // Auto clear feature enabled +#define USB_EP_DUAL_BUFFERING 0x00000008 // Dual buffering enabled +#define USB_EP_DMA_MODE_0 0x00000008 // Enable DMA access using mode 0 +#define USB_EP_DMA_MODE_1 0x00000010 // Enable DMA access using mode 1 +#define USB_EP_DIS_NYET 0x00000020 // Disable NYET response for +// high-speed Bulk and Interrupt +// endpoints in device mode. +#define USB_EP_MODE_ISOC 0x00000000 // Isochronous endpoint +#define USB_EP_MODE_BULK 0x00000100 // Bulk endpoint +#define USB_EP_MODE_INT 0x00000200 // Interrupt endpoint +#define USB_EP_MODE_CTRL 0x00000300 // Control endpoint +#define USB_EP_MODE_MASK 0x00000300 // Mode Mask +#define USB_EP_SPEED_LOW 0x00000000 // Low Speed +#define USB_EP_SPEED_FULL 0x00001000 // Full Speed +#define USB_EP_SPEED_HIGH 0x00004000 // High Speed +#define USB_EP_HOST_IN 0x00000000 // Host IN endpoint +#define USB_EP_HOST_OUT 0x00002000 // Host OUT endpoint +#define USB_EP_DEV_IN 0x00002000 // Device IN endpoint +#define USB_EP_DEV_OUT 0x00000000 // Device OUT endpoint + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hos_pwr_config() as the +// ui32Flags parameter. +// +//***************************************************************************** +#define USB_HOST_PWRFLT_LOW 0x00000010 +#define USB_HOST_PWRFLT_HIGH 0x00000030 +#define USB_HOST_PWRFLT_EP_NONE 0x00000000 +#define USB_HOST_PWRFLT_EP_TRI 0x00000140 +#define USB_HOST_PWRFLT_EP_LOW 0x00000240 +#define USB_HOST_PWRFLT_EP_HIGH 0x00000340 +#define USB_HOST_PWREN_MAN_LOW 0x00000000 +#define USB_HOST_PWREN_MAN_HIGH 0x00000001 +#define USB_HOST_PWREN_AUTOLOW 0x00000002 +#define USB_HOST_PWREN_AUTOHIGH 0x00000003 +#define USB_HOST_PWREN_FILTER 0x00010000 + +//***************************************************************************** +// +// The following are the valid values that can be passed to the +// md_usb_hos_lpm_config() function in the ui32Config parameter. +// +//***************************************************************************** +#define USB_HOST_LPM_RMTWAKE 0x00000100 +#define USB_HOST_LPM_L1 0x00000001 + +//***************************************************************************** +// +// The following are the valid values that can be passed to the +// md_usb_dev_lpm_config() function in the ui32Config parameter. +// +//***************************************************************************** +#define USB_DEV_LPM_NAK 0x00000010 +#define USB_DEV_LPM_NONE 0x00000000 +#define USB_DEV_LPM_EN 0x0000000c +#define USB_DEV_LPM_EXTONLY 0x00000004 + +//***************************************************************************** +// +// The following are the valid values that are returned from the +// md_usb_lpm_link_state_get() function. +// +//***************************************************************************** +#define USB_DEV_LPM_LS_RMTWAKE 0x00000100 +#define USB_DEV_LPM_LS_L1 0x00000001 + +//***************************************************************************** +// +// The following are the valid values that are passed to the md_usb_lpm_int_enable() +// or md_usb_lpm_int_disable() functions or are returned from the md_usb_lpm_status() +// function. +// +//***************************************************************************** +#define USB_INTLPM_ERROR 0x00000020 +#define USB_INTLPM_RESUME 0x00000010 +#define USB_INTLPM_INCOMPLETE 0x00000008 +#define USB_INTLPM_ACK 0x00000004 +#define USB_INTLPM_NYET 0x00000002 +#define USB_INTLPM_STALL 0x00000001 + +//***************************************************************************** +// +// The following are the valid values that are passed to the md_usb_clock_enable() +// functions. +// +//***************************************************************************** +#define USB_CLOCK_INTERNAL 0x00000200 +#define USB_CLOCK_EXTERNAL 0x00000300 + +//***************************************************************************** +// +// The configuration options used with the md_usb_ulpi_config() API. +// +//***************************************************************************** +#define USB_ULPI_EXTVBUS 0x00000001 +#define USB_ULPI_EXTVBUS_IND 0x00000002 + +//***************************************************************************** +// +// The following are special values that can be passed to +// md_usb_hos_endpoint_config_set() as the ui32NAKPollInterval parameter. +// +//***************************************************************************** +#define MAX_NAK_LIMIT 31 // Maximum NAK interval +#define DISABLE_NAK_LIMIT 0 // No NAK timeouts + +//***************************************************************************** +// +// This value specifies the maximum size of transfers on endpoint 0 as 64 +// bytes. This value is fixed in hardware as the FIFO size for endpoint 0. +// +//***************************************************************************** +#define MAX_PACKET_SIZE_EP0 64 + +//***************************************************************************** +// +// These values are used to indicate which endpoint to access. +// +//***************************************************************************** +#define USB_EP_0 0x00000000 // Endpoint 0 +#define USB_EP_1 0x00000010 // Endpoint 1 +#define USB_EP_2 0x00000020 // Endpoint 2 +#define USB_EP_3 0x00000030 // Endpoint 3 +#define USB_EP_4 0x00000040 // Endpoint 4 +#define USB_EP_5 0x00000050 // Endpoint 5 +#define USB_EP_6 0x00000060 // Endpoint 6 +#define USB_EP_7 0x00000070 // Endpoint 7 +#define NUM_USB_EP 8 // Number of supported endpoints + +//***************************************************************************** +// +// These macros allow conversion between 0-based endpoint indices and the +// USB_EP_x values required when calling various USB APIs. +// +//***************************************************************************** +#define IndexToUSBEP(x) ((x) << 4) +#define USBEPToIndex(x) ((x) >> 4) + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hosdev_fifo_config_set() as the +// ui32FIFOSize parameter. +// +//***************************************************************************** +#define USB_FIFO_SZ_8 0x00000000 // 8 byte FIFO +#define USB_FIFO_SZ_16 0x00000001 // 16 byte FIFO +#define USB_FIFO_SZ_32 0x00000002 // 32 byte FIFO +#define USB_FIFO_SZ_64 0x00000003 // 64 byte FIFO +#define USB_FIFO_SZ_128 0x00000004 // 128 byte FIFO +#define USB_FIFO_SZ_256 0x00000005 // 256 byte FIFO +#define USB_FIFO_SZ_512 0x00000006 // 512 byte FIFO +#define USB_FIFO_SZ_1024 0x00000007 // 1024 byte FIFO +#define USB_FIFO_SZ_2048 0x00000008 // 2048 byte FIFO + +//***************************************************************************** +// +// This macro allow conversion from a FIFO size label as defined above to +// a number of bytes +// +//***************************************************************************** +#define USBFIFOSizeToBytes(x) (8 << (x)) + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hosdev_endpoint_data_send() +// as the ui32TransType parameter. +// +//***************************************************************************** +#define USB_TRANS_OUT 0x00000102 // Normal OUT transaction +#define USB_TRANS_IN 0x00000102 // Normal IN transaction +#define USB_TRANS_IN_LAST 0x0000010a // Final IN transaction (for +// endpoint 0 in device mode) +#define USB_TRANS_SETUP 0x0000110a // Setup transaction (for endpoint +// 0) +#define USB_TRANS_STATUS 0x00000142 // Status transaction (for endpoint +// 0) + +//***************************************************************************** +// +// The following are values are returned by the md_usb_hosdev_mode_get() function. +// +//***************************************************************************** +#define USB_DUAL_MODE_HOST 0x00000001 // Dual mode controller is in Host +// mode. +#define USB_DUAL_MODE_DEVICE 0x00000081 // Dual mode controller is in +// Device mode. +#define USB_DUAL_MODE_NONE 0x00000080 // Dual mode controller mode is not +// set. +#define USB_OTG_MODE_ASIDE_HOST 0x0000001d // OTG controller on the A side of +// the cable. +#define USB_OTG_MODE_ASIDE_NPWR 0x00000001 // OTG controller on the A side of +// the cable. +#define USB_OTG_MODE_ASIDE_SESS 0x00000009 // OTG controller on the A side of +// the cable Session Valid. +#define USB_OTG_MODE_ASIDE_AVAL 0x00000011 // OTG controller on the A side of +// the cable A valid. +#define USB_OTG_MODE_ASIDE_DEV 0x00000019 // OTG controller on the A side of +// the cable. +#define USB_OTG_MODE_BSIDE_HOST 0x0000009d // OTG controller on the B side of +// the cable. +#define USB_OTG_MODE_BSIDE_DEV 0x00000099 // OTG controller on the B side of +// the cable. +#define USB_OTG_MODE_BSIDE_NPWR 0x00000081 // OTG controller on the B side of +// the cable. +#define USB_OTG_MODE_NONE 0x00000080 // OTG controller mode is not set. + +//***************************************************************************** +// +// Channel configuration values. +// +//***************************************************************************** +#define DMA_DST_INC_8 0x00000000 +#define DMA_DST_INC_16 0x40000000 +#define DMA_DST_INC_32 0x80000000 +#define DMA_DST_INC_NONE 0xc0000000 +#define DMA_SRC_INC_8 0x00000000 +#define DMA_SRC_INC_16 0x04000000 +#define DMA_SRC_INC_32 0x08000000 +#define DMA_SRC_INC_NONE 0x0c000000 +#define DMA_SIZE_8 0x00000000 +#define DMA_SIZE_16 0x11000000 +#define DMA_SIZE_32 0x22000000 +#define DMA_DST_PROT_PRIV 0x00200000 +#define DMA_SRC_PROT_PRIV 0x00040000 +#define DMA_ARB_1 0x00000000 +#define DMA_ARB_2 0x00004000 +#define DMA_ARB_4 0x00008000 +#define DMA_ARB_8 0x0000c000 +#define DMA_ARB_16 0x00010000 +#define DMA_ARB_32 0x00014000 +#define DMA_ARB_64 0x00018000 +#define DMA_ARB_128 0x0001c000 +#define DMA_ARB_256 0x00020000 +#define DMA_ARB_512 0x00024000 +#define DMA_ARB_1024 0x00028000 +#define DMA_NEXT_USEBURST 0x00000008 + +//***************************************************************************** +// +// The values for the md_usb_dma_channel_int_enable() and md_usb_dma_channel_int_status() +// APIs. +// +//***************************************************************************** +#define USB_DMA_INT_CH8 0x00000080 +#define USB_DMA_INT_CH7 0x00000040 +#define USB_DMA_INT_CH6 0x00000020 +#define USB_DMA_INT_CH5 0x00000010 +#define USB_DMA_INT_CH4 0x00000008 +#define USB_DMA_INT_CH3 0x00000004 +#define USB_DMA_INT_CH2 0x00000002 +#define USB_DMA_INT_CH1 0x00000001 + +//***************************************************************************** +// +// The values for the md_usb_dma_channel_status() API. +// +//***************************************************************************** +#define USB_DMA_STATUS_ERROR 0x00000100 + +//***************************************************************************** +// +// The valid return values for the USBDMAModeSet() and USBDMAModeGet() APIs or +// USBDMAChannelConfig(). +// +//***************************************************************************** +#define USB_DMA_CFG_BURST_NONE 0x00000000 +#define USB_DMA_CFG_BURST_4 0x00000200 +#define USB_DMA_CFG_BURST_8 0x00000400 +#define USB_DMA_CFG_BURST_16 0x00000600 +#define USB_DMA_CFG_INT_EN 0x00000008 +#define USB_DMA_CFG_MODE_0 0x00000000 +#define USB_DMA_CFG_MODE_1 0x00000004 +#define USB_DMA_CFG_DIR_RX 0x00000000 +#define USB_DMA_CFG_DIR_TX 0x00000002 +#define USB_DMA_CFG_EN 0x00000001 + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_mode_config() as the +// ui3Mode parameter. +// +//***************************************************************************** +#define USB_MODE_HOST_VBUS 0x00000004 +#define USB_MODE_HOST 0x00000002 +#define USB_MODE_DEV_VBUS 0x00000005 +#define USB_MODE_DEV 0x00000003 +#define USB_MODE_OTG 0x00000000 + +//***************************************************************************** +// +// Flags that can be passed to DMAChannelAttributeEnable(), +// DMAChannelAttributeDisable(), and returned from DMAChannelAttributeGet(). +// +//***************************************************************************** +#define DMA_ATTR_USEBURST 0x00000001 +#define DMA_ATTR_ALTSELECT 0x00000002 +#define DMA_ATTR_HIGH_PRIORITY 0x00000004 +#define DMA_ATTR_REQMASK 0x00000008 +#define DMA_ATTR_ALL 0x0000000F + +/* Public functions -----------------------------------------------------------*/ +/** + * @{ SYSTEM API. + */ +extern void md_usb_system_int_disable(void); +extern void md_usb_system_int_enable(void); +extern void md_usb_re_config(bool Device); /* Weak defination */ +extern void md_usb_system_delayms(uint32_t delayms); /* Weak defination */ +extern void md_usb_systic_disable(void); +extern void md_usb_controller_reset(void); +extern void md_usb_controller_enable(void); +extern void md_usb_controller_disable(void); +extern void md_usb_clk_phy_enable(void); +extern void md_usb_clk_phy_disable(void); +extern uint32_t md_usb_nvic_number_get(void); +extern void md_usb_nvic_config(uint32_t NvicNum); /* Weak defination */ +extern void md_usb_nvic_enable(void); +extern void md_usb_nvic_disable(void); +/** + * @} SYSTEM API. + */ + +/** + * @{ USB basic API. + */ +/* Host Mode */ +extern void md_usb_hos_reset(bool bStart); +extern void md_usb_hos_resume(bool bStart); +extern void md_usb_hos_suspend(void); +extern void md_usb_hos_request_status(void); +extern void md_usb_hos_request_in(uint32_t ui32Endpoint); +extern void md_usb_hos_request_in_clear(uint32_t ui32Endpoint); +extern uint32_t md_usb_hos_speed_get(void); +extern uint32_t md_usb_hos_addr_get(uint32_t ui32Endpoint, uint32_t ui32Flags); +extern void md_usb_hos_addr_set(uint32_t ui32Endpoint, + uint32_t ui32Addr, + uint32_t ui32Flags); +extern uint32_t md_usb_hos_hub_addr_get(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_hos_hub_addr_set(uint32_t ui32Endpoint, + uint32_t ui32Addr, + uint32_t ui32Flags); +/* Device Mode */ +extern void md_usb_dev_addr_set(uint8_t ui32Address); +extern uint8_t md_usb_dev_addr_get(void); +extern void md_usb_dev_connect(void); +extern void md_usb_dev_disconnect(void); +extern uint32_t md_usb_dev_speed_get(void); +/* Host/Device Mode */ +extern uint32_t md_usb_hosdev_frame_get(void); +extern void md_usb_hosdev_int_disable(uint32_t ui32IntFlags); +extern void md_usb_hosdev_int_enable(uint32_t ui32IntFlags); +extern uint32_t md_usb_hosdev_int_status(void); +extern uint32_t md_usb_hosdev_mode_get(void); +/* otg Mode */ +extern void md_usb_otg_session_request(bool bStart); +extern void md_usb_force_host_mode(void); +extern void md_usb_force_device_mode(void); +extern void md_usb_force_otg_mode(void); +extern void md_usb_mode_config(uint32_t ui32Mode); +/** + * @} USB basic API. + */ + +/** + * @{ USB endpoint API. + */ +/* Host Mode */ +extern void md_usb_hos_endpoint_config_set(uint32_t ui32Endpoint, + uint32_t ui32MaxPacketSize, + uint32_t ui32NAKPollInterval, + uint32_t ui32TargetEndpoint, + uint32_t ui32Flags); +extern void md_usb_hos_endpoint_data_ack(uint32_t ui32Endpoint); +extern void md_usb_hos_endpoint_data_toggle(uint32_t ui32Endpoint, + bool bDataToggle, + uint32_t ui32Flags); +extern void md_usb_hos_endpoint_status_clear(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_hos_endpoint_speed(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_hos_endpoint_ping(uint32_t ui32Endpoint, + bool bEnable); +/* Device Mode */ +extern void md_usb_dev_endpoint_config_set(uint32_t ui32Endpoint, + uint32_t ui32MaxPacketSize, + uint32_t ui32Flags); +extern void md_usb_dev_endpoint_config_get(uint32_t ui32Endpoint, + uint32_t *pui32MaxPacketSize, + uint32_t *pui32Flags); +extern void md_usb_dev_endpoint_ack(uint32_t ui32Endpoint, + bool bIsLastPacket); +extern void md_usb_dev_endpoint_stall(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_dev_endpoint_stall_clear(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_dev_endpoint_status_clear(uint32_t ui32Endpoint, + uint32_t ui32Flags); +/* Host/Device Mode */ +extern uint32_t md_usb_hosdev_endpoint_datavai(uint32_t ui32Endpoint); +extern int32_t md_usb_hosdev_endpoint_data_get(uint32_t ui32Endpoint, + uint8_t *pui8Data, uint32_t *pui32Size); +extern int32_t md_usb_hosdev_endpoint_data_put(uint32_t ui32Endpoint, + uint8_t *pui8Data, + uint32_t ui32Size); +extern int32_t md_usb_hosdev_endpoint_data_send(uint32_t ui32Endpoint, + uint32_t ui32TransType); +extern void md_usb_hosdev_endpoint_data_togglec(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_hosdev_endpoint_pkcount_set(uint32_t ui32Endpoint, + uint32_t ui32Count); +extern uint32_t md_usb_hosdev_endpoint_status(uint32_t ui32Endpoint); +extern void md_usb_hosdev_endpoint_int_disable(uint32_t ui32IntFlags); +extern void md_usb_hosdev_endpoint_int_enable(uint32_t ui32IntFlags); +extern uint32_t md_usb_hosdev_endpoint_int_status(void); +extern uint32_t md_usb_endpoint_number_get(void); +/** + * @} USB endpoint API. + */ + +/** + * @{ USB FIFO API. + */ +extern uint32_t md_usb_hosdev_fifo_addr_get(uint32_t ui32Endpoint); +extern void md_usb_hosdev_fifo_config_get(uint32_t ui32Endpoint, uint32_t *pui32FIFOAddress, + uint32_t *pui32FIFOSize, uint32_t ui32Flags); +extern void md_usb_hosdev_fifo_config_set(uint32_t ui32Endpoint, uint32_t ui32FIFOAddress, + uint32_t ui32FIFOSize, uint32_t ui32Flags); +extern void md_usb_hosdev_fifo_flush(uint32_t ui32Endpoint, uint32_t ui32Flags); +/** + * @} USB FIFO API. + */ + +/** + * @{ USB PWR API.it is not supported by es32f0271. + */ +extern void md_usb_hos_pwr_disable(void); +extern void md_usb_hos_pwr_enable(void); +extern void md_usb_hos_pwr_config(uint32_t ui32Flags); +extern void md_usb_hos_pwrfault_disable(void); +extern void md_usb_hos_pwrfault_enable(void); +/** + * @} USB PWR API. + */ + +/** + * @{ USB LPM API.it is not supported by es32f0271. + */ +extern void md_usb_hos_lpm_send(uint32_t ui32Address, + uint32_t uiEndpoint); +extern void md_usb_hos_lpm_config(uint32_t ui32ResumeTime, + uint32_t ui32Config); +extern bool md_usb_lpm_remotewake_is_enabled(void); +extern void md_usb_hos_lpm_resume(void); +extern void md_usb_dev_lpm_remotewake(void); +extern void md_usb_dev_lpm_config(uint32_t ui32Config); +extern void md_usb_dev_lpm_enable(void); +extern void md_usb_dev_lpm_disable(void); +extern uint32_t md_usb_lpm_link_state_get(void); +extern uint32_t md_usb_lpm_endpoint_get(void); +extern uint32_t md_usb_lpm_status(void); +extern void md_usb_lpm_int_disable(uint32_t ui32Ints); +extern void md_usb_lpm_int_enable(uint32_t ui32Ints); +/** + * @} USB LPM API. + */ + +/** + * @{ USB ULPI API.it is not supported by es32f0271. + */ +extern void md_usb_ulpi_config(uint32_t ui32Config); +extern void md_usb_ulpi_enable(void); +extern void md_usb_ulpi_disable(void); +extern uint8_t md_usb_ulpi_reg_read(uint8_t ui8Reg); +extern void md_usb_ulpi_reg_write(uint8_t ui8Reg, + uint8_t ui8Data); +/** + * @} USB ULPI API. + */ + +/** + * @{ USB DMA API.it is not supported by es32f0271. + */ +extern void md_usb_dma_endpoint_channel_set(uint32_t ui32Endpoint, + uint32_t ui32Channel); +extern void md_usb_dma_endpoint_enable(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_dma_endpoint_disable(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_dma_endpoint_config(uint32_t ui32Endpoint, + uint32_t ui32Config); +extern void md_usb_dma_channel_config(uint32_t ui32Channel, + uint32_t ui32Endpoint, + uint32_t ui32Config); +extern void md_usb_dma_channel_address_set(uint32_t ui32Channel, + void *pvAddress); +extern void *md_usb_dma_channel_address_get(uint32_t ui32Channel); +extern void md_usb_dma_channel_count_set(uint32_t ui32Count, + uint32_t ui32Channel); +extern uint32_t md_usb_dma_channel_count_get(uint32_t ui32Channel); +extern void md_usb_dma_channel_int_enable(uint32_t ui32Channel); +extern void md_usb_dma_channel_int_disable(uint32_t ui32Channel); +extern uint32_t md_usb_dma_channel_int_status(void); +extern void md_usb_dma_channel_enable(uint32_t ui32Channel); +extern void md_usb_dma_channel_disable(uint32_t ui32Channel); +extern uint32_t md_usb_dma_channel_isenabled(uint32_t ui32Channel); +extern uint32_t md_usb_dma_channel_status(uint32_t ui32Channel); +extern void md_usb_dma_channel_status_clear(uint32_t ui32Channel, + uint32_t ui32Status); +/** + * @} USB DMA API. + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics Co., Ltd. *** END OF FILE ****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/ReleaseNote.html b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/ReleaseNote.html new file mode 100644 index 0000000000..de5a1aada3 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/ReleaseNote.html @@ -0,0 +1,17 @@ + + + + +ReleaseNote +

ES32F0271 MD Release Note

+

V1.00 2019-1-4

+

初版发布

+

V1.01 2019-5-7

+

1.修改USB MD库相关接口

+

V1.03 2019-09-23

+
    +
  1. 增加ADC校準函數
  2. + +
+ + \ No newline at end of file diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_adc.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_adc.c new file mode 100644 index 0000000000..d8571b0912 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_adc.c @@ -0,0 +1,298 @@ +/** + ****************************************************************************** + * @file md_adc.c + * @brief ES32F0271 ADC Source File. + * + * @version V1.00.01 + * @data 7/01/2019 + * @author Taipei AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + + +/* Includes -------------------------------------------------------------------*/ +#include "md_adc.h" +#include "md_syscfg.h" +#include + + +/** @addtogroup Micro_Driver + * @{ + */ + + +/** @defgroup ADC ADC + * @brief ADC micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +#define Reference_V1 1 //First reference point +#define Reference_V2 2 //Second reference point + +double Ideal_V1; +double Ideal_V2; +double Reference_V1_ADCValue ; +double Reference_V2_ADCValue ; + +/* Private function prototypes ------------------------------------------------*/ +void (*md_adc_SS0_sample[])(ADC_TypeDef *, uint32_t) = +{ + md_adc_set_ss0_mux0_mux0, + md_adc_set_ss0_mux0_mux1, + md_adc_set_ss0_mux0_mux2, + md_adc_set_ss0_mux0_mux3, + md_adc_set_ss0_mux0_mux4, + md_adc_set_ss0_mux0_mux5, + md_adc_set_ss0_mux0_mux6, + md_adc_set_ss0_mux0_mux7, + md_adc_set_ss0_mux1_mux8, + md_adc_set_ss0_mux1_mux9, + md_adc_set_ss0_mux1_mux10, + md_adc_set_ss0_mux1_mux11, + md_adc_set_ss0_mux1_mux12, + md_adc_set_ss0_mux1_mux13, + md_adc_set_ss0_mux1_mux14, + md_adc_set_ss0_mux1_mux15 +}; + +void (*md_adc_SS1_sample[])(ADC_TypeDef *, uint32_t) = +{ + md_adc_set_ss0_mux0_mux0, + md_adc_set_ss0_mux0_mux1, + md_adc_set_ss0_mux0_mux2, + md_adc_set_ss0_mux0_mux3, + md_adc_set_ss0_mux0_mux4, + md_adc_set_ss0_mux0_mux5, + md_adc_set_ss0_mux0_mux6, + md_adc_set_ss0_mux0_mux7, +}; + +void (*md_adc_SS2_sample[])(ADC_TypeDef *, uint32_t) = +{ + md_adc_set_ss0_mux0_mux0, + md_adc_set_ss0_mux0_mux1, + md_adc_set_ss0_mux0_mux2, + md_adc_set_ss0_mux0_mux3, +}; + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup ADC_PUB_FUNC ADC Public Functions + * @brief ADC Public Functions + * @{ + */ +/** + * @brief ADC Initialization Function. + * @param ADC Instance. + * @param channel + * @retval None + */ +void md_adc_init(ADC_TypeDef *ADCx, md_adc_inittypedef *ADC_InitStruct, uint8_t *channel) +{ + uint8_t i = 0; + + md_syscfg_enable_cfg_currgen(SYSCFG); + md_syscfg_set_cfg_vlrs(SYSCFG, ADC_InitStruct->VRLS); + md_syscfg_enable_cfg_vrefen(SYSCFG); + + if (ADC_InitStruct->SSx == 0) + { + md_adc_set_ss0_con_sel(ADC, ADC_InitStruct->Sel); + md_adc_set_ss0_con_type(ADC, ADC_InitStruct->Type); + + md_adc_set_srate_cntini(ADC, ADC_InitStruct->Cntini); + md_adc_set_srate_cnt(ADC, ADC_InitStruct->Cnt); + md_adc_set_frf_ffrst(ADC); + + + for (i = 0; i < 16; i++) + md_adc_SS0_sample[i](ADC, channel[i]); + + md_adc_enable_ier_ss0ie(ADC); + md_adc_set_ss0_end_end(ADC, ADC_InitStruct->End); + md_adc_enable_ss0_end_ie15(ADC); + md_adc_set_gainh_ch8pga(ADC, MD_ADC_GAIN_CHPGA_X1); + + + md_adc_set_srate(ADC, (ADC_InitStruct->Ckdiv) | ADC_SRATE_CKEN_MSK); + md_adc_enable_ssen_ss0en(ADC); + } + else if (ADC_InitStruct->SSx == 1) + { + md_adc_set_ss1_con_sel(ADC, ADC_InitStruct->Sel); + md_adc_set_ss1_con_type(ADC, ADC_InitStruct->Type); + + md_adc_set_srate_cntini(ADC, ADC_InitStruct->Cntini); + md_adc_set_srate_cnt(ADC, ADC_InitStruct->Cnt); + md_adc_set_frf_ffrst(ADC); + + for (i = 0; i < 8; i++) + md_adc_SS1_sample[i](ADC, channel[i]); + + md_adc_enable_ier_ss1ie(ADC); + md_adc_set_ss1_end_end(ADC, ADC_InitStruct->End); + md_adc_enable_ss1_end_ie7(ADC); + md_adc_set_gainh_ch8pga(ADC, MD_ADC_GAIN_CHPGA_X1); + + md_adc_set_srate(ADC, (ADC_InitStruct->Ckdiv) | ADC_SRATE_CKEN_MSK); + md_adc_enable_ssen_ss1en(ADC); + } + else if (ADC_InitStruct->SSx == 2) + { + md_adc_set_ss2_con_sel(ADC, ADC_InitStruct->Sel); + md_adc_set_ss2_con_type(ADC, ADC_InitStruct->Type); + + md_adc_set_srate_cntini(ADC, ADC_InitStruct->Cntini); + md_adc_set_srate_cnt(ADC, ADC_InitStruct->Cnt); + md_adc_set_frf_ffrst(ADC); + + for (i = 0; i < 4; i++) + md_adc_SS2_sample[i](ADC, channel[i]); + + md_adc_enable_ier_ss2ie(ADC); + md_adc_set_ss2_end_end(ADC, ADC_InitStruct->End); + md_adc_enable_ss2_end_ie3(ADC); + md_adc_set_gainh_ch8pga(ADC, MD_ADC_GAIN_CHPGA_X1); + + md_adc_set_srate(ADC, (ADC_InitStruct->Ckdiv) | ADC_SRATE_CKEN_MSK); + md_adc_enable_ssen_ss2en(ADC); + } + else + { + md_adc_set_ss3_con_sel(ADC, ADC_InitStruct->Sel); + md_adc_set_ss3_con_type(ADC, ADC_InitStruct->Type); + + md_adc_set_srate_cntini(ADC, ADC_InitStruct->Cntini); + md_adc_set_srate_cnt(ADC, ADC_InitStruct->Cnt); + md_adc_set_frf_ffrst(ADC); + + MODIFY_REG(ADC->SS3_MUX0, ADC_SS3_MUX0_MUX0_MSK, MD_ADC_SS_MUX_ADIN8 << ADC_SS3_MUX0_MUX0_POSS); + + md_adc_enable_ier_ss3ie(ADC); + md_adc_set_ss3_end_end(ADC, ADC_InitStruct->End); + md_adc_enable_ss3_end_ie0(ADC); + md_adc_set_gainh_ch8pga(ADC, MD_ADC_GAIN_CHPGA_X1); + + md_adc_set_srate(ADC, (ADC_InitStruct->Ckdiv) | ADC_SRATE_CKEN_MSK); + md_adc_enable_ssen_ss3en(ADC); + } +} + + +/** + * @brief Get the ADC calibration offset data + * @param vref: reference v + * @param vdd: external v + * @param offset: Get Offset + * @param coefficient: Get Coefficient + * @retval None + */ +void md_adc_calibration_data(double vdd, double vref,double *offset,double *coefficient) +{ + Ideal_V1 = Reference_V1 / vref * 4096; + Ideal_V2 = Reference_V2 / vref * 4096; + if (vdd == 5 && vref == 5) + { + if ((FC->ADCTRIM_VDD5V_VREF5V >> 24) == 0xA5) + { + Reference_V1_ADCValue = FC->ADCTRIM_VDD5V_VREF5V & 0xFFF; + Reference_V2_ADCValue = (FC->ADCTRIM_VDD5V_VREF5V >> 12) & 0xFFF; + } + } + else if (vdd == 3.3 && vref == 3.3) + { + if ((FC->ADCTRIM_VDD3V3_VREF3V3 >> 24) == 0xA5) + { + Reference_V1_ADCValue = FC->ADCTRIM_VDD3V3_VREF3V3 & 0xFFF; + Reference_V2_ADCValue = (FC->ADCTRIM_VDD3V3_VREF3V3 >> 12) & 0xFFF; + } + } + else if ((vdd == 5 && vref == 2.5) || (vdd == 3.3 && vref == 2.5)) + { + if ((FC->ADCTRIM_VDD5V_VREF2V5 >> 24) == 0xA5) + { + Reference_V1_ADCValue = FC->ADCTRIM_VDD5V_VREF2V5 & 0xFFF; + Reference_V2_ADCValue = (FC->ADCTRIM_VDD5V_VREF2V5 >> 12) & 0xFFF; + } + } + else + { + + } + +// Reference_V1_ADCValue = 115 ; +// Reference_V2_ADCValue = 365 ; + + printf("Ideal_V1:%.2f\r\n", Ideal_V1); + printf("Ideal_V2:%.2f\r\n", Ideal_V2); + printf("Reference_V1_ADCValue:%.2f\r\n", Reference_V1_ADCValue); + printf("Reference_V2_ADCValue:%.2f\r\n", Reference_V2_ADCValue); + + *offset = (Reference_V2 * Reference_V1_ADCValue - Reference_V1 * Reference_V2_ADCValue) / (Reference_V2 - Reference_V1); + printf("Offset=%.2f\r\n", *offset); + *coefficient = Ideal_V1 / (Reference_V1_ADCValue - *offset); + printf("Coefficient=%.2f\r\n", *coefficient); +} + +/** + * @brief Get the ADC fixed data + * @param SSx: Sequence SSx + * @param offset:input offset + * @param coefficient: input coefficient + * @param calibration :get calibration result + * @retval None + */ + +void md_adc_get_data(uint8_t SSx,double offset,double coefficient, uint16_t *calibration) +{ + uint16_t i, data, s_times; + double calibration_value = 0; + + if (SSx == 0) + s_times = 16; + else if (SSx == 1) + s_times = 8; + else if (SSx == 2) + s_times = 4; + else + s_times = 1; + + for (i = 0; i < s_times; i++) + { + if(SSx == 0) + data = md_adc_get_ss0_data(ADC); + else if(SSx == 1) + data = md_adc_get_ss1_data(ADC); + else if(SSx == 2) + data = md_adc_get_ss2_data(ADC); + else + data = md_adc_get_ss3_data(ADC); + if(data >= 4095) + data = 4095; + printf("data = %4d\r\n",data); + calibration_value = (data - offset) * coefficient; + if (calibration_value >= 4095) + calibration_value = 4095; + *calibration++=(uint16_t)calibration_value; + } +} +/** + * @} ADC_PUB_FUNC ADC Public Functions + */ + +/** + * @} ADC + */ + +/** + * @} Micro_Driver + */ + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_fc.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_fc.c new file mode 100644 index 0000000000..ce5d644209 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_fc.c @@ -0,0 +1,300 @@ +/** + ****************************************************************************** + * @file md_fc.c + * @brief ES32F0271 FC Source File. + * + * @version V1.00.01 + * @date day/mon/year + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Includes -------------------------------------------------------------------*/ +#include "md_syscfg.h" +#include "md_fc.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (FC) + +/** @defgroup FC FC + * @brief FC micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Private constants ----------------------------------------------------------*/ +/** @defgroup MD_FC_Private_Constants FC Private Constants + * @{ + */ + +#define REMAPDATA_BASE (( uint32_t)0x00000000) /* FLASH Main (64K Bytes) */ +#define REMAPINFO_BASE (( uint32_t)0x00000000) /* FLASH Info ( 6K Bytes) - Boot Loader Memory */ + +#define EFOPT_PAGE6_OFFSET (MD_FC_PC_EF_IPAGESZ*6) +#define EFOPT_PAGE7_OFFSET (MD_FC_PC_EF_IPAGESZ*7) +#define EFOPT_PL1_OFFSET (MD_FC_PC_EF_IPAGESZ*7+0x0) +#define EFOPT_PL2_OFFSET (MD_FC_PC_EF_IPAGESZ*6+0x28) +#define EFOPT_REMAP_OFFSET (MD_FC_PC_EF_IPAGESZ*7+0x8) + +/** + * @} MD_FC_Private_Constants + */ + +/* Private function prototypes ------------------------------------------------*/ + +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_FC_Public_Functions FC Public Functions + * @{ + */ + +/** + * @brief FC main erase. + * @note To prevent unexpected code branch, the main erase function must specify a dedicated main erase ID + * @param MEraseID Key for main erase, must be 0xA5A5AA55 + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Main flash erased + * - ERROR: Main erase ID mismatch + */ +ErrorStatus md_fc_merase(uint32_t MEraseID) +{ + ErrorStatus status = ERROR; + + /* Check the ID */ + if (MEraseID != MD_FC_PC_EF_MERASEID) + return status; + + /* Write MERASE to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_MACRO_ERASE); + + status = SUCCESS; + return status; +} + +/** + * @brief FC Sector Erase + * @note To prevent unexpected code branch, the page erase function must specify the complement start address + * @param pSErasePara Pointer to structure md_fc_ControlTypeDef + * @retval An ErrorStatus enumeration value. + * - SUCCESS: Specified page address erased + * - ERROR: Complement of start address mismatch + */ +ErrorStatus md_fc_serase(md_fc_ControlTypeDef *pSErasePara) +{ + ErrorStatus status = ERROR; + + /* Check the start address and complement of start address*/ + if (pSErasePara->SAddr & pSErasePara->SAddrC) + return status; + + /* Write sector address to PA*/ + md_fc_set_pa_prog_addr(pSErasePara->SAddr); + /* Write SERASE to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_SECTOR_ERASE); + + status = SUCCESS; + return status; +} + +/** + * @brief FC Page Program + * @note To prevent unexpected code branch, the page program function must specify the complement start address + * @param pProgramPara Pointer to structure md_fc_ControlTypeDef + * @retval An ErrorStatus enumeration value. + * - SUCCESS: Data in data buffer programed to specified page address + * - ERROR: Complement of start address mismatch + */ +ErrorStatus md_fc_program(md_fc_ControlTypeDef *pProgramPara) +{ + ErrorStatus status = ERROR; + uint16_t BCnt; + + md_fc_set_pa_pcnt(pProgramPara->BCnt); + md_fc_set_pa_prog_addr(pProgramPara->SAddr); + BCnt = pProgramPara->BCnt; + BCnt >>= 3; + + while (BCnt--) + { + /* Check the start address and complement of start address*/ + if (pProgramPara->SAddr & pProgramPara->SAddrC) + return status; + + /* Write lower 32bit program data to PLD*/ + md_fc_set_pld(*pProgramPara->pU32Buf++); + /* Write higher 32bit program data to PHD*/ + md_fc_set_phd(*pProgramPara->pU32Buf++); + /* Write PROGRAM to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_PROG_EFLASH); + } + + status = SUCCESS; + return status; +} + +/** + * @brief FC Page Read + * @param pReadPara Pointer to structure md_fc_ControlTypeDef + * @retval Always return SUCCESS + * - Data in specified page address read to data buffer + */ +ErrorStatus md_fc_read(md_fc_ControlTypeDef *pReadPara) +{ + ErrorStatus status = SUCCESS; + uint32_t *EFAddr; + uint16_t BCnt; + + if (md_syscfg_get_remap_memmod(SYSCFG) == MD_SYSCFG_MEMMOD_MAIN) /* Reamp from Main */ + EFAddr = (uint32_t *)(REMAPDATA_BASE + pReadPara->SAddr); + else + EFAddr = (uint32_t *)(FLASH_BASE + pReadPara->SAddr); + + BCnt = pReadPara->BCnt; + BCnt >>= 2; + + while (BCnt--) + *pReadPara->pU32Buf++ = *EFAddr++; + + return status; +} + +/** + * @brief FC Update Protect Level 1 Setting + * @param pUpdPL1Para Pointer to structure md_fc_UpdProtTypeDdef + * @retval Always return SUCCESS + */ +ErrorStatus md_fc_updprotl1(md_fc_UpdProtTypeDef *pUpdPL1Para) +{ + ErrorStatus status = SUCCESS; + uint32_t EFProtL1L, EFProtL1H; + + EFProtL1L = FC->OP_PRT1L; + EFProtL1H = FC->OP_PRT1H; + + if ((EFProtL1L == 0xffffffffUL) && (EFProtL1H == 0xffffffffUL)) /* First Time to Set Level1 */ + { + /* Write offset address to PA*/ + md_fc_set_pa_prog_addr(EFOPT_PL1_OFFSET); + md_fc_enable_pa_ifren(); + /* Write lower 32bit update data to PLD*/ + md_fc_set_pld(pUpdPL1Para->UpdateL); + /* Write higher 32bit update data to PHD*/ + md_fc_set_phd(pUpdPL1Para->UpdateH); + + /* Write PROGRAM to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_PROG_EFLASH); + } + else + { + /* Write lower 32bit clear data to PLD*/ + md_fc_set_pld(pUpdPL1Para->ClearL); + /* Write higher 32bit clear data to PHD*/ + md_fc_set_phd(pUpdPL1Para->ClearH); + + /* Write lower 32bit data to UPL*/ + md_fc_set_upl(pUpdPL1Para->UpdateL); + /* Write higher 32bit data to UPH*/ + md_fc_set_uph(pUpdPL1Para->UpdateH); + + /* Write UPDPL1 to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_UPDATE_LV1_PROTECT); + } + + return status; +} + +/** + * @brief FC Update Protect Level 2 Setting + * @param pUpdPL2Para Pointer to structure md_fc_UpdProtTypeDdef + * @retval Always return SUCCESS + */ +ErrorStatus md_fc_updprotl2(md_fc_UpdProtTypeDef *pUpdPL2Para) +{ + ErrorStatus status = SUCCESS; + uint32_t EFProtL2L, EFProtL2H; + + EFProtL2L = FC->OP_PRT2L; + EFProtL2H = FC->OP_PRT2H; + + if ((EFProtL2L == 0xffffffffUL) && (EFProtL2H == 0xffffffffUL)) /* First Time to Set Level2 */ + { + /* Write offset address to PA*/ + md_fc_set_pa_prog_addr(EFOPT_PL2_OFFSET); + md_fc_enable_pa_ifren(); + /* Write lower 32bit update data to PLD*/ + md_fc_set_pld(pUpdPL2Para->UpdateL); + /* Write higher 32bit update data to PHD*/ + md_fc_set_phd(pUpdPL2Para->UpdateH); + + /* Write PROGRAM to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_PROG_EFLASH); + } + else + { + /* Write lower 32bit clear data to PLD*/ + md_fc_set_pld(pUpdPL2Para->ClearL); + /* Write higher 32bit clear data to PHD*/ + md_fc_set_phd(pUpdPL2Para->ClearH); + + /* Write lower 32bit data to UPL*/ + md_fc_set_upl(pUpdPL2Para->UpdateL); + /* Write higher 32bit data to UPH*/ + md_fc_set_uph(pUpdPL2Para->UpdateH); + + /* Write UPDPL2 to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_UPDATE_LV2_PROTECT); + } + + return status; +} + +/** + * @brief FC Update Remap Option + * @param UpdRemap New remap setting value (remap address=valus(0x0~0xf)*0x1000, 0x10=BootLoader) + * @retval Always return SUCCESS + */ +ErrorStatus md_fc_updremap(uint8_t UpdRemap) +{ + ErrorStatus status = SUCCESS; + + /* Write sector address to PA*/ + md_fc_enable_pa_ifren(); + md_fc_set_pa_prog_addr(EFOPT_PAGE7_OFFSET); + /* Write SERASE to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_SECTOR_ERASE); + /* Write remap offset address to PA*/ + md_fc_set_pa_prog_addr(EFOPT_REMAP_OFFSET); + md_fc_enable_pa_ifren(); + /* Write lower 32bit remap data to PLD*/ + md_fc_set_pld(0xffffff00UL | UpdRemap); + /* Write higher 32bit remap data to PHD*/ + md_fc_set_phd(0xffffffffUL); + /* Write PROGRAM to CMD*/ + md_fc_set_fc_cmd(MD_FC_PC_CMD_PROG_EFLASH); + + return status; +} + +/** + * @} MD_FC_Public_Functions + */ + +/** + * @} FC + */ +#endif + +/** + * @} Micro_Driver + */ + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_gpio.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_gpio.c new file mode 100644 index 0000000000..0fa1126bab --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_gpio.c @@ -0,0 +1,215 @@ +/** + ****************************************************************************** + * @file md_gpio.c + * @brief ES32F0271 GPIO Source File. + * + * @version V1.00.01 + * @data day/mon/year + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Includes -------------------------------------------------------------------*/ +#include "md_rcu.h" +#include "md_gpio.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) + +/** @defgroup GPIO GPIO + * @brief GPIO micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +/** @defgroup MD_GPIO_Private_Macros GPIO Private Macros + * @{ + */ +#define IS_MD_GPIO_ALL_INSTANCE(__INSTANCE__) ((__INSTANCE__ == GPIOA) \ + || (__INSTANCE__ == GPIOB)) \ +|| (__INSTANCE__ == GPIOC)) \ +|| (__INSTANCE__ == GPIOD)) + +#define IS_MD_GPIO_PIN(__VALUE__) (((__VALUE__) == MD_GPIO_PIN_0) \ + || ((__VALUE__) == MD_GPIO_PIN_1) \ + || ((__VALUE__) == MD_GPIO_PIN_2) \ + || ((__VALUE__) == MD_GPIO_PIN_3) \ + || ((__VALUE__) == MD_GPIO_PIN_4) \ + || ((__VALUE__) == MD_GPIO_PIN_5) \ + || ((__VALUE__) == MD_GPIO_PIN_6) \ + || ((__VALUE__) == MD_GPIO_PIN_7) \ + || ((__VALUE__) == MD_GPIO_PIN_8) \ + || ((__VALUE__) == MD_GPIO_PIN_9) \ + || ((__VALUE__) == MD_GPIO_PIN_10) \ + || ((__VALUE__) == MD_GPIO_PIN_11) \ + || ((__VALUE__) == MD_GPIO_PIN_12) \ + || ((__VALUE__) == MD_GPIO_PIN_13) \ + || ((__VALUE__) == MD_GPIO_PIN_14) \ + || ((__VALUE__) == MD_GPIO_PIN_15)) \ + +#define IS_MD_GPIO_MODE(__VALUE__) (((__VALUE__) == MD_GPIO_MODE_INPUT) \ + || ((__VALUE__) == MD_GPIO_MODE_OUTPUT) \ + || ((__VALUE__) == MD_GPIO_MODE_FUNCTION) \ + || ((__VALUE__) == MD_GPIO_MODE_ANALOG)) + +#define IS_MD_GPIO_OUTPUT_TYPE(__VALUE__) (((__VALUE__) == MD_GPIO_OUTPUT_PUSHPULL) \ + || ((__VALUE__) == MD_GPIO_OUTPUT_OPENDRAIN)) + +#define IS_MD_GPIO_PULL(__VALUE__) (((__VALUE__) == MD_GPIO_PULL_FLOATING) \ + || ((__VALUE__) == MD_GPIO_PULL_UP) \ + || ((__VALUE__) == MD_GPIO_PULL_DOWN) + +#define IS_MD_GPIO_DS(__VALUE__) (((__VALUE__) == MD_GPIO_DS_8mA) \ + || ((__VALUE__) == MD_GPIO_DS_16mA)) + +#define IS_MD_GPIO_FUNCTION(__VALUE__) (((__VALUE__) == MD_GPIO_AF0) \ + || ((__VALUE__) == MD_GPIO_AF1) \ + || ((__VALUE__) == MD_GPIO_AF2) \ + || ((__VALUE__) == MD_GPIO_AF3) \ + || ((__VALUE__) == MD_GPIO_AF4) \ + || ((__VALUE__) == MD_GPIO_AF5) \ + || ((__VALUE__) == MD_GPIO_AF6) \ + || ((__VALUE__) == MD_GPIO_AF7)) + +#define IS_MD_GPIO_IST(__VALUE__) (((__VALUE__) == MD_GPIO_IST_TTL) \ + || ((__VALUE__) == MD_GPIO_IST_CMOS)) + +/** + * @} MD_GPIO_Private_Macros + */ + +/* Private function prototypes ------------------------------------------------*/ + +/* Public functions -----------------------------------------------------------*/ +/** @addtogroup MD_GPIO_Public_Functions GPIO Public Functions + * @{ + */ + +/** @addtogroup MD_GPIO_PF_Init GPIO Public Init Functions + * @{ + */ + +/** + * @brief De-initialize the GPIO registers to their default reset values. + * @param GPIOx GPIO Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: GPIO registers are de-initialized + * - ERROR: GPIO registers are not de-initialized + */ +ErrorStatus md_gpio_deinit(GPIO_TypeDef *GPIOx) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_MD_GPIO_ALL_INSTANCE(GPIOx)); + + /* Force reset of GPIO clock */ + if (GPIOx == GPIOA) + { + md_rcu_enable_ahbrst_gpaen(RCU); + } + else if (GPIOx == GPIOB) + { + md_rcu_enable_ahbrst_gpben(RCU); + } + else if (GPIOx == GPIOC) + { + md_rcu_enable_ahbrst_gpcen(RCU); + } + else /* if(GPIOx==GPIOD) */ + { + md_rcu_enable_ahbrst_gpden(RCU); + } + + status = SUCCESS; + + return status; +} + +/** + * @brief Initialize the GPIO registers according to the specified parameters in GPIO_InitStruct. + * @note As some bits in GPIO configuration registers can only be written when the GPIO is disabled (GPIO_CR1_SPE bit =0), + * GPIO IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned. + * @param GPIOx GPIO Instance + * @param GPIO_InitStruct pointer to a @ref md_gpio_inittypedef structure + * @retval An ErrorStatus enumeration value. (Return always SUCCESS) + */ +ErrorStatus md_gpio_init(GPIO_TypeDef *GPIOx, md_gpio_inittypedef *GPIO_InitStruct) +{ + ErrorStatus status = ERROR; + + /* Check the GPIO Instance GPIOx*/ + assert_param(IS_MD_GPIO_ALL_INSTANCE(GPIOx)); + + /* Check the GPIO parameters from GPIO_InitStruct*/ + assert_param(IS_MD_GPIO_PIN(GPIO_InitStruct->Pin)); + assert_param(IS_MD_GPIO_MODE(GPIO_InitStruct->Mode)); + assert_param(IS_MD_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType)); + assert_param(IS_MD_GPIO_PULL(GPIO_InitStruct->Pull)); + assert_param(IS_MD_GPIO_DS(GPIO_InitStruct->OutDrive)); + assert_param(IS_MD_GPIO_FUNCTION(GPIO_InitStruct->Function)); + + if (POSITION_VAL(GPIO_InitStruct->Pin) <= 7) + { + md_gpio_set_function0_7(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->Function); + } + else + { + md_gpio_set_function8_15(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->Function); + } + + md_gpio_set_mode(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->Mode); + md_gpio_set_output_type(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->OutputType); + md_gpio_set_pull(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->Pull); + md_gpio_set_ds(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->OutDrive); + + status = SUCCESS; + + return status; +} + +/** + * @brief Set each @ref md_gpio_inittypedef field to default value. + * @param GPIO_InitStruct pointer to a @ref md_gpio_inittypedef structure + * whose fields will be set to default values. + * @retval None + */ +void md_gpio_struct_init(md_gpio_inittypedef *GPIO_InitStruct) +{ + /* Set GPIO_InitStruct fields to default values */ + GPIO_InitStruct->Function = MD_GPIO_AF0; + GPIO_InitStruct->Mode = MD_GPIO_MODE_ANALOG; + GPIO_InitStruct->OutDrive = MD_GPIO_DS_8mA; + GPIO_InitStruct->OutputType = MD_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct->Pull = MD_GPIO_PULL_FLOATING; + GPIO_InitStruct->Pin = MD_GPIO_PIN_ALL; +} + +/** + * @} MD_GPIO_PF_Init + */ + +/** + * @} MD_GPIO_Public_Functions + */ + +/** + * @} GPIO + */ +#endif + +/** + * @} Micro_Driver + */ + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_i2c.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_i2c.c new file mode 100644 index 0000000000..e2dab7dc57 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_i2c.c @@ -0,0 +1,245 @@ +/** + ****************************************************************************** + * @file md_i2c.c + * @brief ES32F0271 I2C Source File. + * + * @version V1.00.01 + * @date 4/12/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Includes -------------------------------------------------------------------*/ +#include "md_i2c.h" +#include "md_rcu.h" +#include +#include "stdint.h" +/** @addtogroup Micro_Driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/** + * @brief Initialize the I2C registers according to the specified parameters in I2C_InitStruct. + * @note The parameters in md_i2c_init should be expected values. Otherwise, ERROR result will be returned. + * @param I2Cx I2C Instance + * @param I2C_InitStruct pointer to a @ref md_i2c_inittypedef structure + * @retval An ErrorStatus enumeration value. (Return always SUCCESS) + */ +ErrorStatus md_i2c_init(I2C_TypeDef *I2Cx, md_i2c_inittypedef *I2C_InitStruct) +{ + ErrorStatus status = ERROR; + uint8_t pllmulnow; + + /* Check the I2C Instance I2Cx */ + assert_param(IS_MD_I2C_ALL_INSTANCE(I2Cx)); + + /* Check the I2C parameters from I2C_InitStruct */ + assert_param(IS_MD_I2C_TIMING(I2C_InitStruct->Timing)); + assert_param(IS_MD_I2C_ADDRSIZE(I2C_InitStruct->AddrSize)); + assert_param(IS_MD_I2C_ADDRESS1(I2C_InitStruct->Address1)); + assert_param(IS_MD_I2C_DUALADDRESSMODE(I2C_InitStruct->DualAddressMode)); + assert_param(IS_MD_I2C_ADDRESS2(I2C_InitStruct->Address2)); + assert_param(IS_MD_I2C_ADDRESS2MASKS(I2C_InitStruct->Address2Masks)); + /* Check the PLL clock, if not corrt, modify it */ + pllmulnow = md_rcu_get_cfg_pllmul(RCU); + + if (pllmulnow != (uint8_t)((I2C_InitStruct->Timing) >> 28)) + { + md_rcu_pllreinit((uint8_t)((I2C_InitStruct->Timing) >> 28)); + } + + md_i2c_disable_con1_pe(I2Cx); + md_i2c_set_timingr_presc(I2Cx, ((I2C_InitStruct->Timing) >> 24) & 0xF); + md_i2c_set_timingr_scll(I2Cx, ((I2C_InitStruct->Timing) >> 16) & 0xFF); + md_i2c_set_timingr_sclh(I2Cx, ((I2C_InitStruct->Timing) >> 8) & 0xFF); + md_i2c_set_timingr_sdadel(I2Cx, ((I2C_InitStruct->Timing) >> 4) & 0xF); + md_i2c_set_timingr_scldel(I2Cx, (I2C_InitStruct->Timing) & 0xF); + md_i2c_enable_con1_pe(I2Cx); + + md_i2c_disable_addr1_oa1en(I2Cx); + md_i2c_set_addr1_oa1(I2Cx, I2C_InitStruct->Address1); + + if (I2C_InitStruct->AddrSize == MD_I2C_OA1_10BIT) + md_i2c_set_addr1_oa1mode(I2Cx, MD_I2C_OA1_10BIT); + else + md_i2c_set_addr1_oa1mode(I2Cx, MD_I2C_OA1_7BIT); + + md_i2c_enable_addr1_oa1en(I2Cx); + + if (I2C_InitStruct->DualAddressMode == MD_I2C_DUALADDRESS_ENABLE) + { + md_i2c_disable_addr2_oa2en(I2Cx); + md_i2c_set_addr2_oa2mask(I2Cx, I2C_InitStruct->Address2Masks); + md_i2c_set_addr2_oa2(I2Cx, I2C_InitStruct->Address2); + md_i2c_enable_addr2_oa2en(I2Cx); + } + + status = SUCCESS; + + return status; +} + +/** + * @brief Set each @ref md_i2c_inittypedef field to default value. + * @param UART_InitStruct pointer to a @ref md_i2c_inittypedef structure + * whose fields will be set to default values. + * @retval None + */ +void md_i2c_struct_init(md_i2c_inittypedef *I2C_InitStruct) +{ + /* Set UART_InitStruct fields to default values */ + I2C_InitStruct->Timing = CLK100kHz48M; + I2C_InitStruct->AddrSize = MD_I2C_ADDRESSINGMODE_7BIT; + I2C_InitStruct->Address1 = 0x50 << 1; + I2C_InitStruct->DualAddressMode = MD_I2C_DUALADDRESS_DISABLE; + I2C_InitStruct->Address2 = 0x70 << 1; + I2C_InitStruct->Address2Masks = MD_I2C_ADDR2_NOMASK; +} + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param I2Cx I2C Instance + * @param The number of bytes to be transmitted + * @param Enable/Disable 10-bit addressing mode + * @param Device(slave) address + * @param The pointer to a data buffer + * @retval None + */ +void md_i2c_master_send(I2C_TypeDef *I2Cx, uint8_t Nbyte, uint32_t addr10, uint16_t DevAddr, uint8_t *txbuf) +{ + uint8_t index; + + /* Config Device(slave) address */ + if (addr10 == MD_I2C_ADDRESSINGMODE_10BIT) + md_i2c_set_con2_add10(I2Cx, MD_I2C_ADDRESSINGMODE_10BIT); + else + md_i2c_set_con2_add10(I2Cx, MD_I2C_ADDRESSINGMODE_7BIT); + + md_i2c_set_con2_sadd(I2Cx, DevAddr); + md_i2c_set_con2_nbytes(I2Cx, Nbyte); + md_i2c_set_fcon_txfrst(I2Cx, MD_I2C_TXFIFO_RESET); + md_i2c_set_con2_rd_wrn(I2Cx, MD_I2C_MASTER_WRITE); + md_i2c_set_con2_reload(I2Cx, MD_I2C_NORELOAD_MODE); + /* When NBYTES is matched, the communication will be automatically stop */ + md_i2c_set_con2_autoend(I2Cx, MD_I2C_AUTOEND_MODE); + + if (Nbyte <= 8) + { + for (index = 0; index < Nbyte; index++) + md_i2c_send(I2Cx, *txbuf++); + + Nbyte = 0; + } + else + { + for (index = 0; index < 8; index++) + md_i2c_send(I2Cx, *txbuf++); + + Nbyte -= 8; + } + + /* Start the I2C communication */ + md_i2c_set_con2_start(I2Cx, MD_I2C_START_GENERATION); + + while (Nbyte > 0) + { + while (md_i2c_is_active_stat_txf(I2Cx)); + + md_i2c_send(I2Cx, *txbuf++); + Nbyte--; + } +} + +/** + * @brief Receives in master mode an amount of data in blocking mode. + * @param I2Cx I2C Instance + * @param The number of bytes to be received + * @param Enable/Disable 10-bit addressing mode + * @param Device(slave) address + * @param The pointer to a data buffer + * @retval None + */ +void md_i2c_master_rece(I2C_TypeDef *I2Cx, uint8_t Nbyte, uint32_t addr10, uint16_t DevAddr, uint8_t *rxbuf) +{ + /* Config Device(slave) address */ + if (addr10 == MD_I2C_ADDRESSINGMODE_10BIT) + md_i2c_set_con2_add10(I2Cx, MD_I2C_ADDRESSINGMODE_10BIT); + else + md_i2c_set_con2_add10(I2Cx, MD_I2C_ADDRESSINGMODE_7BIT); + + md_i2c_set_con2_sadd(I2Cx, DevAddr); + md_i2c_set_con2_nbytes(I2Cx, Nbyte); + md_i2c_set_fcon_rxfrst(I2Cx, MD_I2C_RXFIFO_RESET); + md_i2c_set_con2_rd_wrn(I2Cx, MD_I2C_MASTER_READ); + md_i2c_set_con2_reload(I2Cx, MD_I2C_NORELOAD_MODE); + /* When NBYTES is matched, the communication will be automatically stop */ + md_i2c_set_con2_autoend(I2Cx, MD_I2C_AUTOEND_MODE); + /* Start the I2C communication */ + md_i2c_set_con2_start(I2Cx, MD_I2C_START_GENERATION); + + while (Nbyte > 0) + { + /* Wait Rx FIFO non-empty */ + while (md_i2c_is_active_stat_rxe(I2Cx)); + + *rxbuf++ = md_i2c_recv(I2Cx); + Nbyte--; + } +} + +/** + * @brief Transmits in slave mode an amount of data in blocking mode. + * @param I2Cx I2C Instance + * @param The number of bytes to be transmitted, not for NBYTES + * @param The pointer to a data buffer + * @retval None + */ +void md_i2c_slave_send(I2C_TypeDef *I2Cx, uint8_t Num, uint8_t *txbuf) +{ + md_i2c_set_fcon_txfrst(I2Cx, MD_I2C_TXFIFO_RESET); + + while (!(md_i2c_is_active_stat_busy(I2Cx))); + + while (Num > 0) + { + while (md_i2c_is_active_stat_txf(I2Cx)); + + md_i2c_send(I2Cx, *txbuf++); + Num--; + } +} + +/** + * @brief Receives in slave mode an amount of data in blocking mode. + * @param I2Cx I2C Instance + * @param The number of bytes to be transmitted, not for NBYTES + * @param The pointer to a data buffer + * @retval None + */ +void md_i2c_slave_rece(I2C_TypeDef *I2Cx, uint8_t Num, uint8_t *rxbuf) +{ + md_i2c_set_fcon_rxfrst(I2Cx, MD_I2C_RXFIFO_RESET); + + while (!(md_i2c_is_active_stat_busy(I2Cx))); + + while (Num > 0) + { + while (md_i2c_is_active_stat_rxe(I2Cx)); + + *rxbuf++ = md_i2c_recv(I2Cx); + Num--; + } +} + +/** + * @} Micro_Driver + */ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_rcu.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_rcu.c new file mode 100644 index 0000000000..99ac22cf91 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_rcu.c @@ -0,0 +1,378 @@ +/** + ****************************************************************************** + * @file md_rcu.c + * @brief ES32F0271 RCU Source File. + * + * @version V1.00.01 + * @data 6/12/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Includes -------------------------------------------------------------------*/ +#include "md_rcu.h" +#include "md_fc.h" +#include "system_es32f027x.h" + +/** @addtogroup Micro_Driver + * @{ + */ + + +/** @defgroup RCU RCU + * @brief RCU micro driver + * @{ + */ + + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +/** @defgroup MD_RCU_Private_Macros RCU Private Macros + * @{ + */ + + +/** + * @} MD_RCU_Private_Macros + */ + +/* Private function prototypes ------------------------------------------------*/ + +/* Public functions -----------------------------------------------------------*/ +/** @addtogroup MD_RCU_Public_Functions RCU Public Functions + * @{ + */ + +/** @addtogroup MD_RCU_PF_Init RCU Public Init Functions + * @{ + */ + +/** + * @brief + * @param + * @retval None + */ +void md_rcu_init(void) +{ + uint8_t pllmux; + + md_fc_set_con_wait(3); + + md_rcu_set_cfg_mpre(RCU, 0UL); + md_rcu_set_cfg_msw(RCU, MD_RCU_MCO_DISABLE); + md_rcu_set_cfg_pllmul(RCU, 12 - 1); + md_rcu_set_cfg_pllsrc(RCU, MD_RCU_PLL_SRC_HRC); + md_rcu_set_cfg_hoscdiv(RCU, 2 - 1); + md_rcu_set_cfg_ppre(RCU, MD_RCU_PPRE_HCLK_DIV_1); + md_rcu_set_cfg_hpre(RCU, MD_RCU_HPRE_SYSCLK_DIV_1); + md_rcu_set_cfg_sw(RCU, MD_RCU_SYSCLK_PLL0); + + md_rcu_disable_con_csson(RCU); + md_rcu_disable_con_pll1on(RCU); + md_rcu_enable_con_pll0on(RCU); + md_rcu_disable_con_loscon(RCU); + md_rcu_disable_con_lrcon(RCU); + md_rcu_disable_con_hoscon(RCU); + md_rcu_enable_con_hrcon(RCU); + + md_rcu_set_cfg_ckcfg(RCU); + + /* while(md_rcu_get_con_hoscrdy(RCU)==0) {} */ + + /* while(md_rcu_get_con_pll0rdy(RCU)==0) {} */ + + + if (RCU->CON & RCU_CON_HRCON_MSK) /* if HRC enbale */ + while (md_rcu_get_con_hrcrdy(RCU) == 0); /* Wait for HRCRDY = 1 (HRC is ready)*/ + + + if (RCU->CON & RCU_CON_HOSCON_MSK) /* if HOSC enbale */ + while (md_rcu_get_con_hoscrdy(RCU) == 0); /* Wait for HOSCRDY = 1 (HOSC is ready)*/ + + + if (RCU->CON & RCU_CON_LRCON_MSK) /* if LRC enbale */ + while (md_rcu_get_con_lrcrdy(RCU) == 0); /* Wait for LRCRDY = 1 (LRC is ready)*/ + + + if (RCU->CON & RCU_CON_LOSCON_MSK) /* if LOSC enbale */ + while (md_rcu_get_con_loscrdy(RCU) == 0); /* Wait for LOSCRDY = 1 (LOSC is ready)*/ + + if (RCU->CON & RCU_CON_PLL0ON_MSK) /* if PLL enbale */ + while (md_rcu_get_con_pll0rdy(RCU) == 0); /* Wait for PLLRDY = 1 (PLL is ready)*/ + + + + /* PLL Reference Clock Source*/ + if (md_rcu_get_cfg_pllsrc(RCU)) + PLL0Frequency = (uint32_t)(__HOSC / (md_rcu_get_cfg_pllsrc(RCU) + 1)); + else + PLL0Frequency = (uint32_t)(__HRC); + + /* System Frequency */ + switch (md_rcu_get_cfg_sw(RCU)) /* System clock switch(SYSCLK) */ + { + case 0: /*================= HRC selected as system clock*/ + SystemCoreClock = (uint32_t)(__HRC); + break; + + case 1: /*================= HOSC selected as system clock*/ + SystemCoreClock = (uint32_t)(__HOSC); + break; + + case 2: /*================= LRC selected as system clock*/ + SystemCoreClock = (uint32_t)(__LRC); + break; + + case 3: /*================= LOSC selected as system clock*/ + SystemCoreClock = (uint32_t)(__LOSC); + break; + + case 4: /*================= PLL selected as system clock*/ + pllmux = md_rcu_get_cfg_pllmul(RCU) + 1; + + if (pllmux >= 18) pllmux = 18; + + SystemCoreClock = (uint32_t)(PLL0Frequency * pllmux); + break; + + default: + SystemCoreClock = (uint32_t)(__HRC); + break; + } + + /* Core Frequency */ + if (md_rcu_get_cfg_hpre(RCU)) + SystemFrequency_SysClk = SystemCoreClock >> ((md_rcu_get_cfg_hpre(RCU) & 0x07) + 1); + else + SystemFrequency_SysClk = SystemCoreClock; + + /* AHB Frequency */ + SystemFrequency_AHBClk = SystemFrequency_SysClk; + + /* APB Frequency */ + if (md_rcu_get_cfg_ppre(RCU)) + SystemFrequency_APBClk = SystemFrequency_SysClk >> ((md_rcu_get_cfg_ppre(RCU) & 0x03) + 1); + else + SystemFrequency_APBClk = SystemFrequency_SysClk; + + + if (SystemFrequency_AHBClk / 1000000 > 72) + md_fc_set_con_wait(3); + else if (SystemFrequency_AHBClk / 1000000 > 48) + md_fc_set_con_wait(2); + else if (SystemFrequency_AHBClk / 1000000 > 24) + md_fc_set_con_wait(1); + else + md_fc_set_con_wait(0); +} + +void md_rcu_init_set(RCU_TypeDef *rcu, md_rcu_init_typedef *RCU_InitStruct) +{ + uint8_t pllmux; + + md_fc_set_con_wait(3); + + md_rcu_set_cfg_mpre(rcu, RCU_InitStruct->Mpre); + md_rcu_set_cfg_msw(rcu, RCU_InitStruct->Msw); + md_rcu_set_cfg_pllmul(rcu, (RCU_InitStruct->PllMul) - 1); + md_rcu_set_cfg_pllsrc(rcu, RCU_InitStruct->PllSrc); + md_rcu_set_cfg_hoscdiv(rcu, (RCU_InitStruct->HoscDiv) - 1); + md_rcu_set_cfg_ppre(rcu, RCU_InitStruct->Ppre); + md_rcu_set_cfg_hpre(rcu, RCU_InitStruct->Hpre); + md_rcu_set_cfg_sw(rcu, RCU_InitStruct->Sw); + + if(RCU_InitStruct->SysClock & RCU_CON_CSSON_MSK) + md_rcu_enable_con_csson(rcu); + else + md_rcu_disable_con_csson(rcu); + + if(RCU_InitStruct->SysClock & RCU_CON_PLL1ON_MSK) + md_rcu_enable_con_pll1on(rcu); + else + md_rcu_disable_con_pll1on(rcu); + + if(RCU_InitStruct->SysClock & RCU_CON_PLL0ON_MSK) + md_rcu_enable_con_pll0on(rcu); + else + md_rcu_disable_con_pll0on(rcu); + + if(RCU_InitStruct->SysClock & RCU_CON_LOSCON_MSK) + md_rcu_enable_con_loscon(rcu); + else + md_rcu_disable_con_loscon(rcu); + + if(RCU_InitStruct->SysClock & RCU_CON_LRCON_MSK) + md_rcu_enable_con_lrcon(rcu); + else + md_rcu_disable_con_lrcon(rcu); + + if(RCU_InitStruct->SysClock & RCU_CON_HOSCON_MSK) + md_rcu_enable_con_hoscon(rcu); + else + md_rcu_disable_con_hoscon(rcu); + + if(RCU_InitStruct->SysClock & RCU_CON_HRCON_MSK) + md_rcu_enable_con_hrcon(rcu); + else + md_rcu_disable_con_hrcon(rcu); + + md_rcu_set_cfg_ckcfg(rcu); + + /* while(md_rcu_get_con_hoscrdy(RCU)==0) {} */ + + /* while(md_rcu_get_con_pll0rdy(RCU)==0) {} */ + + + if (RCU->CON & RCU_CON_HRCON_MSK) /* if HRC enbale */ + while (md_rcu_get_con_hrcrdy(rcu) == 0); /* Wait for HRCRDY = 1 (HRC is ready)*/ + + + if (RCU->CON & RCU_CON_HOSCON_MSK) /* if HOSC enbale */ + while (md_rcu_get_con_hoscrdy(rcu) == 0); /* Wait for HOSCRDY = 1 (HOSC is ready)*/ + + + if (RCU->CON & RCU_CON_LRCON_MSK) /* if LRC enbale */ + while (md_rcu_get_con_lrcrdy(rcu) == 0); /* Wait for LRCRDY = 1 (LRC is ready)*/ + + + if (RCU->CON & RCU_CON_LOSCON_MSK) /* if LOSC enbale */ + while (md_rcu_get_con_loscrdy(rcu) == 0); /* Wait for LOSCRDY = 1 (LOSC is ready)*/ + + if (RCU->CON & RCU_CON_PLL0ON_MSK) /* if PLL enbale */ + while (md_rcu_get_con_pll0rdy(rcu) == 0); /* Wait for PLLRDY = 1 (PLL is ready)*/ + + + + /* PLL Reference Clock Source*/ + if (md_rcu_get_cfg_pllsrc(rcu)) + PLL0Frequency = (uint32_t)(__HOSC / (md_rcu_get_cfg_pllsrc(rcu) + 1)); + else + PLL0Frequency = (uint32_t)(__HRC); + + /* System Frequency */ + switch (md_rcu_get_cfg_sw(rcu)) /* System clock switch(SYSCLK) */ + { + case 0: /*================= HRC selected as system clock*/ + SystemCoreClock = (uint32_t)(__HRC); + break; + + case 1: /*================= HOSC selected as system clock*/ + SystemCoreClock = (uint32_t)(__HOSC); + break; + + case 2: /*================= LRC selected as system clock*/ + SystemCoreClock = (uint32_t)(__LRC); + break; + + case 3: /*================= LOSC selected as system clock*/ + SystemCoreClock = (uint32_t)(__LOSC); + break; + + case 4: /*================= PLL selected as system clock*/ + pllmux = md_rcu_get_cfg_pllmul(rcu) + 1; + + if (pllmux >= 18) pllmux = 18; + + SystemCoreClock = (uint32_t)(PLL0Frequency * pllmux); + break; + + default: + SystemCoreClock = (uint32_t)(__HRC); + break; + } + + /* Core Frequency */ + if (md_rcu_get_cfg_hpre(rcu)) + SystemFrequency_SysClk = SystemCoreClock >> ((md_rcu_get_cfg_hpre(rcu) & 0x07) + 1); + else + SystemFrequency_SysClk = SystemCoreClock; + + /* AHB Frequency */ + SystemFrequency_AHBClk = SystemFrequency_SysClk; + + /* APB Frequency */ + if (md_rcu_get_cfg_ppre(rcu)) + SystemFrequency_APBClk = SystemFrequency_SysClk >> ((md_rcu_get_cfg_ppre(rcu) & 0x03) + 1); + else + SystemFrequency_APBClk = SystemFrequency_SysClk; + + + if (SystemFrequency_AHBClk / 1000000 > 72) + md_fc_set_con_wait(3); + else if (SystemFrequency_AHBClk / 1000000 > 48) + md_fc_set_con_wait(2); + else if (SystemFrequency_AHBClk / 1000000 > 24) + md_fc_set_con_wait(1); + else + md_fc_set_con_wait(0); +} + + +/** + * @brief + * @param + * @retval None + */ +void md_rcu_pllreinit(uint8_t pllmul) +{ + md_rcu_set_cfg_pllmul(RCU, pllmul); + md_rcu_set_cfg_ckcfg(RCU); + + /* PLL Reference Clock Source */ + if (md_rcu_get_cfg_pllsrc(RCU)) + PLL0Frequency = (uint32_t)(__HOSC / (md_rcu_get_cfg_pllsrc(RCU) + 1)); + else + PLL0Frequency = (uint32_t)(__HRC); + + SystemCoreClock = (uint32_t)(PLL0Frequency * (pllmul + 1)); + + /* Core Frequency */ + if (md_rcu_get_cfg_hpre(RCU)) + SystemFrequency_SysClk = SystemCoreClock >> ((md_rcu_get_cfg_hpre(RCU) & 0x07) + 1); + else + SystemFrequency_SysClk = SystemCoreClock; + + /* AHB Frequency */ + SystemFrequency_AHBClk = SystemFrequency_SysClk; + + /* APB Frequency */ + if (md_rcu_get_cfg_ppre(RCU)) + SystemFrequency_APBClk = SystemFrequency_SysClk >> ((md_rcu_get_cfg_ppre(RCU) & 0x03) + 1); + else + SystemFrequency_APBClk = SystemFrequency_SysClk; + + md_fc_set_con_wait(3); + + if (SystemFrequency_AHBClk / 1000000 > 72) + md_fc_set_con_wait(3); + else if (SystemFrequency_AHBClk / 1000000 > 48) + md_fc_set_con_wait(2); + else if (SystemFrequency_AHBClk / 1000000 > 24) + md_fc_set_con_wait(1); + else + md_fc_set_con_wait(0); +} + +/** + * @} MD_RCU_PF_Init + */ + +/** + * @} MD_RCU_Public_Functions + */ + +/** + * @} RCU + */ + +/** + * @} Micro_Driver + */ + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_spi.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_spi.c new file mode 100644 index 0000000000..c29bb54be6 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_spi.c @@ -0,0 +1,108 @@ +/** + ****************************************************************************** + * @file md_spi.c + * @brief ES32F0271 I2C Source File. + * + * @version V1.00.01 + * @date 4/12/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Includes -------------------------------------------------------------------*/ +#include "md_spi.h" +#include "md_rcu.h" +#include +#include "stdint.h" +/** @addtogroup Micro_Driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/** + * @brief Initialize the SPI registers according to the specified parameters in SPI_initStruct. + * @note The parameters in md_spi_init should be expected values. Otherwise, ERROR result will be returned. + * @param SPIx SPI Instance + * @param SPI_initStruct pointer to a @ref SPI_initStruct structure + * @retval An ErrorStatus enumeration value. (Return always SUCCESS) + */ +void md_spi_struct_init(md_spi_inittypedef *SPI_initStruct) +{ + SPI_initStruct->Mode = MD_SPI_MODE_MASTER; + SPI_initStruct->ClockPhase = MD_SPI_PHASE_1EDGE; + SPI_initStruct->ClockPolarity = MD_SPI_POLARITY_LOW; + SPI_initStruct->BaudRate = MD_SPI_BAUDRATEPRESCALER_DIV256; + SPI_initStruct->BitOrder = MD_SPI_MSB_FIRST; + SPI_initStruct->TransferDirection = MD_SPI_FULL_DUPLEX; + SPI_initStruct->DataWidth = MD_SPI_FRAME_FORMAT_8BIT; + SPI_initStruct->CRCCalculation = MD_SPI_CRCCALCULATION_DISABLE; + SPI_initStruct->CRCPoly = 0x7; + SPI_initStruct->NSS = MD_SPI_NSS_HARD; +} + +/** + * @brief Initialize the SPI registers according to the specified parameters in SPI_initStruct. + * @note The parameters in md_i2c_init should be expected values. Otherwise, ERROR result will be returned. + * @param SPIx SPI Instance + * @param SPI_initStruct pointer to a @ref SPI_initStruct structure + * @retval An ErrorStatus enumeration value. (Return always SUCCESS) + */ +ErrorStatus md_spi_init(SPI_TypeDef *SPIx, md_spi_inittypedef *SPI_InitStruct) +{ + ErrorStatus status = ERROR; + + md_spi_disable_con1_spien(SPIx); + + md_spi_set_con1_mstren(SPIx, SPI_InitStruct->Mode); + md_spi_set_con1_cpha(SPIx, SPI_InitStruct->ClockPhase); + md_spi_set_con1_cpol(SPIx, SPI_InitStruct->ClockPolarity); + md_spi_set_con1_baud(SPIx, SPI_InitStruct->BaudRate); + md_spi_set_con1_lsbfirst(SPIx, SPI_InitStruct->BitOrder); + md_spi_set_con1_bidimode(SPIx, SPI_InitStruct->TransferDirection); + md_spi_set_con1_ssout(SPIx, SPI_InitStruct->NSS); + md_spi_enable_con2_ssoe(SPIx); + + md_spi_enable_con1_spien(SPIx); + + status = SUCCESS; + + return status; +} + +/** + * @brief use to receive single one byte data. + * @note SPI Slave receive data + * @param SPIx SPI Instance + */ +uint8_t SPISSingleRd(SPI_TypeDef *SPIx) +{ + while (md_spi_is_active_flag_stat_rxe(SPIx)); + + return (md_spi_recv_data8(SPIx)); +} + + +/** + * @brief use to send single one byte data. + * @note SPI receive data + * @param SPIx SPI Instance + * @param data SPI send one byte data. + */ +void SPISingleWr(SPI_TypeDef *SPIx, uint8_t data) +{ + while (md_spi_is_active_flag_stat_txf(SPIx)); + + md_spi_send_data8(SPIx, data); +} + +/** + * @} Micro_Driver + */ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_tick.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_tick.c new file mode 100644 index 0000000000..f1420c6eb3 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_tick.c @@ -0,0 +1,207 @@ +/** + ****************************************************************************** + * @file md_tick.c + * @brief ES32F0271 TICK Source File. + * + * @version V1.00.01 + * @date day/mon/year + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ******************************************************************************* + */ + +/* Includes -------------------------------------------------------------------*/ +#include "md_rcu.h" +#include "md_tick.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (TICK) + +/** @addtogroup TICK TICK + * @brief TICK micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Private function prototypes ------------------------------------------------*/ + +#define HDIVON 0 + +/* Private variables ----------------------------------------------------------*/ +/** @defgroup MD_TICK_Private_Variables TICK Private Variables + * @{ + */ +static uint32_t TICKms; +static uint32_t TICK100us; +static uint32_t TICK10us; + +/** + * @} MD_TICK_Private_Variables + */ +/* Public functions -----------------------------------------------------------*/ +/** @defgroup MD_TICK_Public_Functions TICK Public Functions + * @{ + */ + +/** + * @brief Tick Initialization + * @note This function set the maximun load and enable TICK counter + * @note This function also calculate ms, 100us ans 10us counter + * @param None + * @retval None + */ +void md_tick_init(void) +{ +#if HDIVON + HDIV->DIVIDEND = SystemFrequency_SysClk; + HDIV->DIVISOR = 1000; + TICKms = HDIV->QUOTIENT; + HDIV->DIVISOR = 10000; + TICK100us = HDIV->QUOTIENT; + HDIV->DIVISOR = 100000; + TICK10us = HDIV->QUOTIENT; +#else + TICKms = SystemFrequency_SysClk / 1000; + TICK100us = SystemFrequency_SysClk / 10000; + TICK10us = SystemFrequency_SysClk / 100000; +#endif + + md_tick_set_rvr_reload((1 << 24) - 1); /* Maximun ReLoad */ + md_tick_set_cvr_current(0); /* Reset CVR */ + md_tick_set_csr_clksource(1); /* MCU Clock */ + md_tick_enable_csr_enable(); /* Counter Enable */ +} + +/** + * @brief Retrive the TICK counter and converted to millisecond + * @param None + * @retval The ms value converted by TICK counter + */ +uint32_t md_tick_get_mscnt(void) +{ +#if HDIVON + HDIV->DIVIDEND = md_tick_get_cvr_current(); + HDIV->DIVISOR = TICKms; + return (HDIV->QUOTIENT); +#else + return (md_tick_get_cvr_current() / TICKms); +#endif +} + +/** + * @brief Retrive the TICK counter and converted to 100 microseconds + * @param None + * @retval The 100 microseconds value converted by TICK counter + */ +uint32_t md_tick_get_100uscnt(void) +{ +#if HDIVON + HDIV->DIVIDEND = md_tick_get_cvr_current(); + HDIV->DIVISOR = TICK100us; + return (HDIV->QUOTIENT); +#else + return (md_tick_get_cvr_current() / TICK100us); +#endif +} + +/** + * @brief Retrive the TICK counter and converted to 10 microseconds + * @param None + * @retval The 10 microseconds value converted by TICK counter + */ +uint32_t md_tick_get_10uscnt(void) +{ +#if HDIVON + HDIV->DIVIDEND = md_tick_get_cvr_current(); + HDIV->DIVISOR = TICK10us; + return (HDIV->QUOTIENT); +#else + return (md_tick_get_cvr_current() / TICK10us); +#endif +} + +/** + * @brief Delay based on milliseconds + * @param Unit The number of ms in one delay period + * @param msCnt The counter of delay period + * @etVal None + */ +void md_tick_waitms(uint8_t Unit, uint16_t msCnt) +{ + uint32_t mstime; + + mstime = (1 << 24) - (Unit * TICKms); + + while (msCnt--) + { + md_tick_set_cvr_current((1 << 24) - 1); /* Reset CVR */ + + while (md_tick_get_cvr_current() > mstime); + } +} + +/** + * @brief Delay based on 100 microseconds + * @param Unit The number of 100 microseconds in one delay period + * @param msCnt The counter of delay period + * @etVal None + */ +void md_tick_wait100us(uint16_t Unit, uint16_t usCnt) +{ + uint32_t ustime; + + ustime = (1 << 24) - (Unit * TICK100us); + + while (usCnt--) + { + md_tick_set_cvr_current((1 << 24) - 1); /* Reset CVR */ + + while (md_tick_get_cvr_current() > ustime); + } +} + +/** + * @brief Delay based on 10 microseconds + * @param Unit The number of 10 microseconds in one delay period + * @param msCnt The counter of delay period + * @etVal None + */ +void md_tick_wait10us(uint16_t Unit, uint16_t usCnt) +{ + uint32_t ustime; + + ustime = (1 << 24) - (Unit * TICK10us); + + while (usCnt--) + { + md_tick_set_cvr_current((1 << 24) - 1); /* Reset CVR */ + + while (md_tick_get_cvr_current() > ustime); + } +} + + +/** + * @} MD_TICK_Public_Functions + */ + +/** + * @} TICK + */ +#endif + +/** + * @} Micro_Driver + */ + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_uart.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_uart.c new file mode 100644 index 0000000000..5ec9ccf3af --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_uart.c @@ -0,0 +1,127 @@ +/** + ****************************************************************************** + * @file md_uart.c + * @brief ES32F0271 UART Source File. + * + * @version V1.00.01 + * @date 04/12/2018 + * @author Eastsoft AE Team + * @note UART Public Functions + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Includes -------------------------------------------------------------------*/ +#include "system_es32f027x.h" +#include "md_uart.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +/** @defgroup UART UART + * @brief UART micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ +/* Private function prototypes ------------------------------------------------*/ + +/* Public functions -----------------------------------------------------------*/ + +/** @defgroup UART_PUB_FUNC UART Public Functions + * @brief UART Public Functions + * @{ + */ +/** + * @brief Set UART1 baudrate. + * @param UARTx UART Instance. + * @param Baudrate + * @retval None. + */ +void md_uart_set_baudrate(UART_TypeDef *UARTx, uint32_t baudrate) +{ + uint32_t brr; + brr = ((SystemFrequency_APBClk + (baudrate >> 1)) / baudrate); + md_uart_set_brr(UARTx, brr); +} + +/** + * @brief UART Initialization + * @param UART Init Structure + * @retval None + */ +void md_uart_init(UART_TypeDef *UARTx, md_uart_init_typedef *UART_InitStruct) +{ + /* Check the UART_InitStruct */ + assert_param((UART_InitStruct != NULL)); + + md_uart_set_baudrate(UARTx, MD_UART_BAUDRATE_115200); + md_uart_disable_lcon_txen(UARTx); + md_uart_disable_lcon_rxen(UARTx); + md_uart_set_lcon_dls(UARTx, UART_InitStruct->DataWidth); + md_uart_set_lcon_stop(UARTx, UART_InitStruct->StopBits); + md_uart_set_lcon_ps(UARTx, UART_InitStruct->Parity); + md_uart_enable_lcon_pe(UARTx); + md_uart_set_fcon_tfrst(UARTx); + md_uart_set_fcon_rfrst(UARTx); + md_uart_enable_lcon_txen(UARTx); + md_uart_enable_lcon_rxen(UARTx); +} + +/** + * @brief UART1 send character + * @param Character + * @retval None + */ +void md_uart_send(UART_TypeDef *UARTx, uint8_t ch) +{ + while (md_uart_is_active_flag_stat_tffull(UARTx)); // Tx FIFO full + + md_uart_send_txbuf(UART1, ch); // Sent byte +} + +/** + * @brief UART1 receive character. + * @param UART_TypeDef *UARTx. + * @retval unsigned char. + */ +uint8_t md_uart_recv(UART_TypeDef *UARTx) +{ + while (md_uart_is_active_flag_stat_rfempty(UART1)); // Rx FIFO empty + + return (md_uart_get_rxbuf(UART1)); +} + +/** + * @brief Get UARTx baudrate. + * @param UART_TypeDef *UARTx. + * @retval Baudrate. + */ +uint32_t md_uart_get_baudrate(UART_TypeDef *UARTx) +{ + uint32_t brr, baudrate; + + brr = md_uart_get_brr(UARTx); + baudrate = SystemFrequency_APBClk / brr; + return baudrate; +} + + +/** + * @} UART_PUB_FUNC UART Public Functions + */ + +/** + * @} UART + */ + +/** + * @} Micro_Driver + */ + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_usb.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_usb.c new file mode 100644 index 0000000000..b3ae9ce6d5 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_usb.c @@ -0,0 +1,3804 @@ +/** + ************************************************************************************** + * @file md_usb.c + * @brief USB Source File of MD Library. + * @data 03/12/2018 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ************************************************************************************** + */ + +/* Incudes -------------------------------------------------------------------*/ +#include "es32f0271.h" +#include "stdint.h" +#include +#include "usblib\drivers\usb_lowlayer_api.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (USB) + +/** @defgroup USB USB + * @brief USB micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +#define INTERRUPT_MASK_HOST 0x7e +#define INTERRUPT_MASK_DEV 0x6f + +/* Private macros -------------------------------------------------------------*/ +/* Private function prototypes ------------------------------------------------*/ + +/* Public functions -----------------------------------------------------------*/ +/** @addtogroup USB_MD_Public_Functions USB Public Functions + * @{ + */ + +/** @addtogroup USB_MD_PF_SYS USB Public System Functions + * @{ + */ + +/** + * @brief Mask all interrupts except NMI and Hardfault. + * @param None. + * @retval None. + */ +void md_usb_system_int_disable(void) +{ + __set_PRIMASK(1); +} + +/** + * @brief Enable all interrupts. + * @param None. + * @retval None. + */ +void md_usb_system_int_enable(void) +{ + __set_PRIMASK(0); +} + +/** + * @brief Reconfig USB. + * + * This config USB clock to xx MHz as the default configuration. + * If user want to change the clock,just redefine the + * md_usb_re_config() function. + * @param Device Chose device is in device mode or host mode. + * @retval None. + */ +__weak void md_usb_re_config(bool Device) +{ + // + // Config FIFO size of endpoint 0. + // No configuration required for ES32F0271. + // + + // + // For ES32F0271,full-speed is supported in device mode, + // Both full-speeed and low-speed is supported in host mode. + // + if (Device == true) + { + // + // DP pin pull up, in full-speed mode. + // + USB->DPDMCTRL |= (0X01 << USB_DPDMCTL_DPPUD_POSS); + + // + // Enable CID hardware control. + // + USB->SWCID &= ~USB_SWCID_CIDCTRL_MSK; + } + else + { + // + // DM\DP pin pull down, in host mode. + // Connect USN PHY power. + // + USB->DPDMCTRL = (0X02 << USB_DPDMCTL_DPPUD_POSS) | + (0X02 << USB_DPDMCTL_DMPUD_POSS) | + (USB_DPDMCTL_PHYPWREN_MSK); + // + // Enable CID hardware control. + // + USB->SWCID &= ~USB_SWCID_HOST_MSK; + + // + // Enable CID hardware control. + // + USB->SWCID &= ~USB_SWCID_CIDCTRL_MSK; + } +} + +/** + * @brief Delay ticks ms. + * @param ticks The delay ticks. + * @retval None. + */ +__weak void md_usb_system_delayms(uint32_t ticks) +{ + +} + +/** + * @brief Disable systic. + * @param None. + * @retval None. + */ +void md_usb_systic_disable(void) +{ + SysTick->CTRL &= (~SysTick_CTRL_ENABLE_Msk); +} + +/** + * @brief Reset colck of USB controller. + * @param None. + * @retval None. + */ +void md_usb_controller_reset(void) +{ + RCU->AHBRST |= RCU_AHBRST_USBEN_MSK; + RCU->AHBRST &= ~RCU_AHBRST_USBEN_MSK; +} + +/** + * @brief Enable colck of USB controller. + * @param None. + * @retval None. + */ +void md_usb_controller_enable(void) +{ + RCU->AHBEN |= RCU_AHBEN_USBEN_MSK; +} + +/** + * @brief Disable colck of USB controller. + * @param None. + * @retval None. + */ +void md_usb_controller_disable(void) +{ + RCU->AHBEN &= ~RCU_AHBEN_USBEN_MSK; +} + +/** + * @brief Enable phy colck of USB controller. + * + * This function enables clock of USB.To use USB,first, + * open its clock,then enable USB peripheral by clock + * clock manage peripheral. + * + * @param None. + * @retval None. + */ +void md_usb_clk_phy_enable(void) +{ + // + // Make sure the PLL1 has not been enabled. + // + if ((RCU->CON & RCU_CON_PLL1RDY_MSK) + && (RCU->CON & RCU_CON_PLL1ON_MSK)) + { + return; + } + + // + //Open PLL1 and wait it is ready. + // + RCU->CON |= RCU_CON_PLL1ON_MSK; + + while ((RCU->CON & RCU_CON_PLL1RDY_MSK) == 0); +} + +/** + * @brief Disable phy colck of USB controller. + * @param None. + * @retval None. + */ +void md_usb_clk_phy_disable(void) +{ + // + // Close PLL1. + // + RCU->CON &= ~RCU_CON_PLL1ON_MSK; +} + +/** + * @brief Get the USB interrupt number of NVIC. + * @param None. + * @retval None. + */ +uint32_t md_usb_nvic_number_get(void) +{ + return (uint32_t)USB_IRQn; +} + +/** + * @brief Config the USB interrupt of NVIC. + * @note The default priority is 1. + * @param None. + * @retval None. + */ +__weak void md_usb_nvic_config(uint32_t NvicNum) +{ + NVIC_SetPriority((IRQn_Type)NvicNum, 1); +} + +/** + * @brief Enable the USB interrupt of NVIC. + * @param None. + * @retval None. + */ +void md_usb_nvic_enable(void) +{ + NVIC_EnableIRQ((IRQn_Type)USB_IRQn); +} + +/** + * @brief Disable the USB interrupt of NVIC. + * @param None. + * @retval None. + */ +void md_usb_nvic_disable(void) +{ + NVIC_DisableIRQ((IRQn_Type)USB_IRQn); +} + +/** + * @} USB_MD_PF_SYS + */ + +/** @addtogroup USB_MD_PF_BASIC USB Public Basic Functions + * @{ + */ + +/** + * @brief Handles the USB bus reset condition. + * + * When this function is called with the \e bStart parameter set to \b true, + * this function causes the start of a reset condition on the USB bus. + * The caller must then delay at least 20ms before calling this function + * again with the \e bStart parameter set to \b false. + * + * @param bStart specifies whether to start or stop signaling reset on the USB + * bus. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_reset(bool bStart) +{ + // + // Send a reset signal to the bus. + // + if (bStart) + { + USB->POWER |= USB_POWER_RESET_MSK; + } + else + { + USB->POWER &= ~USB_POWER_RESET_MSK; + } +} + +/** + * @brief Handles the USB bus resume condition. + * + * When in device mode, this function brings the USB controller out of the + * suspend state. This call must first be made with the \e bStart parameter + * set to \b true to start resume signaling. The device application must + * then delay at least 10ms but not more than 15ms before calling this + * function with the \e bStart parameter set to \b false. + * + * When in host mode, this function signals devices to leave the suspend + * state. This call must first be made with the \e bStart parameter set to + * \b true to start resume signaling. The host application must then delay + * at least 20ms before calling this function with the \e bStart parameter set + * to \b false. This action causes the controller to complete the resume + * signaling on the USB bus. + * + * @param bStart specifies if the USB controller is entering or leaving the + * resume signaling state. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_resume(bool bStart) +{ + // + // Send a resume signal to the bus. + // + if (bStart) + { + USB->POWER |= USB_POWER_RESUME_MSK; + } + else + { + USB->POWER &= ~USB_POWER_RESUME_MSK; + } +} + +/** + * @brief Puts the USB bus in a suspended state. + * + * When used in host mode, this function puts the USB bus in the suspended + * state. + * + * @note This function must only be called in host mode. + * @retval Returns one of the following: \b USB_LOW_SPEED, \b USB_FULL_SPEED, + * \b USB_HIGH_SPEED, or \b USB_UNDEF_SPEED. + */ +void md_usb_hos_suspend(void) +{ + // + // Send the suspend signaling to the USB bus. + // + USB->POWER |= USB_POWER_SUSPEND_MSK; +} + +/** + * @brief Issues a request for a status IN transaction on endpoint zero. + * + * This function is used to cause a request for a status IN transaction from + * a device on endpoint zero. This function can only be used with endpoint + * zero as that is the only control endpoint that supports this ability. This + * function is used to complete the last phase of a control transaction to a + * device and an interrupt is signaled when the status packet has been + * received. + * + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_request_status(void) +{ + // + // Set the request for a status IN transaction. + // + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_REQPKT_MSK | USB_CSR0L_TXCSRL_STATUSPKT_MSK; +} + +/** + * @brief Schedules a request for an IN transaction on an endpoint in host mode. + * + * This function schedules a request for an IN transaction. When the USB + * device being communicated with responds with the data, the data can be + * retrieved by calling md_usb_hosdev_endpoint_data_get() or via a DMA + * transfer. + * + * @note This function must only be called in host mode and only for IN + * endpoints. + * @param ui32Endpoint is the endpoint to access. + * @retval None. + */ +void md_usb_hos_request_in(uint32_t ui32Endpoint) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + if (ui32Endpoint == USB_EP_0) + { + // + // Set the request for an IN transaction. + // + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_REQPKT_MSK; + } + else + { + // + // Set the request for an IN transaction. + // + USB->RXCSR1 |= USB_RXCSRL_REQPKT_MSK; + } +} + +/** + * @brief Clears a scheduled IN transaction for an endpoint in host mode. + * + * This function clears a previously scheduled IN transaction if it is still + * pending. This function is used to safely disable any scheduled IN + * transactions if the endpoint specified by \e ui32Endpoint is reconfigured + * for communications with other devices. + * + * @note This function must only be called in host mode and only for IN + * endpoints. + * @param ui32Endpoint is the endpoint to access. + * @retval None. + */ +void md_usb_hos_request_in_clear(uint32_t ui32Endpoint) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Set the request for an IN transaction. + // For es32f0271,setup packet is only supported by endpoint0. + // + USB->CSR0L_TXCSRL &= ~USB_CSR0L_TXCSRL_REQPKT_MSK; +} + +/** + * @brief Returns the current speed of the USB device connected. + * + * This function returns the current speed of the USB bus in host mode. + * + * @note This function must only be called in host mode. + * @retval Returns one of the following: \b USB_LOW_SPEED, \b USB_FULL_SPEED, + * \b USB_HIGH_SPEED, or \b USB_UNDEF_SPEED. + */ +uint32_t md_usb_hos_speed_get(void) +{ + // + // If the Full Speed device bit is set, then this is a full speed device. + // + if (USB->DEVCTRL & USB_DEVCTRL_FSDEV_MSK) + { + return (USB_FULL_SPEED); + } + + // + // If the Low Speed device bit is set, then this is a low speed device. + // + if (USB->DEVCTRL & USB_DEVCTRL_LSDEV_MSK) + { + return (USB_LOW_SPEED); + } + + // + // The device speed is not known. + // + return (USB_UNDEF_SPEED); +} + +/** + * @brief Gets the current functional device address for an endpoint. + * + * This function returns the current functional address that an endpoint is + * using to communicate with a device. The \e ui32Flags parameter determines + * if the IN or OUT endpoint's device address is returned. + * + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags determines if this is an IN or an OUT endpoint. + * @note This function must only be called in host mode. + * @retval Returns the current function address being used by an endpoint. + */ +uint32_t md_usb_hos_addr_get(uint32_t ui32Endpoint, uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Because es32f0271 can not read device function address, + // the return value can always be 0. + // + + // + // See if the transmit or receive address is returned. + // + if (ui32Flags & USB_EP_HOST_OUT) + { + // + // Return this endpoint's transmit address. + // + return (USB->FADDR); + } + else + { + // + // Return this endpoint's receive address. + // + return (USB->FADDR); + } +} + +/** + * @brief Sets the functional address for the device that is connected to an + * endpoint in host mode. + * + * This function configures the functional address for a device that is using + * this endpoint for communication. This \e ui32Addr parameter is the address + * of the target device that this endpoint is communicating with. The + * \e ui32Flags parameter indicates if the IN or OUT endpoint is set. + * + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags determines if this is an IN or an OUT endpoint. + * @param ui32Addr is the functional address for the controller to use for + * this endpoint. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_addr_set(uint32_t ui32Endpoint, + uint32_t ui32Addr, uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + +// USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // See if the transmit or receive address is set. + // + if (ui32Flags & USB_EP_HOST_OUT) + { + // + // Set the transmit address. + // + USB->FADDR = ui32Addr; + } + else + { + // + // Set the receive address. + // + USB->FADDR = ui32Addr; + } +} + +/** + * @brief Gets the current device hub address for this endpoint. + * + * This function returns the current hub address that an endpoint is using + * to communicate with a device. The \e ui32Flags parameter determines if the + * device address for the IN or OUT endpoint is returned. + * + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags determines if this is an IN or an OUT endpoint. + * @note This function must only be called in host mode. + * @retval None. + */ +uint32_t md_usb_hos_hub_addr_get(uint32_t ui32Endpoint, uint32_t ui32Flags) +{ + // + // es32f0271 does not support + // + return 0; +} + +/** + * @brief Sets the hub address for the device that is connected to an endpoint. + * + * This function configures the hub address for a device that is using this + * endpoint for communication. The \e ui32Flags parameter determines if the + * device address for the IN or the OUT endpoint is configured by this call + * and sets the speed of the downstream device. Valid values are one of + * \b USB_EP_HOST_OUT or \b USB_EP_HOST_IN optionally ORed with + * \b USB_EP_SPEED_LOW. + * + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags determines if this is an IN or an OUT endpoint. + * @param ui32Addr is the hub address and port for the device using this + * endpoint. The hub address must be defined in bits 0 through 6 with the + * port number in bits 8 through 14. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_hub_addr_set(uint32_t ui32Endpoint, + uint32_t ui32Addr, uint32_t ui32Flags) +{ + // + // es32f0271 does not support + // +} + +/** + * @brief Get USB address. + * @param None. + * @retval USB address. + */ +uint8_t md_usb_dev_addr_get(void) +{ + return (USB->FADDR); +} + +/** + * @brief Set USB address. + * @param ui8Address USB address. + * @retval None. + */ +void md_usb_dev_addr_set(uint8_t ui8Address) +{ + USB->FADDR = ui8Address; +} + +/** + * @brief USB soft connect. + * @param None. + * @retval None. + */ +void md_usb_dev_connect(void) +{ + // + // Enable connection to the USB bus. + // + USB->DPDMCTRL |= USB_DPDMCTL_PHYPWREN_MSK; +} + +/** + * @brief USB soft disconnect. + * @param None. + * @retval None. + */ +void md_usb_dev_disconnect(void) +{ + // + // Disable connection to the USB bus. + // + USB->DPDMCTRL &= ~USB_DPDMCTL_PHYPWREN_MSK; +} + +/** + * @brief Returns the current speed of the USB device connected. + * + * This function returns the current speed of the USB bus in device mode. + * + * @note This function must only be called in device mode. + * @retval Returns one of the following: \b USB_LOW_SPEED, \b USB_FULL_SPEED, + * \b USB_HIGH_SPEED, or \b USB_UNDEF_SPEED. + */ +uint32_t md_usb_dev_speed_get(void) +{ + if (USB->DPDMCTRL & USB_DPDMCTL_DPPUD_MSK) + return USB_FULL_SPEED; + else if (USB->DPDMCTRL & USB_DPDMCTL_DMPUD_MSK) + return USB_LOW_SPEED; + + return USB_UNDEF_SPEED; +} + +/** + * @brief Gets the current frame number. + * + * This function returns the last frame number received. + * + * @param None. + * @retval The last frame number received. + */ +uint32_t md_usb_hosdev_frame_get(void) +{ + uint8_t temp = USB->FRAME1 & 0xff; + return (temp | (uint32_t)((USB->FRAME2 & 0x07) << 8)); +} + +/** + * @brief Disables control interrupts on a specified USB controller. + * + * This function disables the control interrupts for the USB controller + * specified by the \e ui32Base parameter. The \e ui32Flags parameter + * specifies which control interrupts to disable. The flags passed in the + * \e ui32Flags parameters must be the definitions that start with + * \b USB_INTCTRL_* and not any other \b USB_INT flags. + * + * @param ui32IntFlags specifies which control interrupts to disable. + * @retval None. + */ +void md_usb_hosdev_int_disable(uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + assert_param((ui32IntFlags & ~(USB_INTCTRL_ALL)) == 0); + + // + // If any general interrupts were disabled then write the general interrupt + // settings out to the hardware. + // + if (ui32IntFlags & USB_INTCTRL_STATUS) + { + USB->IDR &= ~(ui32IntFlags & USB_INTCTRL_STATUS); + } +} + +/** + * @brief Enables control interrupts on a specified USB controller. + * + * This function Enables the control interrupts for the USB controller + * specified by the \e ui32Base parameter. The \e ui32Flags parameter + * specifies which control interrupts to disable. The flags passed in the + * \e ui32Flags parameters must be the definitions that start with + * \b USB_INTCTRL_* and not any other \b USB_INT flags. + * + * @param ui32IntFlags specifies which control interrupts to Enable. + * @retval None. + */ +void md_usb_hosdev_int_enable(uint32_t ui32IntFlags) +{ + // + // Check the arguments. + // + assert_param((ui32IntFlags & ~(USB_INTCTRL_ALL)) == 0); + + // + // If any general interrupts were disabled then write the general interrupt + // settings out to the hardware. + // + if (ui32IntFlags & USB_INTCTRL_STATUS) + { + USB->IER |= ui32IntFlags & USB_INTCTRL_STATUS; + } +} + +/** + * @brief Returns the control interrupt status on a specified USB controller. + * + * This function reads control interrupt status for a USB controller. This + * call returns the current status for control interrupts only, the endpoint + * interrupt status is retrieved by calling md_usb_hosdev_endpoint_int_status(). + * The bit values returned are compared against the \b USB_INTCTRL_* values. + * + * The following are the meanings of all \b USB_INCTRL_ flags and the modes + * for which they are valid. These values apply to any calls to + * md_usb_hosdev_int_status(), md_usb_hosdev_int_enable(), + * and md_usb_hosdev_int_disable(). + * Some of these flags are only valid in the following modes as indicated in + * the parentheses: Host, Device, and OTG. + * + * - \b USB_INTCTRL_ALL - A full mask of all control interrupt sources. + * - \b USB_INTCTRL_VBUS_ERR - A VBUS error has occurred (Host Only). + * - \b USB_INTCTRL_SESSION - Session Start Detected on A-side of cable + * (OTG Only). + * - \b USB_INTCTRL_SESSION_END - Session End Detected (Device Only) + * - \b USB_INTCTRL_DISCONNECT - Device Disconnect Detected (Host Only) + * - \b USB_INTCTRL_CONNECT - Device Connect Detected (Host Only) + * - \b USB_INTCTRL_SOF - Start of Frame Detected. + * - \b USB_INTCTRL_BABBLE - USB controller detected a device signaling past + * the end of a frame (Host Only) + * - \b USB_INTCTRL_RESET - Reset signaling detected by device (Device Only) + * - \b USB_INTCTRL_RESUME - Resume signaling detected. + * - \b USB_INTCTRL_SUSPEND - Suspend signaling detected by device (Device + * Only) + * - \b USB_INTCTRL_MODE_DETECT - OTG cable mode detection has completed + * (OTG Only) + * - \b USB_INTCTRL_POWER_FAULT - Power Fault detected (Host Only) + * + * @param ui32IntFlags specifies which control interrupts to Enable. + * @note This call clears the source of all of the control status interrupts. + * @retval Returns the status of the control interrupts for a USB controller. + */ +uint32_t md_usb_hosdev_int_status(void) +{ + uint32_t ui32Status; + + // + // Get the general interrupt status, these bits go into the upper 8 bits + // of the returned value. + // + ui32Status = USB->RIF & 0x7F; + + // + // Clear all the general interrupt status. + // + USB->ICR = 0xff; + + // + // Return the combined interrupt status. + // + return (ui32Status); +} + +/** + * @brief Returns the current operating mode of the controller. + * + * This function returns the current operating mode on USB controllers with + * OTG or Dual mode functionality. + * + * For OTG controllers: + * + * The function returns one of the following values on OTG controllers: + * + * \b USB_OTG_MODE_ASIDE_HOST indicates that the controller is in host mode + * on the A-side of the cable. + * + * \b USB_OTG_MODE_ASIDE_DEV indicates that the controller is in device mode + * on the A-side of the cable. + * + * \b USB_OTG_MODE_BSIDE_HOST indicates that the controller is in host mode + * on the B-side of the cable. + * + * \b USB_OTG_MODE_BSIDE_DEV indicates that the controller is in device mode + * on the B-side of the cable. If an OTG session request is started with no + * cable in place, this mode is the default. + * + * \b USB_OTG_MODE_NONE indicates that the controller is not attempting to + * determine its role in the system. + * + * For Dual Mode controllers: + * + * The function returns one of the following values: + * + * \b USB_DUAL_MODE_HOST indicates that the controller is acting as a host. + * + * \b USB_DUAL_MODE_DEVICE indicates that the controller acting as a device. + * + * \b USB_DUAL_MODE_NONE indicates that the controller is not active as + * either a host or device. + * + * @param None. + * @retval Returns \b USB_OTG_MODE_ASIDE_HOST, \b USB_OTG_MODE_ASIDE_DEV, + * \b USB_OTG_MODE_BSIDE_HOST, \b USB_OTG_MODE_BSIDE_DEV, + * \b USB_OTG_MODE_NONE, \b USB_DUAL_MODE_HOST, \b USB_DUAL_MODE_DEVICE, or + * \b USB_DUAL_MODE_NONE. + */ +uint32_t md_usb_hosdev_mode_get(void) +{ + // + // It will not be called for es32f0271,because OTG is not supported. + // + // Checks the current mode in the USB_O_DEVCTL and returns the current + // mode. + // + // USB_OTG_MODE_ASIDE_HOST: USB_DEVCTL_HOST | USB_DEVCTL_SESSION + // USB_OTG_MODE_ASIDE_DEV: USB_DEVCTL_SESSION + // USB_OTG_MODE_BSIDE_HOST: USB_DEVCTL_DEV | USB_DEVCTL_SESSION | + // USB_DEVCTL_HOST + // USB_OTG_MODE_BSIDE_DEV: USB_DEVCTL_DEV | USB_DEVCTL_SESSION + // USB_OTG_MODE_NONE: USB_DEVCTL_DEV + // + return (USB->DEVCTRL & (USB_DEVCTRL_HOST_MSK | USB_DEVCTRL_SESSION_MSK)); +} + +/** + * @brief Starts or ends a session. + * + * This function is used in OTG mode to start a session request or end a + * session. If the \e bStart parameter is set to \b true, then this function + * starts a session and if it is \b false it ends a session. + * + * @param bStart specifies if this call starts or ends a session. + * @retval None. + */ +void md_usb_otg_session_request(bool bStart) +{ + // + // Start or end the session as directed. + // + if (bStart) + { + USB->DEVCTRL |= USB_DEVCTRL_SESSION_MSK; + } + else + { + USB->DEVCTRL &= ~USB_DEVCTRL_SESSION_MSK; + } +} + +/** + * @brief Change the mode of the USB controller to host. + * + * This function changes the mode of the USB controller to host mode. + * + * @note This function must only be called on microcontrollers that support + * OTG operation. + * @param None. + * @retval None. + */ +void md_usb_force_host_mode(void) +{ + unsigned int i; + // + // Force host mode. + // + USB->SWCID &= ~USB_SWCID_HOST_MSK; + USB->SWCID |= USB_SWCID_CIDCTRL_MSK; + USB->DEVCTRL = USB_DEVCTRL_HOSTREQ_MSK; + + i = 20; + + while ((!(USB->DEVCTRL & USB_DEVCTRL_HOST_MSK)) && (i != 0)) + { + i--; + } +} + +/** + * @brief Change the mode of the USB controller to device. + * + * This function changes the mode of the USB controller to device mode. + * + * @note This function must only be called on microcontrollers that support + * OTG operation. + * @param None. + * @retval None. + */ +void md_usb_force_device_mode(void) +{ + // + // Force mode in OTG parts that support forcing USB controller mode. + // This bit is not writable in USB controllers that do not support + // forcing the mode. Not setting the USB_GPCS_DEVMOD bit makes this a + // force of device mode. + // + USB->SWCID |= USB_SWCID_HOST_MSK; + USB->SWCID |= USB_SWCID_CIDCTRL_MSK; +} + +/** + * @brief Change the mode of the USB controller to OTG. + * + * This function changes the mode of the USB controller to OTG mode. + * + * @note This function must only be called on microcontrollers that support + * OTG operation. + * @param None. + * @retval None. + */ +void md_usb_force_otg_mode(void) +{ + // + // Force mode in OTG parts that support forcing USB controller mode. + // This bit is not writable in USB controllers that do not support + // forcing the mode. Not setting the USB_GPCS_DEVMOD bit makes this a + // force of OTG mode. + // + USB->SWCID |= USB_SWCID_HOST_MSK; + USB->SWCID &= ~USB_SWCID_CIDCTRL_MSK; +} + +/** + * @brief Change the operating mode of the USB controller. + * + * This function changes the operating modes of the USB controller. When + * operating in full OTG mode, the USB controller uses the VBUS and ID pins to + * detect mode and voltage changes. While these pins are primarily used in + * OTG mode, they can also affect the operation of host and device modes. In + * device mode, the USB controller can be configured to monitor or ignore + * VBUS. Monitoring VBUS allows the controller to determine if it has been + * disconnected from the host. In host mode, the USB controller uses the + * VBUS pin to detect loss of VBUS caused by excessive power draw due to a + * drop in the VBUS voltage. This call takes the place of + * md_usb_force_host_mode(),md_usb_force_device_mode(), + * and md_usb_force_otg_mode(). + * The \e ui32Mode value should be one of the following values: + * + * - \b USB_MODE_OTG enables operating in full OTG mode, VBUS and ID are + * used by the controller. + * - \b USB_MODE_HOST enables operating only as a host with no monitoring of + * VBUS or ID pins. + * - \b USB_MODE_HOST_VBUS enables operating only as a host with monitoring of + * VBUS pin. This configuration enables detection of VBUS droop while still + * forcing host mode. + * - \b USB_MODE_DEVICE enables operating only as a device with no monitoring + * of VBUS or ID pins. + * - \b USB_MODE_DEVICE_VBUS enables operating only as a device with + * monitoring of VBUS pin. This configuration enables disconnect detection + * while still forcing device mode. + * + * @note Some of the options above are not available on some ES32 devices. + * Please check the data sheet to determine if the USB controller supports a + * particular mode. + * @param ui32Mode specifies the operating mode of the USB OTG pins. + * @retval None. + */ +void md_usb_mode_config(uint32_t ui32Mode) +{ + // + // It is not supported by es32f0271. + // +} + +/** + * @} USB_MD_PF_BASIC + */ + +/** @addtogroup USB_MD_PF_ENDPOINT USB Public Endpoint Functions + * @{ + */ + +/** + * @brief Sets the base configuration for a host endpoint. + * + * This function sets the basic configuration for the transmit or receive + * portion of an endpoint in host mode. The \e ui32Flags parameter determines + * some of the configuration while the other parameters provide the rest. The + * \e ui32Flags parameter determines whether this is an IN endpoint + * (\b USB_EP_HOST_IN or \b USB_EP_DEV_IN) or an OUT endpoint + * (\b USB_EP_HOST_OUT or \b USB_EP_DEV_OUT), whether this is a Full speed + * endpoint (\b USB_EP_SPEED_FULL) or a Low speed endpoint + * (\b USB_EP_SPEED_LOW). + * + * The \b USB_EP_MODE_ flags control the type of the endpoint. + * - \b USB_EP_MODE_CTRL is a control endpoint. + * - \b USB_EP_MODE_ISOC is an isochronous endpoint. + * - \b USB_EP_MODE_BULK is a bulk endpoint. + * - \b USB_EP_MODE_INT is an interrupt endpoint. + * + * The \e ui32NAKPollInterval parameter has different meanings based on the + * \b USB_EP_MODE value and whether or not this call is being made for + * endpoint zero or another endpoint. For endpoint zero or any Bulk + * endpoints, this value always indicates the number of frames to allow a + * device to NAK before considering it a timeout. If this endpoint is an + * isochronous or interrupt endpoint, this value is the polling interval for + * this endpoint. + * + * For interrupt endpoints, the polling interval is the number of frames + * between interrupt IN requests to an endpoint and has a range of 1 to 255. + * For isochronous endpoints this value represents a polling interval of + * 2 ^ (\e ui32NAKPollInterval - 1) frames. When used as a NAK timeout, the + * \e ui32NAKPollInterval value specifies 2 ^ (\e ui32NAKPollInterval - 1) + * frames before issuing a time out. + * + * There are two special time out values that can be specified when setting + * the \e ui32NAKPollInterval value. The first is \b MAX_NAK_LIMIT, which is + * the maximum value that can be passed in this variable. The other is + * \b DISABLE_NAK_LIMIT, which indicates that there is no limit on the + * number of NAKs. + * + * The \b USB_EP_DMA_MODE_ flags determine the type of DMA access to the + * endpoint data FIFOs. The choice of the DMA mode depends on how the DMA + * controller is configured and how it is being used. See the ``Using USB + * with the DMA Controller'' or the ''Using the integrated USB DMA + * Controller'' section for more information on DMA configuration depending + * on the type of DMA that is supported by the USB controller. + * + * When configuring the OUT portion of an endpoint, the \b USB_EP_AUTO_SET bit + * is specified to cause the transmission of data on the USB bus to start + * as soon as the number of bytes specified by \e ui32MaxPayload has been + * written into the OUT FIFO for this endpoint. + * + * When configuring the IN portion of an endpoint, the \b USB_EP_AUTO_REQUEST + * bit can be specified to trigger the request for more data once the FIFO has + * been drained enough to fit \e ui32MaxPayload bytes. The + * \b USB_EP_AUTO_CLEAR bit can be used to clear the data packet ready flag + * automatically once the data has been read from the FIFO. If this option is + * not used, this flag must be manually cleared via a call to + * md_usb_dev_endpoint_status_clear() or md_usb_hos_endpoint_status_clear(). + * + * For interrupt endpoints in low or full speed mode, the polling interval + * (\e ui32NAKPollInterval) is the number of frames between interrupt IN + * requests to an endpoint and has a range of 1 to 255. For interrupt + * endpoints in high speed mode the polling interval is + * 2 ^ (\e ui32NAKPollInterval - 1) microframes between interrupt IN requests + * to an endpoint and has a range of 1 to 16. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags are the status bits that are cleared. + * @param ui32MaxPacketSize is the maximum payload for this endpoint. + * @param ui32NAKPollInterval is the either the NAK timeout limit or the + * polling interval, depending on the type of endpoint. + * @param ui32TargetEndpoint is the endpoint that the host endpoint is + * targeting. + * @param ui32Flags are used to configure other endpoint settings. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_endpoint_config_set(uint32_t ui32Endpoint, + uint32_t ui32MaxPacketSize, + uint32_t ui32NAKPollInterval, + uint32_t ui32TargetEndpoint, + uint32_t ui32Flags) +{ + uint32_t ui32Register; + + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Endpoint zero is configured differently than the other endpoints, so see + // if this is endpoint zero. + // + if (ui32Endpoint == USB_EP_0) + { + // + // Set the NAK timeout. + // + USB->NAKLIMIT0_TXINTERVAL = (uint8_t)ui32NAKPollInterval; + + // + // Set the transfer type information. + // + + // + // Set the speed of this endpoint. + // + if (ui32Flags & USB_EP_SPEED_HIGH) + { + // + // es32f0271 does not support high sepeed + // + } + else if (ui32Flags & USB_EP_SPEED_FULL) + { + } + else + { + } + } + else + { + // + // Start with the target endpoint. + // + ui32Register = ui32TargetEndpoint; + + // + // Set the speed for the device using this endpoint. + // + if (ui32Flags & USB_EP_SPEED_HIGH) + { + // + // es32f0271 does not support high sepeed + // + } + else if (ui32Flags & USB_EP_SPEED_FULL) + { + + } + else + { + + } + + // + // Set the protocol for the device using this endpoint. + // + switch (ui32Flags & USB_EP_MODE_MASK) + { + // + // The bulk protocol is being used. + // + case USB_EP_MODE_BULK: + { + ui32Register |= 0x20; + break; + } + + // + // The isochronous protocol is being used. + // + case USB_EP_MODE_ISOC: + { + ui32Register |= 0x10; + break; + } + + // + // The interrupt protocol is being used. + // + case USB_EP_MODE_INT: + { + ui32Register |= 0x30; + break; + } + + // + // The control protocol is being used. + // + case USB_EP_MODE_CTRL: + { + ui32Register |= 0x00; + break; + } + } + + // + // See if the transmit or receive endpoint is being configured. + // + if (ui32Flags & USB_EP_HOST_OUT) + { + // + // Set the transfer type information. + // + USB->TXTYPE = ui32Register; + + // + // Set the NAK timeout or polling interval. + // + USB->NAKLIMIT0_TXINTERVAL = ui32NAKPollInterval; + + // + // Set the Maximum Payload per transaction. + // + USB->TXMAXP = ui32MaxPacketSize; + + // + // Set the transmit control value to zero. + // + ui32Register = 0; + + // + // Allow auto setting of TxPktRdy when max packet size has been + // loaded into the FIFO. + // + if (ui32Flags & USB_EP_AUTO_SET) + { + ui32Register |= USB_CSR0H_TXCSRH_AUTOSET_MSK; + } + +// // +// // Configure the DMA Mode. +// // +// if(ui32Flags & USB_EP_DMA_MODE_1) +// { +// ui32Register |= USB_TXCSRH1_DMAEN | USB_TXCSRH1_DMAMOD; +// } +// else if(ui32Flags & USB_EP_DMA_MODE_0) +// { +// ui32Register |= USB_TXCSRH1_DMAEN; +// } + + // + // Write out the transmit control value. + // + USB->CSR0H_TXCSRH = (uint8_t)ui32Register; + } + else + { + // + // Set the transfer type information. + // + USB->RXTYPE = ui32Register; + + // + // Set the NAK timeout or polling interval. + // + USB->RXINTERVAL = ui32NAKPollInterval; + + // + // Set the Maximum Payload per transaction. + // + USB->RXMAXP = ui32MaxPacketSize; + + // + // Set the receive control value to zero. + // + ui32Register = 0; + + // + // Allow auto clearing of RxPktRdy when packet of size max packet + // has been unloaded from the FIFO. + // + if (ui32Flags & USB_EP_AUTO_CLEAR) + { + ui32Register |= USB_RXCSRH_AUTOCLR_MSK; + } + + // + // Allow auto generation of DMA requests. + // + if (ui32Flags & USB_EP_AUTO_REQUEST) + { + ui32Register |= USB_RXCSRH_AUTOREQ_MSK; + } + +// // +// // Configure the DMA Mode. +// // +// if(ui32Flags & USB_EP_DMA_MODE_1) +// { +// ui32Register |= USB_RXCSRH1_DMAEN | USB_RXCSRH1_DMAMOD; +// } +// else if(ui32Flags & USB_EP_DMA_MODE_0) +// { +// ui32Register |= USB_RXCSRH1_DMAEN; +// } + + // + // Write out the receive control value. + // + USB->RXCSR2 = (uint8_t)ui32Register; + + +// USB->RXFIFO1=0x18; //Start Address=0x18 +// USB->RXFIFO2=(3<<5); //Size=64, No Double-Packet Buffering +// USB->RXCSR1|=USB_RXCSRL_FLUSH_MSK; //Flush FIFO + } + } +} + +/** + * @brief Acknowledge that data was read from the specified endpoint's FIFO in host mode. + * + * This function acknowledges that the data was read from the endpoint's FIFO. + * This call is used if processing is required between reading the data and + * acknowledging that the data has been read. + * @param ui32Endpoint is the endpoint to access. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_endpoint_data_ack(uint32_t ui32Endpoint) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Clear RxPktRdy. + // + if (ui32Endpoint == USB_EP_0) + { + USB->CSR0L_TXCSRL &= ~USB_CSR0L_TXCSRL_RXRDY_MSK; + } + else + { + USB->RXCSR1 &= ~(USB_RXCSRL_RXRDY_MSK); + } +} + +/** + * @brief Sets the value data toggle on an endpoint in host mode. + * + * This function is used to force the state of the data toggle in host mode. + * If the value passed in the \e bDataToggle parameter is \b false, then the + * data toggle is set to the DATA0 state, and if it is \b true it is set to + * the DATA1 state. The \e ui32Flags parameter can be \b USB_EP_HOST_IN or + * \b USB_EP_HOST_OUT to access the desired portion of this endpoint. The + * \e ui32Flags parameter is ignored for endpoint zero. + * @param ui32Endpoint is the endpoint to access. + * @param bDataToggle specifies whether to set the state to DATA0 or DATA1. + * @param ui32Flags specifies whether to set the IN or OUT endpoint. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_endpoint_data_toggle(uint32_t ui32Endpoint, + bool bDataToggle, uint32_t ui32Flags) +{ + // + // It is not supported by es32f0271. + // + UNUSED(ui32Endpoint); + UNUSED(bDataToggle); + UNUSED(ui32Flags); +} + +/** + * @brief Clears the status bits in this endpoint in host mode. + * + * This function clears the status of any bits that are passed in the + * \e ui32Flags parameter. The \e ui32Flags parameter can take the value + * returned from the md_usb_hosdev_endpoint_status() call. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags are the status bits that are cleared. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_endpoint_status_clear(uint32_t ui32Endpoint, + uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Clear the specified flags for the endpoint. + // + if (ui32Endpoint == USB_EP_0) + { + USB->CSR0L_TXCSRL &= ~(ui32Flags & 0xff); + } + else + { + USB->CSR0L_TXCSRL &= ~(ui32Flags & 0xff); + USB->RXCSR1 &= ~((ui32Flags >> 16) & 0xff); + } +} + +/** + * @brief Changes the speed of the connection for a host endpoint. + * + * This function sets the USB speed for an IN or OUT endpoint in host mode. + * The \e ui32Flags parameter specifies the speed using one of the following + * values: \b USB_EP_SPEED_LOW, \b USB_EP_SPEED_FULL, or \b USB_EP_SPEED_HIGH. + * The \e ui32Flags parameter also specifies which direction is set by + * adding the logical OR in either \b USB_EP_HOST_IN or \b USB_EP_HOST_OUT. + * All other flags are ignored. This function is typically only used for + * endpoint 0, but could be used with other endpoints as well. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags are used to configure other endpoint settings. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_endpoint_speed(uint32_t ui32Endpoint, + uint32_t ui32Flags) +{ + // + // For es32f0271,we can not config endpoint speed. + // + UNUSED(ui32Endpoint); + UNUSED(ui32Flags); +} + +/** + * @brief Enables or disables ping tokens for an endpoint using high-speed control + * transfers in host mode. + * + * This function configures the USB controller to either send or not send ping + * tokens during the data and status phase of high speed control transfers. + * The only supported value for \e ui32Endpoint is \b USB_EP_0 because all + * control transfers are handled using this endpoint. If the \e bEnable is + * \b true then ping tokens are enabled, if \b false then ping tokens are + * disabled. This must be used if the controller must support + * communications with devices that do not support ping tokens in high speed + * mode. + * @param ui32Endpoint specifies the endpoint to enable/disable ping tokens. + * @param bEnable specifies whether enable or disable ping tokens. + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_endpoint_ping(uint32_t ui32Endpoint, + bool bEnable) +{ + // + // It is not supported by es32f0271. + // + UNUSED(ui32Endpoint); + UNUSED(bEnable); +} + +/** + * @brief USB endpoint configuration. + * + * This function sets the basic configuration for an endpoint in device mode. + * Endpoint zero does not have a dynamic configuration, so this function + * must not be called for endpoint zero. The \e ui32Flags parameter + * determines some of the configuration while the other parameters provide the + * rest. + * + * When configuring an IN endpoint, the \b USB_EP_AUTO_SET bit can be + * specified to cause the automatic transmission of data on the USB bus as + * soon as \e ui32MaxPacketSize bytes of data are written into the FIFO for + * this endpoint. This option is commonly used with DMA as no interaction + * is required to start the transmission of data. + * + * The \b USB_EP_MODE_ flags define what the type is for the specified endpoint. + * USB_EP_MODE_CTRL is a control endpoint. + * USB_EP_MODE_ISOC is an isochronous endpoint. + * USB_EP_MODE_BULK is a bulk endpoint. + * USB_EP_MODE_INT is an interrupt endpoint. + * + * When configuring an OUT endpoint, the \b USB_EP_AUTO_REQUEST bit is + * specified to trigger the request for more data once the FIFO has been + * drained enough to receive \e ui32MaxPacketSize more bytes of data. Also + * for OUT endpoints, the \b USB_EP_AUTO_CLEAR bit can be used to clear the + * data packet ready flag automatically once the data has been read from the + * FIFO. If this option is not used, this flag must be manually cleared via a + * call to md_usb_dev_endpoint_status_clear(). Both of these settings can be + * used to remove the need for extra calls when using the controller with DMA. + * + * @param ui32Endpoint The USB endpoint. + * @param ui32MaxPacketSize is the maximum packet size for this endpoint. + * @param ui32Flags are used to configure other endpoint settings. + * @retval None. + */ +void md_usb_dev_endpoint_config_set(uint32_t ui32Endpoint, + uint32_t ui32MaxPacketSize, + uint32_t ui32Flags) +{ + uint32_t ui32Register; + + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Determine if a transmit or receive endpoint is being configured. + // + if (ui32Flags & USB_EP_DEV_IN) /*IN*/ + { + // + // Set the max packet size. + // + USB->TXMAXP = ui32MaxPacketSize; + + // + // The transmit control value is zero unless options are enabled. + // + ui32Register = 0; + + // + // Allow auto setting of TxPktRdy when max packet size has been loaded + // into the FIFO. + // + if (ui32Flags & USB_EP_AUTO_SET) + { + ui32Register |= USB_CSR0H_TXCSRH_AUTOSET_MSK; + } + + // + // Configure the DMA mode. + // + /* es32f0271 does not support DMA */ + + // + // Enable isochronous mode if requested. + // + if ((ui32Flags & USB_EP_MODE_MASK) == USB_EP_MODE_ISOC) + { + ui32Register |= USB_CSR0H_TXCSRH_ISO_MSK; + } + + // + // Write the transmit control value. + // + USB->CSR0H_TXCSRH = (uint8_t)ui32Register; + + // + // Reset the Data toggle to zero. + // + USB->CSR0L_TXCSRL = USB_CSR0L_TXCSRL_CLRDATAT_MSK; + } + else /*OUT*/ + { + // + // Set the MaxPacketSize. + // + USB->RXMAXP = ui32MaxPacketSize; + + // + // The receive control value is zero unless options are enabled. + // + ui32Register = 0; + + // + // Allow auto clearing of RxPktRdy when packet of size max packet + // has been unloaded from the FIFO. + // + if (ui32Flags & USB_EP_AUTO_CLEAR) + { + ui32Register = USB_RXCSRH_AUTOCLR_MSK; + } + +// // +// // Configure the DMA mode. +// // + +// // +// // If requested, disable NYET responses for high-speed bulk and +// // interrupt endpoints. +// // + /*es32f0271 does not support*/ + + // + // Enable isochronous mode if requested. + // + if ((ui32Flags & USB_EP_MODE_MASK) == USB_EP_MODE_ISOC) + { + ui32Register |= USB_RXCSRH_ISO_MSK; + } + + // + // Write the receive control value. + // + USB->RXCSR2 = ui32Register; + + // + // Reset the Data toggle to zero. + // + USB->RXCSR1 = USB_RXCSRL_CLRDT_MSK; + } +} + +/** + * @brief Gets the current configuration for an endpoint. + * + * This function returns the basic configuration for an endpoint in device + * mode. The values returned in \e *pui32MaxPacketSize and \e *pui32Flags are + * equivalent to the \e ui32MaxPacketSize and \e ui32Flags previously passed + * to md_usb_dev_endpoint_config_get() for this endpoint. + * + * @note This function must only be called in device mode. + * @param ui32Endpoint is the endpoint to access. + * @param pui32MaxPacketSize is a pointer which is written with the maximum + * packet size for this endpoint. + * @param pui32Flags is a pointer which is written with the current endpoint + * settings. On entry to the function, this pointer must contain either + * \b USB_EP_DEV_IN or \b USB_EP_DEV_OUT to indicate whether the IN or OUT + * endpoint is to be queried. + * @retval None. + */ +void md_usb_dev_endpoint_config_get(uint32_t ui32Endpoint, + uint32_t *pui32MaxPacketSize, + uint32_t *pui32Flags) +{ + uint32_t ui32Register; + + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Determine if a transmit or receive endpoint is being queried. + // + if (*pui32Flags & USB_EP_DEV_IN) + { + // + // Clear the flags other than the direction bit. + // + *pui32Flags = USB_EP_DEV_IN; + + // + // Get the maximum packet size. + // + *pui32MaxPacketSize = (uint32_t)USB->TXMAXP; + + // + // Get the current transmit control register value.` + // + ui32Register = (uint32_t)(USB->CSR0H_TXCSRH); + + // + // Are we allowing auto setting of TxPktRdy when max packet size has + // been loaded into the FIFO? + // + if (ui32Register & USB_CSR0H_TXCSRH_AUTOSET_MSK) + { + *pui32Flags |= USB_EP_AUTO_SET; + } + + // + // Get the DMA mode. + // + + // + // Are we in isochronous mode? + // + if (ui32Register & USB_CSR0H_TXCSRH_ISO_MSK) + { + *pui32Flags |= USB_EP_MODE_ISOC; + } + else + { + // + // The hardware doesn't differentiate between bulk, interrupt + // and control mode for the endpoint so we just set something + // that isn't isochronous. This protocol ensures that anyone + // modifying the returned flags in preparation for a call to + // USBDevEndpointConfigSet do not see an unexpected mode change. + // If they decode the returned mode, however, they may be in for + // a surprise. + // + *pui32Flags |= USB_EP_MODE_BULK; + } + } + else + { + // + // Clear the flags other than the direction bit. + // + *pui32Flags = USB_EP_DEV_OUT; + + // + // Get the MaxPacketSize. + // + *pui32MaxPacketSize = (uint32_t)USB->RXMAXP; + + // + // Get the current receive control register value. + // + ui32Register = (uint32_t)(USB->RXCSR2); + + // + // Are we allowing auto clearing of RxPktRdy when packet of size max + // packet has been unloaded from the FIFO? + // + if (ui32Register & USB_RXCSRH_AUTOCLR_MSK) + { + *pui32Flags |= USB_EP_AUTO_CLEAR; + } + + // + // Get the DMA mode. + // + + // + // Are we in isochronous mode? + // + if (ui32Register & USB_RXCSRH_ISO_MSK) + { + *pui32Flags |= USB_EP_MODE_ISOC; + } + else + { + // + // The hardware doesn't differentiate between bulk, interrupt + // and control mode for the endpoint so we just set something + // that isn't isochronous. This protocol ensures that anyone + // modifying the returned flags in preparation for a call to + // USBDevEndpointConfigSet do not see an unexpected mode change. + // If they decode the returned mode, however, they may be in for + // a surprise. + // + *pui32Flags |= USB_EP_MODE_BULK; + } + } +} + +/** + * @brief Acknowledge that data was read from the specified endpoint's FIFO in device + * mode. + * + * This function acknowledges that the data was read from the endpoint's FIFO. + * The \e bIsLastPacket parameter is set to a \b true value if this is the + * last in a series of data packets on endpoint zero. The \e bIsLastPacket + * parameter is not used for endpoints other than endpoint zero. This call + * can be used if processing is required between reading the data and + * acknowledging that the data has been read. + * @param ui32Endpoint is the endpoint to access. + * @param bIsLastPacket indicates if this packet is the last one. + * @note This function must only be called in device mode. + * @retval None. + */ +void md_usb_dev_endpoint_ack(uint32_t ui32Endpoint, + bool bIsLastPacket) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Determine which endpoint is being acked. + // + if (ui32Endpoint == USB_EP_0) + { + // + // Clear RxPktRdy, and optionally DataEnd, on endpoint zero. + // + USB->CSR0L_TXCSRL = USB_CSR0L_TXCSRL_RXRDYC_MSK | (bIsLastPacket ? USB_CSR0L_TXCSRL_DATAEND_MSK : 0); + } + else + { + // + // Clear RxPktRdy on all other endpoints. + // + USB->RXCSR1 &= ~USB_RXCSRL_RXRDY_MSK; + } +} + +/** + * @brief Stalls the specified endpoint in device mode. + * + * This function causes the endpoint number passed in to go into a stall + * condition. If the \e ui32Flags parameter is \b USB_EP_DEV_IN, then the + * stall is issued on the IN portion of this endpoint. If the \e ui32Flags + * parameter is \b USB_EP_DEV_OUT, then the stall is issued on the OUT portion + * of this endpoint. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags specifies whether to stall the IN or OUT endpoint. + * @note This function must only be called in device mode. + * @retval None. + */ +void md_usb_dev_endpoint_stall(uint32_t ui32Endpoint, uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Determine how to stall this endpoint. + // + if (ui32Endpoint == USB_EP_0) + { + // + // Perform a stall on endpoint zero. + // + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_RXRDYC_MSK | USB_CSR0L_TXCSRL_STALL_MSK; + } + else if (ui32Flags == USB_EP_DEV_IN) + { + // + // Perform a stall on an IN endpoint. + // + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_STALL_MSK; + } + else + { + // + // Perform a stall on an OUT endpoint. + // + USB->RXCSR1 |= USB_RXCSRL_STALL_MSK; + } +} + +/** + * @brief Clears the stall condition on the specified endpoint in device mode. + * + * This function causes the endpoint number passed in to exit the stall + * condition. If the \e ui32Flags parameter is \b USB_EP_DEV_IN, then the + * stall is cleared on the IN portion of this endpoint. If the \e ui32Flags + * parameter is \b USB_EP_DEV_OUT, then the stall is cleared on the OUT + * portion of this endpoint. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags specifies whether to stall the IN or OUT endpoint. + * @note This function must only be called in device mode. + * @retval None. + */ +void md_usb_dev_endpoint_stall_clear(uint32_t ui32Endpoint, uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Determine how to clear the stall on this endpoint. + // + if (ui32Endpoint == USB_EP_0) + { + // + // Clear the stall on endpoint zero. + // + USB->CSR0L_TXCSRL &= ~USB_CSR0L_TXCSRL_STALLED_MSK; + } + else if (ui32Flags == USB_EP_DEV_IN) + { + // + // Clear the stall on an IN endpoint. + // + USB->CSR0L_TXCSRL &= ~(USB_CSR0L_TXCSRL_SENTSTALL_MSK | USB_CSR0L_TXCSRL_SENDSTALL_MSK); + + // + // Reset the data toggle. + // + /* @yuzr es32f0271 can not realize */ + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_CLRDATAT_MSK; + } + else + { + // + // Clear the stall on an OUT endpoint. + // +// HWREGB(ui32Base + USB_O_RXCSRL1 + EP_OFFSET(ui32Endpoint)) &= +// ~(USB_RXCSRL1_STALL | USB_RXCSRL1_STALLED); + USB->RXCSR1 &= ~(USB_RXCSRL_STALL_MSK | USB_RXCSRL_STALLED_MSK); + + // + // Reset the data toggle. + // + USB->RXCSR1 |= USB_RXCSRL_CLRDT_MSK; + } +} + +/** + * @brief Clears the status bits in this endpoint in device mode. + * + * This function clears the status of any bits that are passed in the + * \e ui32Flags parameter. The \e ui32Flags parameter can take the value + * returned from the USBEndpointStatus() call. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags are the status bits that are cleared. + * @note This function must only be called in device mode. + * @retval None. + */ +void md_usb_dev_endpoint_status_clear(uint32_t ui32Endpoint, uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // If this is endpoint 0, then the bits have different meaning and map + // into the TX memory location. + // + if (ui32Endpoint == USB_EP_0) + { + // + // Set the Serviced RxPktRdy bit to clear the RxPktRdy. + // + if (ui32Flags & USB_DEV_EP0_OUT_PKTRDY) + { + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_RXRDYC_MSK; + } + + // + // Set the serviced Setup End bit to clear the SetupEnd status. + // + if (ui32Flags & USB_DEV_EP0_SETUP_END) + { + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_SETENDC_MSK; + } + + // + // Clear the Sent Stall status flag. + // + if (ui32Flags & USB_DEV_EP0_SENT_STALL) + { + USB->CSR0L_TXCSRL &= ~(USB_CSR0L_TXCSRL_STALLED_MSK); + } + } + else + { + // + // Clear out any TX flags that were passed in. Only + // USB_DEV_TX_SENT_STALL and USB_DEV_TX_UNDERRUN must be cleared. + // + USB->CSR0L_TXCSRL &= ~(ui32Flags & (USB_CSR0L_TXCSRL_STALL_MSK | USB_DEV_TX_UNDERRUN)); + + // + // Clear out valid RX flags that were passed in. Only + // USB_DEV_RX_SENT_STALL, USB_DEV_RX_DATA_ERROR, and USB_DEV_RX_OVERRUN + // must be cleared. + // + USB->RXCSR1 &= ~((ui32Flags & (USB_DEV_RX_SENT_STALL | USB_DEV_RX_DATA_ERROR | + USB_DEV_RX_OVERRUN)) >> 16); + } +} + +/** + * @brief Determines the number of bytes of data available in a specified endpoint's + * FIFO. + * + * This function returns the number of bytes of data currently available in the + * FIFO for the specified receive (OUT) endpoint. It may be used prior to calling + * md_usb_hosdev_endpoint_data_get() to determine the size of buffer required to + * hold the newly-received packet. + * @param ui32Endpoint is the endpoint to access. + * @retval This call returns the number of bytes available in a specified endpoint + * FIFO. + */ +uint32_t md_usb_hosdev_endpoint_datavai(uint32_t ui32Endpoint) +{ + uint8_t temp; //use to clear warning in IAR system + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Get the address of the receive status register to use, based on the + // endpoint. + // + if (ui32Endpoint == USB_EP_0) + { + // + // Is there a packet ready in the FIFO? + // + if (USB->CSR0L_TXCSRL & USB_CSR0L_TXCSRL_RXRDY_MSK) + { + // + // Return the byte count in the FIFO. + // + return (uint32_t)(USB->RXCOUNT1); + } + + return (0); + } + else + { + // + // Is there a packet ready in the FIFO? + // + if (USB->RXCSR1 & USB_RXCSRL_RXRDY_MSK) + { + // + // Return the byte count in the FIFO. + // + temp = USB->RXCOUNT1; + return (uint32_t)(temp | USB->RXCOUNT2 << 8); + } + + return (0); + } +} + +/** + * @brief Retrieves data from the specified endpoint's FIFO. + * + * This function returns the data from the FIFO for the specified endpoint. + * The \e pui32Size parameter indicates the size of the buffer passed in + * the \e pui32Data parameter. The data in the \e pui32Size parameter is + * changed to match the amount of data returned in the \e pui8Data parameter. + * If a zero-byte packet is received, this call does not return an error but + * instead just returns a zero in the \e pui32Size parameter. The only error + * case occurs when there is no data packet available. + * @param ui32Endpoint is the endpoint to access. + * @param pui8Data is a pointer to the data area used to return the data from + * the FIFO. + * @param pui32Size is initially the size of the buffer passed into this call + * via the \e pui8Data parameter. It is set to the amount of data returned in + * the buffer. + * @retval This call returns 0, or -1 if no packet was received. + */ +int32_t md_usb_hosdev_endpoint_data_get(uint32_t ui32Endpoint, + uint8_t *pui8Data, + uint32_t *pui32Size) +{ + uint32_t ui32ByteCount, ui32FIFO; + uint8_t temp; //use to clear warning in IAR system + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Don't allow reading of data if the RxPktRdy bit is not set. + // + if (ui32Endpoint == USB_EP_0) + { + if ((USB->CSR0L_TXCSRL & USB_CSR0L_TXCSRL_RXRDY_MSK) == 0) + { + // + // Can't read the data because none is available. + // + *pui32Size = 0; + + // + // Return a failure since there is no data to read. + // + return (-1); + } + } + else + { + if ((USB->RXCSR1 & USB_RXCSRL_RXRDY_MSK) == 0) + { + // + // Can't read the data because none is available. + // + *pui32Size = 0; + + // + // Return a failure since there is no data to read. + // + return (-1); + } + } + + // + // Get the byte count in the FIFO. + // + if (ui32Endpoint == USB_EP_0) + { + ui32ByteCount = (uint32_t)(USB->RXCOUNT1); + } + else + { + temp = USB->RXCOUNT1; + ui32ByteCount = (uint32_t)(temp | (USB->RXCOUNT2 << 8)); + } + + // + // Determine how many bytes are copied. + // + ui32ByteCount = (ui32ByteCount < *pui32Size) ? ui32ByteCount : *pui32Size; + + // + // Return the number of bytes we are going to read. + // + *pui32Size = ui32ByteCount; + + // + // Calculate the FIFO address. + // + ui32FIFO = (uint32_t)(&USB->EP0FIFO) + 4 * (uint32_t)USBEPToIndex(ui32Endpoint); + + // + // Read the data out of the FIFO. + // + for (; ui32ByteCount > 0; ui32ByteCount--) + { + // + // Read a byte at a time from the FIFO. + // + *pui8Data++ = *((volatile uint8_t *)(ui32FIFO)); + } + + // + // Success. + // + return (0); +} + +/** + * @brief Puts data into the specified endpoint's FIFO. + * + * This function puts the data from the \e pui8Data parameter into the FIFO + * for this endpoint. If a packet is already pending for transmission, then + * this call does not put any of the data into the FIFO and returns -1. Care + * must be taken to not write more data than can fit into the FIFO + * allocated by the call to md_usb_dev_endpoint_config_set(). + * @param ui32Endpoint is the endpoint to access. + * @param pui8Data is a pointer to the data area used as the source for the + * data to put into the FIFO. + * @param ui32Size is the amount of data to put into the FIFO. + * @retval This call returns 0 on success, or -1 to indicate that the FIFO + * is in use and cannot be written. + */ +int32_t md_usb_hosdev_endpoint_data_put(uint32_t ui32Endpoint, + uint8_t *pui8Data, uint32_t ui32Size) +{ + uint32_t ui32FIFO; + + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Don't allow transmit of data if the TxPktRdy bit is already set. + // + if (ui32Endpoint == USB_EP_0) + { + if (USB->CSR0L_TXCSRL & USB_CSR0L_TXCSRL_TXRDY_MSK) + return (-1); + } + else + { + if (USB->CSR0L_TXCSRL & USB_CSR0L_TXCSRL_TXPKTRDY_MSK) + return (-1); + } + + // + // Calculate the FIFO address. + // + ui32FIFO = (uint32_t)(&USB->EP0FIFO) + 4 * (uint32_t)USBEPToIndex(ui32Endpoint); + + // + // Write the data to the FIFO. + // + for (; ui32Size > 0; ui32Size--) + { + *((volatile uint8_t *)(ui32FIFO)) = *pui8Data++; + } + + // + // Success. + // + return (0); +} + +/** + * @brief Starts the transfer of data from an endpoint's FIFO. + * + * This function starts the transfer of data from the FIFO for a specified + * endpoint. This function is called if the \b USB_EP_AUTO_SET bit was + * not enabled for the endpoint. Setting the \e ui32TransType parameter + * allows the appropriate signaling on the USB bus for the type of transaction + * being requested. The \e ui32TransType parameter must be one of the + * following: + * + * - \b USB_TRANS_OUT for OUT transaction on any endpoint in host mode. + * - \b USB_TRANS_IN for IN transaction on any endpoint in device mode. + * - \b USB_TRANS_IN_LAST for the last IN transaction on endpoint zero in a + * sequence of IN transactions. + * \b USB_TRANS_SETUP for setup transactions on endpoint zero. + * \b USB_TRANS_STATUS for status results on endpoint zero. + * @param ui32Endpoint is the endpoint to access. + * @param ui32TransType is set to indicate what type of data is being sent. + * @retval This call returns 0 on success, or -1 if a transmission is already + * in progress. + */ +int32_t md_usb_hosdev_endpoint_data_send(uint32_t ui32Endpoint, + uint32_t ui32TransType) +{ + uint32_t ui32TxPktRdy; + + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Get the bit position of TxPktRdy based on the endpoint. + // + if (ui32Endpoint == USB_EP_0) + { + // + // Don't allow transmit of data if the TxPktRdy bit is already set. + // + if (USB->CSR0L_TXCSRL & USB_CSR0L_TXCSRL_TXRDY_MSK) + { + return (-1); + } + + ui32TxPktRdy = ui32TransType & 0xff; + } + else + { + // + // Don't allow transmit of data if the TxPktRdy bit is already set. + // + if (USB->CSR0L_TXCSRL & USB_CSR0L_TXCSRL_TXPKTRDY_MSK) + { + return (-1); + } + + ui32TxPktRdy = (ui32TransType >> 8) & 0xff; + } + + // + // Set TxPktRdy in order to send the data. + // + USB->CSR0L_TXCSRL = ui32TxPktRdy; + + // + // Success. + // + return (0); +} + +/** + * @brief Forces a flush of an endpoint's FIFO. + * + * This function forces the USB controller to flush out the data in the FIFO. + * The function can be called with either host or device controllers and + * requires the \e ui32Flags parameter be one of \b USB_EP_HOST_OUT, + * \b USB_EP_HOST_IN, \b USB_EP_DEV_OUT, or \b USB_EP_DEV_IN. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags specifies if the IN or OUT endpoint is accessed. + * @retval None. + */ +void md_usb_hosdev_endpoint_data_togglec(uint32_t ui32Endpoint, + uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + if (ui32Flags & (USB_EP_HOST_OUT | USB_EP_DEV_IN)) + { + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_CLRDATAT_MSK; + } + else + { + USB->RXCSR1 |= USB_RXCSRL_CLRDT_MSK; + } +} + +/** + * @brief Sets the number of packets to request when transferring multiple bulk + * packets. + * + * This function sets the number of consecutive bulk packets to request + * when transferring multiple bulk packets with DMA. + * + * @param ui32Endpoint is the endpoint to access. + * @param ui32Count is the number of packets to request. + * @retval None. + */ +void md_usb_hosdev_endpoint_pkcount_set(uint32_t ui32Endpoint, + uint32_t ui32Count) +{ + /* It's not supported by es32f0271 */ +} + +/** + * @brief Returns the current status of an endpoint. + * + * This function returns the status of a specified endpoint. If any of these + * status bits must be cleared, then the md_usb_dev_endpoint_status_clear() or the + * md_usb_hos_endpoint_status_clear() functions must be called. + * + * The following are the status flags for host mode: + * + * - \b USB_HOST_IN_PID_ERROR - PID error on the specified endpoint. + * - \b USB_HOST_IN_NOT_COMP - The device failed to respond to an IN request. + * - \b USB_HOST_IN_STALL - A stall was received on an IN endpoint. + * - \b USB_HOST_IN_DATA_ERROR - There was a CRC or bit-stuff error on an IN + * endpoint in Isochronous mode. + * - \b USB_HOST_IN_NAK_TO - NAKs received on this IN endpoint for more than + * the specified timeout period. + * - \b USB_HOST_IN_ERROR - Failed to communicate with a device using this IN + * endpoint. + * - \b USB_HOST_IN_FIFO_FULL - This IN endpoint's FIFO is full. + * - \b USB_HOST_IN_PKTRDY - Data packet ready on this IN endpoint. + * - \b USB_HOST_OUT_NAK_TO - NAKs received on this OUT endpoint for more than + * the specified timeout period. + * - \b USB_HOST_OUT_NOT_COMP - The device failed to respond to an OUT + * request. + * - \b USB_HOST_OUT_STALL - A stall was received on this OUT endpoint. + * - \b USB_HOST_OUT_ERROR - Failed to communicate with a device using this + * OUT endpoint. + * - \b USB_HOST_OUT_FIFO_NE - This endpoint's OUT FIFO is not empty. + * - \b USB_HOST_OUT_PKTPEND - The data transfer on this OUT endpoint has not + * completed. + * - \b USB_HOST_EP0_NAK_TO - NAKs received on endpoint zero for more than the + * specified timeout period. + * - \b USB_HOST_EP0_ERROR - The device failed to respond to a request on + * endpoint zero. + * - \b USB_HOST_EP0_IN_STALL - A stall was received on endpoint zero for an + * IN transaction. + * - \b USB_HOST_EP0_IN_PKTRDY - Data packet ready on endpoint zero for an IN + * transaction. + * + * The following are the status flags for device mode: + * + * - \b USB_DEV_OUT_SENT_STALL - A stall was sent on this OUT endpoint. + * - \b USB_DEV_OUT_DATA_ERROR - There was a CRC or bit-stuff error on an OUT + * endpoint. + * - \b USB_DEV_OUT_OVERRUN - An OUT packet was not loaded due to a full FIFO. + * - \b USB_DEV_OUT_FIFO_FULL - The OUT endpoint's FIFO is full. + * - \b USB_DEV_OUT_PKTRDY - There is a data packet ready in the OUT + * endpoint's FIFO. + * - \b USB_DEV_IN_NOT_COMP - A larger packet was split up, more data to come. + * - \b USB_DEV_IN_SENT_STALL - A stall was sent on this IN endpoint. + * - \b USB_DEV_IN_UNDERRUN - Data was requested on the IN endpoint and no + * data was ready. + * - \b USB_DEV_IN_FIFO_NE - The IN endpoint's FIFO is not empty. + * - \b USB_DEV_IN_PKTPEND - The data transfer on this IN endpoint has not + * completed. + * - \b USB_DEV_EP0_SETUP_END - A control transaction ended before Data End + * condition was sent. + * - \b USB_DEV_EP0_SENT_STALL - A stall was sent on endpoint zero. + * - \b USB_DEV_EP0_IN_PKTPEND - The data transfer on endpoint zero has not + * completed. + * - \b USB_DEV_EP0_OUT_PKTRDY - There is a data packet ready in endpoint + * zero's OUT FIFO. + * + * @param The current status flags for the endpoint depending on mode. + * @retval None. + */ +uint32_t md_usb_hosdev_endpoint_status(uint32_t ui32Endpoint) +{ + uint32_t ui32Status; + + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Get the TX portion of the endpoint status. + // + ui32Status = USB->CSR0L_TXCSRL; + + // + // Get the RX portion of the endpoint status. + // Return zero if ui32Endpoint is equal to USB_EP_0. + // + ui32Status |= (((ui32Endpoint == USB_EP_0) ? 0x00 : USB->RXCSR1) << 16); + + // + // Return the endpoint status. + // + return (ui32Status); +} + +/** + * @brief Disables endpoint interrupts on a specified USB controller. + * + * This function disables endpoint interrupts for the USB controller specified + * by the \e ui32Base parameter. The \e ui32Flags parameter specifies which + * endpoint interrupts to disable. The flags passed in the \e ui32Flags + * parameters must be the definitions that start with \b USB_INTEP_* and not + * any other \b USB_INT flags. + * @param ui32IntFlags specifies which endpoint interrupts to disable. + * @retval None. + */ +void md_usb_hosdev_endpoint_int_disable(uint32_t ui32IntFlags) +{ + // + // If any transmit interrupts were disabled, then write the transmit + // interrupt settings out to the hardware. + // + USB->TXIER &= + ~(ui32IntFlags & (USB_INTEP_HOST_OUT | USB_INTEP_DEV_IN | USB_INTEP_0)); + + // + // If any receive interrupts were disabled, then write the receive + // interrupt settings out to the hardware. + // + USB->RXIER &= + ~((ui32IntFlags & (USB_INTEP_HOST_IN | USB_INTEP_DEV_OUT)) >> 16); +} + +/** + * @brief Enable endpoint interrupts on a specified USB controller. + * + * This function Enable endpoint interrupts for the USB controller specified + * by the \e ui32Base parameter. The \e ui32Flags parameter specifies which + * endpoint interrupts to disable. The flags passed in the \e ui32Flags + * parameters must be the definitions that start with \b USB_INTEP_* and not + * any other \b USB_INT flags. + * @param ui32IntFlags specifies which endpoint interrupts to Enable. + * @retval None. + */ +void md_usb_hosdev_endpoint_int_enable(uint32_t ui32IntFlags) +{ + // + // If any transmit interrupts were disabled, then write the transmit + // interrupt settings out to the hardware. + // + USB->TXIER |= + ui32IntFlags & (USB_INTEP_HOST_OUT | USB_INTEP_DEV_IN | USB_INTEP_0); + + // + // If any receive interrupts were disabled, then write the receive + // interrupt settings out to the hardware. + // + USB->RXIER |= + ((ui32IntFlags & (USB_INTEP_HOST_IN | USB_INTEP_DEV_OUT)) >> 16); +} + +/** + * @brief Returns the endpoint interrupt status on a specified USB controller. + * + * This function reads endpoint interrupt status for a USB controller. This + * call returns the current status for endpoint interrupts only, the control + * interrupt status is retrieved by calling md_usb_hosdev_int_status(). The bit + * values returned are compared against the \b USB_INTEP_* values. + * These values are grouped into classes for \b USB_INTEP_HOST_* and + * \b USB_INTEP_DEV_* values to handle both host and device modes with all + * endpoints. + * @param None. + * @note This call clears the source of all of the endpoint interrupts. + * @retval Returns the status of the endpoint interrupts for a USB controller. + */ +uint32_t md_usb_hosdev_endpoint_int_status(void) +{ + uint32_t ui32Status; + + // + // Get the transmit interrupt status. + // + ui32Status = USB->TXRIF; + ui32Status |= (USB->RXRIF << 16); + + // + // Clear the transmit interrupt status. + // + USB->TXICR = 0xff; + USB->RXICR = 0xff; + + // + // Return the combined interrupt status. + // + return (ui32Status); +} + +/** + * @brief Change the mode of the USB controller to OTG. + * + * This function changes the mode of the USB controller to OTG mode. + * + * @note This function must only be called on microcontrollers that support + * OTG operation. + * @param None. + * @retval None. + */ +uint32_t md_usb_endpoint_number_get(void) +{ + return 13; +} + +/** + * @} USB_MD_PF_ENDPOINT + */ + +/** @addtogroup USB_MD_PF_FIFO USB Public FIFO Functions + * @{ + */ + +/** + * @brief Returns the absolute FIFO address for a specified endpoint. + * + * This function returns the actual physical address of the FIFO. This + * address is needed when the USB is going to be used with the DMA + * controller and the source or destination address must be set to the + * physical FIFO address for a specified endpoint. This function can also be + * used to provide the physical address to manually read data from an + * endpoints FIFO. + * + * @param ui32Endpoint specifies which endpoint's FIFO address to return. + * @retval None. + */ +uint32_t md_usb_hosdev_fifo_addr_get(uint32_t ui32Endpoint) +{ + return (uint32_t)((uint32_t)(&USB->EP0FIFO) + ((uint32_t)USBEPToIndex(ui32Endpoint) << 2)); +} + +/** + * @brief Returns the FIFO configuration for an endpoint. + * + * This function returns the starting address and size of the FIFO for a + * specified endpoint. Endpoint zero does not have a dynamically configurable + * FIFO, so this function must not be called for endpoint zero. The + * \e ui32Flags parameter specifies whether the endpoint's OUT or IN FIFO must + * be read. If in host mode, the \e ui32Flags parameter must be + * \b USB_EP_HOST_OUT or \b USB_EP_HOST_IN, and if in device mode, the + * \e ui32Flags parameter must be either \b USB_EP_DEV_OUT or + * \b USB_EP_DEV_IN. + * + * @param ui32Endpoint is the endpoint to access. + * @param ui32FIFOAddress is the starting address for the FIFO. + * @param ui32FIFOSize is the size of the FIFO specified by one of the + * USB_FIFO_SZ_ values. + * @param ui32Flags specifies what information to set in the FIFO + * configuration. + * @retval None. + */ +void md_usb_hosdev_fifo_config_get(uint32_t ui32Endpoint, uint32_t *pui32FIFOAddress, + uint32_t *pui32FIFOSize, uint32_t ui32Flags) +{ + uint8_t temp; //use to clear warning in IAR system + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // See if the transmit or receive FIFO is being configured. + // + if (ui32Flags & (USB_EP_HOST_OUT | USB_EP_DEV_IN)) + { + temp = USB->TXFIFO1 & 0xff; + // + // Get the transmit FIFO location and size for this endpoint. + // + *pui32FIFOAddress = (temp | ((USB->TXFIFO2 & 0x0f) << 8)) << 3; + *pui32FIFOSize = (USB->TXFIFO2 & 0xe0) >> USB_TXFIFO2_MAXPKTSIZE_POSS; + } + else + { + temp = USB->RXFIFO1 & 0xff; + // + // Get the receive FIFO location and size for this endpoint. + // + *pui32FIFOAddress = (temp | ((USB->TXFIFO2 & 0x0f) << 8)) << 3; + + *pui32FIFOSize = (USB->RXFIFO2 & 0xe0) >> USB_RXFIFO2_MAXPKTSIZE_POSS; + } +} + +/** + * @brief Sets the FIFO configuration for an endpoint. + * + * This function configures the starting FIFO RAM address and size of the FIFO + * for a specified endpoint. Endpoint zero does not have a dynamically + * configurable FIFO, so this function must not be called for endpoint zero. + * The \e ui32FIFOSize parameter must be one of the values in the + * \b USB_FIFO_SZ_ values. + * + * The \e ui32FIFOAddress value must be a multiple of 8 bytes and directly + * indicates the starting address in the USB controller's FIFO RAM. For + * example, a value of 64 indicates that the FIFO starts 64 bytes into + * the USB controller's FIFO memory. The \e ui32Flags value specifies whether + * the endpoint's OUT or IN FIFO must be configured. If in host mode, use + * \b USB_EP_HOST_OUT or \b USB_EP_HOST_IN, and if in device mode, use + * \b USB_EP_DEV_OUT or \b USB_EP_DEV_IN. + * + * @param ui32Endpoint is the endpoint to access. + * @param ui32FIFOAddress is the starting address for the FIFO. + * @param ui32FIFOSize is the size of the FIFO specified by one of the + * USB_FIFO_SZ_ values. + * @param ui32Flags specifies what information to set in the FIFO + * configuration. + * @retval None. + */ +void md_usb_hosdev_fifo_config_set(uint32_t ui32Endpoint, uint32_t ui32FIFOAddress, + uint32_t ui32FIFOSize, uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // See if the transmit or receive FIFO is being configured. + // + if (ui32Flags & (USB_EP_HOST_OUT | USB_EP_DEV_IN)) + { + // + // Set the transmit FIFO location and size for this endpoint. + // + USB->TXFIFO1 = (uint8_t)((ui32FIFOAddress & 0xffff) >> 3); + + USB->TXFIFO2 = (uint8_t)((((ui32FIFOAddress & 0xffff) >> 3 >> 8) & 0x0f) + | (ui32FIFOSize) << USB_TXFIFO2_MAXPKTSIZE_POSS); + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_FLUSHFIFO_MSK; + } + else + { + // + // Set the receive FIFO location and size for this endpoint. + // + USB->RXFIFO1 = (uint8_t)((ui32FIFOAddress & 0xffff) >> 3); + + USB->RXFIFO2 = (uint8_t)((((ui32FIFOAddress & 0xffff) >> 3 >> 8) & 0x0f) + | (ui32FIFOSize) << USB_RXFIFO2_MAXPKTSIZE_POSS); + USB->RXCSR1 |= USB_RXCSRL_FLUSH_MSK; + } +} + +/** + * @brief Forces a flush of an endpoint's FIFO. + * + * This function forces the USB controller to flush out the data in the FIFO. + * The function can be called with either host or device controllers and + * requires the \e ui32Flags parameter be one of \b USB_EP_HOST_OUT, + * \b USB_EP_HOST_IN, \b USB_EP_DEV_OUT, or \b USB_EP_DEV_IN. + * + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags specifies if the IN or OUT endpoint is accessed. + * @retval None. + */ +void md_usb_hosdev_fifo_flush(uint32_t ui32Endpoint, uint32_t ui32Flags) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Endpoint zero has a different register set for FIFO flushing. + // + if (ui32Endpoint == USB_EP_0) + { + // + // Nothing in the FIFO if neither of these bits are set. + // + if ((USB->CSR0L_TXCSRL + & (USB_CSR0L_TXCSRL_TXRDY_MSK | USB_CSR0L_TXCSRL_RXRDY_MSK)) != 0) + { + // + // Hit the Flush FIFO bit. + // + USB->CSR0H_TXCSRH |= USB_CSR0H_TXCSRH_FLUSH_MSK; + } + } + else + { + // + // Only reset the IN or OUT FIFO. + // + if (ui32Flags & (USB_EP_HOST_OUT | USB_EP_DEV_IN)) + { + // + // Make sure the FIFO is not empty. + // + if (USB->CSR0L_TXCSRL & USB_CSR0L_TXCSRL_TXPKTRDY_MSK) + { + // + // Hit the Flush FIFO bit. + // + USB->CSR0L_TXCSRL |= USB_CSR0L_TXCSRL_FLUSHFIFO_MSK; + } + } + else + { + // + // Make sure that the FIFO is not empty. + // + if (USB->RXCSR1 & USB_RXCSRL_RXRDY_MSK) + { + // + // Hit the Flush FIFO bit. + // + USB->RXCSR1 |= USB_RXCSRL_FLUSH_MSK; + } + } + } +} + +/** + * @} USB_MD_PF_FIFO + */ + + +/** @addtogroup USB_MD_PF_EXPWR USB Public External Power Functions + * @{ + */ + +// +// The following pwr function is not supported by es32f0271 +// +/** + * @brief Disables the external power pin. + * + * This function disables the USBnEPEN signal, which disables an external + * power supply in host mode operation. + * + * @note This function must only be called in host mode. + * @retval None. + */ +__weak void md_usb_hos_pwr_disable(void) +{ +} + +/** + * @brief Enable the external power pin. + * + * This function disables the USBnEPEN signal, which disables an external + * power supply in host mode operation. + * + * @note This function must only be called in host mode. + * @retval None. + */ +__weak void md_usb_hos_pwr_enable(void) +{ + // + // Although Vbus is not supported by es32f0271,we provide Vbus + // from outside. + // + +} + +/** + * @brief Sets the configuration for USB power fault. + * + * This function controls how the USB controller uses its external power + * control pins (USBnPFLT and USBnEPEN). The flags specify the power + * fault level sensitivity, the power fault action, and the power enable level + * and source. + * + * One of the following can be selected as the power fault level sensitivity: + * + * - \b USB_HOST_PWRFLT_LOW - An external power fault is indicated by the pin + * being driven low. + * - \b USB_HOST_PWRFLT_HIGH - An external power fault is indicated by the pin + * being driven high. + * + * One of the following can be selected as the power fault action: + * + * - \b USB_HOST_PWRFLT_EP_NONE - No automatic action when power fault + * detected. + * - \b USB_HOST_PWRFLT_EP_TRI - Automatically tri-state the USBnEPEN pin on a + * power fault. + * - \b USB_HOST_PWRFLT_EP_LOW - Automatically drive USBnEPEN pin low on a + * power fault. + * - \b USB_HOST_PWRFLT_EP_HIGH - Automatically drive USBnEPEN pin high on a + * power fault. + * + * One of the following can be selected as the power enable level and source: + * + * - \b USB_HOST_PWREN_MAN_LOW - USBnEPEN is driven low by the USB controller + * when USBHostPwrEnable() is called. + * - \b USB_HOST_PWREN_MAN_HIGH - USBnEPEN is driven high by the USB + * controller when USBHostPwrEnable() is + * called. + * - \b USB_HOST_PWREN_AUTOLOW - USBnEPEN is driven low by the USB controller + * automatically if USBOTGSessionRequest() has + * enabled a session. + * - \b USB_HOST_PWREN_AUTOHIGH - USBnEPEN is driven high by the USB + * controller automatically if + * USBOTGSessionRequest() has enabled a + * session. + * + * When using the VBUS glitch filter, the \b USB_HOST_PWREN_FILTER can be + * addded to ignore small, short drops in VBUS level caused by high power + * consumption. This feature is mainly used to avoid causing VBUS errors + * caused by devices with high in-rush current. + * + * @note This function must only be called on microcontrollers that support + * host mode or OTG operation. The \b USB_HOST_PWREN_AUTOLOW and + * \b USB_HOST_PWREN_AUTOHIGH parameters can only be specified on devices that + * support OTG operation. + * @retval None. + */ +void md_usb_hos_pwr_config(uint32_t ui32Flags) +{ +} + +/** + * @brief Disable power fault detection. + * + * This function enables power fault detection in the USB controller. If the + * USBnPFLT pin is not in use, this function must not be used. + * + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_pwrfault_disable(void) +{ +} + +/** + * @brief Enable power fault detection. + * + * This function enables power fault detection in the USB controller. If the + * USBnPFLT pin is not in use, this function must not be used. + * + * @note This function must only be called in host mode. + * @retval None. + */ +void md_usb_hos_pwrfault_enable(void) +{ +} + +/** + * @} USB_MD_PF_EXPWR + */ + +/** @addtogroup USB_MD_PF_LPM USB Public LPM Functions + * @{ + */ + +// +// LPM is not supported by es32f0271 +// + +/** + * @brief Sends an LPM request to a device at a specified address and endpoint number. + * + * This function sends an LPM request to a connected device in host mode. + * The \e ui32Address parameter specifies the device address and has a range + * of values from 1 to 127. The \e ui32Endpoint parameter specifies the + * endpoint on the device to which to send the LPM request and must be one of + * the \b USB_EP_* values. The function returns before the LPM request is + * sent, requiring the caller to poll the md_usb_lpm_status() function or wait + * for an interrupt to signal completion of the LPM transaction. This + * function must only be called after the md_usb_hos_lpm_config() has configured + * the LPM transaction settings. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param ui32Address is the target device address for the LPM request. + * @param ui32Endpoint is the target endpoint for the LPM request. + * @retval None. + */ +void md_usb_hos_lpm_send(uint32_t ui32Address, + uint32_t uiEndpoint) +{ +} + +/** + * @brief Sets the global configuration for all LPM requests. + * + * This function sets the global configuration options for LPM transactions + * and must be called at least once before ever calling md_usb_hos_lpm_send(). The + * \e ui32ResumeTime specifies the length of time that the host drives resume + * signaling on the bus in microseconds. The valid values + * for \e ui32ResumeTime are from 50us to 1175us in 75us increments. The + * remaining configuration is specified by the \e ui32Config parameter and + * includes the following options: + * + * - \b USB_HOST_LPM_RMTWAKE allows the device to signal a remote wake from + * the LPM state. + * - \b USB_HOST_LPM_L1 is the LPM mode to enter and must always be included + * in the configuration. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param ui32Address is the target device address for the LPM request. + * @param ui32Endpoint is the target endpoint for the LPM request. + * @retval None. + */ +void md_usb_hos_lpm_config(uint32_t ui32ResumeTime, + uint32_t ui32Config) +{ +} + +/** + * @brief Returns if remote wake is currently enabled. + * + * This function returns the current state of the remote wake setting for host + * or device mode operation. If the controller is acting as a host this + * returns the current setting that is sent to devices when LPM requests are + * sent to a device. If the controller is in device mode, this function + * returns the state of the last LPM request sent from the host and indicates + * if the host enabled remote wakeup. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param None. + * @retval The \b true if remote wake is enabled or \b false if it is not. + */ +bool md_usb_lpm_remotewake_is_enabled(void) +{ + return 0; +} + +/** + * @brief Initiates resume signaling to wake a device from LPM suspend mode. + * + * In host mode, this function initiates resume signaling to wake a device + * that has entered an LPM-triggered low power mode. This LPM-triggered low + * power mode is entered when the md_usb_hos_lpm_send() is called to put a specific + * device into a low power state. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param None. + * @retval None. + */ +void md_usb_hos_lpm_resume(void) +{ +} + +/** + * @brief Initiates remote wake signaling to request the device to leave LPM + * suspend mode. + * + * This function initiates remote wake signaling to request that the host + * wake a device that has entered an LPM-triggered low power mode. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param None. + * @retval None. + */ +void md_usb_dev_lpm_remotewake(void) +{ +} + +/** + * @brief Configures the USB device mode response to LPM requests. + * + * This function sets the global configuration options for LPM + * transactions in device mode and must be called before ever calling + * md_usb_dev_lpm_enable() to set the configuration for LPM transactions. The + * configuration options in device mode are specified in the \e ui32Config + * parameter and include one of the following: + * + * - \b USB_DEV_LPM_NONE disables the USB controller from responding to LPM + * transactions. + * - \b USB_DEV_LPM_EN enables the USB controller to respond to LPM + * and extended transactions. + * - \b USB_DEV_LPM_EXTONLY enables the USB controller to respond to + * extended transactions, but not LPM transactions. + * + * The \e ui32Config option can also optionally include the + * \b USB_DEV_LPM_NAK value to cause the USB controller to NAK all + * transactions other than an LPM transaction once the USB controller is in + * LPM suspend mode. If this value is not included in the \e ui32Config + * parameter, the USB controller does not respond in suspend mode. + * + * The USB controller does not enter LPM suspend mode until the application + * calls the md_usb_dev_lpm_enable() function. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param ui32Config is the combination of configuration options for LPM + * transactions in device mode. + * @retval None. + */ +void md_usb_dev_lpm_config(uint32_t ui32Config) +{ +} + +/** + * @brief Enables the USB controller to respond to LPM suspend requests. + * + * This function is used to automatically respond to an LPM sleep request from + * the USB host controller. If there is no data pending in any transmit + * FIFOs, then the USB controller acknowledges the packet and enters the + * LPM L1 state and generates the \b USB_INTLPM_ACK interrupt. If the USB + * controller has pending transmit data in at least one FIFO, then the USB + * controller responds with NYET and signals the \b USB_INTLPM_INCOMPLETE or + * \b USB_INTLPM_NYET depending on if data is pending in receive or transmit + * FIFOs. A call to md_usb_dev_lpm_enable() is required after every + * LPM resume event to re-enable LPM mode. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param None. + * @retval None. + */ +void md_usb_dev_lpm_enable(void) +{ +} + +/** + * @brief Disables the USB controller to respond to LPM suspend requests. + * + * This function disables the USB controller from responding to LPM + * transactions. When the device enters LPM L1 mode, the USB controller + * automatically disables responding to further LPM transactions. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param None. + * @retval None. + */ +void md_usb_dev_lpm_disable(void) +{ +} + +/** + * @brief Returns the current link state setting. + * + * This function returns the current link state setting for the USB + * controller. When the controller is operating as a host, this link + * state is sent with an LPM request. When the controller is acting + * as a device, this link state was received by the last LPM transaction + * whether it was acknowledged or stalled because the requested + * LPM mode is not supported. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param None. + * @retval The current LPM link state. + */ +uint32_t md_usb_lpm_link_state_get(void) +{ + return 0; +} + +/** + * @brief Returns the current LPM endpoint value. + * + * This function returns the current LPM endpoint value. The meaning of the + * value depends on the mode of operation of the USB controller. When in + * device mode, the value returned is the endpoint that received the last + * LPM transaction. When in host mode this is the endpoint that was last + * sent an LPM transaction, or the endpoint that is configured to be sent when + * the LPM transaction is triggered. The value returned is in the + * \b USB_EP_[0-7] value and a direct endpoint index. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param None. + * @retval The last endpoint to receive an LPM request in device mode or the + * endpoint that the host sends an LPM request as one of the \b USB_EP_[0-7] + * values. + */ +uint32_t md_usb_lpm_endpoint_get(void) +{ + return 0; +} + +/** + * @brief Returns the current LPM interrupt status. + * + * This function returns the current LPM interrupt status for the USB + * controller. + * + * The valid interrupt status bits when the USB controller is acting as a host + * are the following: + * + * - \b USB_INTLPM_ERROR a bus error occurred in the transmission of an LPM + * transaction. + * - \b USB_INTLPM_RESUME the USB controller has resumed from the LPM low + * power state. + * - \b USB_INTLPM_INCOMPLETE the LPM transaction failed because a timeout + * occurred or there were bit errors in the response for three attempts. + * - \b USB_INTLPM_ACK the device has acknowledged an LPM transaction. + * - \b USB_INTLPM_NYET the device has responded with a NYET to an LPM + * transaction. + * - \b USB_INTLPM_STALL the device has stalled an LPM transaction. + * + * The valid interrupt status bits when the USB controller is acting as a + * device are the following: + * + * - \b USB_INTLPM_ERROR an LPM transaction was received that has an + * unsupported link state field. The transaction was stalled, but the + * requested link state can still be read using the md_usb_lpm_link_state_get() + * function. + * - \b USB_INTLPM_RESUME the USB controller has resumed from the LPM low + * power state. + * - \b USB_INTLPM_INCOMPLETE the USB controller responded to an LPM + * transaction with a NYET because data was still in the transmit FIFOs. + * - \b USB_INTLPM_ACK the USB controller acknowledged an LPM transaction and + * is now in the LPM suspend mode. + * - \b USB_INTLPM_NYET the USB controller responded to an LPM transaction + * with a NYET because LPM transactions are not yet enabled by a call to + * md_usb_dev_lpm_enable(). + * - \b USB_INTLPM_STALL the USB controller has stalled an incoming LPM + * transaction. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param None. + * @retval The \b true if remote wake is enabled or \b false if it is not. + */ +uint32_t md_usb_lpm_status(void) +{ + return 0; +} + +/** + * @brief Enables LPM interrupts. + * + * This function enables a set of LPM interrupts so that they can trigger a + * USB interrupt. The \e ui32Ints parameter specifies which of the + * \b USB_INTLPM_* to enable. + * + * The valid interrupt status bits when the USB controller is acting as a host + * are the following: + * + * - \b USB_INTLPM_ERROR a bus error occurred in the transmission of an LPM + * transaction. + * - \b USB_INTLPM_RESUME the USB controller has resumed from LPM low power + * state. + * - \b USB_INTLPM_INCOMPLETE the LPM transaction failed because a timeout + * occurred or there were bit errors in the response for three attempts. + * - \b USB_INTLPM_ACK the device has acknowledged an LPM transaction. + * - \b USB_INTLPM_NYET the device has responded with a NYET to an LPM + * transaction. + * - \b USB_INTLPM_STALL the device has stalled an LPM transaction. + * + * The valid interrupt status bits when the USB controller is acting as a + * device are the following: + * + * - \b USB_INTLPM_ERROR an LPM transaction was received that has an + * unsupported link state field. The transaction was stalled, but the + * requested link state can still be read using the md_usb_lpm_link_state_get() + * function. + * - \b USB_INTLPM_RESUME the USB controller has resumed from the LPM low + * power state. + * - \b USB_INTLPM_INCOMPLETE the USB controller responded to an LPM + * transaction with a NYET because data was still in the transmit FIFOs. + * - \b USB_INTLPM_ACK the USB controller acknowledged an LPM transaction and + * is now in the LPM suspend mode. + * - \b USB_INTLPM_NYET the USB controller responded to an LPM transaction + * with a NYET because LPM transactions are not yet enabled by a call to + * md_usb_dev_lpm_enable(). + * - \b USB_INTLPM_STALL the USB controller has stalled an incoming LPM + * transaction. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param ui32Ints specifies which LPM interrupts to enable. + * @retval None. + */ +void md_usb_lpm_int_enable(uint32_t ui32Ints) +{ +} + +/** + * @brief Disables LPM interrupts. + * + * This function disables the LPM interrupts specified in the \e ui32Ints + * parameter, preventing them from triggering a USB interrupt. + * + * The valid interrupt status bits when the USB controller is acting as a host + * are the following: + * + * - \b USB_INTLPM_ERROR a bus error occurred in the transmission of an LPM + * transaction. + * - \b USB_INTLPM_RESUME the USB controller has resumed from LPM low power + * state. + * - \b USB_INTLPM_INCOMPLETE the LPM transaction failed because a timeout + * occurred or there were bit errors in the response for three attempts. + * - \b USB_INTLPM_ACK the device has acknowledged an LPM transaction. + * - \b USB_INTLPM_NYET the device has responded with a NYET to an LPM + * transaction. + * - \b USB_INTLPM_STALL the device has stalled an LPM transaction. + * + * The valid interrupt status bits when the USB controller is acting as a + * device are the following: + * + * - \b USB_INTLPM_ERROR an LPM transaction was received that has an + * unsupported link state field. The transaction was stalled, but the + * requested link state can still be read using the md_usb_lpm_link_state_get() + * function. + * - \b USB_INTLPM_RESUME the USB controller has resumed from the LPM low + * power state. + * - \b USB_INTLPM_INCOMPLETE the USB controller responded to an LPM + * transaction with a NYET because data was still in the transmit FIFOs. + * - \b USB_INTLPM_ACK the USB controller acknowledged an LPM transaction and + * is now in the LPM suspend mode. + * - \b USB_INTLPM_NYET the USB controller responded to an LPM transaction + * with a NYET because LPM transactions are not yet enabled by a call to + * md_usb_dev_lpm_enable(). + * - \b USB_INTLPM_STALL the USB controller has stalled an incoming LPM + * transaction. + * + * @note This function must only be called in host mode. The USB LPM feature + * is not available on all ES32 devices. Please consult the data sheet for + * the ES32 device that you are using to determine if this feature is + * available. + * @param ui32Ints specifies which LPM interrupts to disable. + * @retval None. + */ +void md_usb_lpm_int_disable(uint32_t ui32Ints) +{ +} + +/** + * @} USB_MD_PF_LPM + */ + +/** @addtogroup USB_MD_PF_ULPI USB Public ULPI Functions + * @{ + */ + +// +// ULPI is not supported by es32f0271 +// + +/** + * @brief Configures the USB controller's ULPI function. + * + * This function is used to configure the USB controller's ULPI function. + * The configuration options are set in the \e ui32Config parameter and are a + * logical OR of the following values: + * + * - \b USB_ULPI_EXTVBUS enables the external ULPI PHY as the source for VBUS + * signaling. + * - \b USB_ULPI_EXTVBUS_IND enables the external ULPI PHY to detect external + * VBUS over-current condition. + * + * @note The USB ULPI feature is not available on all Tiva devices. + * Please consult the data sheet for the Tiva device that you + * are using to determine if this feature is available. + * @param ui32Config contains the configuration options. + * @retval None. + */ +void md_usb_ulpi_config(uint32_t ui32Config) +{ +} + +/** + * @brief Enables the USB controller's ULPI function. + * + * This function enables the USB controller's ULPI function and must be + * called before attempting to access an external ULPI-connected USB PHY. + * + * @note The USB ULPI feature is not available on all Tiva devices. + * Please consult the data sheet for the Tiva device that you + * are using to determine if this feature is available. + * @param None. + * @retval None. + */ +void md_usb_ulpi_enable(void) +{ +} + +/** + * @brief Disables the USB controller's ULPI function. + * + * This function Disables the USB controller's ULPI function and must be + * called before attempting to access an external ULPI-connected USB PHY. + * + * @note The USB ULPI feature is not available on all Tiva devices. + * Please consult the data sheet for the Tiva device that you + * are using to determine if this feature is available. + * @param None. + * @retval None. + */ +void md_usb_ulpi_disable(void) +{ +} + +/** + * @brief Disables the USB controller's ULPI function. + * + * This function Disables the USB controller's ULPI function and must be + * called before attempting to access an external ULPI-connected USB PHY. + * + * @note The USB ULPI feature is not available on all Tiva devices. + * Please consult the data sheet for the Tiva device that you + * are using to determine if this feature is available. + * @param None. + * @retval None. + */ +uint8_t md_usb_ulpi_reg_read(uint8_t ui8Reg) +{ + return 0; +} + +/** + * @brief Writes a value to a register on an external ULPI-connected USB PHY. + * + * This function writes the register address specified in the \e ui8Reg + * parameter with the value specified in the \e ui8Data parameter using the + * ULPI function. This function is blocking and only returns when the + * write access completes. The function does not return if there is not a + * ULPI-connected USB PHY present. + * + * @note The USB ULPI feature is not available on all Tiva devices. + * Please consult the data sheet for the Tiva device that you + * are using to determine if this feature is available. + * @param ui8Reg specifies the register address to write. + * @param ui8Data specifies the data to write. + * @retval None. + */ +void md_usb_ulpi_reg_write(uint8_t ui8Reg, + uint8_t ui8Data) +{ +} + +/** + * @} USB_MD_PF_ULPI + */ + +/** @addtogroup USB_MD_PF_DMA USB Public DMA Functions + * @{ + */ + +// +// USB DMA is not supported by es32f0271 +// + +/** + * @brief Sets the DMA channel to use for a specified endpoint. + * + * This function is used to configure which DMA channel to use with a specified + * endpoint. Receive DMA channels can only be used with receive endpoints + * and transmit DMA channels can only be used with transmit endpoints. + * + * @note This function only has an effect on microcontrollers that have the + * ability to change the DMA channel for an endpoint. Calling this function + * on other devices has no effect. + * @param ui32Endpoint specifies which endpoint's FIFO address to return. + * @param ui32Channel specifies which DMA channel to use for which endpoint. + * @retval None. + */ +void md_usb_dma_endpoint_channel_set(uint32_t ui32Endpoint, + uint32_t ui32Channel) +{ + // + // It is not supported by es32f0271 + // + return; +} + +/** + * @brief Enable DMA on a specified endpoint. + * + * This function enables DMA on a specified endpoint and configures the mode + * according to the values in the \e ui32Flags parameter. The \e ui32Flags + * parameter must have \b USB_EP_DEV_IN or \b USB_EP_DEV_OUT set. Once this + * function is called the only DMA or error interrupts are generated by the + * USB controller. + * + * @note This function only has an effect on microcontrollers that have the + * ability to change the DMA channel for an endpoint. Calling this function + * on other devices has no effect. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags specifies which direction and what mode to use when + * enabling DMA. + * @retval None. + */ +void md_usb_dma_endpoint_enable(uint32_t ui32Endpoint, + uint32_t ui32Flags) +{ + // + // It is not supported by es32f0271 + // + return; +} + +/** + * @brief Disable DMA on a specified endpoint. + * + * This function disables DMA on a specified endpoint to allow non-DMA USB + * transactions to generate interrupts normally. The \e ui32Flags parameter + * must be \b USB_EP_DEV_IN or \b USB_EP_DEV_OUT; all other bits are ignored. + * + * @note This function only has an effect on microcontrollers that have the + * ability to change the DMA channel for an endpoint. Calling this function + * on other devices has no effect. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Flags specifies which direction to disable. + * @retval None. + */ +void md_usb_dma_endpoint_disable(uint32_t ui32Endpoint, + uint32_t ui32Flags) +{ + // + // It is not supported by es32f0271 + // + return; +} + +/** + * @brief Configure the DMA settings for an endpoint. + * + * This function configures the DMA settings for a specified endpoint without + * changing other options that may already be configured. In order for the + * DMA transfer to be enabled, the md_usb_dma_endpoint_enable() function must be + * called before starting the DMA transfer. The configuration + * options are passed in the \e ui32Config parameter and can have the values + * described below. + * + * One of the following values to specify direction: + * - \b USB_EP_HOST_OUT or \b USB_EP_DEV_IN - This setting is used with + * DMA transfers from memory to the USB controller. + * - \b USB_EP_HOST_IN or \b USB_EP_DEV_OUT - This setting is used with + * DMA transfers from the USB controller to memory. + * + * One of the following values: + * - \b USB_EP_DMA_MODE_0(default) - This setting is typically used for + * transfers that do not span multiple packets or when interrupts are + * required for each packet. + * - \b USB_EP_DMA_MODE_1 - This setting is typically used for + * transfers that span multiple packets and do not require interrupts + * between packets. + * + * Values only used with \b USB_EP_HOST_OUT or \b USB_EP_DEV_IN: + * - \b USB_EP_AUTO_SET - This setting is used to allow transmit DMA transfers + * to automatically be sent when a full packet is loaded into a FIFO. + * This is needed with \b USB_EP_DMA_MODE_1 to ensure that packets go + * out when the FIFO becomes full and the DMA has more data to send. + * + * Values only used with \b USB_EP_HOST_IN or \b USB_EP_DEV_OUT: + * - \b USB_EP_AUTO_CLEAR - This setting is used to allow receive DMA + * transfers to automatically be acknowledged as they are received. This is + * needed with \b USB_EP_DMA_MODE_1 to ensure that packets continue to + * be received and acknowledged when the FIFO is emptied by the DMA + * transfer. + * + * Values only used with \b USB_EP_HOST_IN: + * - \b USB_EP_AUTO_REQUEST - This setting is used to allow receive DMA + * transfers to automatically request a new IN transaction when the + * previous transfer has emptied the FIFO. This is typically used in + * conjunction with \b USB_EP_AUTO_CLEAR so that receive DMA transfers + * can continue without interrupting the main processor. + * + * @note This function only has an effect on microcontrollers that have the + * ability to change the DMA channel for an endpoint. Calling this function + * on other devices has no effect. + * @param ui32Endpoint is the endpoint to access. + * @param ui32Config specifies the configuration options for an endpoint. + * @retval None. + */ +void md_usb_dma_endpoint_config(uint32_t ui32Endpoint, uint32_t ui32Config) +{ + // + //Chose endpoint. + // + USB->INDEX = (uint8_t)USBEPToIndex(ui32Endpoint); + + // + // Host out or device in. + // + if ((ui32Config & USB_EP_HOST_OUT) && (ui32Config & USB_EP_AUTO_SET)) + { + USB->CSR0H_TXCSRH |= USB_CSR0H_TXCSRH_AUTOSET_MSK; + } + else + { + if (ui32Config & USB_EP_AUTO_REQUEST) + { + USB->RXCSR2 |= USB_RXCSRH_AUTOREQ_MSK; + } + + if (ui32Config & USB_EP_AUTO_CLEAR) + { + USB->RXCSR2 |= USB_RXCSRH_AUTOCLR_MSK; + } + } +} + +/** + * @brief Assigns and configures an endpoint to a specified integrated USB DMA + * channel. + * + * This function assigns an endpoint and configures the settings for a + * USB DMA channel. The \e ui32Endpoint parameter is one of the + * \b USB_EP_* values and the \e ui32Channel value is a zero-based index of + * the DMA channel to configure. The \e ui32Config parameter is a combination + * of the \b USB_DMA_CFG_* values using the following guidelines. + * + * Use one of the following to set the DMA burst mode: + * - \b USB_DMA_CFG_BURST_NONE disables bursting. + * - \b USB_DMA_CFG_BURST_4 sets the DMA burst size to 4 words. + * - \b USB_DMA_CFG_BURST_8 sets the DMA burst size to 8 words. + * - \b USB_DMA_CFG_BURST_16 sets the DMA burst size to 16 words. + * + * Use one of the following to set the DMA mode: + * - \b USB_DMA_CFG_MODE_0 is typically used when only a single packet is + * being sent via DMA and triggers one completion interrupt per packet. + * - \b USB_DMA_CFG_MODE_1 is typically used when multiple packets are being + * sent via DMA and triggers one completion interrupt per transfer. + * + * Use one of the following to set the direction of the transfer: + * - \b USB_DMA_CFG_DIR_RX selects a DMA transfer from the endpoint to a + * memory location. + * - \b USB_DMA_CFG_DIR_TX selects a DMA transfer to the endpoint from a + * memory location. + * + * The following two optional settings allow an application to immediately + * enable the DMA transfer and/or DMA interrupts when configuring the DMA + * channel: + * - \b USB_DMA_CFG_INT_EN enables interrupts for this channel immediately so + * that an added call to md_usb_dma_channel_int_enable() is not necessary. + * - \b USB_DMA_CFG_EN enables the DMA channel immediately so that an added + * call to md_usb_dma_channel_enable() is not necessary. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller or if it must use the DMA controller for DMA transfers. + * @param ui32Channel specifies which DMA channel to access. + * @param ui32Endpoint is the endpoint to assign to the USB DMA channel. + * @param ui32Config is used to specify the configuration of the USB DMA channel. + * @retval None. + */ +void md_usb_dma_channel_config(uint32_t ui32Channel, + uint32_t ui32Endpoint, uint32_t ui32Config) +{ + // + // It is not supported by es32f0271 + // +} + +/** + * @brief Sets the source or destination address for an integrated USB DMA transfer + * on a specified channel. + * + * This function sets the source or destination address for the USB DMA + * channel number specified in the \e ui32Channel parameter. The + * \e ui32Channel value is a zero-based index of the USB DMA channel. The + * \e pvAddress parameter is a source address if the transfer type for the DMA + * channel is transmit and a destination address if the transfer type is + * receive. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller or if it must use the DMA controller for DMA transfers. + * @param ui32Channel specifies which DMA channel to access. + * @param pvAddress specifies the source or destination address for the USB + * DMA transfer. + * @retval None. + */ +void md_usb_dma_channel_address_set(uint32_t ui32Channel, + void *pvAddress) +{ + // + // It is not supported by es32f0271 + // + return; +} + +/** + * @brief Returns the source or destination address for the specified integrated USB + * DMA channel. + * + * This function returns the DMA address for the channel number specified + * in the \e ui32Channel parameter. The \e ui32Channel value is a zero-based + * index of the DMA channel to query. This function must not be used on + * devices that return \b USB_CONTROLLER_VER_0 from the USBControllerVersion() + * function. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller or if it must use the DMA controller for DMA transfers. + * @param ui32Channel specifies which DMA channel to access. + * @retval The current DMA address for a USB DMA channel. + */ +void *md_usb_dma_channel_address_get(uint32_t ui32Channel) +{ + // + // It is not supported by es32f0271 + // + return 0; +} + +/** + * @brief Sets the transfer count for an integrated USB DMA channel. + * + * This function sets the USB DMA transfer count in bytes for the channel + * number specified in the \e ui32Channel parameter. The \e ui32Channel + * value is a zero-based index of the DMA channel. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller or if it must use the DMA controller for DMA transfers. + * @param ui32Count specifies the number of bytes to transfer. + * @param ui32Channel specifies which DMA channel to access. + * @retval None. + */ +void md_usb_dma_channel_count_set(uint32_t ui32Count, + uint32_t ui32Channel) +{ + // + // It is not supported by es32f0271 + // + return; +} + +/** + * @brief Returns the transfer count for an integrated USB DMA channel. + * + * This function returns the USB DMA transfer count in bytes for the channel + * number specified in the \e ui32Channel parameter. The \e ui32Channel value + * is a zero-based index of the DMA channel to query. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller or if it must use the DMA controller for DMA transfers. + * @param ui32Channel specifies which DMA channel to access. + * @retval The current count for a USB DMA channel. + */ +uint32_t md_usb_dma_channel_count_get(uint32_t ui32Channel) +{ + // + // It is not supported by es32f0271 + // + return 0; +} + +/** + * @brief Returns the available number of integrated USB DMA channels. + * + * This function returns the total number of DMA channels available when using + * the integrated USB DMA controller. This function returns 0 if the + * integrated controller is not present. + * + * @note The number of integrated USB DMA channels or zero if the + * integrated USB DMA controller is not present. + * @param None. + * @retval The number of integrated USB DMA channels or zero if the + * integrated USB DMA controller is not present. + */ +uint32_t md_usb_dma_channel_number(void) +{ + // + // It is not supported by es32f0271 + // + return 0; +} + +/** + * @brief Enable interrupts for a specified integrated USB DMA channel. + * + * This function enables the USB DMA channel interrupt based on the + * \e ui32Channel parameter. The \e ui32Channel value is a zero-based + * index of the USB DMA channel. Once enabled, the md_usb_dma_channel_int_status() + * function returns if a DMA channel has generated an interrupt. + * + * @note The number of integrated USB DMA channels or zero if the + * integrated USB DMA controller is not present. + * @param ui32Channel specifies which DMA channel interrupt to enable. + * @retval None. + */ +void md_usb_dma_channel_int_enable(uint32_t ui32Channel) +{ + // + // It is not supported by es32f0271 + // +} + +/** + * @brief Return the current status of the integrated USB DMA interrupts. + * + * This function returns the current bit-mapped interrupt status for all USB + * DMA channel interrupt sources. Calling this function automatically clears + * all currently pending USB DMA interrupts. + * + * @param None. + * @retval None. + */ +uint32_t md_usb_dma_channel_int_status(void) +{ + return 0; +} + +/** + * @brief Enables USB DMA for a specified channel. + * + * This function enables the USB DMA channel passed in the \e ui32Channel + * parameter. The \e ui32Channel value is a zero-based index of the USB DMA + * channel. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller. + * @param ui32Channel specifies the USB DMA channel to enable. + * @retval None. + */ +void md_usb_dma_channel_enable(uint32_t ui32Channel) +{ + // + // DMA1 will be used by es32f0271 + // + SET_BIT(*(&DMA1->CSR0 + 4 * ui32Channel), DMA_CSR0_CHEN_MSK); +} + +/** + * @brief Disables USB DMA for a specified channel. + * + * This function Disables the USB DMA channel passed in the \e ui32Channel + * parameter. The \e ui32Channel value is a zero-based index of the USB DMA + * channel. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller. + * @param ui32Channel specifies the USB DMA channel to Disable. + * @retval None. + */ +void md_usb_dma_channel_disable(uint32_t ui32Channel) +{ + // + // DMA1 will be used by es32f0271 + // + CLEAR_BIT(*(&DMA1->CSR0 + 4 * ui32Channel), DMA_CSR0_CHEN_MSK); +} + +/** + * @brief Check if the USB channel is enabled. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller. + * @param ui32Channel specifies the USB DMA channel. + * @retval Return 1 if the channel is enabled. + */ +uint32_t md_usb_dma_channel_isenabled(uint32_t ui32Channel) +{ + if (*((uint32_t *)(&DMA1->CSR0 + ui32Channel * 4)) & DMA_CSR0_CHEN_MSK) + return 1; + + return 0; +} + +/** + * @brief Returns the current status for an integrated USB DMA channel. + * + * This function returns the current status for the USB DMA channel specified + * by the \e ui32Channel parameter. The \e ui32Channel value is a zero-based + * index of the USB DMA channel to query. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller or if it must use the DMA controller for DMA transfers. + * @param ui32Channel specifies the USB DMA channel to Disable. + * @retval Returns zero or \b USB_DMACTL0_ERR if there is a pending error + * condition on a DMA channel. + */ +uint32_t md_usb_dma_channel_status(uint32_t ui32Channel) +{ + // + // It is not supported by es32f0271 + // + return 0; +} + +/** + * @brief Clears the integrated USB DMA status for a specified channel. + * + * This function clears the USB DMA channel status for the channel specified + * by the \e ui32Channel parameter. The \e ui32Channel value is a zero-based + * index of the USB DMA channel to query. The \e ui32Status parameter + * specifies the status bits to clear and must be the valid values that are + * returned from a call to the md_usb_dma_channel_status() function. + * + * @note This feature is not available on all ES32 devices. Please + * check the data sheet to determine if the USB controller has a DMA + * controller or if it must use the DMA controller for DMA transfers. + * @param ui32Channel specifies the USB DMA channel to Disable. + * @retval None. + */ +void md_usb_dma_channel_status_clear(uint32_t ui32Channel, + uint32_t ui32Status) +{ + // + // It is not supported by es32f0271 + // +} + +/** + * @} USB_MD_PF_DMA + */ + +/** + * @} USB_MD_Public_Functions + */ + +/** + * @} USB + */ + +#endif + +/** + * @} Micro_Driver + */ + +/******************* (C) COPYRIGHT Eastsoft Microelectronics END OF MAIN.C****/ diff --git a/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_wwdt.c b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_wwdt.c new file mode 100644 index 0000000000..fdba390e17 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/ES32F027x_MD_StdPeriph_Driver/Source/md_wwdt.c @@ -0,0 +1,86 @@ +/** + ****************************************************************************** + * @file md_wwdt.c + * @brief ES32F0271 WWDT Source File. + * + * @version V1.00.01 + * @date 4/12/2018 + * @author Eastsoft AE Team + * @note + * detailed description + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + ******************************************************************************* + */ + +/* Includes -------------------------------------------------------------------*/ +#include "md_rcu.h" +#include "md_wwdt.h" + +/** @addtogroup Micro_Driver + * @{ + */ + +#if defined (WWDT) + +/** @defgroup WWDT WWDT + * @brief WWDT micro driver + * @{ + */ + +/* Private types --------------------------------------------------------------*/ +/* Private variables ----------------------------------------------------------*/ +/* Private constants ----------------------------------------------------------*/ +/* Private macros -------------------------------------------------------------*/ + +/* Public functions -----------------------------------------------------------*/ +/** @addtogroup MD_RCU_Public_Functions RCU Public Functions + * @{ + */ +/** + * @brief De-initialize the GPIO registers to their default reset values. + * @param GPIOx GPIO Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: GPIO registers are de-initialized + * - ERROR: GPIO registers are not de-initialized + */ +void md_wwdt_init(WWDT_TypeDef *WWD, md_wwdt_inittypedef *WWDT_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_MD_WWDT_ALL_INSTANCE(WWD)); + assert_param(IS_MD_WWDT_PRESCALER(WWDT_InitStruct->Prescaler)); + assert_param(IS_MD_WWDT_WINDOW(WWDT_InitStruct->Window)); + assert_param(IS_MD_WWDT_COUNTER(WWDT_InitStruct->Counter)); + assert_param(IS_MD_WWDT_EWI_MODE(WWDT_InitStruct->EWIMode)); + + if (WWDT_InitStruct->EWIMode == WWDT_EWI_ENABLE) + md_wwdt_enable_ier_ewis(WWD); + else + md_wwdt_disable_idr_ewis(WWD); + + md_wwdt_set_con_t(WWD, WWDT_InitStruct->Counter); + md_wwdt_set_cfg_wdgtb(WWD, WWDT_InitStruct->Prescaler); + md_wwdt_set_cfg_w(WWD, WWDT_InitStruct->Window); + md_wwdt_enable_con_wdga(WWD); +} + + + + + + + + + + + +/** + * @} GPIO + */ +#endif + +/** + * @} Micro_Driver + */ + +/******************* (C) COPYRIGHT Eastsoft Microelectronics *****END OF FILE****/ diff --git a/bsp/essemi/es32f0271/libraries/SConscript b/bsp/essemi/es32f0271/libraries/SConscript new file mode 100644 index 0000000000..00008f5fca --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/SConscript @@ -0,0 +1,32 @@ +import rtconfig +Import('RTT_ROOT') +from building import * + +# get current directory +cwd = GetCurrentDir() + +# The set of source files associated with this SConscript file. +src = [] + +src += Glob('ES32F027x_MD_StdPeriph_Driver/Source/*.c') + +#add for startup script +if rtconfig.CROSS_TOOL == 'gcc': + src = src + ['CMSIS/Device/EastSoft/ES32F0271/Startup/gcc/startup_es32f027x.s'] +elif rtconfig.CROSS_TOOL == 'keil': + src = src + ['CMSIS/Device/EastSoft/ES32F0271/Startup/keil/startup_es32f027x.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src = src + ['CMSIS/Device/EastSoft/ES32F0271/Startup/iar/startup_es32f027x.s'] + +src = src + ['CMSIS/Device/EastSoft/ES32F0271/System/system_es32f027x.c'] + +path = [cwd + '/CMSIS/Device/EastSoft/ES32F0271/Include', + cwd + '/CMSIS/Device/EastSoft/ES32F0271/Include/ES32F0271', + cwd + '/CMSIS/Device/EastSoft/ES32F0271/System', + cwd + '/CMSIS/Include', + cwd + '/', + cwd + '/ES32F027x_MD_StdPeriph_Driver/Include'] + +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path) + +Return('group') diff --git a/bsp/essemi/es32f0271/libraries/usblib/drivers/type.h b/bsp/essemi/es32f0271/libraries/usblib/drivers/type.h new file mode 100644 index 0000000000..3d6a812bf6 --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/usblib/drivers/type.h @@ -0,0 +1,41 @@ +/** + ************************************************************************************** + * @file type.h + * @brief Common types and macros. + * @data 12/21/2018 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ************************************************************************************** + */ + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +//***************************************************************************** +// +// Macros for hardware access. +// +//***************************************************************************** +#define HWREG(x) \ + (*((volatile uint32_t *)(x))) +#define HWREGH(x) \ + (*((volatile uint16_t *)(x))) +#define HWREGB(x) \ + (*((volatile uint8_t *)(x))) +#define HWREGBITW(x, b) \ + HWREG(((uint32_t)(x) & 0xF0000000) | 0x02000000 | \ + (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2)) +#define HWREGBITH(x, b) \ + HWREGH(((uint32_t)(x) & 0xF0000000) | 0x02000000 | \ + (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2)) +#define HWREGBITB(x, b) \ + HWREGB(((uint32_t)(x) & 0xF0000000) | 0x02000000 | \ + (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2)) + + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics Co., Ltd. *** END OF FILE ****/ diff --git a/bsp/essemi/es32f0271/libraries/usblib/drivers/usb_lowlayer_api.h b/bsp/essemi/es32f0271/libraries/usblib/drivers/usb_lowlayer_api.h new file mode 100644 index 0000000000..5fee2e973e --- /dev/null +++ b/bsp/essemi/es32f0271/libraries/usblib/drivers/usb_lowlayer_api.h @@ -0,0 +1,728 @@ +/** + ************************************************************************************** + * @file usb_lowlayer_api.h + * @brief USB library lower layer api + * @data 11/9/2018 + * @author Eastsoft AE Team + * @note + * + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. ALL rights reserved. + * + ************************************************************************************** + */ + +/* Includes-------------------------------------------------------------------*/ +#include "stdint.h" +#include + +#ifndef __USB_LOWLAYER_API_H__ +#define __USB_LOWLAYER_API_H__ + + +/** + * If building with a C++ compiler, make all of the definitions in this header + * have a C binding. + */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Public constants -----------------------------------------------------------*/ + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hosdev_int_enable() and +// md_usb_hosdev_int_disable() as the ui32Flags parameter, and are returned from +// md_usb_hosdev_int_status(). +// +//***************************************************************************** +#define USB_INTCTRL_ALL 0x000003FF // All control interrupt sources +#define USB_INTCTRL_STATUS 0x000000FF // Status Interrupts +#define USB_INTCTRL_VBUS_ERR 0x00000080 // VBUS Error +#define USB_INTCTRL_SESSION 0x00000040 // Session Start Detected +#define USB_INTCTRL_SESSION_END 0x00000040 // Session End Detected +#define USB_INTCTRL_DISCONNECT 0x00000020 // Disconnect Detected +#define USB_INTCTRL_CONNECT 0x00000010 // Device Connect Detected +#define USB_INTCTRL_SOF 0x00000008 // Start of Frame Detected +#define USB_INTCTRL_BABBLE 0x00000004 // Babble signaled +#define USB_INTCTRL_RESET 0x00000004 // Reset signaled +#define USB_INTCTRL_RESUME 0x00000002 // Resume detected +#define USB_INTCTRL_SUSPEND 0x00000001 // Suspend detected +#define USB_INTCTRL_MODE_DETECT 0x00000200 // Mode value valid +#define USB_INTCTRL_POWER_FAULT 0x00000100 // Power Fault detected + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hosdev_endpoint_int_enable() +// and md_usb_hosdev_endpoint_int_disable() as the ui32Flags parameter, and +// are returned from md_usb_hosdev_endpoint_int_status(). +// +//***************************************************************************** +#define USB_INTEP_ALL 0xFFFFFFFF // Host IN Interrupts +#define USB_INTEP_HOST_IN 0xFFFE0000 // Host IN Interrupts +#define USB_INTEP_HOST_IN_15 0x80000000 // Endpoint 15 Host IN Interrupt +#define USB_INTEP_HOST_IN_14 0x40000000 // Endpoint 14 Host IN Interrupt +#define USB_INTEP_HOST_IN_13 0x20000000 // Endpoint 13 Host IN Interrupt +#define USB_INTEP_HOST_IN_12 0x10000000 // Endpoint 12 Host IN Interrupt +#define USB_INTEP_HOST_IN_11 0x08000000 // Endpoint 11 Host IN Interrupt +#define USB_INTEP_HOST_IN_10 0x04000000 // Endpoint 10 Host IN Interrupt +#define USB_INTEP_HOST_IN_9 0x02000000 // Endpoint 9 Host IN Interrupt +#define USB_INTEP_HOST_IN_8 0x01000000 // Endpoint 8 Host IN Interrupt +#define USB_INTEP_HOST_IN_7 0x00800000 // Endpoint 7 Host IN Interrupt +#define USB_INTEP_HOST_IN_6 0x00400000 // Endpoint 6 Host IN Interrupt +#define USB_INTEP_HOST_IN_5 0x00200000 // Endpoint 5 Host IN Interrupt +#define USB_INTEP_HOST_IN_4 0x00100000 // Endpoint 4 Host IN Interrupt +#define USB_INTEP_HOST_IN_3 0x00080000 // Endpoint 3 Host IN Interrupt +#define USB_INTEP_HOST_IN_2 0x00040000 // Endpoint 2 Host IN Interrupt +#define USB_INTEP_HOST_IN_1 0x00020000 // Endpoint 1 Host IN Interrupt + +#define USB_INTEP_DEV_OUT 0xFFFE0000 // Device OUT Interrupts +#define USB_INTEP_DEV_OUT_15 0x80000000 // Endpoint 15 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_14 0x40000000 // Endpoint 14 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_13 0x20000000 // Endpoint 13 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_12 0x10000000 // Endpoint 12 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_11 0x08000000 // Endpoint 11 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_10 0x04000000 // Endpoint 10 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_9 0x02000000 // Endpoint 9 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_8 0x01000000 // Endpoint 8 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_7 0x00800000 // Endpoint 7 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_6 0x00400000 // Endpoint 6 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_5 0x00200000 // Endpoint 5 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_4 0x00100000 // Endpoint 4 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_3 0x00080000 // Endpoint 3 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_2 0x00040000 // Endpoint 2 Device OUT Interrupt +#define USB_INTEP_DEV_OUT_1 0x00020000 // Endpoint 1 Device OUT Interrupt + +#define USB_INTEP_HOST_OUT 0x0000FFFE // Host OUT Interrupts +#define USB_INTEP_HOST_OUT_15 0x00008000 // Endpoint 15 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_14 0x00004000 // Endpoint 14 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_13 0x00002000 // Endpoint 13 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_12 0x00001000 // Endpoint 12 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_11 0x00000800 // Endpoint 11 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_10 0x00000400 // Endpoint 10 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_9 0x00000200 // Endpoint 9 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_8 0x00000100 // Endpoint 8 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_7 0x00000080 // Endpoint 7 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_6 0x00000040 // Endpoint 6 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_5 0x00000020 // Endpoint 5 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_4 0x00000010 // Endpoint 4 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_3 0x00000008 // Endpoint 3 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_2 0x00000004 // Endpoint 2 Host OUT Interrupt +#define USB_INTEP_HOST_OUT_1 0x00000002 // Endpoint 1 Host OUT Interrupt + +#define USB_INTEP_DEV_IN 0x0000FFFE // Device IN Interrupts +#define USB_INTEP_DEV_IN_15 0x00008000 // Endpoint 15 Device IN Interrupt +#define USB_INTEP_DEV_IN_14 0x00004000 // Endpoint 14 Device IN Interrupt +#define USB_INTEP_DEV_IN_13 0x00002000 // Endpoint 13 Device IN Interrupt +#define USB_INTEP_DEV_IN_12 0x00001000 // Endpoint 12 Device IN Interrupt +#define USB_INTEP_DEV_IN_11 0x00000800 // Endpoint 11 Device IN Interrupt +#define USB_INTEP_DEV_IN_10 0x00000400 // Endpoint 10 Device IN Interrupt +#define USB_INTEP_DEV_IN_9 0x00000200 // Endpoint 9 Device IN Interrupt +#define USB_INTEP_DEV_IN_8 0x00000100 // Endpoint 8 Device IN Interrupt +#define USB_INTEP_DEV_IN_7 0x00000080 // Endpoint 7 Device IN Interrupt +#define USB_INTEP_DEV_IN_6 0x00000040 // Endpoint 6 Device IN Interrupt +#define USB_INTEP_DEV_IN_5 0x00000020 // Endpoint 5 Device IN Interrupt +#define USB_INTEP_DEV_IN_4 0x00000010 // Endpoint 4 Device IN Interrupt +#define USB_INTEP_DEV_IN_3 0x00000008 // Endpoint 3 Device IN Interrupt +#define USB_INTEP_DEV_IN_2 0x00000004 // Endpoint 2 Device IN Interrupt +#define USB_INTEP_DEV_IN_1 0x00000002 // Endpoint 1 Device IN Interrupt + +#define USB_INTEP_0 0x00000001 // Endpoint 0 Interrupt + +//***************************************************************************** +// +// The following are values that are returned from md_usb_hos_speed_get() 0r +// md_usb_dev_speed_get(). +// +//***************************************************************************** +#define USB_UNDEF_SPEED 0x80000000 // Current speed is undefined +#define USB_HIGH_SPEED 0x00000002 // Current speed is High Speed +#define USB_FULL_SPEED 0x00000001 // Current speed is Full Speed +#define USB_LOW_SPEED 0x00000000 // Current speed is Low Speed + +//***************************************************************************** +// +// The following are values that are returned from md_usb_hosdev_endpoint_status(). The +// USB_HOST_* values are used when the USB controller is in host mode and the +// USB_DEV_* values are used when the USB controller is in device mode. +// +//***************************************************************************** +#define USB_HOST_IN_STATUS 0x114F0000 // Mask of all host IN interrupts +#define USB_HOST_IN_PID_ERROR 0x10000000 // Stall on this endpoint received +#define USB_HOST_IN_NOT_COMP 0x01000000 // Device failed to respond +#define USB_HOST_IN_STALL 0x00400000 // Stall on this endpoint received +#define USB_HOST_IN_DATA_ERROR 0x00080000 // CRC or bit-stuff error +// (ISOC Mode) +#define USB_HOST_IN_NAK_TO 0x00080000 // NAK received for more than the +// specified timeout period +#define USB_HOST_IN_ERROR 0x00040000 // Failed to communicate with a +// device +#define USB_HOST_IN_FIFO_FULL 0x00020000 // RX FIFO full +#define USB_HOST_IN_PKTRDY 0x00010000 // Data packet ready +#define USB_HOST_OUT_STATUS 0x000000A7 // Mask of all host OUT interrupts +#define USB_HOST_OUT_NAK_TO 0x00000080 // NAK received for more than the +// specified timeout period +#define USB_HOST_OUT_NOT_COMP 0x00000080 // No response from device +// (ISOC mode) +#define USB_HOST_OUT_STALL 0x00000020 // Stall on this endpoint received +#define USB_HOST_OUT_ERROR 0x00000004 // Failed to communicate with a +// device +#define USB_HOST_OUT_FIFO_NE 0x00000002 // TX FIFO is not empty +#define USB_HOST_OUT_PKTPEND 0x00000001 // Transmit still being transmitted +#define USB_HOST_EP0_NAK_TO 0x00000080 // NAK received for more than the +// specified timeout period +#define USB_HOST_EP0_STATUS 0x00000040 // This was a status packet +#define USB_HOST_EP0_ERROR 0x00000010 // Failed to communicate with a +// device +#define USB_HOST_EP0_RX_STALL 0x00000004 // Stall on this endpoint received +#define USB_HOST_EP0_RXPKTRDY 0x00000001 // Receive data packet ready +#define USB_DEV_RX_PID_ERROR 0x01000000 // PID error in isochronous +// transfer +#define USB_DEV_RX_SENT_STALL 0x00400000 // Stall was sent on this endpoint +#define USB_DEV_RX_DATA_ERROR 0x00080000 // CRC error on the data +#define USB_DEV_RX_OVERRUN 0x00040000 // OUT packet was not loaded due to +// a full FIFO +#define USB_DEV_RX_FIFO_FULL 0x00020000 // RX FIFO full +#define USB_DEV_RX_PKT_RDY 0x00010000 // Data packet ready +#define USB_DEV_TX_NOT_COMP 0x00000080 // Large packet split up, more data +// to come +#define USB_DEV_TX_SENT_STALL 0x00000020 // Stall was sent on this endpoint +#define USB_DEV_TX_UNDERRUN 0x00000004 // IN received with no data ready +#define USB_DEV_TX_FIFO_NE 0x00000002 // The TX FIFO is not empty +#define USB_DEV_TX_TXPKTRDY 0x00000001 // Transmit still being transmitted +#define USB_DEV_EP0_SETUP_END 0x00000010 // Control transaction ended before +// Data End seen +#define USB_DEV_EP0_SENT_STALL 0x00000004 // Stall was sent on this endpoint +#define USB_DEV_EP0_IN_PKTPEND 0x00000002 // Transmit data packet pending +#define USB_DEV_EP0_OUT_PKTRDY 0x00000001 // Receive data packet ready + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hos_endpoint_config_set() and +// md_usb_dev_endpoint_config_set() as the ui32Flags parameter. +// +//***************************************************************************** +#define USB_EP_AUTO_SET 0x00000001 // Auto set feature enabled +#define USB_EP_AUTO_REQUEST 0x00000002 // Auto request feature enabled +#define USB_EP_AUTO_CLEAR 0x00000004 // Auto clear feature enabled +#define USB_EP_DUAL_BUFFERING 0x00000008 // Dual buffering enabled +#define USB_EP_DMA_MODE_0 0x00000008 // Enable DMA access using mode 0 +#define USB_EP_DMA_MODE_1 0x00000010 // Enable DMA access using mode 1 +#define USB_EP_DIS_NYET 0x00000020 // Disable NYET response for +// high-speed Bulk and Interrupt +// endpoints in device mode. +#define USB_EP_MODE_ISOC 0x00000000 // Isochronous endpoint +#define USB_EP_MODE_BULK 0x00000100 // Bulk endpoint +#define USB_EP_MODE_INT 0x00000200 // Interrupt endpoint +#define USB_EP_MODE_CTRL 0x00000300 // Control endpoint +#define USB_EP_MODE_MASK 0x00000300 // Mode Mask +#define USB_EP_SPEED_LOW 0x00000000 // Low Speed +#define USB_EP_SPEED_FULL 0x00001000 // Full Speed +#define USB_EP_SPEED_HIGH 0x00004000 // High Speed +#define USB_EP_HOST_IN 0x00000000 // Host IN endpoint +#define USB_EP_HOST_OUT 0x00002000 // Host OUT endpoint +#define USB_EP_DEV_IN 0x00002000 // Device IN endpoint +#define USB_EP_DEV_OUT 0x00000000 // Device OUT endpoint + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hos_pwr_config() as the +// ui32Flags parameter. +// +//***************************************************************************** +#define USB_HOST_PWRFLT_LOW 0x00000010 +#define USB_HOST_PWRFLT_HIGH 0x00000030 +#define USB_HOST_PWRFLT_EP_NONE 0x00000000 +#define USB_HOST_PWRFLT_EP_TRI 0x00000140 +#define USB_HOST_PWRFLT_EP_LOW 0x00000240 +#define USB_HOST_PWRFLT_EP_HIGH 0x00000340 +#define USB_HOST_PWREN_MAN_LOW 0x00000000 +#define USB_HOST_PWREN_MAN_HIGH 0x00000001 +#define USB_HOST_PWREN_AUTOLOW 0x00000002 +#define USB_HOST_PWREN_AUTOHIGH 0x00000003 +#define USB_HOST_PWREN_FILTER 0x00010000 + +//***************************************************************************** +// +// The following are the valid values that can be passed to the +// md_usb_hos_lpm_config() function in the ui32Config parameter. +// +//***************************************************************************** +#define USB_HOST_LPM_RMTWAKE 0x00000100 +#define USB_HOST_LPM_L1 0x00000001 + +//***************************************************************************** +// +// The following are the valid values that can be passed to the +// md_usb_dev_lpm_config() function in the ui32Config parameter. +// +//***************************************************************************** +#define USB_DEV_LPM_NAK 0x00000010 +#define USB_DEV_LPM_NONE 0x00000000 +#define USB_DEV_LPM_EN 0x0000000c +#define USB_DEV_LPM_EXTONLY 0x00000004 + +//***************************************************************************** +// +// The following are the valid values that are returned from the +// md_usb_lpm_link_state_get() function. +// +//***************************************************************************** +#define USB_DEV_LPM_LS_RMTWAKE 0x00000100 +#define USB_DEV_LPM_LS_L1 0x00000001 + +//***************************************************************************** +// +// The following are the valid values that are passed to the md_usb_lpm_int_enable() +// or md_usb_lpm_int_disable() functions or are returned from the md_usb_lpm_status() +// function. +// +//***************************************************************************** +#define USB_INTLPM_ERROR 0x00000020 +#define USB_INTLPM_RESUME 0x00000010 +#define USB_INTLPM_INCOMPLETE 0x00000008 +#define USB_INTLPM_ACK 0x00000004 +#define USB_INTLPM_NYET 0x00000002 +#define USB_INTLPM_STALL 0x00000001 + +//***************************************************************************** +// +// The following are the valid values that are passed to the md_usb_clock_enable() +// functions. +// +//***************************************************************************** +#define USB_CLOCK_INTERNAL 0x00000200 +#define USB_CLOCK_EXTERNAL 0x00000300 + +//***************************************************************************** +// +// The configuration options used with the md_usb_ulpi_config() API. +// +//***************************************************************************** +#define USB_ULPI_EXTVBUS 0x00000001 +#define USB_ULPI_EXTVBUS_IND 0x00000002 + +//***************************************************************************** +// +// The following are special values that can be passed to +// md_usb_hos_endpoint_config_set() as the ui32NAKPollInterval parameter. +// +//***************************************************************************** +#define MAX_NAK_LIMIT 31 // Maximum NAK interval +#define DISABLE_NAK_LIMIT 0 // No NAK timeouts + +//***************************************************************************** +// +// This value specifies the maximum size of transfers on endpoint 0 as 64 +// bytes. This value is fixed in hardware as the FIFO size for endpoint 0. +// +//***************************************************************************** +#define MAX_PACKET_SIZE_EP0 64 + +//***************************************************************************** +// +// These values are used to indicate which endpoint to access. +// +//***************************************************************************** +#define USB_EP_0 0x00000000 // Endpoint 0 +#define USB_EP_1 0x00000010 // Endpoint 1 +#define USB_EP_2 0x00000020 // Endpoint 2 +#define USB_EP_3 0x00000030 // Endpoint 3 +#define USB_EP_4 0x00000040 // Endpoint 4 +#define USB_EP_5 0x00000050 // Endpoint 5 +#define USB_EP_6 0x00000060 // Endpoint 6 +#define USB_EP_7 0x00000070 // Endpoint 7 +#define NUM_USB_EP 8 // Number of supported endpoints + +//***************************************************************************** +// +// These macros allow conversion between 0-based endpoint indices and the +// USB_EP_x values required when calling various USB APIs. +// +//***************************************************************************** +#define IndexToUSBEP(x) ((x) << 4) +#define USBEPToIndex(x) ((x) >> 4) + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hosdev_fifo_config_set() as the +// ui32FIFOSize parameter. +// +//***************************************************************************** +#define USB_FIFO_SZ_8 0x00000000 // 8 byte FIFO +#define USB_FIFO_SZ_16 0x00000001 // 16 byte FIFO +#define USB_FIFO_SZ_32 0x00000002 // 32 byte FIFO +#define USB_FIFO_SZ_64 0x00000003 // 64 byte FIFO +#define USB_FIFO_SZ_128 0x00000004 // 128 byte FIFO +#define USB_FIFO_SZ_256 0x00000005 // 256 byte FIFO +#define USB_FIFO_SZ_512 0x00000006 // 512 byte FIFO +#define USB_FIFO_SZ_1024 0x00000007 // 1024 byte FIFO +#define USB_FIFO_SZ_2048 0x00000008 // 2048 byte FIFO + +//***************************************************************************** +// +// This macro allow conversion from a FIFO size label as defined above to +// a number of bytes +// +//***************************************************************************** +#define USBFIFOSizeToBytes(x) (8 << (x)) + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_hosdev_endpoint_data_send() +// as the ui32TransType parameter. +// +//***************************************************************************** +#define USB_TRANS_OUT 0x00000102 // Normal OUT transaction +#define USB_TRANS_IN 0x00000102 // Normal IN transaction +#define USB_TRANS_IN_LAST 0x0000010a // Final IN transaction (for +// endpoint 0 in device mode) +#define USB_TRANS_SETUP 0x0000110a // Setup transaction (for endpoint +// 0) +#define USB_TRANS_STATUS 0x00000142 // Status transaction (for endpoint +// 0) + +//***************************************************************************** +// +// The following are values are returned by the md_usb_hosdev_mode_get() function. +// +//***************************************************************************** +#define USB_DUAL_MODE_HOST 0x00000001 // Dual mode controller is in Host +// mode. +#define USB_DUAL_MODE_DEVICE 0x00000081 // Dual mode controller is in +// Device mode. +#define USB_DUAL_MODE_NONE 0x00000080 // Dual mode controller mode is not +// set. +#define USB_OTG_MODE_ASIDE_HOST 0x0000001d // OTG controller on the A side of +// the cable. +#define USB_OTG_MODE_ASIDE_NPWR 0x00000001 // OTG controller on the A side of +// the cable. +#define USB_OTG_MODE_ASIDE_SESS 0x00000009 // OTG controller on the A side of +// the cable Session Valid. +#define USB_OTG_MODE_ASIDE_AVAL 0x00000011 // OTG controller on the A side of +// the cable A valid. +#define USB_OTG_MODE_ASIDE_DEV 0x00000019 // OTG controller on the A side of +// the cable. +#define USB_OTG_MODE_BSIDE_HOST 0x0000009d // OTG controller on the B side of +// the cable. +#define USB_OTG_MODE_BSIDE_DEV 0x00000099 // OTG controller on the B side of +// the cable. +#define USB_OTG_MODE_BSIDE_NPWR 0x00000081 // OTG controller on the B side of +// the cable. +#define USB_OTG_MODE_NONE 0x00000080 // OTG controller mode is not set. + +//***************************************************************************** +// +// Channel configuration values. +// +//***************************************************************************** +#define DMA_DST_INC_8 0x00000000 +#define DMA_DST_INC_16 0x40000000 +#define DMA_DST_INC_32 0x80000000 +#define DMA_DST_INC_NONE 0xc0000000 +#define DMA_SRC_INC_8 0x00000000 +#define DMA_SRC_INC_16 0x04000000 +#define DMA_SRC_INC_32 0x08000000 +#define DMA_SRC_INC_NONE 0x0c000000 +#define DMA_SIZE_8 0x00000000 +#define DMA_SIZE_16 0x11000000 +#define DMA_SIZE_32 0x22000000 +#define DMA_DST_PROT_PRIV 0x00200000 +#define DMA_SRC_PROT_PRIV 0x00040000 +#define DMA_ARB_1 0x00000000 +#define DMA_ARB_2 0x00004000 +#define DMA_ARB_4 0x00008000 +#define DMA_ARB_8 0x0000c000 +#define DMA_ARB_16 0x00010000 +#define DMA_ARB_32 0x00014000 +#define DMA_ARB_64 0x00018000 +#define DMA_ARB_128 0x0001c000 +#define DMA_ARB_256 0x00020000 +#define DMA_ARB_512 0x00024000 +#define DMA_ARB_1024 0x00028000 +#define DMA_NEXT_USEBURST 0x00000008 + +//***************************************************************************** +// +// The values for the md_usb_dma_channel_int_enable() and md_usb_dma_channel_int_status() +// APIs. +// +//***************************************************************************** +#define USB_DMA_INT_CH8 0x00000080 +#define USB_DMA_INT_CH7 0x00000040 +#define USB_DMA_INT_CH6 0x00000020 +#define USB_DMA_INT_CH5 0x00000010 +#define USB_DMA_INT_CH4 0x00000008 +#define USB_DMA_INT_CH3 0x00000004 +#define USB_DMA_INT_CH2 0x00000002 +#define USB_DMA_INT_CH1 0x00000001 + +//***************************************************************************** +// +// The values for the md_usb_dma_channel_status() API. +// +//***************************************************************************** +#define USB_DMA_STATUS_ERROR 0x00000100 + +//***************************************************************************** +// +// The valid return values for the USBDMAModeSet() and USBDMAModeGet() APIs or +// USBDMAChannelConfig(). +// +//***************************************************************************** +#define USB_DMA_CFG_BURST_NONE 0x00000000 +#define USB_DMA_CFG_BURST_4 0x00000200 +#define USB_DMA_CFG_BURST_8 0x00000400 +#define USB_DMA_CFG_BURST_16 0x00000600 +#define USB_DMA_CFG_INT_EN 0x00000008 +#define USB_DMA_CFG_MODE_0 0x00000000 +#define USB_DMA_CFG_MODE_1 0x00000004 +#define USB_DMA_CFG_DIR_RX 0x00000000 +#define USB_DMA_CFG_DIR_TX 0x00000002 +#define USB_DMA_CFG_EN 0x00000001 + +//***************************************************************************** +// +// The following are values that can be passed to md_usb_mode_config() as the +// ui3Mode parameter. +// +//***************************************************************************** +#define USB_MODE_HOST_VBUS 0x00000004 +#define USB_MODE_HOST 0x00000002 +#define USB_MODE_DEV_VBUS 0x00000005 +#define USB_MODE_DEV 0x00000003 +#define USB_MODE_OTG 0x00000000 + +//***************************************************************************** +// +// Flags that can be passed to DMAChannelAttributeEnable(), +// DMAChannelAttributeDisable(), and returned from DMAChannelAttributeGet(). +// +//***************************************************************************** +#define DMA_ATTR_USEBURST 0x00000001 +#define DMA_ATTR_ALTSELECT 0x00000002 +#define DMA_ATTR_HIGH_PRIORITY 0x00000004 +#define DMA_ATTR_REQMASK 0x00000008 +#define DMA_ATTR_ALL 0x0000000F + +/* Public functions -----------------------------------------------------------*/ +/** + * @{ SYSTEM API. + */ +extern void md_usb_system_int_disable(void); +extern void md_usb_system_int_enable(void); +extern void md_usb_re_config(bool Device); /* Weak defination */ +extern void md_usb_system_delayms(uint32_t delayms); /* Weak defination */ +extern void md_usb_systic_disable(void); +extern void md_usb_controller_reset(void); +extern void md_usb_controller_enable(void); +extern void md_usb_controller_disable(void); +extern void md_usb_clk_phy_enable(void); +extern void md_usb_clk_phy_disable(void); +extern uint32_t md_usb_nvic_number_get(void); +extern void md_usb_nvic_config(uint32_t NvicNum); /* Weak defination */ +extern void md_usb_nvic_enable(void); +extern void md_usb_nvic_disable(void); +/** + * @} SYSTEM API. + */ + +/** + * @{ USB basic API. + */ +/* Host Mode */ +extern void md_usb_hos_reset(bool bStart); +extern void md_usb_hos_resume(bool bStart); +extern void md_usb_hos_suspend(void); +extern void md_usb_hos_request_status(void); +extern void md_usb_hos_request_in(uint32_t ui32Endpoint); +extern void md_usb_hos_request_in_clear(uint32_t ui32Endpoint); +extern uint32_t md_usb_hos_speed_get(void); +extern uint32_t md_usb_hos_addr_get(uint32_t ui32Endpoint, uint32_t ui32Flags); +extern void md_usb_hos_addr_set(uint32_t ui32Endpoint, + uint32_t ui32Addr, + uint32_t ui32Flags); +extern uint32_t md_usb_hos_hub_addr_get(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_hos_hub_addr_set(uint32_t ui32Endpoint, + uint32_t ui32Addr, + uint32_t ui32Flags); +/* Device Mode */ +extern void md_usb_dev_addr_set(uint8_t ui32Address); +extern uint8_t md_usb_dev_addr_get(void); +extern void md_usb_dev_connect(void); +extern void md_usb_dev_disconnect(void); +extern uint32_t md_usb_dev_speed_get(void); +/* Host/Device Mode */ +extern uint32_t md_usb_hosdev_frame_get(void); +extern void md_usb_hosdev_int_disable(uint32_t ui32IntFlags); +extern void md_usb_hosdev_int_enable(uint32_t ui32IntFlags); +extern uint32_t md_usb_hosdev_int_status(void); +extern uint32_t md_usb_hosdev_mode_get(void); +/* otg Mode */ +extern void md_usb_otg_session_request(bool bStart); +extern void md_usb_force_host_mode(void); +extern void md_usb_force_device_mode(void); +extern void md_usb_force_otg_mode(void); +extern void md_usb_mode_config(uint32_t ui32Mode); +/** + * @} USB basic API. + */ + +/** + * @{ USB endpoint API. + */ +/* Host Mode */ +extern void md_usb_hos_endpoint_config_set(uint32_t ui32Endpoint, + uint32_t ui32MaxPacketSize, + uint32_t ui32NAKPollInterval, + uint32_t ui32TargetEndpoint, + uint32_t ui32Flags); +extern void md_usb_hos_endpoint_data_ack(uint32_t ui32Endpoint); +extern void md_usb_hos_endpoint_data_toggle(uint32_t ui32Endpoint, + bool bDataToggle, + uint32_t ui32Flags); +extern void md_usb_hos_endpoint_status_clear(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_hos_endpoint_speed(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_hos_endpoint_ping(uint32_t ui32Endpoint, + bool bEnable); +/* Device Mode */ +extern void md_usb_dev_endpoint_config_set(uint32_t ui32Endpoint, + uint32_t ui32MaxPacketSize, + uint32_t ui32Flags); +extern void md_usb_dev_endpoint_config_get(uint32_t ui32Endpoint, + uint32_t *pui32MaxPacketSize, + uint32_t *pui32Flags); +extern void md_usb_dev_endpoint_ack(uint32_t ui32Endpoint, + bool bIsLastPacket); +extern void md_usb_dev_endpoint_stall(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_dev_endpoint_stall_clear(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_dev_endpoint_status_clear(uint32_t ui32Endpoint, + uint32_t ui32Flags); +/* Host/Device Mode */ +extern uint32_t md_usb_hosdev_endpoint_datavai(uint32_t ui32Endpoint); +extern int32_t md_usb_hosdev_endpoint_data_get(uint32_t ui32Endpoint, + uint8_t *pui8Data, uint32_t *pui32Size); +extern int32_t md_usb_hosdev_endpoint_data_put(uint32_t ui32Endpoint, + uint8_t *pui8Data, + uint32_t ui32Size); +extern int32_t md_usb_hosdev_endpoint_data_send(uint32_t ui32Endpoint, + uint32_t ui32TransType); +extern void md_usb_hosdev_endpoint_data_togglec(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_hosdev_endpoint_pkcount_set(uint32_t ui32Endpoint, + uint32_t ui32Count); +extern uint32_t md_usb_hosdev_endpoint_status(uint32_t ui32Endpoint); +extern void md_usb_hosdev_endpoint_int_disable(uint32_t ui32IntFlags); +extern void md_usb_hosdev_endpoint_int_enable(uint32_t ui32IntFlags); +extern uint32_t md_usb_hosdev_endpoint_int_status(void); +extern uint32_t md_usb_endpoint_number_get(void); +/** + * @} USB endpoint API. + */ + +/** + * @{ USB FIFO API. + */ +extern uint32_t md_usb_hosdev_fifo_addr_get(uint32_t ui32Endpoint); +extern void md_usb_hosdev_fifo_config_get(uint32_t ui32Endpoint, uint32_t *pui32FIFOAddress, + uint32_t *pui32FIFOSize, uint32_t ui32Flags); +extern void md_usb_hosdev_fifo_config_set(uint32_t ui32Endpoint, uint32_t ui32FIFOAddress, + uint32_t ui32FIFOSize, uint32_t ui32Flags); +extern void md_usb_hosdev_fifo_flush(uint32_t ui32Endpoint, uint32_t ui32Flags); +/** + * @} USB FIFO API. + */ + +/** + * @{ USB PWR API.it is not supported by es32f0271. + */ +extern void md_usb_hos_pwr_disable(void); +extern void md_usb_hos_pwr_enable(void); +extern void md_usb_hos_pwr_config(uint32_t ui32Flags); +extern void md_usb_hos_pwrfault_disable(void); +extern void md_usb_hos_pwrfault_enable(void); +/** + * @} USB PWR API. + */ + +/** + * @{ USB LPM API.it is not supported by es32f0271. + */ +extern void md_usb_hos_lpm_send(uint32_t ui32Address, + uint32_t uiEndpoint); +extern void md_usb_hos_lpm_config(uint32_t ui32ResumeTime, + uint32_t ui32Config); +extern bool md_usb_lpm_remotewake_is_enabled(void); +extern void md_usb_hos_lpm_resume(void); +extern void md_usb_dev_lpm_remotewake(void); +extern void md_usb_dev_lpm_config(uint32_t ui32Config); +extern void md_usb_dev_lpm_enable(void); +extern void md_usb_dev_lpm_disable(void); +extern uint32_t md_usb_lpm_link_state_get(void); +extern uint32_t md_usb_lpm_endpoint_get(void); +extern uint32_t md_usb_lpm_status(void); +extern void md_usb_lpm_int_disable(uint32_t ui32Ints); +extern void md_usb_lpm_int_enable(uint32_t ui32Ints); +/** + * @} USB LPM API. + */ + +/** + * @{ USB ULPI API.it is not supported by es32f0271. + */ +extern void md_usb_ulpi_config(uint32_t ui32Config); +extern void md_usb_ulpi_enable(void); +extern void md_usb_ulpi_disable(void); +extern uint8_t md_usb_ulpi_reg_read(uint8_t ui8Reg); +extern void md_usb_ulpi_reg_write(uint8_t ui8Reg, + uint8_t ui8Data); +/** + * @} USB ULPI API. + */ + +/** + * @{ USB DMA API.it is not supported by es32f0271. + */ +extern void md_usb_dma_endpoint_channel_set(uint32_t ui32Endpoint, + uint32_t ui32Channel); +extern void md_usb_dma_endpoint_enable(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_dma_endpoint_disable(uint32_t ui32Endpoint, + uint32_t ui32Flags); +extern void md_usb_dma_endpoint_config(uint32_t ui32Endpoint, + uint32_t ui32Config); +extern void md_usb_dma_channel_config(uint32_t ui32Channel, + uint32_t ui32Endpoint, + uint32_t ui32Config); +extern void md_usb_dma_channel_address_set(uint32_t ui32Channel, + void *pvAddress); +extern void *md_usb_dma_channel_address_get(uint32_t ui32Channel); +extern void md_usb_dma_channel_count_set(uint32_t ui32Count, + uint32_t ui32Channel); +extern uint32_t md_usb_dma_channel_count_get(uint32_t ui32Channel); +extern void md_usb_dma_channel_int_enable(uint32_t ui32Channel); +extern void md_usb_dma_channel_int_disable(uint32_t ui32Channel); +extern uint32_t md_usb_dma_channel_int_status(void); +extern void md_usb_dma_channel_enable(uint32_t ui32Channel); +extern void md_usb_dma_channel_disable(uint32_t ui32Channel); +extern uint32_t md_usb_dma_channel_isenabled(uint32_t ui32Channel); +extern uint32_t md_usb_dma_channel_status(uint32_t ui32Channel); +extern void md_usb_dma_channel_status_clear(uint32_t ui32Channel, + uint32_t ui32Status); +/** + * @} USB DMA API. + */ + +#ifdef __cplusplus +} +#endif + +#endif + +/******************* (C) COPYRIGHT Eastsoft Microelectronics Co., Ltd. *** END OF FILE ****/ diff --git a/bsp/essemi/es32f0271/project.uvoptx b/bsp/essemi/es32f0271/project.uvoptx new file mode 100644 index 0000000000..bd379df962 --- /dev/null +++ b/bsp/essemi/es32f0271/project.uvoptx @@ -0,0 +1,797 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\keil\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 0 + 0 + 1 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 3 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0ES32F0271 -FL010000 -FS00 -FP0($$Device:ES32F0271LT$Flash\ES32F0271.FLM) + + + 0 + CMSIS_AGDI + -X"" -O206 -S0 -C0 -P00 -TO18 -TC10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0ES32F0271.FLM -FS00 -FL010000 -FP0($$Device:ES32F0271LT$Flash\ES32F0271.FLM) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Kernel + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\..\..\src\clock.c + clock.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + ..\..\..\src\components.c + components.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ..\..\..\src\device.c + device.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\..\src\idle.c + idle.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\..\src\ipc.c + ipc.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\..\src\irq.c + irq.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\..\src\kservice.c + kservice.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\..\..\src\mem.c + mem.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\..\src\mempool.c + mempool.c + 0 + 0 + + + 1 + 10 + 1 + 0 + 0 + 0 + ..\..\..\src\object.c + object.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + ..\..\..\src\scheduler.c + scheduler.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + ..\..\..\src\signal.c + signal.c + 0 + 0 + + + 1 + 13 + 1 + 0 + 0 + 0 + ..\..\..\src\thread.c + thread.c + 0 + 0 + + + 1 + 14 + 1 + 0 + 0 + 0 + ..\..\..\src\timer.c + timer.c + 0 + 0 + + + + + Applications + 0 + 0 + 0 + 0 + + 2 + 15 + 1 + 0 + 0 + 0 + applications\main.c + main.c + 0 + 0 + + + + + Drivers + 0 + 0 + 0 + 0 + + 3 + 16 + 1 + 0 + 0 + 0 + drivers\board.c + board.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + drivers\drv_gpio.c + drv_gpio.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + drivers\drv_uart.c + drv_uart.c + 0 + 0 + + + + + Libraries + 0 + 0 + 0 + 0 + + 4 + 19 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_adc.c + md_adc.c + 0 + 0 + + + 4 + 20 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_fc.c + md_fc.c + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_gpio.c + md_gpio.c + 0 + 0 + + + 4 + 22 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_i2c.c + md_i2c.c + 0 + 0 + + + 4 + 23 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_rcu.c + md_rcu.c + 0 + 0 + + + 4 + 24 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_spi.c + md_spi.c + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_tick.c + md_tick.c + 0 + 0 + + + 4 + 26 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_uart.c + md_uart.c + 0 + 0 + + + 4 + 27 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_usb.c + md_usb.c + 0 + 0 + + + 4 + 28 + 1 + 0 + 0 + 0 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_wwdt.c + md_wwdt.c + 0 + 0 + + + 4 + 29 + 2 + 0 + 0 + 0 + libraries\CMSIS\Device\EastSoft\ES32F0271\Startup\keil\startup_es32f027x.s + startup_es32f027x.s + 0 + 0 + + + 4 + 30 + 1 + 0 + 0 + 0 + libraries\CMSIS\Device\EastSoft\ES32F0271\System\system_es32f027x.c + system_es32f027x.c + 0 + 0 + + + + + cpu + 0 + 0 + 0 + 0 + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\backtrace.c + backtrace.c + 0 + 0 + + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\div0.c + div0.c + 0 + 0 + + + 5 + 33 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\showmem.c + showmem.c + 0 + 0 + + + 5 + 34 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m0\cpuport.c + cpuport.c + 0 + 0 + + + 5 + 35 + 2 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m0\context_rvds.S + context_rvds.S + 0 + 0 + + + + + DeviceDrivers + 0 + 0 + 0 + 0 + + 6 + 36 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\pin.c + pin.c + 0 + 0 + + + 6 + 37 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\serial\serial.c + serial.c + 0 + 0 + + + 6 + 38 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\completion.c + completion.c + 0 + 0 + + + 6 + 39 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\dataqueue.c + dataqueue.c + 0 + 0 + + + 6 + 40 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\pipe.c + pipe.c + 0 + 0 + + + 6 + 41 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\ringblk_buf.c + ringblk_buf.c + 0 + 0 + + + 6 + 42 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\ringbuffer.c + ringbuffer.c + 0 + 0 + + + 6 + 43 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\waitqueue.c + waitqueue.c + 0 + 0 + + + 6 + 44 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\workqueue.c + workqueue.c + 0 + 0 + + + + + finsh + 0 + 0 + 0 + 0 + + 7 + 45 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\shell.c + shell.c + 0 + 0 + + + 7 + 46 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\cmd.c + cmd.c + 0 + 0 + + + 7 + 47 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\msh.c + msh.c + 0 + 0 + + + +
diff --git a/bsp/essemi/es32f0271/project.uvprojx b/bsp/essemi/es32f0271/project.uvprojx new file mode 100644 index 0000000000..664a6e8f02 --- /dev/null +++ b/bsp/essemi/es32f0271/project.uvprojx @@ -0,0 +1,662 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC + 0 + + + ES32F0271LT + Eastsoft + Eastsoft.ES32_DFP.1.0.4 + http://www.essemi.com + IRAM(0x20000000,0x00002000) IROM(0x00000000,0x00010000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0ES32F0271 -FS00 -FL010000 -FP0($$Device:ES32F0271LT$Flash\ES32F0271.FLM)) + 0 + $$Device:ES32F0271LT$Device\Include\es32f027x.h + + + + + + + + + + $$Device:ES32F0271LT$SVD\es32f027x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\keil\ + rtthread + 1 + 0 + 0 + 1 + 1 + .\build\keil\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DARMCM1.DLL + -pCM0 + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 1 + 0x0 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 3 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + .;..\..\..\include;applications;.;drivers;libraries\CMSIS\Device\EastSoft\ES32F0271\Include;libraries\CMSIS\Device\EastSoft\ES32F0271\Include\ES32F0271;libraries\CMSIS\Device\EastSoft\ES32F0271\System;libraries\CMSIS\Include;libraries;libraries\ES32F027x_MD_StdPeriph_Driver\Include;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m0;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\finsh;..\..\..\components\libc\compilers\common + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + Kernel + + + clock.c + 1 + ..\..\..\src\clock.c + + + components.c + 1 + ..\..\..\src\components.c + + + device.c + 1 + ..\..\..\src\device.c + + + idle.c + 1 + ..\..\..\src\idle.c + + + ipc.c + 1 + ..\..\..\src\ipc.c + + + irq.c + 1 + ..\..\..\src\irq.c + + + kservice.c + 1 + ..\..\..\src\kservice.c + + + mem.c + 1 + ..\..\..\src\mem.c + + + mempool.c + 1 + ..\..\..\src\mempool.c + + + object.c + 1 + ..\..\..\src\object.c + + + scheduler.c + 1 + ..\..\..\src\scheduler.c + + + signal.c + 1 + ..\..\..\src\signal.c + + + thread.c + 1 + ..\..\..\src\thread.c + + + timer.c + 1 + ..\..\..\src\timer.c + + + + + Applications + + + main.c + 1 + applications\main.c + + + + + Drivers + + + board.c + 1 + drivers\board.c + + + drv_gpio.c + 1 + drivers\drv_gpio.c + + + drv_uart.c + 1 + drivers\drv_uart.c + + + + + Libraries + + + md_adc.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_adc.c + + + md_fc.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_fc.c + + + md_gpio.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_gpio.c + + + md_i2c.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_i2c.c + + + md_rcu.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_rcu.c + + + md_spi.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_spi.c + + + md_tick.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_tick.c + + + md_uart.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_uart.c + + + md_usb.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_usb.c + + + md_wwdt.c + 1 + libraries\ES32F027x_MD_StdPeriph_Driver\Source\md_wwdt.c + + + startup_es32f027x.s + 2 + libraries\CMSIS\Device\EastSoft\ES32F0271\Startup\keil\startup_es32f027x.s + + + system_es32f027x.c + 1 + libraries\CMSIS\Device\EastSoft\ES32F0271\System\system_es32f027x.c + + + + + cpu + + + backtrace.c + 1 + ..\..\..\libcpu\arm\common\backtrace.c + + + div0.c + 1 + ..\..\..\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\..\libcpu\arm\common\showmem.c + + + cpuport.c + 1 + ..\..\..\libcpu\arm\cortex-m0\cpuport.c + + + context_rvds.S + 2 + ..\..\..\libcpu\arm\cortex-m0\context_rvds.S + + + + + DeviceDrivers + + + pin.c + 1 + ..\..\..\components\drivers\misc\pin.c + + + serial.c + 1 + ..\..\..\components\drivers\serial\serial.c + + + completion.c + 1 + ..\..\..\components\drivers\src\completion.c + + + dataqueue.c + 1 + ..\..\..\components\drivers\src\dataqueue.c + + + pipe.c + 1 + ..\..\..\components\drivers\src\pipe.c + + + ringblk_buf.c + 1 + ..\..\..\components\drivers\src\ringblk_buf.c + + + ringbuffer.c + 1 + ..\..\..\components\drivers\src\ringbuffer.c + + + waitqueue.c + 1 + ..\..\..\components\drivers\src\waitqueue.c + + + workqueue.c + 1 + ..\..\..\components\drivers\src\workqueue.c + + + + + finsh + + + shell.c + 1 + ..\..\..\components\finsh\shell.c + + + cmd.c + 1 + ..\..\..\components\finsh\cmd.c + + + msh.c + 1 + ..\..\..\components\finsh\msh.c + + + + + + + + + + + + + +
diff --git a/bsp/essemi/es32f0271/rtconfig.h b/bsp/essemi/es32f0271/rtconfig.h new file mode 100644 index 0000000000..4a0cf3306a --- /dev/null +++ b/bsp/essemi/es32f0271/rtconfig.h @@ -0,0 +1,183 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 256 +#define RT_DEBUG +#define RT_DEBUG_COLOR + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x40002 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 256 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + + +/* Command shell */ + +#define RT_USING_FINSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 2048 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_USING_MSH_ONLY +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SERIAL +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_PIN + +/* Using USB */ + + +/* POSIX layer and C standard library */ + + +/* Network */ + +/* Socket abstraction layer */ + + +/* Network interface device */ + + +/* light weight TCP/IP stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + +#define SOC_ES32F0271LT + +/* Hardware Drivers Config */ + +/* On-chip Peripheral Drivers */ + +/* PIN Drivers */ + +#define BSP_USING_GPIO + +/* UART Drivers */ + +#define BSP_USING_UART1 + +/* SPI Drivers */ + + +/* I2C Drivers */ + + +/* HWtimer Drivers */ + + +/* PWM Drivers */ + + +/* RTC Drivers */ + + +/* ADC Drivers */ + + +/* Onboard Peripheral Drivers */ + +/* Offboard Peripheral Drivers */ + + +#endif diff --git a/bsp/essemi/es32f0271/rtconfig.py b/bsp/essemi/es32f0271/rtconfig.py new file mode 100644 index 0000000000..eb371bf3a7 --- /dev/null +++ b/bsp/essemi/es32f0271/rtconfig.py @@ -0,0 +1,135 @@ +import os +import sys + +# toolchains options +CROSS_TOOL = 'keil' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +# device options +ARCH = 'arm' +CPU = 'cortex-m0' + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': # not support gcc yet + PLATFORM = 'gcc' + EXEC_PATH = 'C:/GCC' + +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = 'C:/Keil' + +elif CROSS_TOOL == 'iar': # not support iar yet + PLATFORM = 'iar' + EXEC_PATH = 'C:/IAR' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' +#BUILD = 'release' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + DEVICE = ' -mcpu=' + CPU + ' -mthumb -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T drivers/linker_scripts/link.lds' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2 -g' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + OBJCPY + ' -O ihex $TARGET rtthread.hex\n' + SIZE + ' $TARGET \n' +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --device DARMSTM' + CFLAGS = '-c ' + DEVICE + ' --apcs=interwork --c99' + AFLAGS = DEVICE + ' --apcs=interwork ' + LFLAGS = DEVICE + ' --scatter "drivers/linker_scripts/link.sct" --info sizes --info totals --info unused --info veneers --list rtthread.map --strict' + + CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCC/include' + LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/ARMCC/lib' + + CFLAGS += ' -D__MICROLIB ' + AFLAGS += ' --pd "__MICROLIB SETA 1" ' + LFLAGS += ' --library_type=microlib ' + EXEC_PATH += '/ARM/ARMCC/bin' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = '-Dewarm' + + CFLAGS = DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M0' + CFLAGS += ' -e' + CFLAGS += ' --fpu=None' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' --silent' + + AFLAGS = DEVICE + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M0' + AFLAGS += ' --fpu None' + AFLAGS += ' -S' + + LFLAGS = ' --config "drivers\linker_scripts\link.icf"' + LFLAGS += ' --redirect _Printf=_PrintfTiny' + LFLAGS += ' --redirect _Scanf=_ScanfSmall' + if BUILD == 'debug': + CFLAGS += ' --debug' + CFLAGS += ' -On' + else: + CFLAGS += ' -Oh' + + LFLAGS += ' --entry __iar_program_start' + EXEC_PATH = EXEC_PATH + '/arm/bin/' + POST_ACTION = '' diff --git a/bsp/essemi/es32f0271/template.uvoptx b/bsp/essemi/es32f0271/template.uvoptx new file mode 100644 index 0000000000..bb8cce6ff2 --- /dev/null +++ b/bsp/essemi/es32f0271/template.uvoptx @@ -0,0 +1,177 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\keil\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 0 + 0 + 1 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 3 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0ES32F0271 -FL010000 -FS00 -FP0($$Device:ES32F0271LT$Flash\ES32F0271.FLM) + + + 0 + CMSIS_AGDI + -X"" -O206 -S0 -C0 -P00 -TO18 -TC10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0ES32F0271.FLM -FS00 -FL010000 -FP0($$Device:ES32F0271LT$Flash\ES32F0271.FLM) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + +
diff --git a/bsp/essemi/es32f0271/template.uvprojx b/bsp/essemi/es32f0271/template.uvprojx new file mode 100644 index 0000000000..ce19e112f5 --- /dev/null +++ b/bsp/essemi/es32f0271/template.uvprojx @@ -0,0 +1,389 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread + 0x4 + ARM-ADS + 0 + + + ES32F0271LT + Eastsoft + Eastsoft.ES32_DFP.1.0.4 + http://www.essemi.com + IRAM(0x20000000,0x00002000) IROM(0x00000000,0x00010000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0ES32F0271 -FS00 -FL010000 -FP0($$Device:ES32F0271LT$Flash\ES32F0271.FLM)) + 0 + $$Device:ES32F0271LT$Device\Include\es32f027x.h + + + + + + + + + + $$Device:ES32F0271LT$SVD\es32f027x.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\keil\ + rtthread + 1 + 0 + 0 + 1 + 1 + .\build\keil\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DARMCM1.DLL + -pCM0 + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 1 + 0x0 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 3 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + + + + + + + +
-- Gitee From ebaa90d64845a5c9a0fd0221128ac0f0c177cdae Mon Sep 17 00:00:00 2001 From: essemi-yuzr Date: Fri, 22 Nov 2019 16:06:37 +0800 Subject: [PATCH 002/110] Add ADC drivers --- bsp/essemi/es32f0271/drivers/drv_adc.c | 148 +++++++++++++++++++++++++ bsp/essemi/es32f0271/drivers/drv_adc.h | 16 +++ 2 files changed, 164 insertions(+) create mode 100644 bsp/essemi/es32f0271/drivers/drv_adc.c create mode 100644 bsp/essemi/es32f0271/drivers/drv_adc.h diff --git a/bsp/essemi/es32f0271/drivers/drv_adc.c b/bsp/essemi/es32f0271/drivers/drv_adc.c new file mode 100644 index 0000000000..d111b54f22 --- /dev/null +++ b/bsp/essemi/es32f0271/drivers/drv_adc.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-10-23 yuzrain the first version + */ + +#include +#include +#include +#include "board.h" +#include "drv_adc.h" +#include "md_gpio.h" +#include "md_adc.h" +#include "md_rcu.h" +#include "md_syscfg.h" + +#ifdef RT_USING_ADC + +#define BSP_ADC_CHANNEL_NUM 8 + +/* define adc instance */ +static struct rt_adc_device _device_adc0; + +/* enable or disable adc */ +static rt_err_t es32f0_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled) +{ + RT_ASSERT(device != RT_NULL); + + if (enabled) + { + md_adc_enable_ssen_ss0en(ADC); + } + else + { + md_adc_disable_ssen_ss0en(ADC); + } + + return RT_EOK; +} + +static void _adc_channel_config(rt_uint32_t channel) +{ + /* select gpio pin as adc function */ + switch (channel) + { + case 0: + md_gpio_set_mode(GPIOA, MD_GPIO_PIN_0, MD_GPIO_MODE_ANALOG); + break; + case 1: + md_gpio_set_mode(GPIOA, MD_GPIO_PIN_1, MD_GPIO_MODE_ANALOG); + break; + case 2: + md_gpio_set_mode(GPIOA, MD_GPIO_PIN_2, MD_GPIO_MODE_ANALOG); + break; + case 3: + md_gpio_set_mode(GPIOA, MD_GPIO_PIN_3, MD_GPIO_MODE_ANALOG); + break; + case 4: + md_gpio_set_mode(GPIOA, MD_GPIO_PIN_4, MD_GPIO_MODE_ANALOG); + break; + case 5: + md_gpio_set_mode(GPIOA, MD_GPIO_PIN_5, MD_GPIO_MODE_ANALOG); + break; + case 6: + md_gpio_set_mode(GPIOA, MD_GPIO_PIN_6, MD_GPIO_MODE_ANALOG); + break; + case 7: + md_gpio_set_mode(GPIOA, MD_GPIO_PIN_7, MD_GPIO_MODE_ANALOG); + break; + default: + break; + } +} + +static rt_err_t es32f0_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value) +{ + rt_uint32_t chn_data[BSP_ADC_CHANNEL_NUM]; + rt_uint32_t i; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(value != RT_NULL); + + /* config adc channel */ + _adc_channel_config(channel); + + md_adc_set_swtri_ss0(ADC); + + while ((ADC->RIF & ADC_RIF_SS0RIF_MSK) == 0); + + for (i=0; i Date: Wed, 18 Dec 2019 14:20:55 +0800 Subject: [PATCH 003/110] [net][lwip] add personalized RT-Thread sign into lwip protocol stack as hostname. Signed-off-by: liuxianliang --- components/net/lwip-1.4.1/src/lwipopts.h | 8 ++++++++ components/net/lwip-1.4.1/src/netif/ethernetif.c | 14 +++++++++++++- components/net/lwip-2.0.2/src/lwipopts.h | 7 +++++++ components/net/lwip-2.0.2/src/netif/ethernetif.c | 11 +++++++++-- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/components/net/lwip-1.4.1/src/lwipopts.h b/components/net/lwip-1.4.1/src/lwipopts.h index dd59acd589..598c3262a6 100644 --- a/components/net/lwip-1.4.1/src/lwipopts.h +++ b/components/net/lwip-1.4.1/src/lwipopts.h @@ -499,6 +499,14 @@ /* no read/write/close for socket */ #define LWIP_POSIX_SOCKETS_IO_NAMES 0 + +/** + * LWIP_NETIF_HOSTNAME==1: Support netif hostname + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 1 +#endif + #define LWIP_NETIF_API 1 /* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */ diff --git a/components/net/lwip-1.4.1/src/netif/ethernetif.c b/components/net/lwip-1.4.1/src/netif/ethernetif.c index 9d8fa650a4..70dd9c00d0 100644 --- a/components/net/lwip-1.4.1/src/netif/ethernetif.c +++ b/components/net/lwip-1.4.1/src/netif/ethernetif.c @@ -440,8 +440,13 @@ static err_t eth_netif_device_init(struct netif *netif) rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flags) { struct netif* netif; - +#if LWIP_NETIF_HOSTNAME +#define LWIP_HOSTNAME_LEN 16 + char *hostname = RT_NULL; + netif = (struct netif*) rt_malloc (sizeof(struct netif) + LWIP_HOSTNAME_LEN); +#else netif = (struct netif*) rt_malloc (sizeof(struct netif)); +#endif if (netif == RT_NULL) { rt_kprintf("malloc netif failed\n"); @@ -476,6 +481,13 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ netif->output = etharp_output; netif->linkoutput = ethernetif_linkoutput; +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + hostname = (char *)netif + sizeof(struct netif); + rt_sprintf(hostname, "RT-Thread_%02x%02x", name[0], name[1]); + netif->hostname = hostname; +#endif /* LWIP_NETIF_HOSTNAME */ + /* if tcp thread has been started up, we add this netif to the system */ if (rt_thread_find("tcpip") != RT_NULL) { diff --git a/components/net/lwip-2.0.2/src/lwipopts.h b/components/net/lwip-2.0.2/src/lwipopts.h index f90ef1a825..c53863e1ab 100644 --- a/components/net/lwip-2.0.2/src/lwipopts.h +++ b/components/net/lwip-2.0.2/src/lwipopts.h @@ -531,6 +531,13 @@ #define LWIP_TCP_KEEPALIVE 1 #endif +/** + * LWIP_NETIF_HOSTNAME==1: Support netif hostname + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 1 +#endif + /** * LWIP_NETIF_API==1: Support netif api (in netifapi.c) */ diff --git a/components/net/lwip-2.0.2/src/netif/ethernetif.c b/components/net/lwip-2.0.2/src/netif/ethernetif.c index a7bed3065f..87aecdb58b 100644 --- a/components/net/lwip-2.0.2/src/netif/ethernetif.c +++ b/components/net/lwip-2.0.2/src/netif/ethernetif.c @@ -481,8 +481,13 @@ static err_t eth_netif_device_init(struct netif *netif) rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flags) { struct netif* netif; - +#if LWIP_NETIF_HOSTNAME +#define LWIP_HOSTNAME_LEN 16 + char *hostname = RT_NULL; + netif = (struct netif*) rt_malloc (sizeof(struct netif) + LWIP_HOSTNAME_LEN); +#else netif = (struct netif*) rt_malloc (sizeof(struct netif)); +#endif if (netif == RT_NULL) { rt_kprintf("malloc netif failed\n"); @@ -519,7 +524,9 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ - netif->hostname = "rtthread"; + hostname = (char *)netif + sizeof(struct netif); + rt_sprintf(hostname, "RT-Thread_%02x%02x", name[0], name[1]); + netif->hostname = hostname; #endif /* LWIP_NETIF_HOSTNAME */ /* if tcp thread has been started up, we add this netif to the system */ -- Gitee From a9cad2b95b75b5b07dcb91b6db85fa6e6a508aa1 Mon Sep 17 00:00:00 2001 From: liuxianliang Date: Thu, 19 Dec 2019 10:28:22 +0800 Subject: [PATCH 004/110] [net][lwip] rename hostname, change "RT-Thread_xx" into "RTTHREAD_xx" Signed-off-by: liuxianliang --- components/net/lwip-1.4.1/src/netif/ethernetif.c | 4 ++-- components/net/lwip-2.0.2/src/netif/ethernetif.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/net/lwip-1.4.1/src/netif/ethernetif.c b/components/net/lwip-1.4.1/src/netif/ethernetif.c index 70dd9c00d0..f729b27b93 100644 --- a/components/net/lwip-1.4.1/src/netif/ethernetif.c +++ b/components/net/lwip-1.4.1/src/netif/ethernetif.c @@ -483,8 +483,8 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ - hostname = (char *)netif + sizeof(struct netif); - rt_sprintf(hostname, "RT-Thread_%02x%02x", name[0], name[1]); + hostname = (char *)netif + sizeof(struct netif); + rt_sprintf(hostname, "RTTHREAD_%02x%02x", name[0], name[1]); netif->hostname = hostname; #endif /* LWIP_NETIF_HOSTNAME */ diff --git a/components/net/lwip-2.0.2/src/netif/ethernetif.c b/components/net/lwip-2.0.2/src/netif/ethernetif.c index 87aecdb58b..4ce0993f37 100644 --- a/components/net/lwip-2.0.2/src/netif/ethernetif.c +++ b/components/net/lwip-2.0.2/src/netif/ethernetif.c @@ -524,8 +524,8 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ - hostname = (char *)netif + sizeof(struct netif); - rt_sprintf(hostname, "RT-Thread_%02x%02x", name[0], name[1]); + hostname = (char *)netif + sizeof(struct netif); + rt_sprintf(hostname, "RTTHREAD_%02x%02x", name[0], name[1]); netif->hostname = hostname; #endif /* LWIP_NETIF_HOSTNAME */ -- Gitee From 0135c7bd8b64af3882830c1eccf49cd831af61de Mon Sep 17 00:00:00 2001 From: tyustli <1225613647@qq.com> Date: Thu, 19 Dec 2019 17:36:18 +0800 Subject: [PATCH 005/110] port usb host driver to stm32 new series --- bsp/stm32/libraries/HAL_Drivers/SConscript | 7 +- bsp/stm32/libraries/HAL_Drivers/drv_common.c | 1 + bsp/stm32/libraries/HAL_Drivers/drv_usbh.c | 248 ++++++++++++++++++ bsp/stm32/libraries/HAL_Drivers/drv_usbh.h | 21 ++ .../board/CubeMX_Config/.mxproject | 8 +- .../board/CubeMX_Config/CubeMX_Config.ioc | 59 +++-- .../CubeMX_Config/Inc/stm32f4xx_hal_conf.h | 2 +- .../board/CubeMX_Config/Inc/stm32f4xx_it.h | 1 + .../board/CubeMX_Config/Src/main.c | 35 +++ .../CubeMX_Config/Src/stm32f4xx_hal_msp.c | 73 ++++++ .../board/CubeMX_Config/Src/stm32f4xx_it.c | 15 ++ .../stm32f407-atk-explorer/board/Kconfig | 15 ++ bsp/stm32/stm32f429-atk-apollo/README.md | 4 +- .../board/CubeMX_Config/.mxproject | 8 +- .../CubeMX_Config/Inc/stm32f4xx_hal_conf.h | 4 +- .../board/CubeMX_Config/Inc/stm32f4xx_it.h | 1 + .../board/CubeMX_Config/STM32F429IG.ioc | 60 ++--- .../board/CubeMX_Config/Src/main.c | 78 +++--- .../CubeMX_Config/Src/stm32f4xx_hal_msp.c | 135 +++++----- .../board/CubeMX_Config/Src/stm32f4xx_it.c | 15 ++ bsp/stm32/stm32f429-atk-apollo/board/Kconfig | 15 ++ .../board/CubeMX_Config/.mxproject | 8 +- .../board/CubeMX_Config/CubeMX_Config.ioc | 72 ++--- .../CubeMX_Config/Inc/stm32f7xx_hal_conf.h | 2 +- .../board/CubeMX_Config/Inc/stm32f7xx_it.h | 1 + .../board/CubeMX_Config/Src/main.c | 35 +++ .../CubeMX_Config/Src/stm32f7xx_hal_msp.c | 70 +++++ .../board/CubeMX_Config/Src/stm32f7xx_it.c | 16 +- bsp/stm32/stm32f767-atk-apollo/board/Kconfig | 19 +- 29 files changed, 813 insertions(+), 215 deletions(-) create mode 100644 bsp/stm32/libraries/HAL_Drivers/drv_usbh.c create mode 100644 bsp/stm32/libraries/HAL_Drivers/drv_usbh.h diff --git a/bsp/stm32/libraries/HAL_Drivers/SConscript b/bsp/stm32/libraries/HAL_Drivers/SConscript index 02f68afa25..c7d5825f8f 100644 --- a/bsp/stm32/libraries/HAL_Drivers/SConscript +++ b/bsp/stm32/libraries/HAL_Drivers/SConscript @@ -72,10 +72,10 @@ if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32F7']): if GetDepend(['BSP_USING_ON_CHIP_FLASH', 'SOC_SERIES_STM32L4']): src += ['drv_flash/drv_flash_l4.c'] - + if GetDepend('RT_USING_HWCRYPTO'): src += ['drv_crypto.c'] - + if GetDepend(['BSP_USING_WDT']): src += ['drv_wdt.c'] @@ -88,6 +88,9 @@ if GetDepend(['BSP_USING_USBD']): if GetDepend(['BSP_USING_PULSE_ENCODER']): src += ['drv_pulse_encoder.c'] +if GetDepend(['BSP_USING_USBH']): + src += ['drv_usbh.c'] + src += ['drv_common.c'] path = [cwd] diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_common.c b/bsp/stm32/libraries/HAL_Drivers/drv_common.c index 1203757a65..02e0d82be5 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_common.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_common.c @@ -67,6 +67,7 @@ void HAL_ResumeTick(void) void HAL_Delay(__IO uint32_t Delay) { + rt_thread_mdelay(Delay); } /* re-implement tick interface for STM32 HAL */ diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usbh.c b/bsp/stm32/libraries/HAL_Drivers/drv_usbh.c new file mode 100644 index 0000000000..680a93e722 --- /dev/null +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usbh.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-10-30 ZYH the first version + * 2019-12-19 tyustli port to stm32 series + */ +#include "drv_usbh.h" +#include "board.h" + +static HCD_HandleTypeDef stm32_hhcd_fs; +static struct rt_completion urb_completion; +static volatile rt_bool_t connect_status = RT_FALSE; + +void OTG_FS_IRQHandler(void) +{ + rt_interrupt_enter(); + HAL_HCD_IRQHandler(&stm32_hhcd_fs); + rt_interrupt_leave(); +} + +void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) +{ + uhcd_t hcd = (uhcd_t)hhcd->pData; + if (!connect_status) + { + connect_status = RT_TRUE; + RT_DEBUG_LOG(RT_DEBUG_USB, ("usb connected\n")); + rt_usbh_root_hub_connect_handler(hcd, OTG_FS_PORT, RT_FALSE); + } +} + +void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) +{ + uhcd_t hcd = (uhcd_t)hhcd->pData; + if (connect_status) + { + connect_status = RT_FALSE; + RT_DEBUG_LOG(RT_DEBUG_USB, ("usb disconnnect\n")); + rt_usbh_root_hub_disconnect_handler(hcd, OTG_FS_PORT); + } +} + +void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) +{ + rt_completion_done(&urb_completion); +} + +static rt_err_t drv_reset_port(rt_uint8_t port) +{ + RT_DEBUG_LOG(RT_DEBUG_USB, ("reset port\n")); + HAL_HCD_ResetPort(&stm32_hhcd_fs); + return RT_EOK; +} + +static int drv_pipe_xfer(upipe_t pipe, rt_uint8_t token, void *buffer, int nbytes, int timeouts) +{ + int timeout = timeouts; + + while (1) + { + if (!connect_status) + { + return -1; + } + rt_completion_init(&urb_completion); + HAL_HCD_HC_SubmitRequest(&stm32_hhcd_fs, + pipe->pipe_index, + (pipe->ep.bEndpointAddress & 0x80) >> 7, + pipe->ep.bmAttributes, + token, + buffer, + nbytes, + 0); + rt_completion_wait(&urb_completion, timeout); + rt_thread_mdelay(1); + if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_NAK) + { + RT_DEBUG_LOG(RT_DEBUG_USB, ("nak\n")); + if (pipe->ep.bmAttributes == USB_EP_ATTR_INT) + { + rt_thread_delay((pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) > 0 ? (pipe->ep.bInterval * RT_TICK_PER_SECOND / 1000) : 1); + } + HAL_HCD_HC_Halt(&stm32_hhcd_fs, pipe->pipe_index); + HAL_HCD_HC_Init(&stm32_hhcd_fs, + pipe->pipe_index, + pipe->ep.bEndpointAddress, + pipe->inst->address, + USB_OTG_SPEED_FULL, + pipe->ep.bmAttributes, + pipe->ep.wMaxPacketSize); + continue; + } + else if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == HC_STALL) + { + RT_DEBUG_LOG(RT_DEBUG_USB, ("stall\n")); + pipe->status = UPIPE_STATUS_STALL; + if (pipe->callback != RT_NULL) + { + pipe->callback(pipe); + } + return -1; + } + else if (HAL_HCD_HC_GetState(&stm32_hhcd_fs, pipe->pipe_index) == URB_ERROR) + { + RT_DEBUG_LOG(RT_DEBUG_USB, ("error\n")); + pipe->status = UPIPE_STATUS_ERROR; + if (pipe->callback != RT_NULL) + { + pipe->callback(pipe); + } + return -1; + } + else if(URB_DONE == HAL_HCD_HC_GetURBState(&stm32_hhcd_fs, pipe->pipe_index)) + { + RT_DEBUG_LOG(RT_DEBUG_USB, ("ok\n")); + pipe->status = UPIPE_STATUS_OK; + if (pipe->callback != RT_NULL) + { + pipe->callback(pipe); + } + size_t size = HAL_HCD_HC_GetXferCount(&stm32_hhcd_fs, pipe->pipe_index); + if (pipe->ep.bEndpointAddress & 0x80) + { + return size; + } + else if (pipe->ep.bEndpointAddress & 0x00) + { + return size; + } + return nbytes; + } + + continue; + } +} + +static rt_uint16_t pipe_index = 0; +static rt_uint8_t drv_get_free_pipe_index(void) +{ + rt_uint8_t idx; + for (idx = 1; idx < 16; idx++) + { + if (!(pipe_index & (0x01 << idx))) + { + pipe_index |= (0x01 << idx); + return idx; + } + } + return 0xff; +} + +static void drv_free_pipe_index(rt_uint8_t index) +{ + pipe_index &= ~(0x01 << index); +} + +static rt_err_t drv_open_pipe(upipe_t pipe) +{ + pipe->pipe_index = drv_get_free_pipe_index(); + HAL_HCD_HC_Init(&stm32_hhcd_fs, + pipe->pipe_index, + pipe->ep.bEndpointAddress, + pipe->inst->address, + USB_OTG_SPEED_FULL, + pipe->ep.bmAttributes, + pipe->ep.wMaxPacketSize); + /* Set DATA0 PID token*/ + if (stm32_hhcd_fs.hc[pipe->pipe_index].ep_is_in) + { + stm32_hhcd_fs.hc[pipe->pipe_index].toggle_in = 0; + } + else + { + stm32_hhcd_fs.hc[pipe->pipe_index].toggle_out = 0; + } + return RT_EOK; +} + +static rt_err_t drv_close_pipe(upipe_t pipe) +{ + HAL_HCD_HC_Halt(&stm32_hhcd_fs, pipe->pipe_index); + drv_free_pipe_index(pipe->pipe_index); + return RT_EOK; +} + +static struct uhcd_ops _uhcd_ops = +{ + drv_reset_port, + drv_pipe_xfer, + drv_open_pipe, + drv_close_pipe, +}; + +static rt_err_t stm32_hcd_init(rt_device_t device) +{ + HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef *)device->user_data; + hhcd->Instance = USB_OTG_FS; + hhcd->Init.Host_channels = 8; + hhcd->Init.speed = HCD_SPEED_FULL; + hhcd->Init.dma_enable = DISABLE; + hhcd->Init.phy_itface = HCD_PHY_EMBEDDED; + hhcd->Init.Sof_enable = DISABLE; + RT_ASSERT(HAL_HCD_Init(hhcd) == HAL_OK); + HAL_HCD_Start(hhcd); +#ifdef USBH_USING_CONTROLLABLE_POWER + rt_pin_mode(USBH_POWER_PIN, PIN_MODE_OUTPUT); + rt_pin_write(USBH_POWER_PIN, PIN_LOW); +#endif + return RT_EOK; +} + +int stm_usbh_register(void) +{ + rt_err_t res = -RT_ERROR; + + uhcd_t uhcd = (uhcd_t)rt_malloc(sizeof(struct uhcd)); + if (uhcd == RT_NULL) + { + rt_kprintf("uhcd malloc failed\r\n"); + return -RT_ERROR; + } + + rt_memset((void *)uhcd, 0, sizeof(struct uhcd)); + + uhcd->parent.type = RT_Device_Class_USBHost; + uhcd->parent.init = stm32_hcd_init; + uhcd->parent.user_data = &stm32_hhcd_fs; + + uhcd->ops = &_uhcd_ops; + uhcd->num_ports = OTG_FS_PORT; + stm32_hhcd_fs.pData = uhcd; + + res = rt_device_register(&uhcd->parent, "usbh", RT_DEVICE_FLAG_DEACTIVATE); + if (res != RT_EOK) + { + rt_kprintf("register usb host failed res = %d\r\n", res); + return -RT_ERROR; + } + + rt_usb_host_init(); + + return RT_EOK; +} +INIT_DEVICE_EXPORT(stm_usbh_register); diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usbh.h b/bsp/stm32/libraries/HAL_Drivers/drv_usbh.h new file mode 100644 index 0000000000..e08f482f28 --- /dev/null +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usbh.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-12-12 ZYH the first version + * 2019-12-19 tyustli port to stm32 series + */ +#ifndef __DRV_USBH_H__ +#define __DRV_USBH_H__ +#include + +#define OTG_FS_PORT 1 + +int stm_usbh_register(void); + +#endif + +/************* end of file ************/ diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/.mxproject index 031ff82f9a..3c0602b619 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/.mxproject +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/.mxproject @@ -1,14 +1,14 @@ [PreviousGenFiles] -HeaderPath=E:/workspace/rt-thread/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc +HeaderPath=F:/rt-thread/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc HeaderFiles=stm32f4xx_it.h;stm32f4xx_hal_conf.h;main.h; -SourcePath=E:/workspace/rt-thread/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src +SourcePath=F:/rt-thread/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src SourceFiles=stm32f4xx_it.c;stm32f4xx_hal_msp.c;main.c; [PreviousLibFiles] -LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f407xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h; +LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f407xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h; [PreviousUsedKeilFiles] -SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;null; +SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;null; HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc; CDefines=USE_HAL_DRIVER;STM32F407xx;USE_HAL_DRIVER;STM32F407xx; diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/CubeMX_Config.ioc index fcc30e407e..52c20c220f 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/CubeMX_Config.ioc +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/CubeMX_Config.ioc @@ -19,6 +19,7 @@ Mcu.IP13=TIM13 Mcu.IP14=TIM14 Mcu.IP15=USART1 Mcu.IP16=USART3 +Mcu.IP17=USB_OTG_FS Mcu.IP2=IWDG Mcu.IP3=NVIC Mcu.IP4=RCC @@ -27,7 +28,7 @@ Mcu.IP6=SDIO Mcu.IP7=SPI1 Mcu.IP8=SPI2 Mcu.IP9=SYS -Mcu.IPNb=17 +Mcu.IPNb=18 Mcu.Name=STM32F407Z(E-G)Tx Mcu.Package=LQFP144 Mcu.Pin0=PC14-OSC32_IN @@ -44,35 +45,37 @@ Mcu.Pin18=PC9 Mcu.Pin19=PA9 Mcu.Pin2=PH0-OSC_IN Mcu.Pin20=PA10 -Mcu.Pin21=PA13 -Mcu.Pin22=PA14 -Mcu.Pin23=PC10 -Mcu.Pin24=PC11 -Mcu.Pin25=PC12 -Mcu.Pin26=PD2 -Mcu.Pin27=PG11 -Mcu.Pin28=PG13 -Mcu.Pin29=PG14 +Mcu.Pin21=PA11 +Mcu.Pin22=PA12 +Mcu.Pin23=PA13 +Mcu.Pin24=PA14 +Mcu.Pin25=PC10 +Mcu.Pin26=PC11 +Mcu.Pin27=PC12 +Mcu.Pin28=PD2 +Mcu.Pin29=PG11 Mcu.Pin3=PH1-OSC_OUT -Mcu.Pin30=PB3 -Mcu.Pin31=PB4 -Mcu.Pin32=PB5 -Mcu.Pin33=PB6 -Mcu.Pin34=PB7 -Mcu.Pin35=VP_IWDG_VS_IWDG -Mcu.Pin36=VP_RTC_VS_RTC_Activate -Mcu.Pin37=VP_SYS_VS_Systick -Mcu.Pin38=VP_TIM2_VS_ClockSourceINT -Mcu.Pin39=VP_TIM11_VS_ClockSourceINT +Mcu.Pin30=PG13 +Mcu.Pin31=PG14 +Mcu.Pin32=PB3 +Mcu.Pin33=PB4 +Mcu.Pin34=PB5 +Mcu.Pin35=PB6 +Mcu.Pin36=PB7 +Mcu.Pin37=VP_IWDG_VS_IWDG +Mcu.Pin38=VP_RTC_VS_RTC_Activate +Mcu.Pin39=VP_SYS_VS_Systick Mcu.Pin4=PC1 -Mcu.Pin40=VP_TIM13_VS_ClockSourceINT -Mcu.Pin41=VP_TIM14_VS_ClockSourceINT +Mcu.Pin40=VP_TIM2_VS_ClockSourceINT +Mcu.Pin41=VP_TIM11_VS_ClockSourceINT +Mcu.Pin42=VP_TIM13_VS_ClockSourceINT +Mcu.Pin43=VP_TIM14_VS_ClockSourceINT Mcu.Pin5=PC2 Mcu.Pin6=PC3 Mcu.Pin7=PA1 Mcu.Pin8=PA2 Mcu.Pin9=PA3 -Mcu.PinsNb=42 +Mcu.PinsNb=44 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F407ZGTx @@ -83,6 +86,7 @@ NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.OTG_FS_IRQn=true\:0\:0\:false\:false\:true\:true\:true NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SPI1_IRQn=true\:0\:0\:false\:false\:true\:true\:true @@ -94,6 +98,10 @@ PA1.Mode=RMII PA1.Signal=ETH_REF_CLK PA10.Mode=Asynchronous PA10.Signal=USART1_RX +PA11.Mode=Host_Only +PA11.Signal=USB_OTG_FS_DM +PA12.Mode=Host_Only +PA12.Signal=USB_OTG_FS_DP PA13.Mode=Serial_Wire PA13.Signal=SYS_JTMS-SWDIO PA14.Mode=Serial_Wire @@ -174,7 +182,7 @@ PH0-OSC_IN.Signal=RCC_OSC_IN PH1-OSC_OUT.Mode=HSE-External-Oscillator PH1-OSC_OUT.Signal=RCC_OSC_OUT PinOutPanel.RotationAngle=0 -ProjectManager.AskForMigrate=false +ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false @@ -260,6 +268,9 @@ USART1.IPParameters=VirtualMode USART1.VirtualMode=VM_ASYNC USART3.IPParameters=VirtualMode USART3.VirtualMode=VM_ASYNC +USB_OTG_FS.IPParameters=VirtualMode,phy_itface +USB_OTG_FS.VirtualMode=Host_Only +USB_OTG_FS.phy_itface=HCD_PHY_EMBEDDED VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h index 9b15113c2c..dc0a83626e 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h @@ -81,7 +81,7 @@ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ -/* #define HAL_HCD_MODULE_ENABLED */ +#define HAL_HCD_MODULE_ENABLED /* #define HAL_DSI_MODULE_ENABLED */ /* #define HAL_QSPI_MODULE_ENABLED */ /* #define HAL_QSPI_MODULE_ENABLED */ diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_it.h b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_it.h index d87cf45f97..44c3bafe0f 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_it.h +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_it.h @@ -73,6 +73,7 @@ void PendSV_Handler(void); void SysTick_Handler(void); void SPI1_IRQHandler(void); void USART1_IRQHandler(void); +void OTG_FS_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/main.c index ef64d82dc1..2c69b3dfa3 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/main.c @@ -84,6 +84,8 @@ TIM_HandleTypeDef htim14; UART_HandleTypeDef huart1; UART_HandleTypeDef huart3; +HCD_HandleTypeDef hhcd_USB_OTG_FS; + /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ @@ -106,6 +108,7 @@ static void MX_SDIO_SD_Init(void); static void MX_TIM2_Init(void); static void MX_SPI2_Init(void); static void MX_TIM4_Init(void); +static void MX_USB_OTG_FS_HCD_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ @@ -158,6 +161,7 @@ int main(void) MX_TIM2_Init(); MX_SPI2_Init(); MX_TIM4_Init(); + MX_USB_OTG_FS_HCD_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -758,6 +762,37 @@ static void MX_USART3_UART_Init(void) } +/** + * @brief USB_OTG_FS Initialization Function + * @param None + * @retval None + */ +static void MX_USB_OTG_FS_HCD_Init(void) +{ + + /* USER CODE BEGIN USB_OTG_FS_Init 0 */ + + /* USER CODE END USB_OTG_FS_Init 0 */ + + /* USER CODE BEGIN USB_OTG_FS_Init 1 */ + + /* USER CODE END USB_OTG_FS_Init 1 */ + hhcd_USB_OTG_FS.Instance = USB_OTG_FS; + hhcd_USB_OTG_FS.Init.Host_channels = 8; + hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL; + hhcd_USB_OTG_FS.Init.dma_enable = DISABLE; + hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED; + hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE; + if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USB_OTG_FS_Init 2 */ + + /* USER CODE END USB_OTG_FS_Init 2 */ + +} + /** * @brief GPIO Initialization Function * @param None diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c index 90a333827e..1597ab0ec0 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c @@ -852,6 +852,79 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) } +/** +* @brief HCD MSP Initialization +* This function configures the hardware resources used in this example +* @param hhcd: HCD handle pointer +* @retval None +*/ +void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hhcd->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */ + + /* USER CODE END USB_OTG_FS_MspInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USB_OTG_FS GPIO Configuration + PA11 ------> USB_OTG_FS_DM + PA12 ------> USB_OTG_FS_DP + */ + GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + /* USB_OTG_FS interrupt Init */ + HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */ + + /* USER CODE END USB_OTG_FS_MspInit 1 */ + } + +} + +/** +* @brief HCD MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hhcd: HCD handle pointer +* @retval None +*/ + +void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hhcd) +{ + + if(hhcd->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); + + /**USB_OTG_FS GPIO Configuration + PA11 ------> USB_OTG_FS_DM + PA12 ------> USB_OTG_FS_DP + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); + + /* USB_OTG_FS interrupt DeInit */ + HAL_NVIC_DisableIRQ(OTG_FS_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 1 */ + } + +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_it.c b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_it.c index 149f219b9c..b512c4ef42 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_it.c +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_it.c @@ -73,6 +73,7 @@ /* External variables --------------------------------------------------------*/ extern SPI_HandleTypeDef hspi1; extern UART_HandleTypeDef huart1; +extern HCD_HandleTypeDef hhcd_USB_OTG_FS; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -241,6 +242,20 @@ void USART1_IRQHandler(void) /* USER CODE END USART1_IRQn 1 */ } +/** + * @brief This function handles USB On The Go FS global interrupt. + */ +void OTG_FS_IRQHandler(void) +{ + /* USER CODE BEGIN OTG_FS_IRQn 0 */ + + /* USER CODE END OTG_FS_IRQn 0 */ + HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS); + /* USER CODE BEGIN OTG_FS_IRQn 1 */ + + /* USER CODE END OTG_FS_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/bsp/stm32/stm32f407-atk-explorer/board/Kconfig b/bsp/stm32/stm32f407-atk-explorer/board/Kconfig index 5afd038648..624f55b7f8 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/Kconfig +++ b/bsp/stm32/stm32f407-atk-explorer/board/Kconfig @@ -296,6 +296,21 @@ menu "On-chip Peripheral Drivers" select RT_USING_DFS default n + menuconfig BSP_USING_USBH + bool "Enable USB Host" + select RT_USING_USB_HOST + default n + if BSP_USING_USBH + menuconfig RT_USBH_MSTORAGE + bool "Enable Udisk Drivers" + default n + if RT_USBH_MSTORAGE + config UDISK_MOUNTPOINT + string "Udisk mount dir" + default "/" + endif + endif + menuconfig BSP_USING_PULSE_ENCODER bool "Enable Pulse Encoder" default n diff --git a/bsp/stm32/stm32f429-atk-apollo/README.md b/bsp/stm32/stm32f429-atk-apollo/README.md index f616cebdbd..6ec5108a3a 100644 --- a/bsp/stm32/stm32f429-atk-apollo/README.md +++ b/bsp/stm32/stm32f429-atk-apollo/README.md @@ -47,7 +47,7 @@ | MPU9250九轴传感器 | 支持 | | | SDRAM | 支持 | | | SD卡 | 支持 | | -| CAN | 暂不支持 | | +| CAN | 支持 | 和 USB Host 引脚冲突,如需使用该外设,请使用 CubeMX 重新配置 | | **片上外设** | **支持情况** | **备注** | | GPIO | 支持 | PA0, PA1... PK15 ---> PIN: 0, 1...176 | | UART | 支持 | UART1/2/3 | @@ -61,7 +61,7 @@ | SDIO | 支持 | | | PWM | 支持 | | | USB Device | 暂不支持 | 即将支持 | -| USB Host | 暂不支持 | 即将支持 | +| USB Host | 支持 | 和 CAN1 引脚冲突,如需使用该外设,请使用 CubeMX 重新配置 | | **扩展模块** | **支持情况** | **备注** | | ATK-ESP8266 模块 | 暂不支持 | 即将支持 | diff --git a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/.mxproject index ce6cbcb32b..5ccdc033db 100644 --- a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/.mxproject +++ b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/.mxproject @@ -1,17 +1,17 @@ [PreviousGenFiles] -HeaderPath=E:/work_relative/RT_THREAD/rt-thread/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc +HeaderPath=F:/rt-thread/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc HeaderFiles=stm32f4xx_it.h;stm32f4xx_hal_conf.h;main.h; -SourcePath=E:/work_relative/RT_THREAD/rt-thread/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src +SourcePath=F:/rt-thread/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src SourceFiles=stm32f4xx_it.c;stm32f4xx_hal_msp.c;main.c; [PreviousLibFiles] -LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sdram.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sdram.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f429xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; +LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sdram.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sdram.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f429xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; [] SourceFiles=;; [PreviousUsedKeilFiles] -SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;../\Src/system_stm32f4xx.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;../\Src/system_stm32f4xx.c;../Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;null; +SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;../\Src/system_stm32f4xx.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;../\Src/system_stm32f4xx.c;../Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;null; HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc; CDefines=USE_HAL_DRIVER;STM32F429xx;USE_HAL_DRIVER;STM32F429xx; diff --git a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h index 65a892fc3d..953a90cf2f 100644 --- a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h +++ b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h @@ -38,7 +38,7 @@ #define HAL_ADC_MODULE_ENABLED /* #define HAL_CRYP_MODULE_ENABLED */ -#define HAL_CAN_MODULE_ENABLED +/* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_DAC_MODULE_ENABLED */ @@ -68,7 +68,7 @@ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ -/* #define HAL_HCD_MODULE_ENABLED */ +#define HAL_HCD_MODULE_ENABLED /* #define HAL_DSI_MODULE_ENABLED */ /* #define HAL_QSPI_MODULE_ENABLED */ /* #define HAL_QSPI_MODULE_ENABLED */ diff --git a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc/stm32f4xx_it.h b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc/stm32f4xx_it.h index e3b003d9ad..c80fb5271c 100644 --- a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc/stm32f4xx_it.h +++ b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Inc/stm32f4xx_it.h @@ -72,6 +72,7 @@ void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); void USART1_IRQHandler(void); +void OTG_FS_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/STM32F429IG.ioc b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/STM32F429IG.ioc index fad96a6839..ad57d049ee 100644 --- a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/STM32F429IG.ioc +++ b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/STM32F429IG.ioc @@ -5,34 +5,32 @@ ADC1.NbrOfConversionFlag=1 ADC1.Rank-0\#ChannelRegularConversion=1 ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES ADC1.master=1 -CAN1.CalculateTimeQuantum=355.55555555555554 -CAN1.IPParameters=CalculateTimeQuantum ETH.IPParameters=MediaInterface ETH.MediaInterface=ETH_MEDIA_INTERFACE_RMII File.Version=6 KeepUserPlacement=false Mcu.Family=STM32F4 Mcu.IP0=ADC1 -Mcu.IP1=CAN1 -Mcu.IP10=SPI1 -Mcu.IP11=SPI2 -Mcu.IP12=SPI5 -Mcu.IP13=SYS -Mcu.IP14=TIM2 -Mcu.IP15=TIM11 -Mcu.IP16=TIM13 -Mcu.IP17=TIM14 -Mcu.IP18=USART1 -Mcu.IP19=USART2 -Mcu.IP2=ETH -Mcu.IP20=USART3 -Mcu.IP3=FMC -Mcu.IP4=IWDG -Mcu.IP5=NVIC -Mcu.IP6=RCC -Mcu.IP7=RTC -Mcu.IP8=SAI1 -Mcu.IP9=SDIO +Mcu.IP1=ETH +Mcu.IP10=SPI2 +Mcu.IP11=SPI5 +Mcu.IP12=SYS +Mcu.IP13=TIM2 +Mcu.IP14=TIM11 +Mcu.IP15=TIM13 +Mcu.IP16=TIM14 +Mcu.IP17=USART1 +Mcu.IP18=USART2 +Mcu.IP19=USART3 +Mcu.IP2=FMC +Mcu.IP20=USB_OTG_FS +Mcu.IP3=IWDG +Mcu.IP4=NVIC +Mcu.IP5=RCC +Mcu.IP6=RTC +Mcu.IP7=SAI1 +Mcu.IP8=SDIO +Mcu.IP9=SPI1 Mcu.IPNb=21 Mcu.Name=STM32F429I(E-G)Tx Mcu.Package=LQFP176 @@ -138,6 +136,7 @@ NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.OTG_FS_IRQn=true\:0\:0\:false\:false\:true\:true\:true NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false @@ -148,11 +147,10 @@ PA1.Mode=RMII PA1.Signal=ETH_REF_CLK PA10.Mode=Asynchronous PA10.Signal=USART1_RX -PA11.Locked=true -PA11.Mode=Master -PA11.Signal=CAN1_RX -PA12.Mode=Master -PA12.Signal=CAN1_TX +PA11.Mode=Host_Only +PA11.Signal=USB_OTG_FS_DM +PA12.Mode=Host_Only +PA12.Signal=USB_OTG_FS_DP PA13.Mode=Serial_Wire PA13.Signal=SYS_JTMS-SWDIO PA14.Mode=Serial_Wire @@ -300,7 +298,7 @@ ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 ProjectManager.KeepUserCode=true -ProjectManager.LastFirmware=true +ProjectManager.LastFirmware=false ProjectManager.LibraryCopy=0 ProjectManager.MainLocation=Src ProjectManager.NoMain=false @@ -357,8 +355,7 @@ RCC.VCOSAIOutputFreq_ValueR=50000000 RCC.VcooutputI2S=160000000 RCC.VcooutputI2SQ=160000000 SAI1.ErrorAudioFreq-SAI_A_MasterWithClock=-49.13 % -SAI1.FrameLength-SAI_B_SyncSlave=8 -SAI1.IPParameters=Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,Synchro-SAI_B_SyncSlave,FrameLength-SAI_B_SyncSlave,Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,Synchro-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock +SAI1.IPParameters=Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,Synchro-SAI_B_SyncSlave,Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,Synchro-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock SAI1.Instance-SAI_A_MasterWithClock=SAI$Index_Block_A SAI1.Instance-SAI_B_SyncSlave=SAI$Index_Block_B SAI1.MClockEnable-SAI_A_MasterWithClock=SAI_MASTERCLOCK_ENABLE @@ -468,6 +465,9 @@ USART2.IPParameters=VirtualMode USART2.VirtualMode=VM_ASYNC USART3.IPParameters=VirtualMode USART3.VirtualMode=VM_ASYNC +USB_OTG_FS.IPParameters=VirtualMode,phy_itface +USB_OTG_FS.VirtualMode=Host_Only +USB_OTG_FS.phy_itface=HCD_PHY_EMBEDDED VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled diff --git a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/main.c index 342aa48b67..e17a48a050 100644 --- a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/main.c @@ -64,8 +64,6 @@ /* Private variables ---------------------------------------------------------*/ ADC_HandleTypeDef hadc1; -CAN_HandleTypeDef hcan1; - ETH_HandleTypeDef heth; IWDG_HandleTypeDef hiwdg; @@ -90,6 +88,8 @@ UART_HandleTypeDef huart1; UART_HandleTypeDef huart2; UART_HandleTypeDef huart3; +HCD_HandleTypeDef hhcd_USB_OTG_FS; + SDRAM_HandleTypeDef hsdram1; /* USER CODE BEGIN PV */ @@ -114,10 +114,10 @@ static void MX_TIM2_Init(void); static void MX_SPI1_Init(void); static void MX_SPI2_Init(void); static void MX_SPI5_Init(void); -static void MX_CAN1_Init(void); static void MX_SAI1_Init(void); static void MX_USART2_UART_Init(void); static void MX_USART3_UART_Init(void); +static void MX_USB_OTG_FS_HCD_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ @@ -171,10 +171,10 @@ int main(void) MX_SPI1_Init(); MX_SPI2_Init(); MX_SPI5_Init(); - MX_CAN1_Init(); MX_SAI1_Init(); MX_USART2_UART_Init(); MX_USART3_UART_Init(); + MX_USB_OTG_FS_HCD_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -309,43 +309,6 @@ static void MX_ADC1_Init(void) } -/** - * @brief CAN1 Initialization Function - * @param None - * @retval None - */ -static void MX_CAN1_Init(void) -{ - - /* USER CODE BEGIN CAN1_Init 0 */ - - /* USER CODE END CAN1_Init 0 */ - - /* USER CODE BEGIN CAN1_Init 1 */ - - /* USER CODE END CAN1_Init 1 */ - hcan1.Instance = CAN1; - hcan1.Init.Prescaler = 16; - hcan1.Init.Mode = CAN_MODE_NORMAL; - hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; - hcan1.Init.TimeSeg1 = CAN_BS1_1TQ; - hcan1.Init.TimeSeg2 = CAN_BS2_1TQ; - hcan1.Init.TimeTriggeredMode = DISABLE; - hcan1.Init.AutoBusOff = DISABLE; - hcan1.Init.AutoWakeUp = DISABLE; - hcan1.Init.AutoRetransmission = DISABLE; - hcan1.Init.ReceiveFifoLocked = DISABLE; - hcan1.Init.TransmitFifoPriority = DISABLE; - if (HAL_CAN_Init(&hcan1) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN CAN1_Init 2 */ - - /* USER CODE END CAN1_Init 2 */ - -} - /** * @brief ETH Initialization Function * @param None @@ -500,7 +463,7 @@ static void MX_SAI1_Init(void) hsai_BlockB1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; hsai_BlockB1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE; hsai_BlockB1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY; - hsai_BlockB1.FrameInit.FrameLength = 8; + hsai_BlockB1.FrameInit.FrameLength = 24; hsai_BlockB1.FrameInit.ActiveFrameLength = 1; hsai_BlockB1.FrameInit.FSDefinition = SAI_FS_STARTFRAME; hsai_BlockB1.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; @@ -920,6 +883,37 @@ static void MX_USART3_UART_Init(void) } +/** + * @brief USB_OTG_FS Initialization Function + * @param None + * @retval None + */ +static void MX_USB_OTG_FS_HCD_Init(void) +{ + + /* USER CODE BEGIN USB_OTG_FS_Init 0 */ + + /* USER CODE END USB_OTG_FS_Init 0 */ + + /* USER CODE BEGIN USB_OTG_FS_Init 1 */ + + /* USER CODE END USB_OTG_FS_Init 1 */ + hhcd_USB_OTG_FS.Instance = USB_OTG_FS; + hhcd_USB_OTG_FS.Init.Host_channels = 8; + hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL; + hhcd_USB_OTG_FS.Init.dma_enable = DISABLE; + hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED; + hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE; + if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USB_OTG_FS_Init 2 */ + + /* USER CODE END USB_OTG_FS_Init 2 */ + +} + /* FMC initialization function */ static void MX_FMC_Init(void) { diff --git a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c index 20fa0028c0..ad60e8e19a 100644 --- a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c +++ b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c @@ -160,71 +160,6 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) } -/** -* @brief CAN MSP Initialization -* This function configures the hardware resources used in this example -* @param hcan: CAN handle pointer -* @retval None -*/ -void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) -{ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(hcan->Instance==CAN1) - { - /* USER CODE BEGIN CAN1_MspInit 0 */ - - /* USER CODE END CAN1_MspInit 0 */ - /* Peripheral clock enable */ - __HAL_RCC_CAN1_CLK_ENABLE(); - - __HAL_RCC_GPIOA_CLK_ENABLE(); - /**CAN1 GPIO Configuration - PA11 ------> CAN1_RX - PA12 ------> CAN1_TX - */ - GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF9_CAN1; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* USER CODE BEGIN CAN1_MspInit 1 */ - - /* USER CODE END CAN1_MspInit 1 */ - } - -} - -/** -* @brief CAN MSP De-Initialization -* This function freeze the hardware resources used in this example -* @param hcan: CAN handle pointer -* @retval None -*/ -void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan) -{ - if(hcan->Instance==CAN1) - { - /* USER CODE BEGIN CAN1_MspDeInit 0 */ - - /* USER CODE END CAN1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_CAN1_CLK_DISABLE(); - - /**CAN1 GPIO Configuration - PA11 ------> CAN1_RX - PA12 ------> CAN1_TX - */ - HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); - - /* USER CODE BEGIN CAN1_MspDeInit 1 */ - - /* USER CODE END CAN1_MspDeInit 1 */ - } - -} - /** * @brief ETH MSP Initialization * This function configures the hardware resources used in this example @@ -909,6 +844,76 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) } +/** +* @brief HCD MSP Initialization +* This function configures the hardware resources used in this example +* @param hhcd: HCD handle pointer +* @retval None +*/ +void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hhcd->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */ + + /* USER CODE END USB_OTG_FS_MspInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USB_OTG_FS GPIO Configuration + PA11 ------> USB_OTG_FS_DM + PA12 ------> USB_OTG_FS_DP + */ + GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + /* USB_OTG_FS interrupt Init */ + HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */ + + /* USER CODE END USB_OTG_FS_MspInit 1 */ + } + +} + +/** +* @brief HCD MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hhcd: HCD handle pointer +* @retval None +*/ +void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hhcd) +{ + if(hhcd->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); + + /**USB_OTG_FS GPIO Configuration + PA11 ------> USB_OTG_FS_DM + PA12 ------> USB_OTG_FS_DP + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); + + /* USB_OTG_FS interrupt DeInit */ + HAL_NVIC_DisableIRQ(OTG_FS_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 1 */ + } + +} + static uint32_t FMC_Initialized = 0; static void HAL_FMC_MspInit(void){ diff --git a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/stm32f4xx_it.c b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/stm32f4xx_it.c index 80653c5ad3..ecc64e0079 100644 --- a/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/stm32f4xx_it.c +++ b/bsp/stm32/stm32f429-atk-apollo/board/CubeMX_Config/Src/stm32f4xx_it.c @@ -72,6 +72,7 @@ /* External variables --------------------------------------------------------*/ extern UART_HandleTypeDef huart1; +extern HCD_HandleTypeDef hhcd_USB_OTG_FS; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -226,6 +227,20 @@ void USART1_IRQHandler(void) /* USER CODE END USART1_IRQn 1 */ } +/** + * @brief This function handles USB On The Go FS global interrupt. + */ +void OTG_FS_IRQHandler(void) +{ + /* USER CODE BEGIN OTG_FS_IRQn 0 */ + + /* USER CODE END OTG_FS_IRQn 0 */ + HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS); + /* USER CODE BEGIN OTG_FS_IRQn 1 */ + + /* USER CODE END OTG_FS_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/bsp/stm32/stm32f429-atk-apollo/board/Kconfig b/bsp/stm32/stm32f429-atk-apollo/board/Kconfig index 4705be7b46..1d693397c1 100644 --- a/bsp/stm32/stm32f429-atk-apollo/board/Kconfig +++ b/bsp/stm32/stm32f429-atk-apollo/board/Kconfig @@ -270,6 +270,21 @@ menu "On-chip Peripheral Drivers" select RT_USING_WDT default n + menuconfig BSP_USING_USBH + bool "Enable USB Host" + select RT_USING_USB_HOST + default n + if BSP_USING_USBH + menuconfig RT_USBH_MSTORAGE + bool "Enable Udisk Drivers" + default n + if RT_USBH_MSTORAGE + config UDISK_MOUNTPOINT + string "Udisk mount dir" + default "/" + endif + endif + config BSP_USING_SDIO bool "Enable SDIO" select RT_USING_SDIO diff --git a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/.mxproject index ac37a7c72b..f27f66a833 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/.mxproject +++ b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/.mxproject @@ -1,14 +1,14 @@ [PreviousGenFiles] -HeaderPath=E:/work/rtt/rt-thread/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc +HeaderPath=F:/rt-thread/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc HeaderFiles=stm32f7xx_it.h;stm32f7xx_hal_conf.h;main.h; -SourcePath=E:/work/rtt/rt-thread/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src +SourcePath=F:/rt-thread/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src SourceFiles=stm32f7xx_it.c;stm32f7xx_hal_msp.c;main.c; [PreviousLibFiles] -LibFiles=Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_adc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_adc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_cortex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_eth.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_fmc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_sdram.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_iwdg.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_ltdc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_ltdc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dsi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_qspi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rtc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rtc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_sdmmc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_sd.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_spi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_spi_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_tim.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_tim_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_uart.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_uart_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_flash.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_flash_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_gpio.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_gpio_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dma.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dma_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_pwr.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_pwr_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_def.h;Drivers/STM32F7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_i2c.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_i2c_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_exti.h;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cortex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_eth.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_fmc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sdram.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_iwdg.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dsi.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_qspi.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_sdmmc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_uart.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_uart_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_gpio.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_exti.c;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_adc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_adc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_cortex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_eth.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_fmc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_sdram.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_iwdg.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_ltdc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_ltdc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dsi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_qspi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rtc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rtc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_sdmmc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_sd.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_spi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_spi_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_tim.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_tim_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_uart.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_uart_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_flash.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_flash_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_gpio.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_gpio_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dma.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dma_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_pwr.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_pwr_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_def.h;Drivers/STM32F7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_i2c.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_i2c_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32F7xx/Include/stm32f767xx.h;Drivers/CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h;Drivers/CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h;Drivers/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h; +LibFiles=Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_adc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_adc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_cortex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_eth.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_fmc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_sdram.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_iwdg.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_ltdc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_ltdc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dsi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_qspi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rtc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rtc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_sdmmc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_sd.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_spi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_spi_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_tim.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_tim_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_uart.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_uart_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_hcd.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_usb.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_flash.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_flash_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_gpio.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_gpio_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dma.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dma_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_pwr.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_pwr_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_def.h;Drivers/STM32F7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_i2c.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_i2c_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_exti.h;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cortex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_eth.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_fmc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sdram.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_iwdg.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dsi.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_qspi.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_sdmmc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_uart.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_uart_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_hcd.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_usb.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_gpio.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c_ex.c;Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_exti.c;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_adc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_adc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_cortex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_eth.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_fmc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_sdram.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_iwdg.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_ltdc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_ltdc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dsi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_qspi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rtc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rtc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_sdmmc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_sd.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_spi.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_spi_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_tim.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_tim_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_uart.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_uart_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_hcd.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_ll_usb.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_flash.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_flash_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_gpio.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_gpio_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dma.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_dma_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_pwr.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_pwr_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_def.h;Drivers/STM32F7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_i2c.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_i2c_ex.h;Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32F7xx/Include/stm32f767xx.h;Drivers/CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h;Drivers/CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h;Drivers/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h; [PreviousUsedKeilFiles] -SourceFiles=..\Src\main.c;..\Src\stm32f7xx_it.c;..\Src\stm32f7xx_hal_msp.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cortex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_eth.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_fmc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sdram.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_iwdg.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dsi.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_qspi.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_sdmmc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_spi_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_uart.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_gpio.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c_ex.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_exti.c;../\Src/system_stm32f7xx.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cortex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_eth.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_fmc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sdram.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_iwdg.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dsi.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_qspi.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_sdmmc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_spi_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_uart.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_gpio.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c_ex.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_exti.c;../\Src/system_stm32f7xx.c;../Drivers/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c;null; +SourceFiles=..\Src\main.c;..\Src\stm32f7xx_it.c;..\Src\stm32f7xx_hal_msp.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cortex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_eth.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_fmc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sdram.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_iwdg.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dsi.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_qspi.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_sdmmc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_spi_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_uart.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_hcd.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_usb.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_gpio.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c_ex.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_exti.c;../\Src/system_stm32f7xx.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_adc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_cortex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_eth.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_fmc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sdram.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_iwdg.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_ltdc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dsi.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_qspi.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rtc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_sdmmc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_spi.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_spi_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_tim_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_uart.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_uart_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_hcd.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_ll_usb.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_rcc_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_flash_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_gpio.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_dma_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pwr_ex.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c.c;../Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2c_ex.c;..\Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_exti.c;../\Src/system_stm32f7xx.c;../Drivers/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c;null; HeaderPath=..\Drivers\STM32F7xx_HAL_Driver\Inc;..\Drivers\STM32F7xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F7xx\Include;..\Drivers\CMSIS\Include;..\Inc; CDefines=USE_HAL_DRIVER;STM32F767xx;USE_HAL_DRIVER;STM32F767xx; diff --git a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/CubeMX_Config.ioc index b22dcde7c8..506854c422 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/CubeMX_Config.ioc +++ b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/CubeMX_Config.ioc @@ -28,6 +28,7 @@ Mcu.IP17=TIM14 Mcu.IP18=USART1 Mcu.IP19=USART2 Mcu.IP2=ETH +Mcu.IP20=USB_OTG_FS Mcu.IP3=FMC Mcu.IP4=IWDG Mcu.IP5=LTDC @@ -35,13 +36,15 @@ Mcu.IP6=NVIC Mcu.IP7=QUADSPI Mcu.IP8=RCC Mcu.IP9=RTC -Mcu.IPNb=20 +Mcu.IPNb=21 Mcu.Name=STM32F767I(G-I)Tx Mcu.Package=LQFP176 Mcu.Pin0=PC14/OSC32_IN Mcu.Pin1=PC15/OSC32_OUT Mcu.Pin10=PF5 -Mcu.Pin100=VP_TIM14_VS_ClockSourceINT +Mcu.Pin100=VP_TIM11_VS_ClockSourceINT +Mcu.Pin101=VP_TIM13_VS_ClockSourceINT +Mcu.Pin102=VP_TIM14_VS_ClockSourceINT Mcu.Pin11=PF6 Mcu.Pin12=PF7 Mcu.Pin13=PF8 @@ -111,35 +114,35 @@ Mcu.Pin70=PC9 Mcu.Pin71=PA8 Mcu.Pin72=PA9 Mcu.Pin73=PA10 -Mcu.Pin74=PA13 -Mcu.Pin75=PH14 -Mcu.Pin76=PI2 -Mcu.Pin77=PA14 -Mcu.Pin78=PC10 -Mcu.Pin79=PC11 +Mcu.Pin74=PA11 +Mcu.Pin75=PA12 +Mcu.Pin76=PA13 +Mcu.Pin77=PH14 +Mcu.Pin78=PI2 +Mcu.Pin79=PA14 Mcu.Pin8=PF3 -Mcu.Pin80=PC12 -Mcu.Pin81=PD0 -Mcu.Pin82=PD1 -Mcu.Pin83=PD2 -Mcu.Pin84=PD5 -Mcu.Pin85=PD6 -Mcu.Pin86=PG12 -Mcu.Pin87=PG13 -Mcu.Pin88=PG14 -Mcu.Pin89=PG15 +Mcu.Pin80=PC10 +Mcu.Pin81=PC11 +Mcu.Pin82=PC12 +Mcu.Pin83=PD0 +Mcu.Pin84=PD1 +Mcu.Pin85=PD2 +Mcu.Pin86=PD5 +Mcu.Pin87=PD6 +Mcu.Pin88=PG12 +Mcu.Pin89=PG13 Mcu.Pin9=PF4 -Mcu.Pin90=PB6 -Mcu.Pin91=PB8 -Mcu.Pin92=PB9 -Mcu.Pin93=PI5 -Mcu.Pin94=VP_IWDG_VS_IWDG -Mcu.Pin95=VP_RTC_VS_RTC_Activate -Mcu.Pin96=VP_SYS_VS_Systick -Mcu.Pin97=VP_TIM3_VS_ClockSourceINT -Mcu.Pin98=VP_TIM11_VS_ClockSourceINT -Mcu.Pin99=VP_TIM13_VS_ClockSourceINT -Mcu.PinsNb=101 +Mcu.Pin90=PG14 +Mcu.Pin91=PG15 +Mcu.Pin92=PB6 +Mcu.Pin93=PB8 +Mcu.Pin94=PB9 +Mcu.Pin95=PI5 +Mcu.Pin96=VP_IWDG_VS_IWDG +Mcu.Pin97=VP_RTC_VS_RTC_Activate +Mcu.Pin98=VP_SYS_VS_Systick +Mcu.Pin99=VP_TIM3_VS_ClockSourceINT +Mcu.PinsNb=103 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F767IGTx @@ -150,6 +153,7 @@ NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.OTG_FS_IRQn=true\:0\:0\:false\:false\:true\:true\:true NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false @@ -160,6 +164,10 @@ PA1.Signal=ETH_REF_CLK PA10.Locked=true PA10.Mode=Asynchronous PA10.Signal=USART1_RX +PA11.Mode=Host_Only +PA11.Signal=USB_OTG_FS_DM +PA12.Mode=Host_Only +PA12.Signal=USB_OTG_FS_DP PA13.Mode=Serial_Wire PA13.Signal=SYS_JTMS-SWDIO PA14.Mode=Serial_Wire @@ -377,7 +385,7 @@ RCC.I2C2Freq_Value=54000000 RCC.I2C3Freq_Value=54000000 RCC.I2C4Freq_Value=54000000 RCC.I2SFreq_Value=96000000 -RCC.IPParameters=AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CECFreq_Value,CortexFreq_Value,DFSDMAudioFreq_Value,DFSDMFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I2SFreq_Value,LCDTFTFreq_Value,LPTIM1Freq_Value,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLI2SPCLKFreq_Value,PLLI2SQCLKFreq_Value,PLLI2SRCLKFreq_Value,PLLI2SRoutputFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,PLLQoutputFreq_Value,PLLRFreq_Value,PLLSAIN,PLLSAIPCLKFreq_Value,PLLSAIQCLKFreq_Value,PLLSAIR,PLLSAIRCLKFreq_Value,PLLSAIRDiv,PLLSAIoutputFreq_Value,PLLSourceVirtual,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMC2Freq_Value,SDMMCClockSelection,SDMMCFreq_Value,SPDIFRXFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,UART7Freq_Value,UART8Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,USBFreq_Value,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAIOutputFreq_Value +RCC.IPParameters=AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CECFreq_Value,CortexFreq_Value,DFSDMAudioFreq_Value,DFSDMFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I2SFreq_Value,LCDTFTFreq_Value,LPTIM1Freq_Value,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLI2SPCLKFreq_Value,PLLI2SQCLKFreq_Value,PLLI2SRCLKFreq_Value,PLLI2SRoutputFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,PLLQoutputFreq_Value,PLLRFreq_Value,PLLSAIN,PLLSAIPCLKFreq_Value,PLLSAIQCLKFreq_Value,PLLSAIR,PLLSAIRCLKFreq_Value,PLLSAIRDiv,PLLSAIoutputFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMC2Freq_Value,SDMMCClockSelection,SDMMCFreq_Value,SPDIFRXFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,UART7Freq_Value,UART8Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,USBFreq_Value,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAIOutputFreq_Value RCC.LCDTFTFreq_Value=9000000 RCC.LPTIM1Freq_Value=54000000 RCC.LSI_VALUE=32000 @@ -400,7 +408,6 @@ RCC.PLLSAIR=4 RCC.PLLSAIRCLKFreq_Value=72000000 RCC.PLLSAIRDiv=RCC_PLLSAIDIVR_8 RCC.PLLSAIoutputFreq_Value=144000000 -RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE RCC.RNGFreq_Value=48000000 RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE RCC.RTCFreq_Value=32768 @@ -514,6 +521,9 @@ USART1.IPParameters=VirtualMode-Asynchronous USART1.VirtualMode-Asynchronous=VM_ASYNC USART2.IPParameters=VirtualMode-Asynchronous USART2.VirtualMode-Asynchronous=VM_ASYNC +USB_OTG_FS.IPParameters=VirtualMode,phy_itface +USB_OTG_FS.VirtualMode=Host_Only +USB_OTG_FS.phy_itface=HCD_PHY_EMBEDDED VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled diff --git a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h index 311e5d1c73..f14364403e 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h +++ b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc/stm32f7xx_hal_conf.h @@ -70,7 +70,7 @@ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ /* #define HAL_PCD_MODULE_ENABLED */ -/* #define HAL_HCD_MODULE_ENABLED */ +#define HAL_HCD_MODULE_ENABLED /* #define HAL_DFSDM_MODULE_ENABLED */ /* #define HAL_DSI_MODULE_ENABLED */ /* #define HAL_JPEG_MODULE_ENABLED */ diff --git a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc/stm32f7xx_it.h b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc/stm32f7xx_it.h index a398e3c63b..7212cae561 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc/stm32f7xx_it.h +++ b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Inc/stm32f7xx_it.h @@ -71,6 +71,7 @@ void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); +void OTG_FS_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/main.c index d3f40d6dc3..69926873b4 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/main.c @@ -87,6 +87,8 @@ TIM_HandleTypeDef htim14; UART_HandleTypeDef huart1; UART_HandleTypeDef huart2; +HCD_HandleTypeDef hhcd_USB_OTG_FS; + SDRAM_HandleTypeDef hsdram1; /* USER CODE BEGIN PV */ @@ -112,6 +114,7 @@ static void MX_TIM13_Init(void); static void MX_TIM14_Init(void); static void MX_TIM3_Init(void); static void MX_LTDC_Init(void); +static void MX_USB_OTG_FS_HCD_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -172,6 +175,7 @@ int main(void) MX_TIM14_Init(); MX_TIM3_Init(); MX_LTDC_Init(); + MX_USB_OTG_FS_HCD_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -883,6 +887,37 @@ static void MX_USART2_UART_Init(void) } +/** + * @brief USB_OTG_FS Initialization Function + * @param None + * @retval None + */ +static void MX_USB_OTG_FS_HCD_Init(void) +{ + + /* USER CODE BEGIN USB_OTG_FS_Init 0 */ + + /* USER CODE END USB_OTG_FS_Init 0 */ + + /* USER CODE BEGIN USB_OTG_FS_Init 1 */ + + /* USER CODE END USB_OTG_FS_Init 1 */ + hhcd_USB_OTG_FS.Instance = USB_OTG_FS; + hhcd_USB_OTG_FS.Init.Host_channels = 8; + hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL; + hhcd_USB_OTG_FS.Init.dma_enable = DISABLE; + hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED; + hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE; + if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USB_OTG_FS_Init 2 */ + + /* USER CODE END USB_OTG_FS_Init 2 */ + +} + /* FMC initialization function */ static void MX_FMC_Init(void) { diff --git a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c index 5e6b7067a8..3fe29e92c9 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c +++ b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/stm32f7xx_hal_msp.c @@ -1057,6 +1057,76 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) } +/** +* @brief HCD MSP Initialization +* This function configures the hardware resources used in this example +* @param hhcd: HCD handle pointer +* @retval None +*/ +void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hhcd->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */ + + /* USER CODE END USB_OTG_FS_MspInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USB_OTG_FS GPIO Configuration + PA11 ------> USB_OTG_FS_DM + PA12 ------> USB_OTG_FS_DP + */ + GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + /* USB_OTG_FS interrupt Init */ + HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */ + + /* USER CODE END USB_OTG_FS_MspInit 1 */ + } + +} + +/** +* @brief HCD MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hhcd: HCD handle pointer +* @retval None +*/ +void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hhcd) +{ + if(hhcd->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); + + /**USB_OTG_FS GPIO Configuration + PA11 ------> USB_OTG_FS_DM + PA12 ------> USB_OTG_FS_DP + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); + + /* USB_OTG_FS interrupt DeInit */ + HAL_NVIC_DisableIRQ(OTG_FS_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 1 */ + } + +} + static uint32_t FMC_Initialized = 0; static void HAL_FMC_MspInit(void){ diff --git a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/stm32f7xx_it.c b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/stm32f7xx_it.c index fc333c38eb..f1e4c9ebf8 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/stm32f7xx_it.c +++ b/bsp/stm32/stm32f767-atk-apollo/board/CubeMX_Config/Src/stm32f7xx_it.c @@ -71,7 +71,7 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ - +extern HCD_HandleTypeDef hhcd_USB_OTG_FS; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -212,6 +212,20 @@ void SysTick_Handler(void) /* please refer to the startup file (startup_stm32f7xx.s). */ /******************************************************************************/ +/** + * @brief This function handles USB On The Go FS global interrupt. + */ +void OTG_FS_IRQHandler(void) +{ + /* USER CODE BEGIN OTG_FS_IRQn 0 */ + + /* USER CODE END OTG_FS_IRQn 0 */ + HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS); + /* USER CODE BEGIN OTG_FS_IRQn 1 */ + + /* USER CODE END OTG_FS_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/bsp/stm32/stm32f767-atk-apollo/board/Kconfig b/bsp/stm32/stm32f767-atk-apollo/board/Kconfig index c344d3a8c4..82efc63223 100644 --- a/bsp/stm32/stm32f767-atk-apollo/board/Kconfig +++ b/bsp/stm32/stm32f767-atk-apollo/board/Kconfig @@ -17,7 +17,7 @@ menu "Onboard Peripheral Drivers" config BSP_USING_RS232 bool "Enable RS232 (uart2 pin conflict with Ethernet)" - select BSP_USING_UART + select BSP_USING_UART select BSP_USING_UART2 default n @@ -246,6 +246,21 @@ menu "On-chip Peripheral Drivers" select RT_USING_WDT default n + menuconfig BSP_USING_USBH + bool "Enable USB Host" + select RT_USING_USB_HOST + default n + if BSP_USING_USBH + menuconfig RT_USBH_MSTORAGE + bool "Enable Udisk Drivers" + default n + if RT_USBH_MSTORAGE + config UDISK_MOUNTPOINT + string "Udisk mount dir" + default "/" + endif + endif + config BSP_USING_SDIO bool "Enable SDIO" select RT_USING_SDIO @@ -255,7 +270,7 @@ menu "On-chip Peripheral Drivers" config BSP_USING_LTDC bool "Enable LTDC" default n - + source "../libraries/HAL_Drivers/Kconfig" endmenu -- Gitee From 15ceaad6e4d381b521d2cc623419f6974ab72a40 Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Fri, 20 Dec 2019 22:02:11 +0800 Subject: [PATCH 006/110] [BSP/stm32f427-robomaster-a] Correct RAM configuration information --- bsp/stm32/stm32f427-robomaster-a/README.md | 2 +- bsp/stm32/stm32f427-robomaster-a/board/board.h | 2 +- .../stm32f427-robomaster-a/board/linker_scripts/link.icf | 6 ++++-- .../stm32f427-robomaster-a/board/linker_scripts/link.lds | 9 +++++---- .../stm32f427-robomaster-a/board/linker_scripts/link.sct | 6 ++++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/bsp/stm32/stm32f427-robomaster-a/README.md b/bsp/stm32/stm32f427-robomaster-a/README.md index 9b288d5048..bba5febd73 100644 --- a/bsp/stm32/stm32f427-robomaster-a/README.md +++ b/bsp/stm32/stm32f427-robomaster-a/README.md @@ -22,7 +22,7 @@ RoboMaster开发板套件是一款面向机器人DIY的开源主控套件。开 该开发板常用 **板载资源** 如下: -- MCU:STM32f427IIH6,主频 180MHz,2048KB FLASH ,128KB RAM +- MCU:STM32f427IIH6,主频 180MHz,2048KB FLASH ,256KB RAM(含64KB CCM RAM未使用) - 常用外设 - LED:2个,D10(红色,PE11),D9(绿色,PE14) - 按键:1个,KEY(PB2) diff --git a/bsp/stm32/stm32f427-robomaster-a/board/board.h b/bsp/stm32/stm32f427-robomaster-a/board/board.h index 57c8e4a954..4c74f95682 100644 --- a/bsp/stm32/stm32f427-robomaster-a/board/board.h +++ b/bsp/stm32/stm32f427-robomaster-a/board/board.h @@ -25,7 +25,7 @@ extern "C" { #define STM32_FLASH_SIZE (2048 * 1024) #define STM32_FLASH_END_ADDRESS ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE)) -#define STM32_SRAM1_SIZE (128) +#define STM32_SRAM1_SIZE (192) #define STM32_SRAM1_START (0x20000000) #define STM32_SRAM1_END (STM32_SRAM1_START + STM32_SRAM1_SIZE * 1024) diff --git a/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.icf b/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.icf index a481a85ff3..03094ef488 100644 --- a/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.icf +++ b/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.icf @@ -6,8 +6,10 @@ define symbol __ICFEDIT_intvec_start__ = 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; -define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; -define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; +define symbol __ICFEDIT_region_RAM1_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM1_end__ = 0x2002FFFF; +define symbol __ICFEDIT_region_RAM2_start__ = 0x10000000; +define symbol __ICFEDIT_region_RAM2_end__ = 0x1000FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x0400; diff --git a/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.lds b/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.lds index 9d870aef5e..739d488555 100644 --- a/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.lds +++ b/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.lds @@ -6,7 +6,8 @@ MEMORY { ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048k /* 2048KB flash */ - RAM (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128KB sram */ + RAM1 (rw) : ORIGIN = 0x20000000, LENGTH = 192k /* 192K sram */ + RAM2 (rw) : ORIGIN = 0x10000000, LENGTH = 64k /* 64K sram */ } ENTRY(Reset_Handler) _system_stack_size = 0x200; @@ -88,7 +89,7 @@ SECTIONS . = ALIGN(4); /* This is used by the startup in order to initialize the .data secion */ _edata = . ; - } > RAM + } > RAM1 .stack : { @@ -97,7 +98,7 @@ SECTIONS . = . + _system_stack_size; . = ALIGN(4); _estack = .; - } > RAM + } > RAM1 __bss_start = .; .bss : @@ -115,7 +116,7 @@ SECTIONS _ebss = . ; *(.bss.init) - } > RAM + } > RAM1 __bss_end = .; _end = .; diff --git a/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.sct b/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.sct index b4e850d630..aca2546c3a 100644 --- a/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.sct +++ b/bsp/stm32/stm32f427-robomaster-a/board/linker_scripts/link.sct @@ -8,8 +8,10 @@ LR_IROM1 0x08000000 0x00200000 { ; load region size_region *(InRoot$$Sections) .ANY (+RO) } - RW_IRAM1 0x20000000 0x00020000 { ; RW data + RW_IRAM1 0x20000000 0x00030000 { ; RW data + .ANY (+RW +ZI) + } + RW_IRAM2 0x10000000 0x00010000 { ; RW data .ANY (+RW +ZI) } } - -- Gitee From 5ef1bfc878f4a70359479a45d76af2c54e1eb922 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Sat, 21 Dec 2019 07:25:12 +0800 Subject: [PATCH 007/110] [bsp] Remove unnecessary files. --- .../imxrt1064xxx/settings/project.crun | 13 - .../imxrt1064xxx/settings/project.dbgdt | 4 - .../imxrt1064xxx/settings/project.dnx | 83 ---- .../settings/project.rtthread.cspy.bat | 40 -- .../settings/project.rtthread.cspy.ps1 | 31 -- .../settings/project.rtthread.driver.xcl | 35 -- .../settings/project.rtthread.general.xcl | 17 - .../imxrt1064xxx/settings/project.wsdt | 428 ------------------ .../settings/project_rtthread.jlink | 39 -- .../imxrt1064xxx/settings/template.wsdt | 302 ------------ .../include/SDL_config_macosx.h.orig | 197 -------- 11 files changed, 1189 deletions(-) delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.crun delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.dbgdt delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.dnx delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.cspy.bat delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.cspy.ps1 delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.driver.xcl delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.general.xcl delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.wsdt delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project_rtthread.jlink delete mode 100644 bsp/imxrt/libraries/templates/imxrt1064xxx/settings/template.wsdt delete mode 100644 bsp/simulator/SDL2-2.0.7/include/SDL_config_macosx.h.orig diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.crun b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.crun deleted file mode 100644 index d71ea555a9..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.crun +++ /dev/null @@ -1,13 +0,0 @@ - - - 1 - - - * - * - * - 0 - 1 - - - diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.dbgdt b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.dbgdt deleted file mode 100644 index 9e08d96592..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.dbgdt +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.dnx b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.dnx deleted file mode 100644 index e02a226dce..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.dnx +++ /dev/null @@ -1,83 +0,0 @@ - - - - 0 - 1 - 90 - 1 - 1 - 1 - main - 0 - 50 - - - 0 - 1 - - - 0 - 0 - 1 - 0 - 1 - 0 - - - 0 - 0 - 1 - 0 - 1 - - - 1 - - - 1 - 0 - 1 - 0 - 1 - - - 10000000 - 0 - 1 - - - _ 0 - _ 0 - - - 2336342137 - - - D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\CONFIG\debugger\NXP\MIMXRT1064xxx6A.ddf - - - CMSIS-DAP:0232000005d92a5e00000000000000000000000097969905 - - 0 - 0 - 0 - - - 1 - - - _ 0 - _ "" - _ 0 - - - 0 - - - 0 - - - 0 - 0 - - diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.cspy.bat b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.cspy.bat deleted file mode 100644 index 47542db642..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.cspy.bat +++ /dev/null @@ -1,40 +0,0 @@ -@REM This batch file has been generated by the IAR Embedded Workbench -@REM C-SPY Debugger, as an aid to preparing a command line for running -@REM the cspybat command line utility using the appropriate settings. -@REM -@REM Note that this file is generated every time a new debug session -@REM is initialized, so you may want to move or rename the file before -@REM making changes. -@REM -@REM You can launch cspybat by typing the name of this batch file followed -@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). -@REM -@REM Read about available command line parameters in the C-SPY Debugging -@REM Guide. Hints about additional command line parameters that may be -@REM useful in specific cases: -@REM --download_only Downloads a code image without starting a debug -@REM session afterwards. -@REM --silent Omits the sign-on message. -@REM --timeout Limits the maximum allowed execution time. -@REM - - -@echo off - -if not "%~1" == "" goto debugFile - -@echo on - -"D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\common\bin\cspybat" -f "D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\settings\project.rtthread.general.xcl" --backend -f "D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\settings\project.rtthread.driver.xcl" - -@echo off -goto end - -:debugFile - -@echo on - -"D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\common\bin\cspybat" -f "D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\settings\project.rtthread.general.xcl" "--debug_file=%~1" --backend -f "D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\settings\project.rtthread.driver.xcl" - -@echo off -:end \ No newline at end of file diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.cspy.ps1 b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.cspy.ps1 deleted file mode 100644 index 41a322c06c..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.cspy.ps1 +++ /dev/null @@ -1,31 +0,0 @@ -param([String]$debugfile = ""); - -# This powershell file has been generated by the IAR Embedded Workbench -# C - SPY Debugger, as an aid to preparing a command line for running -# the cspybat command line utility using the appropriate settings. -# -# Note that this file is generated every time a new debug session -# is initialized, so you may want to move or rename the file before -# making changes. -# -# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed -# by the name of the debug file (usually an ELF / DWARF or UBROF file). -# -# Read about available command line parameters in the C - SPY Debugging -# Guide. Hints about additional command line parameters that may be -# useful in specific cases : -# --download_only Downloads a code image without starting a debug -# session afterwards. -# --silent Omits the sign - on message. -# --timeout Limits the maximum allowed execution time. -# - - -if ($debugfile -eq "") -{ -& "D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\common\bin\cspybat" -f "D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\settings\project.rtthread.general.xcl" --backend -f "D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\settings\project.rtthread.driver.xcl" -} -else -{ -& "D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\common\bin\cspybat" -f "D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\settings\project.rtthread.general.xcl" --debug_file=$debugfile --backend -f "D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\settings\project.rtthread.driver.xcl" -} diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.driver.xcl b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.driver.xcl deleted file mode 100644 index 1e60917538..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.driver.xcl +++ /dev/null @@ -1,35 +0,0 @@ -"--endian=little" - -"--cpu=Cortex-M7" - -"--fpu=VFPv5_D16" - -"-p" - -"D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\CONFIG\debugger\NXP\MIMXRT1064xxx6A.ddf" - -"--semihosting" - -"--device=MIMXRT1052xxx5B" - -"--multicore_nr_of_cores=1" - -"--jet_probe=cmsisdap" - -"--jet_standard_reset=4,0,0" - -"--reset_style=\"0,-,0,Disabled__no_reset_\"" - -"--reset_style=\"1,-,0,Software\"" - -"--reset_style=\"2,-,0,Hardware\"" - -"--reset_style=\"3,-,0,Core\"" - -"--reset_style=\"4,-,1,System\"" - -"--drv_catch_exceptions=0xff0" - - - - diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.general.xcl b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.general.xcl deleted file mode 100644 index 52bcf1d138..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.rtthread.general.xcl +++ /dev/null @@ -1,17 +0,0 @@ -"D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\bin\armproc.dll" - -"D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\bin\armJET.dll" - -"D:\doc\rtthread\git\rt-thread\bsp\imxrt\imxrt1064-nxp-evk\build\iar\Exe\rtthread.out" - ---plugin="D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\bin\armbat.dll" - ---device_macro="D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\config\debugger\NXP\iMXRT.dmac" - ---device_macro="D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\config\debugger\NXP\iMXRT_Trace.dmac" - ---flash_loader="D:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\config\flashloader\NXP\FlashIMXRT1064_SIP.board" - - - - diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.wsdt b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.wsdt deleted file mode 100644 index 367e0ed4c5..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project.wsdt +++ /dev/null @@ -1,428 +0,0 @@ - - - - - project/rtthread - - - - - 34048 - 34049 - 34050 - 34051 - 34052 - 34053 - 34054 - 34055 - 34056 - 34057 - 34058 - 34059 - 34060 - 34061 - 34062 - 34063 - 34064 - 34065 - 34066 - - - - - 34000 - 34001 - 0 - - - - - 57600 - 57601 - 57603 - 33024 - 0 - 57607 - 0 - 57635 - 57634 - 57637 - 0 - 57643 - 57644 - 0 - 33090 - 33057 - 57636 - 57640 - 57641 - 33026 - 33065 - 33063 - 33064 - 33053 - 33054 - 0 - 33035 - 33036 - 34399 - 0 - 33038 - 33039 - 0 - - - - 18 - 1869 - 2 - - 0 - -1 - - - - 214 - 27 - 27 - 27 - - - project - project/Applications - - - - 14 - 12 - - - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 14000000040026810000020000000C8100000700000055840000090000000E81000002000000 - - - 3F000D8400000F84000008840000FFFFFFFF54840000328100001C81000009840000D4840000D6840000D7840000D8840000D9840000DA840000DB840000DC840000DD840000DE840000DF840000E0840000E1840000E2840000E3840000EB8400002481000040E100007784000007840000808C000044D5000055840000568400005984000020DE000021DE000026DE000028DE000023DE000022DE000024DE000027DE000025DE000020920000289200002992000037920000389200003492000033920000259200001E9200001D9200000484000006840000328400003084000002840000038400000E8400001084000005840000318400000A840000 - 0D00268100002D0000000F8100001F00000020810000270000000C8100001C00000044920000100000001F9200000D0000000E8100001E0000001F810000260000002D9200000F0000000B8100001B000000D18400000C0000000D8100001D0000002C9200000E000000 - - - 0 - 0A0000000A0000006E0000006E000000 - 00000000E603000080070000F9030000 - 4096 - 0 - 0 - 32767 - 0 - - - 1 - - - 34050 - 000000001D00000036010000F8000000 - 000000000000000036010000DB000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 4294967295 - 000A000063000000180B00003B020000 - 000000004C0000001801000024020000 - 4096 - 0 - 0 - 32767 - 0 - - - 1 - - - 34051 - 000000001D00000036010000F8000000 - 04000000400200007C070000CC030000 - 32768 - 0 - 0 - 32767 - 0 - - - 1 - - - 21 - 1879 - 501 - 125 - 2 - D:\doc\NXP\RTT_BSP\imxrt_bsp\bsp\imxrt\imxrt1064-nxp-evk\BuildLog.log - 0 - -1 - - - 34055 - 000000001D00000036010000F8000000 - 04000000400200007C070000CC030000 - 4096 - 0 - 0 - 32767 - 0 - - - 1 - - - 34056 - 000000001D00000036010000F8000000 - 04000000400200007C070000CC030000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34057 - 000000001D00000036010000F8000000 - 04000000400200007C070000CC030000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34058 - 000000001D00000036010000F8000000 - 04000000400200007C070000CC030000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34059 - 000000001D00000036010000F8000000 - 04000000400200007C070000CC030000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34061 - 000000001D00000036010000F8000000 - 04000000400200007C070000CC030000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34052 - 000000001D000000AD020000D0000000 - 0000000000000000AD020000B3000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34053 - 000000001D00000036010000F8000000 - 000000000000000036010000DB000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34054 - 000000001D00000036010000F8000000 - 000000000000000036010000DB000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34060 - 000000001D00000018010000D4010000 - 040000005A00000014010000D0010000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34064 - 000000001D00000018010000D4010000 - 00000000600000001801000024020000 - 4096 - 0 - 0 - 32767 - 0 - - - 1 - - - 34062 - 000000001D00000036010000F8000000 - 000000000000000036010000DB000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34063 - 000000001D00000036010000F8000000 - 000000000000000036010000DB000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 0000000010000000000000000010000001000000FFFFFFFFFFFFFFFF180100004C0000001C01000024020000010000000200001004000000010000000000000000000000FFFFFFFF0100000010850000FFFF02000B004354616262656450616E650010000001000000000A000063000000180B00003B020000000000004C0000001801000024020000000000004010005601000000FFFEFF0957006F0072006B0073007000610063006500010000001085000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF1085000001000000FFFFFFFF10850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000080000001000000FFFFFFFFFFFFFFFF000000002402000080070000280200000100000001000010040000000100000056FEFFFFED010000FFFFFFFF07000000038500000785000008850000098500000A8500000B8500000D85000001800080000001000000000A00003F02000080110000FD030000000000002802000080070000E6030000000000004080005607000000FFFEFF054200750069006C006400010000000385000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000785000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000D85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF0385000001000000FFFFFFFF03850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000028500000000000000000000000000000000000001000000028500000100000002850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000128500000000000000000000000000000000000001000000128500000100000012850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000118500000000000000000000000000000000000001000000118500000100000011850000000000000000000000000000 - - - CMSIS-Pack - 00200000010000000200FFFF01001100434D4643546F6F6C426172427574746F6ED0840000000004000B000000FFFEFF0000000000000000000000000001000000010000000180D1840000000000000C000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B002F000000 - - - 34048 - 0A0000000A0000006E0000006E000000 - 000300001A0000004503000034000000 - 8192 - 1 - 0 - 47 - 0 - - - 1 - - - Main - 00200000010000002000FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000031000000FFFEFF000000000000000000000000000100000001000000018001E100000000000032000000FFFEFF000000000000000000000000000100000001000000018003E100000000000034000000FFFEFF0000000000000000000000000001000000010000000180008100000000000015000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E100000000000037000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E100000000040039000000FFFEFF000000000000000000000000000100000001000000018022E100000000040038000000FFFEFF000000000000000000000000000100000001000000018025E10000000000003B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE10000000004003E000000FFFEFF00000000000000000000000000010000000100000001802CE10000000004003F000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6E4281000000000000FFFFFFFFFFFEFF0000000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF00960000000000000000000180218100000000040028000000FFFEFF000000000000000000000000000100000001000000018024E10000000000003A000000FFFEFF000000000000000000000000000100000001000000018028E10000000004003C000000FFFEFF000000000000000000000000000100000001000000018029E10000000000003D000000FFFEFF0000000000000000000000000001000000010000000180028100000000000017000000FFFEFF000000000000000000000000000100000001000000018029810000000000002C000000FFFEFF000000000000000000000000000100000001000000018027810000000000002A000000FFFEFF000000000000000000000000000100000001000000018028810000000000002B000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040024000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040025000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000000000001B000000FFFEFF00000000000000000000000000010000000100000001800C810000000000001C000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000030000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E810000000000001E000000FFFEFF00000000000000000000000000010000000100000001800F810000000000001F000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00E8020000 - - - 34049 - 0A0000000A0000006E0000006E000000 - 000000001A000000FE02000034000000 - 8192 - 1 - 0 - 744 - 0 - - - 1 - - - 34065 - 000A000017000000220B0000C8000000 - 000000000000000022010000B1000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34066 - 000A000017000000800C0000A8000000 - 00000000000000008002000091000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - - - 010000000300000001000000000000000000000001000000010000000200000000000000010000000100000000000000280000002800000001000000010000000000000001000000FFFEFF1C2400570053005F0044004900520024005C006100700070006C00690063006100740069006F006E0073005C006D00610069006E002E00630001000000FFFF010014004966436F6E74656E7453746F72616765496D706CFFFEFF00FFFEFFFF24013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E003300300038003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E003300300038003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF066D00610069006E002E00630000000000FFFFFFFFFFFFFFFF0000000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD5000100000001000000020000001C0B000063000000801100003B020000 - - - - diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project_rtthread.jlink b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project_rtthread.jlink deleted file mode 100644 index 39b6d054aa..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/project_rtthread.jlink +++ /dev/null @@ -1,39 +0,0 @@ -[BREAKPOINTS] -ForceImpTypeAny = 0 -ShowInfoWin = 1 -EnableFlashBP = 2 -BPDuringExecution = 0 -[CFI] -CFISize = 0x00 -CFIAddr = 0x00 -[CPU] -MonModeVTableAddr = 0xFFFFFFFF -MonModeDebug = 0 -MaxNumAPs = 0 -LowPowerHandlingMode = 0 -OverrideMemMap = 0 -AllowSimulation = 1 -ScriptFile="" -[FLASH] -CacheExcludeSize = 0x00 -CacheExcludeAddr = 0x00 -MinNumBytesFlashDL = 0 -SkipProgOnCRCMatch = 1 -VerifyDownload = 1 -AllowCaching = 1 -EnableFlashDL = 2 -Override = 0 -Device="ARM7" -[GENERAL] -WorkRAMSize = 0x00 -WorkRAMAddr = 0x00 -RAMUsageLimit = 0x00 -[SWO] -SWOLogFile="" -[MEM] -RdOverrideOrMask = 0x00 -RdOverrideAndMask = 0xFFFFFFFF -RdOverrideAddr = 0xFFFFFFFF -WrOverrideOrMask = 0x00 -WrOverrideAndMask = 0xFFFFFFFF -WrOverrideAddr = 0xFFFFFFFF diff --git a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/template.wsdt b/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/template.wsdt deleted file mode 100644 index 17763ac682..0000000000 --- a/bsp/imxrt/libraries/templates/imxrt1064xxx/settings/template.wsdt +++ /dev/null @@ -1,302 +0,0 @@ - - - - - - - - 34048 - 34049 - 34050 - 34051 - 34052 - 34053 - 34054 - 34055 - 34056 - 34057 - 34058 - 34059 - - - - - 34000 - 34001 - 0 - - - - - 57600 - 57601 - 57603 - 33024 - 0 - 57607 - 0 - 57635 - 57634 - 57637 - 0 - 57643 - 57644 - 0 - 33090 - 33057 - 57636 - 57640 - 57641 - 33026 - 33065 - 33063 - 33064 - 33053 - 33054 - 0 - 33035 - 33036 - 34399 - 0 - 33038 - 33039 - 0 - - - - - 214 - 27 - 27 - 27 - - - - - 14 - 12 - - - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 000000000000 - - - 0000 - 0000 - - - 0 - 0A0000000A0000006E0000006E000000 - 0000000038050000000A000051050000 - 4096 - 0 - 0 - 32767 - 0 - - - 1 - - - 4294967295 - 000000001D00000018010000D4010000 - 00000000390000001801000038050000 - 4096 - 0 - 0 - 32767 - 0 - - - 1 - - - 34050 - 000000001D00000036010000F8000000 - 040000007E0400003201000018050000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34053 - 000000001D00000036010000F8000000 - 000000007A040000000A000038050000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34054 - 000000001D00000036010000F8000000 - 000000007A040000000A000038050000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34055 - 000000001D00000036010000F8000000 - 000000007A040000000A000038050000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34056 - 000000001D00000036010000F8000000 - 000000007A040000000A000038050000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34058 - 000000001D00000036010000F8000000 - 000000007A040000000A000038050000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34051 - 000000001D000000AD020000D0000000 - 0000000000000000AD020000B3000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34052 - 000000001D00000036010000F8000000 - 000000000000000036010000DB000000 - 32768 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34057 - 000000001D00000018010000D4010000 - 040000005A00000014010000D0010000 - 4096 - 0 - 0 - 32767 - 0 - - - 0 - - - - 34059 - 000000001D00000018010000D4010000 - 00000000560000001801000038050000 - 4096 - 0 - 0 - 32767 - 0 - - - 1 - - - 0000000008000000000000000010000001000000FFFFFFFFFFFFFFFF18010000390000001C01000038050000010000000200001004000000010000000000000000000000FFFFFFFF02000000098500000B850000FFFF02000B004354616262656450616E650010000001000000000000001D00000018010000D401000000000000390000001801000038050000000000004010005602000000FFFEFF0E53006F0075007200630065002000420072006F007700730065007200000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0957006F0072006B0073007000610063006500010000000B85000001000000FFFFFFFFFFFFFFFF01000000000000000000000000000000000000000000000001000000FFFFFFFF0985000001000000FFFFFFFF09850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100001004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100001004000000010000000000000000000000038500000000000000000000000000000000000001000000038500000100000003850000000000000080000000000000FFFFFFFFFFFFFFFF0000000059040000000A00005D040000000000000100001004000000010000000000000000000000FFFFFFFF0600000002850000058500000685000007850000088500000A85000001800080000000000000000000001D00000036010000F8000000000000005D040000000A000038050000000000004080004606000000FFFEFF054200750069006C006400000000000285000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000585000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000685000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000785000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000A85000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF0285000001000000FFFFFFFF02850000000000000000000000000000 - - - CMSIS-Pack - 00200000010000000200FFFF01001100434D4643546F6F6C426172427574746F6ED08400000000040009000000FFFEFF0000000000000000000000000001000000010000000180D1840000000000000A000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B00FF7F0000 - - - 34048 - 0A0000000A0000006E0000006E000000 - 000300001C0000004703000038000000 - 8192 - 1 - 0 - 32767 - 0 - - - 1 - - - Main - 00200000010000002000FFFF01001100434D4643546F6F6C426172427574746F6E00E10000000000002E000000FFFEFF000000000000000000000000000100000001000000018001E10000000000002F000000FFFEFF000000000000000000000000000100000001000000018003E100000000040031000000FFFEFF0000000000000000000000000001000000010000000180008100000000000011000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E100000000040034000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E100000000040036000000FFFEFF000000000000000000000000000100000001000000018022E100000000040035000000FFFEFF000000000000000000000000000100000001000000018025E100000000040038000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE10000000004003C000000FFFEFF00000000000000000000000000010000000100000001802CE10000000004003D000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6E4281000000000400FFFFFFFFFFFEFF0000000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF00960000000000000000000180218100000000040025000000FFFEFF000000000000000000000000000100000001000000018024E100000000040037000000FFFEFF000000000000000000000000000100000001000000018028E100000000040039000000FFFEFF000000000000000000000000000100000001000000018029E10000000004003A000000FFFEFF0000000000000000000000000001000000010000000180028100000000040013000000FFFEFF0000000000000000000000000001000000010000000180298100000000040029000000FFFEFF0000000000000000000000000001000000010000000180278100000000040027000000FFFEFF0000000000000000000000000001000000010000000180288100000000040028000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040021000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040022000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B8100000000040017000000FFFEFF00000000000000000000000000010000000100000001800C8100000000040018000000FFFEFF00000000000000000000000000010000000100000001805F860000000004002D000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E810000000004001A000000FFFEFF00000000000000000000000000010000000100000001800F810000000004001B000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00FF7F0000 - - - 34049 - 0A0000000A0000006E0000006E000000 - 000000001C0000000003000039000000 - 8192 - 1 - 0 - 32767 - 0 - - - 1 - - - - - 01000000030000000100000000000000000000000100000001000000FFFFFFFF00000000010000000100000000000000280000002800000000000000 - - - - diff --git a/bsp/simulator/SDL2-2.0.7/include/SDL_config_macosx.h.orig b/bsp/simulator/SDL2-2.0.7/include/SDL_config_macosx.h.orig deleted file mode 100644 index f03f1ae3dd..0000000000 --- a/bsp/simulator/SDL2-2.0.7/include/SDL_config_macosx.h.orig +++ /dev/null @@ -1,197 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2017 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef SDL_config_macosx_h_ -#define SDL_config_macosx_h_ -#define SDL_config_h_ - -#include "SDL_platform.h" - -/* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */ -#include - -/* This is a set of defines to configure the SDL features */ - -#ifdef __LP64__ - #define SIZEOF_VOIDP 8 -#else - #define SIZEOF_VOIDP 4 -#endif - -/* Useful headers */ -#define HAVE_ALLOCA_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_STDIO_H 1 -#define STDC_HEADERS 1 -#define HAVE_STRING_H 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_CTYPE_H 1 -#define HAVE_MATH_H 1 -#define HAVE_SIGNAL_H 1 - -/* C library functions */ -#define HAVE_MALLOC 1 -#define HAVE_CALLOC 1 -#define HAVE_REALLOC 1 -#define HAVE_FREE 1 -#define HAVE_ALLOCA 1 -#define HAVE_GETENV 1 -#define HAVE_SETENV 1 -#define HAVE_PUTENV 1 -#define HAVE_UNSETENV 1 -#define HAVE_QSORT 1 -#define HAVE_ABS 1 -#define HAVE_BCOPY 1 -#define HAVE_MEMSET 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMCMP 1 -#define HAVE_STRLEN 1 -#define HAVE_STRLCPY 1 -#define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 -#define HAVE_STRCHR 1 -#define HAVE_STRRCHR 1 -#define HAVE_STRSTR 1 -#define HAVE_STRTOL 1 -#define HAVE_STRTOUL 1 -#define HAVE_STRTOLL 1 -#define HAVE_STRTOULL 1 -#define HAVE_STRTOD 1 -#define HAVE_ATOI 1 -#define HAVE_ATOF 1 -#define HAVE_STRCMP 1 -#define HAVE_STRNCMP 1 -#define HAVE_STRCASECMP 1 -#define HAVE_STRNCASECMP 1 -#define HAVE_VSSCANF 1 -#define HAVE_VSNPRINTF 1 -#define HAVE_CEIL 1 -#define HAVE_COPYSIGN 1 -#define HAVE_COS 1 -#define HAVE_COSF 1 -#define HAVE_FABS 1 -#define HAVE_FLOOR 1 -#define HAVE_LOG 1 -#define HAVE_POW 1 -#define HAVE_SCALBN 1 -#define HAVE_SIN 1 -#define HAVE_SINF 1 -#define HAVE_SQRT 1 -#define HAVE_SQRTF 1 -#define HAVE_TAN 1 -#define HAVE_TANF 1 -#define HAVE_SIGACTION 1 -#define HAVE_SETJMP 1 -#define HAVE_NANOSLEEP 1 -#define HAVE_SYSCONF 1 -#define HAVE_SYSCTLBYNAME 1 -#define HAVE_ATAN 1 -#define HAVE_ATAN2 1 -#define HAVE_ACOS 1 -#define HAVE_ASIN 1 - -/* Enable various audio drivers */ -#define SDL_AUDIO_DRIVER_COREAUDIO 1 -#define SDL_AUDIO_DRIVER_DISK 1 -#define SDL_AUDIO_DRIVER_DUMMY 1 - -/* Enable various input drivers */ -#define SDL_JOYSTICK_IOKIT 1 -#define SDL_HAPTIC_IOKIT 1 - -/* Enable various shared object loading systems */ -#define SDL_LOADSO_DLOPEN 1 - -/* Enable various threading systems */ -#define SDL_THREAD_PTHREAD 1 -#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 - -/* Enable various timer systems */ -#define SDL_TIMER_UNIX 1 - -/* Enable various video drivers */ -#define SDL_VIDEO_DRIVER_COCOA 1 -#define SDL_VIDEO_DRIVER_DUMMY 1 -#undef SDL_VIDEO_DRIVER_X11 -#define SDL_VIDEO_DRIVER_X11_DYNAMIC "/usr/X11R6/lib/libX11.6.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "/usr/X11R6/lib/libXext.6.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "/usr/X11R6/lib/libXinerama.1.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "/usr/X11R6/lib/libXi.6.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/usr/X11R6/lib/libXrandr.2.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/usr/X11R6/lib/libXss.1.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/usr/X11R6/lib/libXxf86vm.1.dylib" -#define SDL_VIDEO_DRIVER_X11_XDBE 1 -#define SDL_VIDEO_DRIVER_X11_XINERAMA 1 -#define SDL_VIDEO_DRIVER_X11_XRANDR 1 -#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 -#define SDL_VIDEO_DRIVER_X11_XSHAPE 1 -#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1 -#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 - -#ifdef MAC_OS_X_VERSION_10_8 -/* - * No matter the versions targeted, this is the 10.8 or later SDK, so you have - * to use the external Xquartz, which is a more modern Xlib. Previous SDKs - * used an older Xlib. - */ -#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 -#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 -#define SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1 -#endif - -#ifndef SDL_VIDEO_RENDER_OGL -#define SDL_VIDEO_RENDER_OGL 1 -#endif - -/* Enable OpenGL support */ -#ifndef SDL_VIDEO_OPENGL -#define SDL_VIDEO_OPENGL 1 -#endif -#ifndef SDL_VIDEO_OPENGL_CGL -#define SDL_VIDEO_OPENGL_CGL 1 -#endif -#ifndef SDL_VIDEO_OPENGL_GLX -#define SDL_VIDEO_OPENGL_GLX 1 -#endif - -/* Enable Vulkan support */ -/* Metal/MoltenVK/Vulkan only supported on 64-bit architectures and 10.11+ */ -#if TARGET_CPU_X86_64 -#define SDL_VIDEO_VULKAN 1 -#else -#define SDL_VIDEO_VULKAN 0 -#endif - -/* Enable system power support */ -#define SDL_POWER_MACOSX 1 - -/* enable filesystem support */ -#define SDL_FILESYSTEM_COCOA 1 - -/* Enable assembly routines */ -#define SDL_ASSEMBLY_ROUTINES 1 -#ifdef __ppc__ -#define SDL_ALTIVEC_BLITTERS 1 -#endif - -#endif /* SDL_config_macosx_h_ */ -- Gitee From f9ef8c7ed9544e731d271789f978a8f80099e0e2 Mon Sep 17 00:00:00 2001 From: liuxianliang Date: Sat, 21 Dec 2019 17:43:32 +0800 Subject: [PATCH 008/110] [net][lwip] modified hostname, support lwIP 1.4.1 ,lwIP 2.0.2 and lwIP 2.1.2 Signed-off-by: liuxianliang --- components/net/lwip-1.4.1/src/lwipopts.h | 4 +- .../net/lwip-1.4.1/src/netif/ethernetif.c | 16 +++---- .../net/lwip-2.0.2/src/netif/ethernetif.c | 42 ++++++++--------- components/net/lwip-2.1.0/src/lwipopts.h | 7 +++ .../net/lwip-2.1.0/src/netif/ethernetif.c | 46 ++++++++++--------- 5 files changed, 62 insertions(+), 53 deletions(-) diff --git a/components/net/lwip-1.4.1/src/lwipopts.h b/components/net/lwip-1.4.1/src/lwipopts.h index 598c3262a6..a23a167970 100644 --- a/components/net/lwip-1.4.1/src/lwipopts.h +++ b/components/net/lwip-1.4.1/src/lwipopts.h @@ -264,8 +264,8 @@ #endif /* - * You can re-define following setting in rtcofnig.h to overwrite the default - * setting in the lwip opts.h + * You can re-define following setting in rtcofnig.h to overwrite the default + * setting in the lwip opts.h */ /* MEMP_NUM_NETBUF: the number of struct netbufs. */ // #define MEMP_NUM_NETBUF 2 diff --git a/components/net/lwip-1.4.1/src/netif/ethernetif.c b/components/net/lwip-1.4.1/src/netif/ethernetif.c index f729b27b93..75f86d75d8 100644 --- a/components/net/lwip-1.4.1/src/netif/ethernetif.c +++ b/components/net/lwip-1.4.1/src/netif/ethernetif.c @@ -165,7 +165,7 @@ static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled) extern int lwip_ping_recv(int s, int *ttl); extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size); -int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, +int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp) { int s, ttl, recv_len, result = 0; @@ -180,7 +180,7 @@ int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, struct addrinfo hint, *res = RT_NULL; struct sockaddr_in *h = RT_NULL; struct in_addr ina; - + RT_ASSERT(netif); RT_ASSERT(host); RT_ASSERT(ping_resp); @@ -199,7 +199,7 @@ int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, return -RT_ERROR; } rt_memcpy(&(ping_resp->ip_addr), &target_addr, sizeof(ip_addr_t)); - + /* new a socket */ if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { @@ -267,7 +267,7 @@ const struct netdev_ops lwip_netdev_ops = lwip_netdev_set_addr_info, #ifdef RT_LWIP_DNS lwip_netdev_set_dns_server, -#else +#else NULL, #endif /* RT_LWIP_DNS */ @@ -315,7 +315,7 @@ static int netdev_add(struct netif *lwip_netif) rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN); result = netdev_register(netdev, name, (void *)lwip_netif); - + /* Update netdev info after registered */ netdev->flags = lwip_netif->flags; netdev->mtu = lwip_netif->mtu; @@ -325,7 +325,7 @@ static int netdev_add(struct netif *lwip_netif) netdev->ip_addr = lwip_netif->ip_addr; netdev->gw = lwip_netif->gw; netdev->netmask = lwip_netif->netmask; - + #ifdef RT_LWIP_DHCP netdev_low_level_set_dhcp_status(netdev, RT_TRUE); #endif @@ -484,7 +484,7 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ hostname = (char *)netif + sizeof(struct netif); - rt_sprintf(hostname, "RTTHREAD_%02x%02x", name[0], name[1]); + rt_sprintf(hostname, "rtthread_%02x%02x", name[0], name[1]); netif->hostname = hostname; #endif /* LWIP_NETIF_HOSTNAME */ @@ -642,7 +642,7 @@ static void eth_rx_thread_entry(void* parameter) while (1) { if(device->eth_rx == RT_NULL) break; - + p = device->eth_rx(&(device->parent)); if (p != RT_NULL) { diff --git a/components/net/lwip-2.0.2/src/netif/ethernetif.c b/components/net/lwip-2.0.2/src/netif/ethernetif.c index 4ce0993f37..6c5621281c 100644 --- a/components/net/lwip-2.0.2/src/netif/ethernetif.c +++ b/components/net/lwip-2.0.2/src/netif/ethernetif.c @@ -173,7 +173,7 @@ static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled) extern int lwip_ping_recv(int s, int *ttl); extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size); -int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, +int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp) { int s, ttl, recv_len, result = 0; @@ -188,7 +188,7 @@ int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, struct addrinfo hint, *res = RT_NULL; struct sockaddr_in *h = RT_NULL; struct in_addr ina; - + RT_ASSERT(netif); RT_ASSERT(host); RT_ASSERT(ping_resp); @@ -207,7 +207,7 @@ int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, return -RT_ERROR; } rt_memcpy(&(ping_resp->ip_addr), &target_addr, sizeof(ip_addr_t)); - + /* new a socket */ if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { @@ -275,7 +275,7 @@ const struct netdev_ops lwip_netdev_ops = lwip_netdev_set_addr_info, #ifdef RT_LWIP_DNS lwip_netdev_set_dns_server, -#else +#else NULL, #endif /* RT_LWIP_DNS */ @@ -323,8 +323,8 @@ static int netdev_add(struct netif *lwip_netif) rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN); result = netdev_register(netdev, name, (void *)lwip_netif); - - /* Update netdev info after registered */ + + /* Update netdev info after registered */ netdev->flags = lwip_netif->flags; netdev->mtu = lwip_netif->mtu; netdev->ops = &lwip_netdev_ops; @@ -333,7 +333,7 @@ static int netdev_add(struct netif *lwip_netif) netdev->ip_addr = lwip_netif->ip_addr; netdev->gw = lwip_netif->gw; netdev->netmask = lwip_netif->netmask; - + #ifdef RT_LWIP_DHCP netdev_low_level_set_dhcp_status(netdev, RT_TRUE); #endif @@ -412,7 +412,7 @@ static err_t eth_netif_device_init(struct netif *netif) /* network interface device register */ netdev_add(netif); #endif /* RT_USING_NETDEV */ - + ethif = (struct eth_device*)netif->state; if (ethif != RT_NULL) { @@ -525,7 +525,7 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ hostname = (char *)netif + sizeof(struct netif); - rt_sprintf(hostname, "RTTHREAD_%02x%02x", name[0], name[1]); + rt_sprintf(hostname, "rtthread_%02x%02x", name[0], name[1]); netif->hostname = hostname; #endif /* LWIP_NETIF_HOSTNAME */ @@ -538,7 +538,7 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ ipaddr.addr = inet_addr(RT_LWIP_IPADDR); gw.addr = inet_addr(RT_LWIP_GWADDR); netmask.addr = inet_addr(RT_LWIP_MSKADDR); -#else +#else IP4_ADDR(&ipaddr, 0, 0, 0, 0); IP4_ADDR(&gw, 0, 0, 0, 0); IP4_ADDR(&netmask, 0, 0, 0, 0); @@ -690,7 +690,7 @@ static void eth_rx_thread_entry(void* parameter) while (1) { if(device->eth_rx == RT_NULL) break; - + p = device->eth_rx(&(device->parent)); if (p != RT_NULL) { @@ -713,9 +713,9 @@ static void eth_rx_thread_entry(void* parameter) } #endif -/* this function does not need, - * use eth_system_device_init_private() - * call by lwip_system_init(). +/* this function does not need, + * use eth_system_device_init_private() + * call by lwip_system_init(). */ int eth_system_device_init(void) { @@ -862,22 +862,22 @@ void list_if(void) ip6_addr_t *addr; int addr_state; int i; - + addr = (ip6_addr_t *)&netif->ip6_addr[0]; addr_state = netif->ip6_addr_state[0]; - - rt_kprintf("\nipv6 link-local: %s state:%02X %s\n", ip6addr_ntoa(addr), + + rt_kprintf("\nipv6 link-local: %s state:%02X %s\n", ip6addr_ntoa(addr), addr_state, ip6_addr_isvalid(addr_state)?"VALID":"INVALID"); - + for(i=1; iip6_addr[i]; addr_state = netif->ip6_addr_state[i]; - - rt_kprintf("ipv6[%d] address: %s state:%02X %s\n", i, ip6addr_ntoa(addr), + + rt_kprintf("ipv6[%d] address: %s state:%02X %s\n", i, ip6addr_ntoa(addr), addr_state, ip6_addr_isvalid(addr_state)?"VALID":"INVALID"); } - + } rt_kprintf("\r\n"); #endif /* LWIP_IPV6 */ diff --git a/components/net/lwip-2.1.0/src/lwipopts.h b/components/net/lwip-2.1.0/src/lwipopts.h index 405e95ce64..7e02a8a9f9 100644 --- a/components/net/lwip-2.1.0/src/lwipopts.h +++ b/components/net/lwip-2.1.0/src/lwipopts.h @@ -538,6 +538,13 @@ #define LWIP_TCP_KEEPALIVE 1 #endif +/** + * LWIP_NETIF_HOSTNAME==1: Support netif hostname + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 1 +#endif + /** * LWIP_NETIF_API==1: Support netif api (in netifapi.c) */ diff --git a/components/net/lwip-2.1.0/src/netif/ethernetif.c b/components/net/lwip-2.1.0/src/netif/ethernetif.c index 66ea1d2376..f73ed635a1 100755 --- a/components/net/lwip-2.1.0/src/netif/ethernetif.c +++ b/components/net/lwip-2.1.0/src/netif/ethernetif.c @@ -174,7 +174,7 @@ static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled) extern int lwip_ping_recv(int s, int *ttl); extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size); -int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, +int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp) { int s, ttl, recv_len, result = 0; @@ -189,7 +189,7 @@ int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, struct addrinfo hint, *res = RT_NULL; struct sockaddr_in *h = RT_NULL; struct in_addr ina; - + RT_ASSERT(netif); RT_ASSERT(host); RT_ASSERT(ping_resp); @@ -208,7 +208,7 @@ int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len, return -RT_ERROR; } rt_memcpy(&(ping_resp->ip_addr), &target_addr, sizeof(ip_addr_t)); - + /* new a socket */ if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { @@ -276,7 +276,7 @@ const struct netdev_ops lwip_netdev_ops = lwip_netdev_set_addr_info, #ifdef RT_LWIP_DNS lwip_netdev_set_dns_server, -#else +#else NULL, #endif /* RT_LWIP_DNS */ @@ -315,7 +315,7 @@ static int netdev_add(struct netif *lwip_netif) { return -ERR_IF; } - + #ifdef SAL_USING_LWIP extern int sal_lwip_netdev_set_pf_info(struct netdev *netdev); /* set the lwIP network interface device protocol family information */ @@ -324,7 +324,7 @@ static int netdev_add(struct netif *lwip_netif) rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN); result = netdev_register(netdev, name, (void *)lwip_netif); - + /* Update netdev info after registered */ netdev->flags = lwip_netif->flags; netdev->mtu = lwip_netif->mtu; @@ -367,7 +367,7 @@ static int netdev_flags_sync(struct netif *lwip_netif) { return -ERR_IF; } - + netdev->mtu = lwip_netif->mtu; netdev->flags |= lwip_netif->flags; @@ -430,7 +430,7 @@ static err_t eth_netif_device_init(struct netif *netif) /* copy device flags to netif flags */ netif->flags = (ethif->flags & 0xff); netif->mtu = ETHERNET_MTU; - + /* set output */ netif->output = etharp_output; @@ -518,13 +518,15 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ /* set linkoutput */ netif->linkoutput = ethernetif_linkoutput; - + /* get hardware MAC address */ rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr); #if LWIP_NETIF_HOSTNAME /* Initialize interface hostname */ - netif->hostname = "rtthread"; + hostname = (char *)netif + sizeof(struct netif); + rt_sprintf(hostname, "rtthread_%02x%02x", name[0], name[1]); + netif->hostname = hostname; #endif /* LWIP_NETIF_HOSTNAME */ /* if tcp thread has been started up, we add this netif to the system */ @@ -536,7 +538,7 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_ ipaddr.addr = inet_addr(RT_LWIP_IPADDR); gw.addr = inet_addr(RT_LWIP_GWADDR); netmask.addr = inet_addr(RT_LWIP_MSKADDR); -#else +#else IP4_ADDR(&ipaddr, 0, 0, 0, 0); IP4_ADDR(&gw, 0, 0, 0, 0); IP4_ADDR(&netmask, 0, 0, 0, 0); @@ -688,7 +690,7 @@ static void eth_rx_thread_entry(void* parameter) while (1) { if(device->eth_rx == RT_NULL) break; - + p = device->eth_rx(&(device->parent)); if (p != RT_NULL) { @@ -711,9 +713,9 @@ static void eth_rx_thread_entry(void* parameter) } #endif -/* this function does not need, - * use eth_system_device_init_private() - * call by lwip_system_init(). +/* this function does not need, + * use eth_system_device_init_private() + * call by lwip_system_init(). */ int eth_system_device_init(void) { @@ -860,22 +862,22 @@ void list_if(void) ip6_addr_t *addr; int addr_state; int i; - + addr = (ip6_addr_t *)&netif->ip6_addr[0]; addr_state = netif->ip6_addr_state[0]; - - rt_kprintf("\nipv6 link-local: %s state:%02X %s\n", ip6addr_ntoa(addr), + + rt_kprintf("\nipv6 link-local: %s state:%02X %s\n", ip6addr_ntoa(addr), addr_state, ip6_addr_isvalid(addr_state)?"VALID":"INVALID"); - + for(i=1; iip6_addr[i]; addr_state = netif->ip6_addr_state[i]; - - rt_kprintf("ipv6[%d] address: %s state:%02X %s\n", i, ip6addr_ntoa(addr), + + rt_kprintf("ipv6[%d] address: %s state:%02X %s\n", i, ip6addr_ntoa(addr), addr_state, ip6_addr_isvalid(addr_state)?"VALID":"INVALID"); } - + } rt_kprintf("\r\n"); #endif /* LWIP_IPV6 */ -- Gitee From 9893f6461039d6c40e169a5565916be4e4507a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=BB=E5=85=89=E4=BC=9F?= Date: Sat, 21 Dec 2019 00:17:38 +0800 Subject: [PATCH 009/110] =?UTF-8?q?ulogbuffer=E5=A2=9E=E5=8A=A01=EF=BC=8C?= =?UTF-8?q?=E4=B8=BA\0=E9=A2=84=E7=95=99=E7=A9=BA=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RGW --- components/utilities/ulog/ulog.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/utilities/ulog/ulog.c b/components/utilities/ulog/ulog.c index 8a8d142eff..ca356f92f2 100644 --- a/components/utilities/ulog/ulog.c +++ b/components/utilities/ulog/ulog.c @@ -81,12 +81,12 @@ struct rt_ulog /* all backends */ rt_slist_t backend_list; /* the thread log's line buffer */ - char log_buf_th[ULOG_LINE_BUF_SIZE]; + char log_buf_th[ULOG_LINE_BUF_SIZE + 1]; #ifdef ULOG_USING_ISR_LOG /* the ISR log's line buffer */ rt_base_t output_locker_isr_lvl; - char log_buf_isr[ULOG_LINE_BUF_SIZE]; + char log_buf_isr[ULOG_LINE_BUF_SIZE + 1]; #endif /* ULOG_USING_ISR_LOG */ #ifdef ULOG_USING_ASYNC_OUTPUT @@ -728,6 +728,8 @@ void ulog_hexdump(const char *tag, rt_size_t width, rt_uint8_t *buf, rt_size_t s } /* package newline sign */ log_len += ulog_strcpy(log_len, log_buf + log_len, ULOG_NEWLINE_SIGN); + /*add string end sign*/ + log_buf[log_len] = '\0'; /* do log output */ do_output(LOG_LVL_DBG, NULL, RT_TRUE, log_buf, log_len); } -- Gitee From a4dba7b5831faad7f3582909a3a76a48f2f5bba0 Mon Sep 17 00:00:00 2001 From: ZYH Date: Wed, 25 Dec 2019 13:15:10 +0800 Subject: [PATCH 010/110] [Components][USB][ECM] fix build error --- components/drivers/usb/usbdevice/class/ecm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/drivers/usb/usbdevice/class/ecm.c b/components/drivers/usb/usbdevice/class/ecm.c index b98b5007f4..cf948adbfc 100644 --- a/components/drivers/usb/usbdevice/class/ecm.c +++ b/components/drivers/usb/usbdevice/class/ecm.c @@ -419,12 +419,12 @@ rt_err_t rt_ecm_eth_tx(rt_device_t dev, struct pbuf* p) p->tot_len = USB_ETH_MTU; } - result = rt_sem_take(&device->tx_buffer_free, rt_tick_from_millisecond(1000)); + result = rt_sem_take(&ecm_eth_dev->tx_buffer_free, rt_tick_from_millisecond(1000)); if(result != RT_EOK) { LOG_W("wait for buffer free timeout"); /* if cost 1s to wait send done it said that connection is close . drop it */ - rt_sem_release(&device->tx_buffer_free); + rt_sem_release(&ecm_eth_dev->tx_buffer_free); return result; } -- Gitee From 121366d6c89e97ac9c1257d08b4af59ee68c4ec3 Mon Sep 17 00:00:00 2001 From: tonyzheng-rockchip Date: Thu, 26 Dec 2019 11:03:51 +0800 Subject: [PATCH 011/110] Fix dlmodule must depends on file system issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 解决dlmodule只能依赖于文件系统的问题; 增加dlmodule扩展接口,以适应更多需求; --- components/libc/libdl/dlmodule.c | 184 ++++++++++++++++++++++++++++++- components/libc/libdl/dlmodule.h | 10 ++ 2 files changed, 193 insertions(+), 1 deletion(-) diff --git a/components/libc/libdl/dlmodule.c b/components/libc/libdl/dlmodule.c index dbebfc8961..25e9beaeb0 100644 --- a/components/libc/libdl/dlmodule.c +++ b/components/libc/libdl/dlmodule.c @@ -14,7 +14,9 @@ #include "dlmodule.h" #include "dlelf.h" +#if defined(RT_USING_POSIX) #include +#endif #define DBG_TAG "DLMD" #define DBG_LVL DBG_INFO @@ -419,11 +421,12 @@ struct rt_dlmodule *rt_module_self(void) struct rt_dlmodule* dlmodule_load(const char* filename) { - int fd, length = 0; + int fd = -1, length = 0; rt_err_t ret = RT_EOK; rt_uint8_t *module_ptr = RT_NULL; struct rt_dlmodule *module = RT_NULL; +#if defined(RT_USING_POSIX) fd = open(filename, O_RDONLY, 0); if (fd >= 0) { @@ -446,6 +449,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename) { goto __exit; } +#endif + + if (!module_ptr) goto __exit; /* check ELF header */ if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 && @@ -512,7 +518,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename) return module; __exit: +#if defined(RT_USING_POSIX) if (fd >= 0) close(fd); +#endif if (module_ptr) rt_free(module_ptr); if (module) dlmodule_destroy(module); @@ -558,6 +566,180 @@ struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_s return module; } +struct rt_dlmodule* dlmodule_ext_load(const char* filename, struct rt_dlmodule_ops* ops) +{ + int fd = -1, length = 0; + rt_err_t ret = RT_EOK; + rt_uint8_t *module_ptr = RT_NULL; + struct rt_dlmodule *module = RT_NULL; + + if (ops) + { + RT_ASSERT(ops->load); + RT_ASSERT(ops->unload); + module_ptr = ops->load(filename); + } +#if defined(RT_USING_POSIX) + else + { + fd = open(filename, O_RDONLY, 0); + if (fd >= 0) + { + length = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + + if (length == 0) goto __exit; + + module_ptr = (uint8_t*) rt_malloc (length); + if (!module_ptr) goto __exit; + + if (read(fd, module_ptr, length) != length) + goto __exit; + + /* close file and release fd */ + close(fd); + fd = -1; + } + else + { + goto __exit; + } + } +#endif + + if (!module_ptr) goto __exit; + + /* check ELF header */ + if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 && + rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0) + { + rt_kprintf("Module: magic error\n"); + goto __exit; + } + + /* check ELF class */ + if (elf_module->e_ident[EI_CLASS] != ELFCLASS32) + { + rt_kprintf("Module: ELF class error\n"); + goto __exit; + } + + module = dlmodule_create(); + if (!module) goto __exit; + + /* set the name of module */ + _dlmodule_set_name(module, filename); + + LOG_D("rt_module_load: %.*s", RT_NAME_MAX, module->parent.name); + + if (elf_module->e_type == ET_REL) + { + ret = dlmodule_load_relocated_object(module, module_ptr); + } + else if (elf_module->e_type == ET_DYN) + { + ret = dlmodule_load_shared_object(module, module_ptr); + } + else + { + rt_kprintf("Module: unsupported elf type\n"); + goto __exit; + } + + /* check return value */ + if (ret != RT_EOK) goto __exit; + + /* release module data */ + if (ops) + { + ops->unload(module_ptr); + } + else + { + rt_free(module_ptr); + } + + /* increase module reference count */ + module->nref ++; + + /* deal with cache */ +#ifdef RT_USING_CACHE + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, module->mem_space, module->mem_size); + rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, module->mem_space, module->mem_size); +#endif + + /* set module initialization and cleanup function */ + module->init_func = dlsym(module, "module_init"); + module->cleanup_func = dlsym(module, "module_cleanup"); + module->stat = RT_DLMODULE_STAT_INIT; + /* do module initialization */ + if (module->init_func) + { + module->init_func(module); + } + + return module; + +__exit: +#if defined(RT_USING_POSIX) + if (fd >= 0) close(fd); +#endif + if (module_ptr) + { + if (ops) + { + ops->unload(module_ptr); + } + else + { + rt_free(module_ptr); + } + } + + if (module) dlmodule_destroy(module); + + return RT_NULL; +} + +struct rt_dlmodule* dlmodule_ext_exec(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops) +{ + struct rt_dlmodule *module = RT_NULL; + + module = dlmodule_ext_load(pgname, ops); + if (module) + { + if (module->entry_addr) + { + /* exec this module */ + rt_thread_t tid; + + module->cmd_line = rt_strdup(cmd); + + /* check stack size and priority */ + if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1; + if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048; + + tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module, + module->stack_size, module->priority, 10); + if (tid) + { + tid->module_id = module; + module->main_thread = tid; + + rt_thread_startup(tid); + } + else + { + /* destory dl module */ + dlmodule_destroy(module); + module = RT_NULL; + } + } + } + + return module; +} + void dlmodule_exit(int ret_code) { rt_thread_t thread; diff --git a/components/libc/libdl/dlmodule.h b/components/libc/libdl/dlmodule.h index 4a4ead3303..48e42e0079 100644 --- a/components/libc/libdl/dlmodule.h +++ b/components/libc/libdl/dlmodule.h @@ -59,6 +59,12 @@ struct rt_dlmodule struct rt_module_symtab *symtab; /* module symbol table */ }; +struct rt_dlmodule_ops +{ + rt_uint8_t *(*load)(const char* filename); /* load dlmodule file data */ + rt_err_t (*unload)(rt_uint8_t *param); /* unload dlmodule file data */ +}; + struct rt_dlmodule *dlmodule_create(void); rt_err_t dlmodule_destroy(struct rt_dlmodule* module); @@ -66,6 +72,10 @@ struct rt_dlmodule *dlmodule_self(void); struct rt_dlmodule *dlmodule_load(const char* pgname); struct rt_dlmodule *dlmodule_exec(const char* pgname, const char* cmd, int cmd_size); + +struct rt_dlmodule* dlmodule_ext_load(const char* filename, struct rt_dlmodule_ops* ops); +struct rt_dlmodule* dlmodule_ext_exec(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops); + void dlmodule_exit(int ret_code); struct rt_dlmodule *dlmodule_find(const char *name); -- Gitee From 00fa2e2d7882351483c025127e3b1f875ad9edb2 Mon Sep 17 00:00:00 2001 From: tyustli <1225613647@qq.com> Date: Thu, 26 Dec 2019 14:10:06 +0800 Subject: [PATCH 012/110] solve gcc build err --- .../imxrt1052-atk-commander/board/Kconfig | 21 + bsp/imxrt/libraries/drivers/SConscript | 24 +- bsp/imxrt/libraries/drivers/drv_usbd.c | 338 ++ .../libraries/drivers/usb/device/usb_device.h | 644 +++ .../drivers/usb/device/usb_device_dci.c | 1462 +++++ .../drivers/usb/device/usb_device_dci.h | 177 + .../drivers/usb/device/usb_device_ehci.c | 1807 +++++++ .../drivers/usb/device/usb_device_ehci.h | 219 + .../libraries/drivers/usb/host/usb_host.h | 726 +++ .../drivers/usb/host/usb_host_devices.c | 1414 +++++ .../drivers/usb/host/usb_host_devices.h | 178 + .../drivers/usb/host/usb_host_ehci.c | 4747 +++++++++++++++++ .../drivers/usb/host/usb_host_ehci.h | 499 ++ .../libraries/drivers/usb/host/usb_host_hci.c | 1052 ++++ .../libraries/drivers/usb/host/usb_host_hci.h | 131 + bsp/imxrt/libraries/drivers/usb/include/usb.h | 140 + .../drivers/usb/include/usb_device_config.h | 185 + .../libraries/drivers/usb/include/usb_ehci.h | 140 + .../libraries/drivers/usb/include/usb_misc.h | 452 ++ .../libraries/drivers/usb/include/usb_spec.h | 296 + bsp/imxrt/libraries/drivers/usb/phy/usb_phy.c | 240 + bsp/imxrt/libraries/drivers/usb/phy/usb_phy.h | 113 + 22 files changed, 15002 insertions(+), 3 deletions(-) create mode 100644 bsp/imxrt/libraries/drivers/drv_usbd.c create mode 100644 bsp/imxrt/libraries/drivers/usb/device/usb_device.h create mode 100644 bsp/imxrt/libraries/drivers/usb/device/usb_device_dci.c create mode 100644 bsp/imxrt/libraries/drivers/usb/device/usb_device_dci.h create mode 100644 bsp/imxrt/libraries/drivers/usb/device/usb_device_ehci.c create mode 100644 bsp/imxrt/libraries/drivers/usb/device/usb_device_ehci.h create mode 100644 bsp/imxrt/libraries/drivers/usb/host/usb_host.h create mode 100644 bsp/imxrt/libraries/drivers/usb/host/usb_host_devices.c create mode 100644 bsp/imxrt/libraries/drivers/usb/host/usb_host_devices.h create mode 100644 bsp/imxrt/libraries/drivers/usb/host/usb_host_ehci.c create mode 100644 bsp/imxrt/libraries/drivers/usb/host/usb_host_ehci.h create mode 100644 bsp/imxrt/libraries/drivers/usb/host/usb_host_hci.c create mode 100644 bsp/imxrt/libraries/drivers/usb/host/usb_host_hci.h create mode 100644 bsp/imxrt/libraries/drivers/usb/include/usb.h create mode 100644 bsp/imxrt/libraries/drivers/usb/include/usb_device_config.h create mode 100644 bsp/imxrt/libraries/drivers/usb/include/usb_ehci.h create mode 100644 bsp/imxrt/libraries/drivers/usb/include/usb_misc.h create mode 100644 bsp/imxrt/libraries/drivers/usb/include/usb_spec.h create mode 100644 bsp/imxrt/libraries/drivers/usb/phy/usb_phy.c create mode 100644 bsp/imxrt/libraries/drivers/usb/phy/usb_phy.h diff --git a/bsp/imxrt/imxrt1052-atk-commander/board/Kconfig b/bsp/imxrt/imxrt1052-atk-commander/board/Kconfig index 859c2a4fdd..67ca41ca13 100644 --- a/bsp/imxrt/imxrt1052-atk-commander/board/Kconfig +++ b/bsp/imxrt/imxrt1052-atk-commander/board/Kconfig @@ -123,6 +123,27 @@ menu "Onboard Peripheral Drivers" config BSP_USING_SDRAM bool "Enable SDRAM" default n + + menuconfig BSP_USING_USB_HOST + bool "Enable USB Host" + select RT_USING_USB_HOST + default n + if BSP_USING_USB_HOST + menuconfig RT_USBH_MSTORAGE + bool "Enable Udisk Drivers" + default n + if RT_USBH_MSTORAGE + config UDISK_MOUNTPOINT + string "Udisk mount dir" + default "/" + endif + endif + + config BSP_USING_USB_DEVICE + bool "Enable USB Device" + select RT_USING_USB_DEVICE + default n + endmenu endmenu diff --git a/bsp/imxrt/libraries/drivers/SConscript b/bsp/imxrt/libraries/drivers/SConscript index 7320ff84af..940ff5eb6e 100644 --- a/bsp/imxrt/libraries/drivers/SConscript +++ b/bsp/imxrt/libraries/drivers/SConscript @@ -1,8 +1,10 @@ from building import * -cwd = GetCurrentDir() - src = [] +cwd = [] +CPPDEFINES = [] + +cwd = GetCurrentDir() if GetDepend('BSP_USING_GPIO'): src += ['drv_gpio.c'] @@ -43,8 +45,24 @@ if GetDepend('BSP_USING_LCD'): if GetDepend('BSP_USING_ETH'): src += ['drv_eth.c'] +if GetDepend('BSP_USING_USB_DEVICE'): + src += ['drv_usbd.c'] + src += Glob('usb/device/*.c') + +if GetDepend('BSP_USING_USB_DEVICE'): + src += Glob('usb/phy/*.c') + CPPDEFINES += ['ENDIANNESS'] + +if GetDepend('BSP_USING_USB_HOST'): + src += ['drv_usbh.c'] + src += Glob('usb/host/*.c') + +if GetDepend('BSP_USING_USB_HOST'): + src += Glob('usb/phy/*.c') + CPPDEFINES += ['ENDIANNESS'] + path = [cwd,cwd + '/config'] -group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path) +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES=CPPDEFINES) Return('group') diff --git a/bsp/imxrt/libraries/drivers/drv_usbd.c b/bsp/imxrt/libraries/drivers/drv_usbd.c new file mode 100644 index 0000000000..b034ba7a72 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/drv_usbd.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-12-04 ZYH first implementation + */ +#include +#include +#include +#include +#include +#include +#include + +/* USB PHY condfiguration */ +#define BOARD_USB_PHY_D_CAL (0x0CU) +#define BOARD_USB_PHY_TXCAL45DP (0x06U) +#define BOARD_USB_PHY_TXCAL45DM (0x06U) + +static usb_device_handle ehci0_handle; +static struct udcd _fsl_udc_0; + +static usb_status_t usb_device_callback(usb_device_handle handle, uint32_t callbackEvent, void *eventParam); +static usb_status_t usb_device_endpoint_callback(usb_device_handle handle, usb_device_endpoint_callback_message_struct_t *message, void *callbackParam); + +static void USB_DeviceIsrEnable(uint8_t controllerId) +{ + uint8_t irqNumber; +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) + uint8_t usbDeviceEhciIrq[] = USBHS_IRQS; + irqNumber = usbDeviceEhciIrq[controllerId - kUSB_ControllerEhci0]; +#endif + /* Install isr, set priority, and enable IRQ. */ +#if defined(__GIC_PRIO_BITS) + GIC_SetPriority((IRQn_Type)irqNumber, 3); +#else + NVIC_SetPriority((IRQn_Type)irqNumber, 3); +#endif + EnableIRQ((IRQn_Type)irqNumber); +} + +/*! + * @brief Initializes USB specific setting that was not set by the Clocks tool. + */ +static void USB_DeviceClockInit(uint8_t controllerId) +{ +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) + usb_phy_config_struct_t phyConfig = { + BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM, + }; +#endif +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) + if (controllerId == kUSB_ControllerEhci0) + { + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); + } + else + { + CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); + } + USB_EhciPhyInit(controllerId, 0, &phyConfig); +#endif +} + +static struct ep_id _ehci0_ep_pool[] = +{ + {0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED }, + {0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED}, + {0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED}, + {0x2, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED}, + {0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED}, + {0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED}, + {0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED}, + {0x4, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED}, + {0x4, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED}, + {0x5, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED}, + {0x5, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED}, + {0x6, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED}, + {0x6, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED}, + {0x7, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED}, + {0x7, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED}, + {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED }, +}; + +/*! + * @brief USB Interrupt service routine. + * + * This function serves as the USB interrupt service routine. + * + * @return None. + */ +void USB_OTG1_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + USB_DeviceEhciIsrFunction(ehci0_handle); + /* leave interrupt */ + rt_interrupt_leave(); +} + +static rt_err_t _ehci0_ep_set_stall(rt_uint8_t address) +{ + USB_DeviceStallEndpoint(ehci0_handle, address); + return RT_EOK; +} + +static rt_err_t _ehci0_ep_clear_stall(rt_uint8_t address) +{ + USB_DeviceUnstallEndpoint(ehci0_handle, address); + return RT_EOK; +} + +static rt_err_t _ehci0_set_address(rt_uint8_t address) +{ + USB_DeviceSetStatus(ehci0_handle, kUSB_DeviceStatusAddress, &address); + return RT_EOK; +} + +static rt_err_t _ehci0_set_config(rt_uint8_t address) +{ + return RT_EOK; +} + +static rt_err_t _ehci0_ep_enable(uep_t ep) +{ + usb_device_endpoint_init_struct_t ep_init; + usb_device_endpoint_callback_struct_t ep_callback; + rt_uint32_t param = ep->ep_desc->bEndpointAddress; + RT_ASSERT(ep != RT_NULL); + RT_ASSERT(ep->ep_desc != RT_NULL); + ep_init.maxPacketSize = ep->ep_desc->wMaxPacketSize; + ep_init.endpointAddress = ep->ep_desc->bEndpointAddress; + ep_init.transferType = ep->ep_desc->bmAttributes; + ep_init.zlt = 0; + ep_callback.callbackFn = usb_device_endpoint_callback; + ep_callback.callbackParam = (void *)param; + ep_callback.isBusy = 0; + USB_DeviceInitEndpoint(ehci0_handle, &ep_init, &ep_callback); + return RT_EOK; +} +static rt_err_t _ehci0_ep_disable(uep_t ep) +{ + RT_ASSERT(ep != RT_NULL); + RT_ASSERT(ep->ep_desc != RT_NULL); + USB_DeviceDeinitEndpoint(ehci0_handle, ep->ep_desc->bEndpointAddress); + return RT_EOK; +} + +static rt_size_t _ehci0_ep_read(rt_uint8_t address, void *buffer) +{ + rt_size_t size = 0; + + RT_ASSERT(buffer != RT_NULL); + + return size; +} + +static rt_size_t _ehci0_ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size) +{ + USB_DeviceRecvRequest(ehci0_handle, address, buffer, size); + return size; +} + +static rt_size_t _ehci0_ep_write(rt_uint8_t address, void *buffer, rt_size_t size) +{ + USB_DeviceSendRequest(ehci0_handle, address, buffer, size); + return size; +} + +static rt_err_t _ehci0_ep0_send_status(void) +{ + _ehci0_ep_write(0x00, NULL, 0); + return RT_EOK; +} + +static rt_err_t _ehci0_suspend(void) +{ + return RT_EOK; +} + +static rt_err_t _ehci0_wakeup(void) +{ + return RT_EOK; +} + +const static struct udcd_ops _ehci0_udc_ops = +{ + _ehci0_set_address, + _ehci0_set_config, + _ehci0_ep_set_stall, + _ehci0_ep_clear_stall, + _ehci0_ep_enable, + _ehci0_ep_disable, + _ehci0_ep_read_prepare, + _ehci0_ep_read, + _ehci0_ep_write, + _ehci0_ep0_send_status, + _ehci0_suspend, + _ehci0_wakeup, +}; + +static rt_err_t drv_ehci0_usbd_init(rt_device_t device) +{ + usb_status_t result; + USB_DeviceClockInit(kUSB_ControllerEhci0); + + result = USB_DeviceInit(kUSB_ControllerEhci0, usb_device_callback, &ehci0_handle); + RT_ASSERT(ehci0_handle); + if(result == kStatus_USB_Success) + { + USB_DeviceIsrEnable(kUSB_ControllerEhci0); + USB_DeviceRun(ehci0_handle); + } + else + { + rt_kprintf("USB_DeviceInit ehci0 error\r\n"); + return RT_ERROR; + } + return RT_EOK; +} + +static int rt_usbd_init(void) +{ + rt_memset((void *)&_fsl_udc_0, 0, sizeof(struct udcd)); + _fsl_udc_0.parent.type = RT_Device_Class_USBDevice; + _fsl_udc_0.parent.init = drv_ehci0_usbd_init; + _fsl_udc_0.ops = &_ehci0_udc_ops; + /* Register endpoint infomation */ + _fsl_udc_0.ep_pool = _ehci0_ep_pool; + _fsl_udc_0.ep0.id = &_ehci0_ep_pool[0]; + + _fsl_udc_0.device_is_hs = RT_FALSE; + rt_device_register((rt_device_t)&_fsl_udc_0, "usbd", 0); + rt_usb_device_init(); + + return 0; +} +INIT_DEVICE_EXPORT(rt_usbd_init); + +static usb_status_t usb_device_endpoint_callback(usb_device_handle handle, usb_device_endpoint_callback_message_struct_t *message, void *callbackParam) +{ + rt_uint32_t ep_addr = (rt_uint32_t)callbackParam; + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + udcd_t udcd = RT_NULL; + uint8_t state; + if(deviceHandle->controllerId == kUSB_ControllerEhci0) + udcd = &_fsl_udc_0; + + if(message->isSetup) + { + rt_usbd_ep0_setup_handler(udcd, (struct urequest*)message->buffer); + } + else if(ep_addr == 0x00) + { + USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state); + if(state == kUSB_DeviceStateAddressing) + { + if (kStatus_USB_Success == USB_DeviceSetStatus(handle, kUSB_DeviceStatusAddress, NULL)) + { + state = kUSB_DeviceStateAddress; + USB_DeviceSetStatus(handle, kUSB_DeviceStatusDeviceState, &state); + } + } + rt_usbd_ep0_out_handler(udcd, message->length); + } + else if(ep_addr == 0x80) + { + USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state); + if(state == kUSB_DeviceStateAddressing) + { + if (kStatus_USB_Success == USB_DeviceSetStatus(handle, kUSB_DeviceStatusAddress, NULL)) + { + state = kUSB_DeviceStateAddress; + USB_DeviceSetStatus(handle, kUSB_DeviceStatusDeviceState, &state); + } + } + rt_usbd_ep0_in_handler(udcd); + } + else if(ep_addr & 0x80) + { + rt_usbd_ep_in_handler(udcd, ep_addr, message->length); + } + else + { + rt_usbd_ep_out_handler(udcd, ep_addr, message->length); + } + return kStatus_USB_Success; +} + +static usb_status_t usb_device_callback(usb_device_handle handle, uint32_t callbackEvent, void *eventParam) +{ + usb_status_t error = kStatus_USB_Error; + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_device_endpoint_init_struct_t ep0_init = + { + 0x40, + 0x00, + USB_EP_ATTR_CONTROL, + 0 + }; + usb_device_endpoint_callback_struct_t ep0_callback = + { + usb_device_endpoint_callback, + 0, + 0 + }; + udcd_t udcd = RT_NULL; + if(deviceHandle->controllerId == kUSB_ControllerEhci0) + udcd = &_fsl_udc_0; + + switch (callbackEvent) + { + case kUSB_DeviceEventBusReset: + ep0_init.endpointAddress = 0x00; + ep0_callback.callbackParam = (void *)0x00; + USB_DeviceInitEndpoint(deviceHandle, &ep0_init, &ep0_callback); + ep0_init.endpointAddress = 0x80; + ep0_callback.callbackParam = (void *)0x80; + USB_DeviceInitEndpoint(deviceHandle, &ep0_init, &ep0_callback); + rt_usbd_reset_handler(udcd); + break; + case kUSB_DeviceEventAttach: + rt_usbd_connect_handler(udcd); + break; + case kUSB_DeviceEventDetach: + rt_usbd_disconnect_handler(udcd); + break; + } + return error; +} + +/********************* end of file ************************/ diff --git a/bsp/imxrt/libraries/drivers/usb/device/usb_device.h b/bsp/imxrt/libraries/drivers/usb/device/usb_device.h new file mode 100644 index 0000000000..99e8a879f8 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/device/usb_device.h @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_USB_DEVICE_H__ +#define __FSL_USB_DEVICE_H__ + +/*! + * @addtogroup usb_device_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines Get/Set status Types */ +typedef enum _usb_device_status +{ + kUSB_DeviceStatusTestMode = 1U, /*!< Test mode */ + kUSB_DeviceStatusSpeed, /*!< Current speed */ + kUSB_DeviceStatusOtg, /*!< OTG status */ + kUSB_DeviceStatusDevice, /*!< Device status */ + kUSB_DeviceStatusEndpoint, /*!< Endpoint state usb_device_endpoint_status_t */ + kUSB_DeviceStatusDeviceState, /*!< Device state */ + kUSB_DeviceStatusAddress, /*!< Device address */ + kUSB_DeviceStatusSynchFrame, /*!< Current frame */ + kUSB_DeviceStatusBus, /*!< Bus status */ + kUSB_DeviceStatusBusSuspend, /*!< Bus suspend */ + kUSB_DeviceStatusBusSleep, /*!< Bus suspend */ + kUSB_DeviceStatusBusResume, /*!< Bus resume */ + kUSB_DeviceStatusRemoteWakeup, /*!< Remote wakeup state */ + kUSB_DeviceStatusBusSleepResume, /*!< Bus resume */ +} usb_device_status_t; + +/*! @brief Defines USB 2.0 device state */ +typedef enum _usb_device_state +{ + kUSB_DeviceStateConfigured = 0U, /*!< Device state, Configured*/ + kUSB_DeviceStateAddress, /*!< Device state, Address*/ + kUSB_DeviceStateDefault, /*!< Device state, Default*/ + kUSB_DeviceStateAddressing, /*!< Device state, Address setting*/ + kUSB_DeviceStateTestMode, /*!< Device state, Test mode*/ +} usb_device_state_t; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +typedef enum _usb_dcd_detection_sequence_status +{ + kUSB_DcdDetectionNotEnabled = 0x0U, + kUSB_DcdDataPinDetectionCompleted = 0x01U, + kUSB_DcdChargingPortDetectionCompleted = 0x02U, + kUSB_DcdChargerTypeDetectionCompleted = 0x03U, +} usb_dcd_detection_sequence_status_t; + +typedef enum _usb_dcd_detection_sequence_results +{ + kUSB_DcdDetectionNoResults = 0x0U, + kUSB_DcdDetectionStandardHost = 0x01U, + kUSB_DcdDetectionChargingPort = 0x02U, + kUSB_DcdDetectionDedicatedCharger = 0x03U, +} usb_dcd_detection_sequence_results_t; +#endif + +/*! @brief Defines endpoint state */ +typedef enum _usb_endpoint_status +{ + kUSB_DeviceEndpointStateIdle = 0U, /*!< Endpoint state, idle*/ + kUSB_DeviceEndpointStateStalled, /*!< Endpoint state, stalled*/ +} usb_device_endpoint_status_t; + +/*! @brief Control endpoint index */ +#define USB_CONTROL_ENDPOINT (0U) +/*! @brief Control endpoint maxPacketSize */ +#define USB_CONTROL_MAX_PACKET_SIZE (64U) + +#if (USB_DEVICE_CONFIG_EHCI && (USB_CONTROL_MAX_PACKET_SIZE != (64U))) +#error For high speed, USB_CONTROL_MAX_PACKET_SIZE must be 64!!! +#endif + +/*! @brief The setup packet size of USB control transfer. */ +#define USB_SETUP_PACKET_SIZE (8U) +/*! @brief USB endpoint mask */ +#define USB_ENDPOINT_NUMBER_MASK (0x0FU) + +/*! @brief Default invalid value or the endpoint callback length of cancelled transfer */ +#define USB_UNINITIALIZED_VAL_32 (0xFFFFFFFFU) + +/*! @brief Available common EVENT types in device callback */ +typedef enum _usb_device_event +{ + kUSB_DeviceEventBusReset = 1U, /*!< USB bus reset signal detected */ + kUSB_DeviceEventSuspend, /*!< USB bus suspend signal detected */ + kUSB_DeviceEventResume, /*!< USB bus resume signal detected. The resume signal is driven by itself or a host */ + kUSB_DeviceEventSleeped, /*!< USB bus LPM suspend signal detected */ + kUSB_DeviceEventLPMResume, /*!< USB bus LPM resume signal detected. The resume signal is driven by itself or a host + */ + kUSB_DeviceEventError, /*!< An error is happened in the bus. */ + kUSB_DeviceEventDetach, /*!< USB device is disconnected from a host. */ + kUSB_DeviceEventAttach, /*!< USB device is connected to a host. */ + kUSB_DeviceEventSetConfiguration, /*!< Set configuration. */ + kUSB_DeviceEventSetInterface, /*!< Set interface. */ + + kUSB_DeviceEventGetDeviceDescriptor, /*!< Get device descriptor. */ + kUSB_DeviceEventGetConfigurationDescriptor, /*!< Get configuration descriptor. */ + kUSB_DeviceEventGetStringDescriptor, /*!< Get string descriptor. */ + kUSB_DeviceEventGetHidDescriptor, /*!< Get HID descriptor. */ + kUSB_DeviceEventGetHidReportDescriptor, /*!< Get HID report descriptor. */ + kUSB_DeviceEventGetHidPhysicalDescriptor, /*!< Get HID physical descriptor. */ + kUSB_DeviceEventGetBOSDescriptor, /*!< Get configuration descriptor. */ + kUSB_DeviceEventGetDeviceQualifierDescriptor, /*!< Get device qualifier descriptor. */ + kUSB_DeviceEventVendorRequest, /*!< Vendor request. */ + kUSB_DeviceEventSetRemoteWakeup, /*!< Enable or disable remote wakeup function. */ + kUSB_DeviceEventGetConfiguration, /*!< Get current configuration index */ + kUSB_DeviceEventGetInterface, /*!< Get current interface alternate setting value */ + kUSB_DeviceEventSetBHNPEnable, +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) + kUSB_DeviceEventDcdTimeOut, /*!< Dcd detect result is timeout */ + kUSB_DeviceEventDcdUnknownType, /*!< Dcd detect result is unknown type */ + kUSB_DeviceEventSDPDetected, /*!< The SDP facility is detected */ + kUSB_DeviceEventChargingPortDetected, /*!< The charging port is detected */ + kUSB_DeviceEventChargingHostDetected, /*!< The CDP facility is detected */ + kUSB_DeviceEventDedicatedChargerDetected, /*!< The DCP facility is detected */ +#endif +} usb_device_event_t; + +/*! @brief Endpoint callback message structure */ +typedef struct _usb_device_endpoint_callback_message_struct +{ + uint8_t *buffer; /*!< Transferred buffer */ + uint32_t length; /*!< Transferred data length */ + uint8_t isSetup; /*!< Is in a setup phase */ +} usb_device_endpoint_callback_message_struct_t; + +/*! + * @brief Endpoint callback function typedef. + * + * This callback function is used to notify the upper layer what the transfer result is. + * This callback pointer is passed when a specified endpoint is initialized by calling API #USB_DeviceInitEndpoint. + * + * @param handle The device handle. It equals to the value returned from #USB_DeviceInit. + * @param message The result of a transfer, which includes transfer buffer, transfer length, and whether is in a + * setup phase. + * phase for control pipe. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * + * @return A USB error code or kStatus_USB_Success. + */ +typedef usb_status_t (*usb_device_endpoint_callback_t)(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); + +/*! + * @brief Device callback function typedef. + * + * This callback function is used to notify the upper layer that the device status has changed. + * This callback pointer is passed by calling API #USB_DeviceInit. + * + * @param handle The device handle. It equals the value returned from #USB_DeviceInit. + * @param callbackEvent The callback event type. See enumeration #usb_device_event_t. + * @param eventParam The event parameter for this callback. The parameter type is determined by the callback event. + * + * @return A USB error code or kStatus_USB_Success. + */ +typedef usb_status_t (*usb_device_callback_t)(usb_device_handle handle, uint32_t callbackEvent, void *eventParam); + +/*! @brief Endpoint callback structure */ +typedef struct _usb_device_endpoint_callback_struct +{ + usb_device_endpoint_callback_t callbackFn; /*!< Endpoint callback function*/ + void *callbackParam; /*!< Parameter for callback function*/ + uint8_t isBusy; +} usb_device_endpoint_callback_struct_t; + +/*! @brief Endpoint initialization structure */ +typedef struct _usb_device_endpoint_init_struct +{ + uint16_t maxPacketSize; /*!< Endpoint maximum packet size */ + uint8_t endpointAddress; /*!< Endpoint address*/ + uint8_t transferType; /*!< Endpoint transfer type*/ + uint8_t zlt; /*!< ZLT flag*/ +} usb_device_endpoint_init_struct_t; + +/*! @brief Endpoint status structure */ +typedef struct _usb_device_endpoint_status_struct +{ + uint8_t endpointAddress; /*!< Endpoint address */ + uint16_t endpointStatus; /*!< Endpoint status : idle or stalled */ +} usb_device_endpoint_status_struct_t; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! @brief USB DCD charge timing specification structure */ +typedef struct _usb_device_dcd_charging_time +{ + uint16_t dcdSeqInitTime; /*!< The dcd sequence init time */ + uint16_t dcdDbncTime; /*!< The debounce time period on DP signal */ + uint16_t dcdDpSrcOnTime; /*!< The time period comparator enabled */ + uint16_t dcdTimeWaitAfterPrD; /*!< The time period between primary and secondary detection */ + uint8_t dcdTimeDMSrcOn; /*!< The amount of time that the modules enable the Vdm_src */ +} usb_device_dcd_charging_time_t; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @name USB device APIs + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Initializes the USB device stack. + * + * This function initializes the USB device module specified by the controllerId. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] deviceCallback Function pointer of the device callback. + * @param[out] handle It is an out parameter used to return the pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success The device is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id. + * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invalid. There is an empty + * interface entity. + * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than the IP's endpoint number. + * Or, the device has been initialized. + * Or, the mutex or message queue is created failed. + */ +extern usb_status_t USB_DeviceInit(uint8_t controllerId, + usb_device_callback_t deviceCallback, + usb_device_handle *handle); + +/*! + * @brief Enables the device functionality. + * + * The function enables the device functionality, so that the device can be recognized by the host when the device + * detects that it has been connected to a host. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +extern usb_status_t USB_DeviceRun(usb_device_handle handle); + +/*! + * @brief Disables the device functionality. + * + * The function disables the device functionality. After this function called, even if the device is detached to the + * host, + * it can't work. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + */ +extern usb_status_t USB_DeviceStop(usb_device_handle handle); + +/*! + * @brief De-initializes the device controller. + * + * The function de-initializes the device controller specified by the handle. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + */ +extern usb_status_t USB_DeviceDeinit(usb_device_handle handle); + +/*! + * @brief Sends data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. The function is not reentrant. + * @param[in] length The data length need to be sent. + * + * @retval kStatus_USB_Success The send request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value indicates whether the sending request is successful or not. The transfer done is notified by + * the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue on the application level. + * The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +extern usb_status_t USB_DeviceSendRequest(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. The function is not reentrant. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length want to be received. + * + * @retval kStatus_USB_Success The receive request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value indicates whether the receiving request is successful or not. The transfer done is notified by + * the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue on the application level. + * The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +extern usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Cancels the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The transfer is cancelled. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Initializes a specified endpoint. + * + * The function is used to initialize a specified endpoint. The corresponding endpoint callback is also initialized. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] epInit Endpoint initialization structure. See the structure usb_device_endpoint_init_struct_t. + * @param[in] epCallback Endpoint callback structure. See the structure + * usb_device_endpoint_callback_struct_t. + * + * @retval kStatus_USB_Success The endpoint is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is + * more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle, + usb_device_endpoint_init_struct_t *epInit, + usb_device_endpoint_callback_struct_t *epCallback); + +/*! + * @brief Deinitializes a specified endpoint. + * + * The function is used to deinitializes a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is de-initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Stalls a specified endpoint. + * + * The function is used to stall a specified endpoint. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Unstalls a specified endpoint. + * + * The function is used to unstall a specified endpoint. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is unstalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Gets the status of the selected item. + * + * The function is used to get the status of the selected item. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] type The selected item. See the structure #usb_device_status_t. + * @param[out] param The parameter type is determined by the selected item. + * + * @retval kStatus_USB_Success Get status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The parameter is NULL pointer. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type. + */ +extern usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param); + +/*! + * @brief Sets the status of the selected item. + * + * The function is used to set the status of the selected item. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] type The selected item. See the structure #usb_device_status_t. + * @param[in] param The parameter type is determined by the selected item. + * + * @retval kStatus_USB_Success Set status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type or the parameter is NULL pointer. + */ +extern usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param); + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! + * @brief Initializes the device dcd module. + * + * The function initializes the device dcd module. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] time_param The time parameter used to config the dcd timing registers. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +extern usb_status_t USB_DeviceDcdInitModule(usb_device_handle handle, void *time_param); + +/*! + * @brief De-initializes the device dcd module. + * + * The function de-initializes the device dcd module specified by the handle. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + */ +extern usb_status_t USB_DeviceDcdDeinitModule(usb_device_handle handle); +#endif +/*! + * @brief Device task function. + * + * The function is used to handle the controller message. + * This function should not be called in the application directly. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceTaskFunction(void *deviceHandle); + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +/*! + * @brief Device KHCI task function. + * + * The function is used to handle the KHCI controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceKhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/*! + * @brief Device EHCI task function. + * + * The function is used to handle the EHCI controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceEhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! + * @brief Device EHCI DCD ISR function. + * + * The function is the EHCI DCD interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceDcdHSIsrFunction(void *deviceHandle); +#endif +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +/*! + * @brief Device LPC ip3511 controller task function. + * + * The function is used to handle the LPC ip3511 controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceLpcIp3511TaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#endif + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +/*! + * @brief Device KHCI ISR function. + * + * The function is the KHCI interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceKhciIsrFunction(void *deviceHandle); +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! + * @brief Device KHCI DCD ISR function. + * + * The function is the KHCI DCD interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceDcdIsrFunction(void *deviceHandle); +#endif +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/*! + * @brief Device EHCI ISR function. + * + * The function is the EHCI interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceEhciIsrFunction(void *deviceHandle); +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +/*! + * @brief Device LPC USB ISR function. + * + * The function is the LPC USB interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle); +#endif + +/*! + * @brief Gets the device stack version function. + * + * The function is used to get the device stack version. + * + * @param[out] version The version structure pointer to keep the device stack version. + * + */ +extern void USB_DeviceGetVersion(uint32_t *version); + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) +/*! + * @brief Update the hardware tick. + * + * The function is used to update the hardware tick. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] tick Current hardware tick(uint is ms). + * + */ +extern usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick); +#endif + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* __USB_DEVICE_H__ */ diff --git a/bsp/imxrt/libraries/drivers/usb/device/usb_device_dci.c b/bsp/imxrt/libraries/drivers/usb/device/usb_device_dci.c new file mode 100644 index 0000000000..7a9e0d305f --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/device/usb_device_dci.c @@ -0,0 +1,1462 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "usb_device.h" +#include "usb_device_dci.h" + +#include "fsl_device_registers.h" + +#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U)) + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +#include "usb_device_khci.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +#include "usb_device_ehci.h" +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#include "usb_device_lpcip3511.h" +#endif + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) +#include "fsl_cache.h" +#endif +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle); +static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle); +static usb_status_t USB_DeviceGetControllerInterface( + uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface); +static usb_status_t USB_DeviceTransfer(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); +static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param); +static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) +static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); + +#endif +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) +static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#endif +static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL static usb_device_struct_t s_UsbDevice[USB_DEVICE_CONFIG_NUM]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device handle. + * + * This function allocates a device handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_Error The device has been initialized. + */ +static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle) +{ + uint32_t count; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + /* Check the controller is initialized or not. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDevice[count].controllerHandle) && (controllerId == s_UsbDevice[count].controllerId)) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Error; + } + } + /* Get a free device handle. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if (NULL == s_UsbDevice[count].controllerHandle) + { + s_UsbDevice[count].controllerId = controllerId; + *handle = &s_UsbDevice[count]; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device handle. + * + * This function frees a device handle. + * + * @param handle The device handle. + * + * @retval kStatus_USB_Success Free device handle successfully. + */ +static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle) +{ + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + handle->controllerHandle = NULL; + handle->controllerId = 0U; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +/* KHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceKhciInterface = { + USB_DeviceKhciInit, USB_DeviceKhciDeinit, USB_DeviceKhciSend, + USB_DeviceKhciRecv, USB_DeviceKhciCancel, USB_DeviceKhciControl +}; +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/* EHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = { + USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend, + USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl +}; +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +/* EHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceLpc3511IpInterface = { + USB_DeviceLpc3511IpInit, USB_DeviceLpc3511IpDeinit, USB_DeviceLpc3511IpSend, + USB_DeviceLpc3511IpRecv, USB_DeviceLpc3511IpCancel, USB_DeviceLpc3511IpControl +}; +#endif + +/*! + * @brief Get the controller interface handle. + * + * This function is used to get the controller interface handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param controllerInterface It is out parameter, is used to return pointer of the device controller handle to the + * caller. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_ControllerNotFound The controller id is invalided. + */ +static usb_status_t USB_DeviceGetControllerInterface( + uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface) +{ + usb_status_t error = kStatus_USB_ControllerNotFound; + switch (controllerId) + { +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) + /* Get the KHCI controller driver interface */ + case kUSB_ControllerKhci0: + case kUSB_ControllerKhci1: + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceKhciInterface; + error = kStatus_USB_Success; + break; +#endif +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) + /* Get the EHCI controller driver interface */ + case kUSB_ControllerEhci0: + case kUSB_ControllerEhci1: + error = kStatus_USB_Success; + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceEhciInterface; + break; +#endif +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) + /* Get the EHCI controller driver interface */ + case kUSB_ControllerLpcIp3511Fs0: + case kUSB_ControllerLpcIp3511Fs1: + case kUSB_ControllerLpcIp3511Hs0: + case kUSB_ControllerLpcIp3511Hs1: + error = kStatus_USB_Success; + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceLpc3511IpInterface; + break; +#endif + default: + break; + } + return error; +} + +/*! + * @brief Start a new transfer. + * + * This function is used to start a new transfer. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param endpointAddress Endpoint address. Bit7 is direction, 0U - USB_OUT, 1U - USB_IN. + * @param buffer The memory address to be transferred, or the memory address to hold the data need to be + * sent. + * @param length The length of the data. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_InvalidHandle The device handle is invalided. + * @retval kStatus_USB_ControllerNotFound The controller interface is not found. + * @retval kStatus_USB_Error The device is doing reset. + */ +static usb_status_t USB_DeviceTransfer(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t error = kStatus_USB_Error; + uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + USB_OSA_SR_ALLOC(); + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + if (deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy) + { + return kStatus_USB_Busy; + } + USB_OSA_ENTER_CRITICAL(); + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 1U; + USB_OSA_EXIT_CRITICAL(); + if (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) + { +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + if (length) + { + DCACHE_CleanByRange((uint32_t)buffer, length); + } +#endif + /* Call the controller send interface. */ + error = deviceHandle->controllerInterface->deviceSend(deviceHandle->controllerHandle, endpointAddress, + buffer, length); + } + else + { +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + if (length) + { + DCACHE_CleanInvalidateByRange((uint32_t)buffer, length); + } +#endif + /* Call the controller receive interface. */ + error = deviceHandle->controllerInterface->deviceRecv(deviceHandle->controllerHandle, endpointAddress, + buffer, length); + } + if (kStatus_USB_Success != error) + { + USB_OSA_ENTER_CRITICAL(); + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + USB_OSA_EXIT_CRITICAL(); + } + } + else + { + error = kStatus_USB_ControllerNotFound; + } + return error; +} + +/*! + * @brief Control the status of the selected item. + * + * This function is used to control the status of the selected item.. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param type The control type, please refer to the enumeration usb_device_control_type_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_InvalidHandle The device handle is invalided. + * @retval kStatus_USB_ControllerNotFound The controller interface is not found. + * @retval kStatus_USB_Error Unsupport type. + * Or, the param is NULL pointer. + */ +static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t error = kStatus_USB_Error; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + /* Call the controller control interface. */ + error = deviceHandle->controllerInterface->deviceControl(deviceHandle->controllerHandle, type, param); + } + else + { + error = kStatus_USB_ControllerNotFound; + } + return error; +} + +/*! + * @brief Handle the reset notification. + * + * This function is used to handle the reset notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @retval kStatus_USB_Success Get a device handle successfully. + */ +static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_SR_ALLOC(); +#endif + + handle->isResetting = 1U; + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + /* Clear remote wakeup feature */ + handle->remotewakeup = 0U; +#endif + +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_ENTER_CRITICAL(); + handle->epCallbackDirectly = 1; + USB_OSA_EXIT_CRITICAL(); +#endif + /* Set the controller to default status. */ + USB_DeviceControl(handle, kUSB_DeviceControlSetDefaultStatus, NULL); +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_ENTER_CRITICAL(); + handle->epCallbackDirectly = 0; + USB_OSA_EXIT_CRITICAL(); +#endif + + handle->state = kUSB_DeviceStateDefault; + handle->deviceAddress = 0U; + + for (uint32_t count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++) + { + handle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL; + handle->epCallback[count].callbackParam = NULL; + handle->epCallback[count].isBusy = 0U; + } + + /* Call device callback to notify the application that the USB bus reset signal detected. */ + handle->deviceCallback(handle, kUSB_DeviceEventBusReset, NULL); + + handle->isResetting = 0U; + return kStatus_USB_Success; +} + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! + * @brief Handle the suspend notification. + * + * This function is used to handle the suspend notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus suspend signal detected. */ + return handle->deviceCallback(handle, kUSB_DeviceEventSuspend, NULL); +} + +/*! + * @brief Handle the resume notification. + * + * This function is used to handle the resume notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus resume signal detected. */ + return handle->deviceCallback(handle, kUSB_DeviceEventResume, NULL); +} +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) +/*! + * @brief Handle the suspend notification. + * + * This function is used to handle the suspend notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus suspend signal detected. */ + return handle->deviceCallback(handle, kUSB_DeviceEventSleeped, NULL); +} +#endif +/*! + * @brief Handle the remotewakeup notification. + * + * This function is used to handle the remotewakeup notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param flag The buffer pointer to store remotewakeup flag. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetRemoteWakeUp(usb_device_struct_t *handle, uint8_t **flag) +{ + /* Call device callback to notify the application that the USB bus suspend signal detected. */ + return USB_DeviceControl(handle, kUSB_DeviceControlGetRemoteWakeUp, flag); +} + +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + +#if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)) +usb_status_t USB_DeviceErrorNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus error signal detected. */ + return handle->deviceCallback(handle, kUSB_DeviceEventError, NULL); +} +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) +/*! + * @brief Handle the detach notification. + * + * This function is used to handle the detach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device is disconnected from a host. */ + return handle->deviceCallback(handle, kUSB_DeviceEventDetach, NULL); +} + +/*! + * @brief Handle the attach notification. + * + * This function is used to handle the attach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device is connected to a host. */ + return handle->deviceCallback(handle, kUSB_DeviceEventAttach, NULL); +} +#endif + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))) +/*! + * @brief Handle the dcd module timeout notification. + * + * This function is used to handle the dcd module timeout notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdTimeOutNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device charger detect timeout happened. */ + return handle->deviceCallback(handle, kUSB_DeviceEventDcdTimeOut, NULL); +} + +/*! + * @brief Handle the dcd module unknown port type notification. + * + * This function is used to handle the dcd module unknown port type notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdUnknownPortTypeNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device charger detect unknown port type happened. */ + return handle->deviceCallback(handle, kUSB_DeviceEventDcdUnknownType, NULL); +} + +/*! + * @brief Handle the SDP facility is detected notification. + * + * This function is used to handle the SDP facility is detectednotification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdSDPDetectNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the SDP facility is detected. */ + return handle->deviceCallback(handle, kUSB_DeviceEventSDPDetected, NULL); +} + +/*! + * @brief Handle the charging port is detected notification. + * + * This function is used to handle the charging port is detectednotification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdChargingPortDetectNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the charing port is detected. */ + return handle->deviceCallback(handle, kUSB_DeviceEventChargingPortDetected, NULL); +} + +/*! + * @brief Handle the CDP facility is detected notification. + * + * This function is used to handle the CDP facility is detectednotification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdChargingHostDetectNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the CDP facility is detected. */ + return handle->deviceCallback(handle, kUSB_DeviceEventChargingHostDetected, NULL); +} + +/*! + * @brief Handle the DCP facility is detected notification. + * + * This function is used to handle the DCP facility is detectednotification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ + +static usb_status_t USB_DeviceDcdDedicatedChargerDetectNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the DCP facility is detected. */ + return handle->deviceCallback(handle, kUSB_DeviceEventDedicatedChargerDetected, NULL); +} +#endif + +/*! + * @brief Handle the attach notification. + * + * This function is used to handle the attach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message) +{ + uint8_t endpoint = message->code & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (message->code & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + usb_status_t error = kStatus_USB_Error; + + switch (message->code) + { + case kUSB_DeviceNotifyBusReset: + error = USB_DeviceResetNotification(handle, message); + break; +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + case kUSB_DeviceNotifySuspend: + error = USB_DeviceSuspendNotification(handle, message); + break; + case kUSB_DeviceNotifyResume: + error = USB_DeviceResumeNotification(handle, message); + break; +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + case kUSB_DeviceNotifyLPMSleep: + error = USB_DeviceSleepNotification(handle, message); + break; +#endif +#endif + +#if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)) + case kUSB_DeviceNotifyError: + error = USB_DeviceErrorNotification(handle, message); + break; +#endif + +#if USB_DEVICE_CONFIG_DETACH_ENABLE + case kUSB_DeviceNotifyDetach: + error = USB_DeviceDetachNotification(handle, message); + break; + case kUSB_DeviceNotifyAttach: + error = USB_DeviceAttachNotification(handle, message); + break; +#endif +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))) + case kUSB_DeviceNotifyDcdTimeOut: + error = USB_DeviceDcdTimeOutNotification(handle, message); + break; + case kUSB_DeviceNotifyDcdUnknownPortType: + error = USB_DeviceDcdUnknownPortTypeNotification(handle, message); + break; + case kUSB_DeviceNotifySDPDetected: + error = USB_DeviceDcdSDPDetectNotification(handle, message); + break; + case kUSB_DeviceNotifyChargingPortDetected: + error = USB_DeviceDcdChargingPortDetectNotification(handle, message); + break; + case kUSB_DeviceNotifyChargingHostDetected: + error = USB_DeviceDcdChargingHostDetectNotification(handle, message); + break; + case kUSB_DeviceNotifyDedicatedChargerDetected: + error = USB_DeviceDcdDedicatedChargerDetectNotification(handle, message); + break; +#endif + + default: + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + if (handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = message->buffer; + endpointCallbackMessage.length = message->length; + endpointCallbackMessage.isSetup = message->isSetup; + if (message->isSetup) + { + handle->epCallback[0].isBusy = 0U; + handle->epCallback[1].isBusy = 0U; + } + else + { + handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + /* Call endpoint callback */ + error = handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn( + handle, &endpointCallbackMessage, + handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam); + } + } + break; + } + return error; +} + +/*! + * @brief Notify the device that the controller status changed. + * + * This function is used to notify the device that the controller status changed. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg; + + if ((NULL == msg) || (NULL == handle)) + { + return kStatus_USB_InvalidHandle; + } + + /* The device callback is invalid or not. */ + if (!deviceHandle->deviceCallback) + { + return kStatus_USB_Error; + } + +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + if (deviceHandle->epCallbackDirectly) + { + if ((message->code & USB_ENDPOINT_NUMBER_MASK) && (!(message->code & 0x70U))) + { + return USB_DeviceNotification(deviceHandle, message); + } + } + + /* Add the message to message queue when the device task is enabled. */ + if (kStatus_USB_OSA_Success != USB_OsaMsgqSend(deviceHandle->notificationQueue, (void *)message)) + { + return kStatus_USB_Busy; + } + return kStatus_USB_Success; +#else + /* Handle the notification by calling USB_DeviceNotification. */ + return USB_DeviceNotification(deviceHandle, message); +#endif +} + +/*! + * @brief Initialize the USB device stack. + * + * This function initializes the USB device module specified by the controllerId. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param deviceCallback Function pointer of the device callback. + * @param handle It is out parameter, is used to return pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success The device is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id. + * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invaild, There is an empty + * interface entity. + * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than IP's endpoint number. + * Or, the device has been initialized. + * Or, the message queue is created failed. + */ +usb_status_t USB_DeviceInit(uint8_t controllerId, usb_device_callback_t deviceCallback, usb_device_handle *handle) +{ + usb_device_struct_t *deviceHandle = NULL; + usb_status_t error; + uint32_t count; + + if (NULL == handle) + { + return kStatus_USB_InvalidHandle; + } + + /* Allocate a device handle by using the controller id. */ + error = USB_DeviceAllocateHandle(controllerId, &deviceHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Save the device callback */ + deviceHandle->deviceCallback = deviceCallback; + /* Save the controller id */ + deviceHandle->controllerId = controllerId; + /* Clear the device address */ + deviceHandle->deviceAddress = 0U; + /* Clear the device reset state */ + deviceHandle->isResetting = 0U; + + /* Initialize the enpoints */ + for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++) + { + deviceHandle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL; + deviceHandle->epCallback[count].callbackParam = NULL; + deviceHandle->epCallback[count].isBusy = 0U; + } + + /* Get the controller interface according to the controller id */ + error = USB_DeviceGetControllerInterface(controllerId, &deviceHandle->controllerInterface); + if (kStatus_USB_Success != error) + { + USB_DeviceFreeHandle(deviceHandle); + return error; + } + if (NULL == deviceHandle->controllerInterface) + { + USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_ControllerNotFound; + } + if (((usb_device_controller_init_t)NULL == deviceHandle->controllerInterface->deviceInit) || + ((usb_device_controller_deinit_t)NULL == deviceHandle->controllerInterface->deviceDeinit) || + ((usb_device_controller_send_t)NULL == deviceHandle->controllerInterface->deviceSend) || + ((usb_device_controller_recv_t)NULL == deviceHandle->controllerInterface->deviceRecv) || + ((usb_device_controller_cancel_t)NULL == deviceHandle->controllerInterface->deviceCancel) || + ((usb_device_controller_control_t)NULL == deviceHandle->controllerInterface->deviceControl)) + { + USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_InvalidControllerInterface; + } + +#if USB_DEVICE_CONFIG_USE_TASK + /* Create a message queue when the device handle is enabled. */ + if (kStatus_USB_OSA_Success != + USB_OsaMsgqCreate(&deviceHandle->notificationQueue, USB_DEVICE_CONFIG_MAX_MESSAGES, + (1U + (sizeof(usb_device_callback_message_struct_t) - 1U) / sizeof(uint32_t)))) + { + USB_DeviceDeinit(deviceHandle); + return kStatus_USB_Error; + } +#endif + + *handle = deviceHandle; + + /* Initialize the controller */ + error = deviceHandle->controllerInterface->deviceInit(controllerId, deviceHandle, &deviceHandle->controllerHandle); + if (kStatus_USB_Success != error) + { + USB_DeviceDeinit(deviceHandle); + *handle = NULL; + return error; + } + /* Set the device to deafult state */ + deviceHandle->state = kUSB_DeviceStateDefault; + + return error; +} + +/*! + * @brief Enable the device functionality. + * + * The function enables the device functionality, so that the device can be recognized by the host when the device + * detects that it has been connected to a host. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceRun(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlRun, NULL); +} +/*! + * @brief Disable the device functionality. + * + * The function disables the device functionality, after this function called, even the device is detached to the host, + * and the device can't work. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + */ +usb_status_t USB_DeviceStop(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlStop, NULL); +} +/*! + * @brief De-initialize the device controller. + * + * The function de-initializes the device controller specified by the handle. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + */ +usb_status_t USB_DeviceDeinit(usb_device_handle handle) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + /* De-initialize the controller */ + if (NULL != deviceHandle->controllerInterface) + { + deviceHandle->controllerInterface->deviceDeinit(deviceHandle->controllerHandle); + deviceHandle->controllerInterface = (usb_device_controller_interface_struct_t *)NULL; + } + +#if USB_DEVICE_CONFIG_USE_TASK + /* Destroy the message queue. */ + if (NULL != deviceHandle->notificationQueue) + { + USB_OsaMsgqDestroy(deviceHandle->notificationQueue); + deviceHandle->notificationQueue = NULL; + } +#endif + + /* Free the device handle. */ + USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_Success; +} + +/*! + * @brief Send data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @retval kStatus_USB_Success The send request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate dtds for current tansfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceSendRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length) +{ + return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | + (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Receive data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @retval kStatus_USB_Success The receive request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate dtds for current tansfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length) +{ + return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | + (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Cancel the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The transfer is cancelled. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t error = kStatus_USB_Error; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + error = deviceHandle->controllerInterface->deviceCancel(deviceHandle->controllerHandle, endpointAddress); + } + else + { + error = kStatus_USB_ControllerNotFound; + } + return error; +} + +/*! + * @brief Initialize a specified endpoint. + * + * The function is used to initialize a specified endpoint and the corresponding endpoint callback is also initialized. + * + * @param handle The device handle got from USB_DeviceInit. + * @param epInit Endpoint initizlization structure. Please refer to the structure usb_device_endpoint_init_struct_t. + * @param epCallback Endpoint callback structure. Please refer to the structure + * usb_device_endpoint_callback_struct_t. + * + * @retval kStatus_USB_Success The endpoint is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is + * more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle, + usb_device_endpoint_init_struct_t *epInit, + usb_device_endpoint_callback_struct_t *epCallback) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + uint8_t endpoint; + uint8_t direction; + + if (!deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if ((!epInit) || (!epCallback)) + { + return kStatus_USB_InvalidParameter; + } + + endpoint = epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK; + direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = epCallback->callbackFn; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = + epCallback->callbackParam; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + else + { + return kStatus_USB_InvalidParameter; + } + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointInit, epInit); +} + +/*! + * @brief De-initizlize a specified endpoint. + * + * The function is used to de-initizlize a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is de-initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + usb_status_t error = kStatus_USB_Error; +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_SR_ALLOC(); +#endif + + if (!deviceHandle) + { + return kStatus_USB_InvalidHandle; + } +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_ENTER_CRITICAL(); + deviceHandle->epCallbackDirectly = 1; + USB_OSA_EXIT_CRITICAL(); +#endif + error = USB_DeviceControl(handle, kUSB_DeviceControlEndpointDeinit, &endpointAddress); +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_ENTER_CRITICAL(); + deviceHandle->epCallbackDirectly = 0; + USB_OSA_EXIT_CRITICAL(); +#endif + + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = + (usb_device_endpoint_callback_t)NULL; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = NULL; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + else + { + return kStatus_USB_InvalidParameter; + } + return error; +} + +/*! + * @brief Stall a specified endpoint. + * + * The function is used to stall a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS) + { + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointStall, &endpointAddress); + } + else + { + return kStatus_USB_InvalidParameter; + } +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is un-stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS) + { + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointUnstall, &endpointAddress); + } + else + { + return kStatus_USB_InvalidParameter; + } +} + +/*! + * @brief Get the status of the selected item. + * + * The function is used to get the status of the selected item. + * + * @param handle The device handle got from USB_DeviceInit. + * @param type The selected item. Please refer to the structure usb_device_status_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Get status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The param is NULL pointer. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type. + */ +usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param) +{ + uint8_t *temp8; + usb_status_t error = kStatus_USB_Error; + + if (NULL == param) + { + return kStatus_USB_InvalidParameter; + } + switch (type) + { + case kUSB_DeviceStatusSpeed: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetSpeed, param); + break; + case kUSB_DeviceStatusOtg: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetOtgStatus, param); + break; + case kUSB_DeviceStatusDeviceState: + temp8 = (uint8_t *)param; + error = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->state; + break; + case kUSB_DeviceStatusAddress: + temp8 = (uint8_t *)param; + error = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->deviceAddress; + break; + case kUSB_DeviceStatusDevice: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetDeviceStatus, param); + break; + case kUSB_DeviceStatusEndpoint: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetEndpointStatus, param); + break; + case kUSB_DeviceStatusSynchFrame: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetSynchFrame, param); + break; +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + case kUSB_DeviceStatusRemoteWakeup: + temp8 = (uint8_t *)param; + error = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->remotewakeup; + break; +#endif + default: + break; + } + return error; +} + +/*! + * @brief Set the status of the selected item. + * + * The function is used to set the status of the selected item. + * + * @param handle The device handle got from USB_DeviceInit. + * @param type The selected item. Please refer to the structure usb_device_status_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Set status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type, or the param is NULL pointer. + */ +usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param) +{ + usb_status_t error = kStatus_USB_Error; + switch (type) + { +#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \ + (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + case kUSB_DeviceStatusTestMode: + error = USB_DeviceControl(handle, kUSB_DeviceControlSetTestMode, param); + break; +#endif + case kUSB_DeviceStatusOtg: + error = USB_DeviceControl(handle, kUSB_DeviceControlSetOtgStatus, param); + break; + case kUSB_DeviceStatusDeviceState: + if (NULL != param) + { + error = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->state = (uint8_t)(*(uint8_t *)param); + } + break; + case kUSB_DeviceStatusAddress: + if (kUSB_DeviceStateAddressing != ((usb_device_struct_t *)handle)->state) + { + if (NULL != param) + { + error = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->deviceAddress = (uint8_t)(*(uint8_t *)param); + ((usb_device_struct_t *)handle)->state = kUSB_DeviceStateAddressing; + } + } + else + { + error = USB_DeviceControl(handle, kUSB_DeviceControlSetDeviceAddress, + &((usb_device_struct_t *)handle)->deviceAddress); + } + break; + case kUSB_DeviceStatusBusResume: + error = USB_DeviceControl(handle, kUSB_DeviceControlResume, param); + break; + case kUSB_DeviceStatusBusSleepResume: + error = USB_DeviceControl(handle, kUSB_DeviceControlSleepResume, param); + break; +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + case kUSB_DeviceStatusRemoteWakeup: + if (NULL != param) + { + error = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->remotewakeup = (uint8_t)(*(uint8_t *)param); + } + break; +#endif + case kUSB_DeviceStatusBusSuspend: + error = USB_DeviceControl(handle, kUSB_DeviceControlSuspend, param); + break; + case kUSB_DeviceStatusBusSleep: + error = USB_DeviceControl(handle, kUSB_DeviceControlSleep, param); + break; + default: + break; + } + return error; +} + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))) +/*! + * @brief Initializes the device dcd module. + * + * The function initializes the device dcd module. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceDcdInitModule(usb_device_handle handle, void *time_param) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlDcdInitModule, time_param); +} + +/*! + * @brief De-initializes the device dcd module. + * + * The function de-intializes the device dcd module. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceDcdDeinitModule(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlDcdDeinitModule, NULL); +} +#endif + +#if USB_DEVICE_CONFIG_USE_TASK +/*! + * @brief Device task function. + * + * The function is used to handle controller message. + * This function should not be called in applicartion directly. + * + * @param handle The device handle got from USB_DeviceInit. + */ +void USB_DeviceTaskFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + static usb_device_callback_message_struct_t message; + + if (deviceHandle) + { + /* Get the message from the queue */ + if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(handle->notificationQueue, (uint32_t *)&message, 0U)) + { + /* Handle the message */ + USB_DeviceNotification(handle, &message); + } + } +} +#endif + +/*! + * @brief Get dvice stack version function. + * + * The function is used to get dvice stack version. + * + * @param[out] version The version structure pointer to keep the device stack version. + * + */ +void USB_DeviceGetVersion(uint32_t *version) +{ + if (version) + { + *version = + (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX); + } +} + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) +/*! + * @brief Update the hardware tick. + * + * The function is used to update the hardware tick. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] tick Current hardware tick. + * + */ +usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick) +{ + usb_device_struct_t *deviceHandle; + usb_status_t status = kStatus_USB_Success; + + if (handle == NULL) + { + return kStatus_USB_InvalidHandle; + } + deviceHandle = (usb_device_struct_t *)handle; + + deviceHandle->hwTick = tick; + + return status; +} +#endif +#endif /* USB_DEVICE_CONFIG_NUM */ diff --git a/bsp/imxrt/libraries/drivers/usb/device/usb_device_dci.h b/bsp/imxrt/libraries/drivers/usb/device/usb_device_dci.h new file mode 100644 index 0000000000..fd4fdceb04 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/device/usb_device_dci.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __USB_DEVICE_DCI_H__ +#define __USB_DEVICE_DCI_H__ + +/*! + * @addtogroup usb_device_controller_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Macro to define controller handle */ +#define usb_device_controller_handle usb_device_handle + +/*! @brief Available notify types for device notification */ +typedef enum _usb_device_notification +{ + kUSB_DeviceNotifyBusReset = 0x10U, /*!< Reset signal detected */ + kUSB_DeviceNotifySuspend, /*!< Suspend signal detected */ + kUSB_DeviceNotifyResume, /*!< Resume signal detected */ + kUSB_DeviceNotifyLPMSleep, /*!< LPM signal detected */ + kUSB_DeviceNotifyLPMResume, /*!< Resume signal detected */ + kUSB_DeviceNotifyError, /*!< Errors happened in bus */ + kUSB_DeviceNotifyDetach, /*!< Device disconnected from a host */ + kUSB_DeviceNotifyAttach, /*!< Device connected to a host */ +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) + kUSB_DeviceNotifyDcdTimeOut, /*!< Device charger detection timeout */ + kUSB_DeviceNotifyDcdUnknownPortType, /*!< Device charger detection unknown port type */ + kUSB_DeviceNotifySDPDetected, /*!< The SDP facility is detected */ + kUSB_DeviceNotifyChargingPortDetected, /*!< The charging port is detected */ + kUSB_DeviceNotifyChargingHostDetected, /*!< The CDP facility is detected */ + kUSB_DeviceNotifyDedicatedChargerDetected, /*!< The DCP facility is detected */ +#endif +} usb_device_notification_t; + +/*! @brief Device notification message structure */ +typedef struct _usb_device_callback_message_struct +{ + uint8_t *buffer; /*!< Transferred buffer */ + uint32_t length; /*!< Transferred data length */ + uint8_t code; /*!< Notification code */ + uint8_t isSetup; /*!< Is in a setup phase */ +} usb_device_callback_message_struct_t; + +/*! @brief Control type for controller */ +typedef enum _usb_device_control_type +{ + kUSB_DeviceControlRun = 0U, /*!< Enable the device functionality */ + kUSB_DeviceControlStop, /*!< Disable the device functionality */ + kUSB_DeviceControlEndpointInit, /*!< Initialize a specified endpoint */ + kUSB_DeviceControlEndpointDeinit, /*!< De-initialize a specified endpoint */ + kUSB_DeviceControlEndpointStall, /*!< Stall a specified endpoint */ + kUSB_DeviceControlEndpointUnstall, /*!< Unstall a specified endpoint */ + kUSB_DeviceControlGetDeviceStatus, /*!< Get device status */ + kUSB_DeviceControlGetEndpointStatus, /*!< Get endpoint status */ + kUSB_DeviceControlSetDeviceAddress, /*!< Set device address */ + kUSB_DeviceControlGetSynchFrame, /*!< Get current frame */ + kUSB_DeviceControlResume, /*!< Drive controller to generate a resume signal in USB bus */ + kUSB_DeviceControlSleepResume, /*!< Drive controller to generate a LPM resume signal in USB bus */ + kUSB_DeviceControlSuspend, /*!< Drive controller to enetr into suspend mode */ + kUSB_DeviceControlSleep, /*!< Drive controller to enetr into sleep mode */ + kUSB_DeviceControlSetDefaultStatus, /*!< Set controller to default status */ + kUSB_DeviceControlGetSpeed, /*!< Get current speed */ + kUSB_DeviceControlGetOtgStatus, /*!< Get OTG status */ + kUSB_DeviceControlSetOtgStatus, /*!< Set OTG status */ + kUSB_DeviceControlSetTestMode, /*!< Drive xCHI into test mode */ + kUSB_DeviceControlGetRemoteWakeUp, /*!< Get flag of LPM Remote Wake-up Enabled by USB host. */ +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) + kUSB_DeviceControlDcdInitModule, + kUSB_DeviceControlDcdDeinitModule, +#endif +} usb_device_control_type_t; + +/*! @brief USB device controller initialization function typedef */ +typedef usb_status_t (*usb_device_controller_init_t)(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *controllerHandle); + +/*! @brief USB device controller de-initialization function typedef */ +typedef usb_status_t (*usb_device_controller_deinit_t)(usb_device_controller_handle controllerHandle); + +/*! @brief USB device controller send data function typedef */ +typedef usb_status_t (*usb_device_controller_send_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! @brief USB device controller receive data function typedef */ +typedef usb_status_t (*usb_device_controller_recv_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! @brief USB device controller cancel transfer function in a specified endpoint typedef */ +typedef usb_status_t (*usb_device_controller_cancel_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress); + +/*! @brief USB device controller control function typedef */ +typedef usb_status_t (*usb_device_controller_control_t)(usb_device_controller_handle controllerHandle, + usb_device_control_type_t command, + void *param); + +/*! @brief USB device controller interface structure */ +typedef struct _usb_device_controller_interface_struct +{ + usb_device_controller_init_t deviceInit; /*!< Controller initialization */ + usb_device_controller_deinit_t deviceDeinit; /*!< Controller de-initialization */ + usb_device_controller_send_t deviceSend; /*!< Controller send data */ + usb_device_controller_recv_t deviceRecv; /*!< Controller receive data */ + usb_device_controller_cancel_t deviceCancel; /*!< Controller cancel transfer */ + usb_device_controller_control_t deviceControl; /*!< Controller control */ +} usb_device_controller_interface_struct_t; + +/*! @brief USB device status structure */ +typedef struct _usb_device_struct +{ +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + volatile uint64_t hwTick; /*!< Current hw tick(ms)*/ +#endif + usb_device_controller_handle controllerHandle; /*!< Controller handle */ + const usb_device_controller_interface_struct_t *controllerInterface; /*!< Controller interface handle */ +#if USB_DEVICE_CONFIG_USE_TASK + usb_osa_msgq_handle notificationQueue; /*!< Message queue */ +#endif + usb_device_callback_t deviceCallback; /*!< Device callback function pointer */ + usb_device_endpoint_callback_struct_t + epCallback[USB_DEVICE_CONFIG_ENDPOINTS << 1U]; /*!< Endpoint callback function structure */ + uint8_t deviceAddress; /*!< Current device address */ + uint8_t controllerId; /*!< Controller ID */ + uint8_t state; /*!< Current device state */ +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + uint8_t remotewakeup; /*!< Remote wakeup is enabled or not */ +#endif + uint8_t isResetting; /*!< Is doing device reset or not */ +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + uint8_t epCallbackDirectly; /*!< Whether call ep callback directly when the task is enabled */ +#endif +} usb_device_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! @}*/ + +#endif /* __USB_DEVICE_DCI_H__ */ diff --git a/bsp/imxrt/libraries/drivers/usb/device/usb_device_ehci.c b/bsp/imxrt/libraries/drivers/usb/device/usb_device_ehci.c new file mode 100644 index 0000000000..dd7780c772 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/device/usb_device_ehci.c @@ -0,0 +1,1807 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "fsl_device_registers.h" +#include +#include "usb_device.h" +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) + +#include "usb_device_dci.h" + +#include "usb_device_ehci.h" +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#include "usb_phy.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U) + +#error The SOC does not suppoort dedicated RAM case. + +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static void USB_DeviceEhciSetDefaultState(usb_device_ehci_state_struct_t *ehciState); +static usb_status_t USB_DeviceEhciEndpointInit(usb_device_ehci_state_struct_t *ehciState, + usb_device_endpoint_init_struct_t *epInit); +static usb_status_t USB_DeviceEhciEndpointDeinit(usb_device_ehci_state_struct_t *ehciState, uint8_t ep); +static usb_status_t USB_DeviceEhciEndpointStall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep); +static usb_status_t USB_DeviceEhciEndpointUnstall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep); +static void USB_DeviceEhciFillSetupBuffer(usb_device_ehci_state_struct_t *ehciState, uint8_t ep); +static void USB_DeviceEhciCancelControlPipe(usb_device_ehci_state_struct_t *ehciState, + uint8_t endpoint, + uint8_t direction); +static void USB_DeviceEhciInterruptTokenDone(usb_device_ehci_state_struct_t *ehciState); +static void USB_DeviceEhciInterruptPortChange(usb_device_ehci_state_struct_t *ehciState); +static void USB_DeviceEhciInterruptReset(usb_device_ehci_state_struct_t *ehciState); +static void USB_DeviceEhciInterruptSof(usb_device_ehci_state_struct_t *ehciState); +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +static void USB_DeviceEhciInterruptSuspend(usb_device_ehci_state_struct_t *ehciState); +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ +static usb_status_t USB_DeviceEhciTransfer(usb_device_ehci_state_struct_t *ehciState, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +extern usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Apply for QH buffer, 2048-byte alignment */ +USB_RAM_ADDRESS_ALIGNMENT(2048) +USB_CONTROLLER_DATA static uint8_t qh_buffer[(USB_DEVICE_CONFIG_EHCI - 1) * 2048 + + USB_DEVICE_CONFIG_ENDPOINTS * 2 * sizeof(usb_device_ehci_qh_struct_t)]; + +/* Apply for DTD buffer, 32-byte alignment */ +USB_RAM_ADDRESS_ALIGNMENT(32) +USB_CONTROLLER_DATA static usb_device_ehci_dtd_struct_t +s_UsbDeviceEhciDtd[USB_DEVICE_CONFIG_EHCI][USB_DEVICE_CONFIG_EHCI_MAX_DTD]; + +/* Apply for ehci device state structure */ +static usb_device_ehci_state_struct_t g_UsbDeviceEhciSate[USB_DEVICE_CONFIG_EHCI]; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +/* Apply for device dcd state structure */ +static usb_device_dcd_state_struct_t s_UsbDeviceDcdHSState[USB_DEVICE_CONFIG_EHCI]; +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * @brief EHCI NC get USB NC bass address. + * + * This function is used to get USB NC bass address. + * + * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t. + * + * @retval USB NC bass address. + */ +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) +void *USB_EhciNCGetBase(uint8_t controllerId) +{ + void *usbNCBase = NULL; +#if ((defined FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + uint32_t instance; + uint32_t newinstance = 0; + uint32_t usbnc_base_temp[] = USBNC_BASE_ADDRS; + uint32_t usbnc_base[] = USBNC_BASE_ADDRS; + + if (controllerId < kUSB_ControllerEhci0) + { + return NULL; + } + + controllerId = controllerId - kUSB_ControllerEhci0; + + for (instance = 0; instance < (sizeof(usbnc_base_temp) / sizeof(usbnc_base_temp[0])); instance++) + { + if (usbnc_base_temp[instance]) + { + usbnc_base[newinstance++] = usbnc_base_temp[instance]; + } + } + if (controllerId > newinstance) + { + return NULL; + } + + usbNCBase = (void *)usbnc_base[controllerId]; +#endif + return usbNCBase; +} +#endif +#endif + +/*! + * @brief Set device controller state to default state. + * + * The function is used to set device controller state to default state. + * The function will be called when USB_DeviceEhciInit called or the control type kUSB_DeviceControlGetEndpointStatus + * received in USB_DeviceEhciControl. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciSetDefaultState(usb_device_ehci_state_struct_t *ehciState) +{ + usb_device_ehci_dtd_struct_t *p; + + /* Initialize the dtd free queue */ + ehciState->dtdFree = ehciState->dtd; + p = ehciState->dtdFree; + for (uint32_t i = 1U; i < USB_DEVICE_CONFIG_EHCI_MAX_DTD; i++) + { + p->nextDtdPointer = (uint32_t)&ehciState->dtd[i]; + p = (usb_device_ehci_dtd_struct_t *)p->nextDtdPointer; + } + p->nextDtdPointer = 0U; + ehciState->dtdCount = USB_DEVICE_CONFIG_EHCI_MAX_DTD; + + /* Not use interrupt threshold. */ + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_ITC_MASK; + ehciState->registerBase->USBCMD |= USBHS_USBCMD_ITC(0U); + + /* Disable setup lockout, please refer to "Control Endpoint Operation" section in RM. */ + ehciState->registerBase->USBMODE |= USBHS_USBMODE_SLOM_MASK; + + /* Set the endian by using CPU's endian */ +#if (ENDIANNESS == USB_BIG_ENDIAN) + ehciState->registerBase->USBMODE |= USBHS_USBMODE_ES_MASK; +#else + ehciState->registerBase->USBMODE &= ~USBHS_USBMODE_ES_MASK; +#endif + /* Initialize the QHs of endpoint. */ + for (uint32_t i = 0U; i < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); i++) + { + ehciState->qh[i].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + ehciState->qh[i].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize = + USB_CONTROL_MAX_PACKET_SIZE; + ehciState->dtdHard[i] = NULL; + ehciState->dtdTail[i] = NULL; + ehciState->qh[i].endpointStatusUnion.endpointStatusBitmap.isOpened = 0U; + } + + /* Add QH buffer address to USBHS_EPLISTADDR_REG */ + ehciState->registerBase->EPLISTADDR = (uint32_t)ehciState->qh; + + /* Clear device address */ + ehciState->registerBase->DEVICEADDR = 0U; + +#if defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U) + ehciState->registerBase->OTGSC = ehciState->registerBase->OTGSC & 0x0000FFFF; + ehciState->registerBase->OTGSC |= USBHS_OTGSC_BSVIE_MASK; +#endif /* USB_DEVICE_CONFIG_DETACH_ENABLE */ + + /* Enable reset, sof, token, stall interrupt */ + ehciState->registerBase->USBINTR = + (USBHS_USBINTR_UE_MASK | USBHS_USBINTR_UEE_MASK | USBHS_USBINTR_PCE_MASK | USBHS_USBINTR_URE_MASK +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + | USBHS_USBINTR_SLE_MASK +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + ); + + /* Clear reset flag */ + ehciState->isResetting = 0U; +} + +/*! + * @brief Initialize a specified endpoint. + * + * The function is used to initialize a specified endpoint. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param epInit The endpoint initialization structure pointer. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciEndpointInit(usb_device_ehci_state_struct_t *ehciState, + usb_device_endpoint_init_struct_t *epInit) +{ + uint32_t primeBit = 1U << ((epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK) + + ((epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U)); + uint16_t maxPacketSize = epInit->maxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK; + uint8_t endpoint = (epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK); + uint8_t direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | direction; + uint8_t transferType = epInit->transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK; + + /* Cancel pending transfer of the endpoint */ + USB_DeviceEhciCancel(ehciState, epInit->endpointAddress); + + if ((ehciState->registerBase->EPPRIME & primeBit) || (ehciState->registerBase->EPSR & primeBit)) + { + return kStatus_USB_Busy; + } + + /* Make the endpoint max packet size align with USB Specification 2.0. */ + if (USB_ENDPOINT_ISOCHRONOUS == transferType) + { + if (maxPacketSize > USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE) + { + maxPacketSize = USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE; + } + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.mult = + 1U + ((maxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK) >> + USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT); + } + else + { + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.mult = 0U; + } + + /* Save the max packet size of the endpoint */ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize = + maxPacketSize; + /* Set ZLT bit. */ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = !epInit->zlt; + + /* Enable the endpoint. */ + if (USB_ENDPOINT_CONTROL == transferType) + { + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.ios = 1U; + ehciState->registerBase->EPCR0 |= + (direction ? + (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXR_MASK | ((uint32_t)transferType << USBHS_EPCR_TXT_SHIFT)) : + (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXR_MASK | ((uint32_t)transferType << USBHS_EPCR_RXT_SHIFT))); + } + else + { + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.ios = 0U; + ehciState->registerBase->EPCR[endpoint - 1U] |= + (direction ? + (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXR_MASK | ((uint32_t)transferType << USBHS_EPCR_TXT_SHIFT)) : + (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXR_MASK | ((uint32_t)transferType << USBHS_EPCR_RXT_SHIFT))); + } + + ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened = 1U; + return kStatus_USB_Success; +} + +/*! + * @brief De-initialize a specified endpoint. + * + * The function is used to de-initialize a specified endpoint. + * Current transfer of the endpoint will be cancelled and the specified endpoint will be disabled. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciEndpointDeinit(usb_device_ehci_state_struct_t *ehciState, uint8_t ep) +{ + uint32_t primeBit = + 1U << ((ep & USB_ENDPOINT_NUMBER_MASK) + ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U)); + uint8_t endpoint = (ep & USB_ENDPOINT_NUMBER_MASK); + uint8_t direction = + (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | direction; + + ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened = 0U; + + /* Cancel the transfer of the endpoint */ + USB_DeviceEhciCancel(ehciState, ep); + + if ((ehciState->registerBase->EPPRIME & primeBit) || (ehciState->registerBase->EPSR & primeBit)) + { + return kStatus_USB_Busy; + } + + /* Clear endpoint state */ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristics = 0U; + /* Disable the endpoint */ + if (!endpoint) + { + ehciState->registerBase->EPCR0 &= + ~(direction ? (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXT_MASK) : (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXT_MASK)); + } + else + { + ehciState->registerBase->EPCR[endpoint - 1U] &= + ~(direction ? (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXT_MASK) : (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXT_MASK)); + } + + return kStatus_USB_Success; +} + +/*! + * @brief Stall a specified endpoint. + * + * The function is used to stall a specified endpoint. + * Current transfer of the endpoint will be cancelled and the specified endpoint will be stalled. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciEndpointStall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep) +{ + uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = + (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | direction; + + /* Cancel the transfer of the endpoint */ + USB_DeviceEhciCancel(ehciState, ep); + + /* Set endpoint stall flag. */ + if (ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.ios) + { + if (!endpoint) + { + ehciState->registerBase->EPCR0 |= (USBHS_EPCR_TXS_MASK | USBHS_EPCR_RXS_MASK); + } + else + { + ehciState->registerBase->EPCR[endpoint - 1U] |= (USBHS_EPCR_TXS_MASK | USBHS_EPCR_RXS_MASK); + } + } + else + { + if (!endpoint) + { + ehciState->registerBase->EPCR0 |= (direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK); + } + else + { + ehciState->registerBase->EPCR[endpoint - 1U] |= (direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK); + } + } + + return kStatus_USB_Success; +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be cancelled and the specified endpoint will be un-stalled. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciEndpointUnstall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep) +{ + uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = + (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + + /* Clear the endpoint stall state */ + if (!endpoint) + { + ehciState->registerBase->EPCR0 &= ~(direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK); + } + else + { + ehciState->registerBase->EPCR[endpoint - 1U] &= ~(direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK); + ehciState->registerBase->EPCR[endpoint - 1U] |= (direction ? USBHS_EPCR_TXR_MASK : USBHS_EPCR_RXR_MASK); + } + + return kStatus_USB_Success; +} + +/*! + * @brief Get setup packet data. + * + * The function is used to get setup packet data and copy to a backup buffer. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param ep The endpoint number. + * + */ +static void USB_DeviceEhciFillSetupBuffer(usb_device_ehci_state_struct_t *ehciState, uint8_t ep) +{ + uint8_t waitingSafelyAccess = 1U; + uint8_t index = (ep * 2U) | USB_OUT; + + /* Write 1U to clear corresponding bit in EPSETUPSR. */ + ehciState->registerBase->EPSETUPSR = 1U << ep; + + while (waitingSafelyAccess) + { + /* Set the setup tripwire bit. */ + ehciState->registerBase->USBCMD |= USBHS_USBCMD_SUTW_MASK; + + /* Copy setup packet data to backup buffer */ + ehciState->qh[index].setupBufferBack[0] = ehciState->qh[index].setupBuffer[0]; + ehciState->qh[index].setupBufferBack[1] = ehciState->qh[index].setupBuffer[1]; + + /* Read the USBCMD[SUTW] bit. If set, jump out from the while loop; if cleared continue */ + if (ehciState->registerBase->USBCMD & USBHS_USBCMD_SUTW_MASK) + { + waitingSafelyAccess = 0U; + } + } + /* Clear the setup tripwire bit */ + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_SUTW_MASK; + + /* Poll until the EPSETUPSR bit clearred */ + while (ehciState->registerBase->EPSETUPSR & (1U << ep)) + { + } +} + +/*! + * @brief Cancel the transfer of the control pipe. + * + * The function is used to cancel the transfer of the control pipe. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param endpoint The endpoint number. + * @param direction The direction of the endpoint. + * + */ +static void USB_DeviceEhciCancelControlPipe(usb_device_ehci_state_struct_t *ehciState, + uint8_t endpoint, + uint8_t direction) +{ + usb_device_ehci_dtd_struct_t *currentDtd; + uint32_t index = ((uint32_t)endpoint << 1U) + (uint32_t)direction; + usb_device_callback_message_struct_t message; + + message.buffer = NULL; + message.length = 0U; + /* Get the dtd of the control pipe */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + while (currentDtd) + { + /* Pass the transfer buffer address */ + if (NULL == message.buffer) + { + uint32_t bufferAddress = currentDtd->bufferPointerPage[0]; + message.buffer = (uint8_t *)((bufferAddress & USB_DEVICE_ECHI_DTD_PAGE_MASK) | + (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest)); + } + /* If the dtd is active, set the message length to USB_UNINITIALIZED_VAL_32. Or set the length by using finished + * length. */ + if (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE) + { + message.length = USB_UNINITIALIZED_VAL_32; + } + else + { + message.length += (currentDtd->reservedUnion.originalBufferInfo.originalBufferLength - + currentDtd->dtdTokenUnion.dtdTokenBitmap.totalBytes); + } + + /* Move the dtd head pointer to next. */ + /* If the pointer of the head equals to the tail, set the dtd queue to null. */ + if (ehciState->dtdHard[index] == ehciState->dtdTail[index]) + { + ehciState->dtdHard[index] = NULL; + ehciState->dtdTail[index] = NULL; + ehciState->qh[index].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + } + else + { + ehciState->dtdHard[index] = (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer; + } + + /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */ + if ((currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) || + (0 == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK))) + { + message.code = endpoint | (uint8_t)((uint32_t)direction << 0x07U); + message.isSetup = 0U; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + message.buffer = NULL; + message.length = 0U; + } + + /* Clear the token field of the dtd. */ + currentDtd->dtdTokenUnion.dtdToken = 0U; + /* Add the dtd to the free dtd queue. */ + currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree; + ehciState->dtdFree = currentDtd; + ehciState->dtdCount++; + + /* Get the next in-used dtd. */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + } +} + +/*! + * @brief Handle the endpoint token done interrupt. + * + * The function is used to handle the endpoint token done interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptTokenDone(usb_device_ehci_state_struct_t *ehciState) +{ + uint32_t status; + uint32_t primeBit; + usb_device_ehci_dtd_struct_t *currentDtd; + usb_device_callback_message_struct_t message; + uint8_t endpoint; + uint8_t direction; + uint8_t count; + uint8_t index; + + /* Get the EPSETUPSR to check the setup packect received in which one endpoint. */ + status = ehciState->registerBase->EPSETUPSR; + + if (status) + { + for (endpoint = 0U; endpoint < USB_DEVICE_CONFIG_ENDPOINTS; endpoint++) + { + /* Check the endpoint receive the setup packet. */ + if (status & (1U << endpoint)) + { + /* Get last setup packet */ + usb_setup_struct_t *deviceSetup = + (usb_setup_struct_t *)&ehciState->qh[(uint8_t)((uint32_t)endpoint << 1U) + USB_OUT].setupBufferBack; + + /* Check the direction of the data phase. */ + direction = (deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_IN) >> USB_REQUEST_TYPE_DIR_SHIFT; + /* Cancel the data phase transfer */ + USB_DeviceEhciCancelControlPipe(ehciState, endpoint, direction); + /* Cancel the status phase transfer */ + USB_DeviceEhciCancelControlPipe(ehciState, endpoint, 1U ^ direction); + message.code = (endpoint) | (USB_OUT << 0x07U); + message.buffer = (uint8_t *)deviceSetup; + message.length = USB_SETUP_PACKET_SIZE; + message.isSetup = 1U; + /* Fill the setup packet to the backup buffer */ + USB_DeviceEhciFillSetupBuffer(ehciState, endpoint); + /* Notify the up layer the EHCI status changed. */ + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } + } + } + /* Read the USBHS_EPCOMPLETE_REG to get the endpoint transfer done status */ + status = ehciState->registerBase->EPCOMPLETE; + /* Clear the endpoint transfer done status */ + ehciState->registerBase->EPCOMPLETE = status; + + if (status) + { + for (count = 0U; count < 32U; count++) + { + /* Check the transfer is done or not in the specified endpoint. */ + if (status & ((uint32_t)(1U << count))) + { + if (count > 15U) + { + endpoint = count - 16U; + direction = USB_IN; + } + else + { + endpoint = count; + direction = USB_OUT; + } + if (endpoint >= USB_DEVICE_CONFIG_ENDPOINTS) + { + continue; + } + index = (endpoint << 1U) + direction; + message.buffer = NULL; + message.length = 0U; + + /* Get the in-used dtd of the specified endpoint. */ + currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + while (currentDtd) + { + uint8_t isTokenDone = 0; + /* Get the in-used dtd of the specified endpoint. */ + currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + + while (currentDtd) + { + /* Don't handle the active dtd. */ + if ((currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE) || + (currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc)) + { + if ((!(currentDtd->dtdTokenUnion.dtdTokenBitmap.status & + USB_DEVICE_ECHI_DTD_STATUS_ACTIVE)) && + (currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc)) + { + isTokenDone = 1U; + } + break; + } + currentDtd = (usb_device_ehci_dtd_struct_t *)(currentDtd->nextDtdPointer & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + } + + if ((0 == isTokenDone) && (currentDtd)) + { + break; + } + + /* Get the in-used dtd of the specified endpoint. */ + currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + while (currentDtd) + { + /* Don't handle the active dtd. */ + if (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE) + { + break; + } + + /* Save the transfer buffer address */ + if (NULL == message.buffer) + { + message.buffer = + (uint8_t *)((currentDtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_MASK) | + (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest)); + } + /* Save the transferred data length */ + message.length += (currentDtd->reservedUnion.originalBufferInfo.originalBufferLength - + currentDtd->dtdTokenUnion.dtdTokenBitmap.totalBytes); + + /* Move the dtd queue head pointer to next */ + if (ehciState->dtdHard[index] == ehciState->dtdTail[index]) + { + ehciState->dtdHard[index] = NULL; + ehciState->dtdTail[index] = NULL; + ehciState->qh[index].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + } + else + { + ehciState->dtdHard[index] = + (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer; + } + + /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */ + if ((currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) || + (0 == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK))) + { + message.code = endpoint | (uint8_t)((uint32_t)direction << 0x07U); + message.isSetup = 0U; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + message.buffer = NULL; + message.length = 0U; + } + /* Clear the token field of the dtd */ + currentDtd->dtdTokenUnion.dtdToken = 0U; + currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree; + ehciState->dtdFree = currentDtd; + ehciState->dtdCount++; + /* Get the next in-used dtd */ + currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + + if ((NULL != currentDtd) && + (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE)) + { + primeBit = 1U << (endpoint + 16U * direction); + + /* Try to prime the next dtd. */ + ehciState->registerBase->EPPRIME = primeBit; + + /* Whether the endpoint transmit/receive buffer is ready or not. If not, wait for prime bit + * cleared and prime the next dtd. */ + if (!(ehciState->registerBase->EPSR & primeBit)) + { + /* Wait for the endpoint prime bit cleared by HW */ + while (ehciState->registerBase->EPPRIME & primeBit) + { + } + + /* If the endpoint transmit/receive buffer is not ready */ + if (!(ehciState->registerBase->EPSR & primeBit)) + { + /* Prime next dtd and prime the transfer */ + ehciState->qh[index].nextDtdPointer = (uint32_t)currentDtd; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + ehciState->registerBase->EPPRIME = primeBit; + } + } + } + } + } + } + } + } +} + +/*! + * @brief Handle the port status change interrupt. + * + * The function is used to handle the port status change interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptPortChange(usb_device_ehci_state_struct_t *ehciState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + + /* Whether the port is doing reset. */ + if (!(ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_PR_MASK)) + { + /* If not, update the USB speed. */ + if (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_HSP_MASK) + { + ehciState->speed = USB_SPEED_HIGH; + } + else + { + ehciState->speed = USB_SPEED_FULL; + } + + /* If the device reset flag is non-zero, notify the up layer the device reset finished. */ + if (ehciState->isResetting) + { + message.code = kUSB_DeviceNotifyBusReset; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + ehciState->isResetting = 0U; + } + } + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + if ((ehciState->isSuspending) && (!(ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_SUSP_MASK))) + { + /* Set the resume flag */ + ehciState->isSuspending = 0U; + + message.code = kUSB_DeviceNotifyResume; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ +} + +/*! + * @brief Handle the reset interrupt. + * + * The function is used to handle the reset interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptReset(usb_device_ehci_state_struct_t *ehciState) +{ + uint32_t status = 0U; + + /* Clear the setup flag */ + status = ehciState->registerBase->EPSETUPSR; + ehciState->registerBase->EPSETUPSR = status; + /* Clear the endpoint complete flag */ + status = ehciState->registerBase->EPCOMPLETE; + ehciState->registerBase->EPCOMPLETE = status; + + do + { + /* Flush the pending transfers */ + ehciState->registerBase->EPFLUSH = USBHS_EPFLUSH_FERB_MASK | USBHS_EPFLUSH_FETB_MASK; + } while (ehciState->registerBase->EPPRIME & (USBHS_EPPRIME_PERB_MASK | USBHS_EPPRIME_PETB_MASK)); + + /* Whether is the port reset. If yes, set the isResetting flag. Or, notify the up layer. */ + if (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_PR_MASK) + { + ehciState->isResetting = 1U; + } + else + { + usb_device_callback_message_struct_t message; + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyBusReset; + message.length = 0U; + message.isSetup = 0U; + + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } +} + +/*! + * @brief Handle the sof interrupt. + * + * The function is used to handle the sof interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptSof(usb_device_ehci_state_struct_t *ehciState) +{ +} + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! + * @brief Handle the suspend interrupt. + * + * The function is used to handle the suspend interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptSuspend(usb_device_ehci_state_struct_t *ehciState) +{ + /* If the port is in suspend state, notify the up layer */ + if (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_SUSP_MASK) + { +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) +#else + if (ehciState->registerPhyBase->USB1_VBUS_DET_STAT & USBPHY_USB1_VBUS_DET_STAT_VBUS_VALID_3V_MASK) +#endif + { + usb_device_callback_message_struct_t message; + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + message.code = kUSB_DeviceNotifySuspend; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } + } +} +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + +/*! + * @brief Get dtds and link to QH. + * + * The function is used to get dtds and link to QH. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param endpointAddress The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * @param buffer The memory address needed to be transferred. + * @param length Data length. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciTransfer(usb_device_ehci_state_struct_t *ehciState, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_ehci_dtd_struct_t *dtd; + usb_device_ehci_dtd_struct_t *dtdHard; + uint32_t index = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | + ((endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT); + uint32_t primeBit = 1U << ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) + + ((endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U)); + uint8_t epStatus = primeBit; + uint32_t sendLength; + uint32_t currentIndex = 0U; + uint32_t dtdRequestCount = (length + USB_DEVICE_ECHI_DTD_TOTAL_BYTES - 1U) / USB_DEVICE_ECHI_DTD_TOTAL_BYTES; + uint8_t qhIdle = 0U; + uint8_t waitingSafelyAccess = 1U; + USB_OSA_SR_ALLOC(); + + if (!ehciState) + { + return kStatus_USB_InvalidHandle; + } + + if (0U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened) + { + return kStatus_USB_Error; + } + /* Return error when ehci is doing reset */ + if (ehciState->isResetting) + { + return kStatus_USB_Error; + } + + if (!dtdRequestCount) + { + dtdRequestCount = 1U; + } + + USB_OSA_ENTER_CRITICAL(); + /* The free dtd count need to not less than the transfer requests. */ + if (dtdRequestCount > (uint32_t)ehciState->dtdCount) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; + } + + do + { + /* The transfer length need to not more than USB_DEVICE_ECHI_DTD_TOTAL_BYTES for each dtd. */ + if (length > USB_DEVICE_ECHI_DTD_TOTAL_BYTES) + { + sendLength = USB_DEVICE_ECHI_DTD_TOTAL_BYTES; + } + else + { + sendLength = length; + } + length -= sendLength; + + /* Get a free dtd */ + dtd = ehciState->dtdFree; + + ehciState->dtdFree = (usb_device_ehci_dtd_struct_t *)dtd->nextDtdPointer; + ehciState->dtdCount--; + + /* Save the dtd head when current active buffer offset is zero. */ + if (!currentIndex) + { + dtdHard = dtd; + } + + /* Set the dtd field */ + dtd->nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + dtd->dtdTokenUnion.dtdToken = 0U; + dtd->bufferPointerPage[0] = (uint32_t)(buffer + currentIndex); + dtd->bufferPointerPage[1] = + (dtd->bufferPointerPage[0] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK) & USB_DEVICE_ECHI_DTD_PAGE_MASK; + dtd->bufferPointerPage[2] = dtd->bufferPointerPage[1] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK; + dtd->bufferPointerPage[3] = dtd->bufferPointerPage[2] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK; + dtd->bufferPointerPage[4] = dtd->bufferPointerPage[3] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK; + + dtd->dtdTokenUnion.dtdTokenBitmap.totalBytes = sendLength; + + /* Save the data length needed to be transferred. */ + dtd->reservedUnion.originalBufferInfo.originalBufferLength = sendLength; + /* Save the original buffer address */ + dtd->reservedUnion.originalBufferInfo.originalBufferOffest = + dtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK; + dtd->reservedUnion.originalBufferInfo.dtdInvalid = 0U; + + /* Set the IOC field in last dtd. */ + if (!length) + { + dtd->dtdTokenUnion.dtdTokenBitmap.ioc = 1U; + } + + /* Set dtd active */ + dtd->dtdTokenUnion.dtdTokenBitmap.status = USB_DEVICE_ECHI_DTD_STATUS_ACTIVE; + + /* Move the buffer offset index */ + currentIndex += sendLength; + + /* Add dtd to the in-used dtd queue */ + if (ehciState->dtdTail[index]) + { + ehciState->dtdTail[index]->nextDtdPointer = (uint32_t)dtd; + ehciState->dtdTail[index] = dtd; + } + else + { + ehciState->dtdHard[index] = dtd; + ehciState->dtdTail[index] = dtd; + qhIdle = 1U; + } + } while (length); + + /* If the QH is not empty */ + if (!qhIdle) + { + /* If the prime bit is set, nothing need to do. */ + if (ehciState->registerBase->EPPRIME & primeBit) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + + /* To safely a dtd */ + while (waitingSafelyAccess) + { + /* set the ATDTW flag to USBHS_USBCMD_REG. */ + ehciState->registerBase->USBCMD |= USBHS_USBCMD_ATDTW_MASK; + /* Read EPSR */ + epStatus = ehciState->registerBase->EPSR; + /* Wait the ATDTW bit set */ + if (ehciState->registerBase->USBCMD & USBHS_USBCMD_ATDTW_MASK) + { + waitingSafelyAccess = 0U; + } + } + /* Clear the ATDTW bit */ + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_ATDTW_MASK; + } + + /* If QH is empty or the endpoint is not primed, need to link current dtd head to the QH. */ + /* When the endpoint is not primed if qhIdle is zero, it means the QH is empty. */ + if ((qhIdle) || (!(epStatus & primeBit))) + { + ehciState->qh[index].nextDtdPointer = (uint32_t)dtdHard; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + ehciState->registerBase->EPPRIME = primeBit; + while (!(ehciState->registerBase->EPSR & primeBit)) + { + if (ehciState->registerBase->EPCOMPLETE & primeBit) + { + break; + } + else + { + ehciState->registerBase->EPPRIME = primeBit; + } + } + } + + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +/*! + * @brief Initialize the USB device EHCI instance. + * + * This function initializes the USB device EHCI module specified by the controllerId. + * + * @param controllerId The controller id of the USB IP. Please refer to enumeration type usb_controller_index_t. + * @param handle Pointer of the device handle, used to identify the device object is belonged to. + * @param ehciHandle It is out parameter, is used to return pointer of the device EHCI handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *ehciHandle) +{ + usb_device_ehci_state_struct_t *ehciState; + uint32_t ehci_base[] = USBHS_BASE_ADDRS; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + usb_device_dcd_state_struct_t *dcdHSState; + uint32_t dcd_base[] = USBHSDCD_BASE_ADDRS; + usb_device_callback_message_struct_t message; +#endif + + if ((controllerId < kUSB_ControllerEhci0) || + ((uint32_t)(controllerId - kUSB_ControllerEhci0) >= USB_DEVICE_CONFIG_EHCI) || + ((uint32_t)(controllerId - kUSB_ControllerEhci0) >= (sizeof(ehci_base) / sizeof(uint32_t)))) + { + return kStatus_USB_ControllerNotFound; + } + + ehciState = &g_UsbDeviceEhciSate[controllerId - kUSB_ControllerEhci0]; + + ehciState->dtd = s_UsbDeviceEhciDtd[controllerId - kUSB_ControllerEhci0]; + ehciState->qh = (usb_device_ehci_qh_struct_t *)&qh_buffer[(controllerId - kUSB_ControllerEhci0) * 2048]; + + ehciState->controllerId = controllerId; + + ehciState->registerBase = (USBHS_Type *)ehci_base[controllerId - kUSB_ControllerEhci0]; +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + ehciState->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciState->registerNcBase = (USBNC_Type *)USB_EhciNCGetBase(controllerId); +#endif + +#endif + + /* Get the HW's endpoint count */ + ehciState->endpointCount = + (uint8_t)((ehciState->registerBase->DCCPARAMS & USBHS_DCCPARAMS_DEN_MASK) >> USBHS_DCCPARAMS_DEN_SHIFT); + + if (ehciState->endpointCount < USB_DEVICE_CONFIG_ENDPOINTS) + { + return kStatus_USB_Error; + } + ehciState->deviceHandle = (usb_device_struct_t *)handle; + + /* Clear the controller mode field and set to device mode. */ + ehciState->registerBase->USBMODE &= ~USBHS_USBMODE_CM_MASK; + ehciState->registerBase->USBMODE |= USBHS_USBMODE_CM(0x02U); + + /* Set the EHCI to default status. */ + USB_DeviceEhciSetDefaultState(ehciState); + *ehciHandle = (usb_device_controller_handle)ehciState; +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + dcdHSState = &s_UsbDeviceDcdHSState[controllerId - kUSB_ControllerEhci0]; + + dcdHSState->controllerId = controllerId; + + dcdHSState->dcdRegisterBase = (USBHSDCD_Type *)dcd_base[controllerId - kUSB_ControllerEhci0]; + + dcdHSState->deviceHandle = (usb_device_struct_t *)handle; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + if (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK) + { + /* Device is connected to a host. */ + message.code = kUSB_DeviceNotifyAttach; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief De-initialize the USB device EHCI instance. + * + * This function de-initializes the USB device EHCI module. + * + * @param ehciHandle Pointer of the device EHCI handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciDeinit(usb_device_controller_handle ehciHandle) +{ + usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle; + + if (!ehciHandle) + { + return kStatus_USB_InvalidHandle; + } + + /* Disable all interrupt. */ + ehciState->registerBase->USBINTR = 0U; + /* Stop the device functionality. */ + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_RS_MASK; + /* Reset the controller. */ + ehciState->registerBase->USBCMD |= USBHS_USBCMD_RST_MASK; + + return kStatus_USB_Success; +} + +/*! + * @brief Send data through a specified endpoint. + * + * This function sends data through a specified endpoint. + * + * @param ehciHandle Pointer of the device EHCI handle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceEhciSend(usb_device_controller_handle ehciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + /* Add dtd to the QH */ + return USB_DeviceEhciTransfer( + (usb_device_ehci_state_struct_t *)ehciHandle, + (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Receive data through a specified endpoint. + * + * This function Receives data through a specified endpoint. + * + * @param ehciHandle Pointer of the device EHCI handle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceEhciRecv(usb_device_controller_handle ehciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + /* Add dtd to the QH */ + return USB_DeviceEhciTransfer( + (usb_device_ehci_state_struct_t *)ehciHandle, + (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Cancel the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param ehciHandle Pointer of the device EHCI handle. + * @param ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, 0U - OUT. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciCancel(usb_device_controller_handle ehciHandle, uint8_t ep) +{ + usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle; + usb_device_callback_message_struct_t message; + usb_device_ehci_dtd_struct_t *currentDtd; + uint32_t primeBit = + 1U << ((ep & USB_ENDPOINT_NUMBER_MASK) + ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U)); + uint8_t index = + ((ep & USB_ENDPOINT_NUMBER_MASK) << 1U) | ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x07U); + + USB_OSA_SR_ALLOC(); + + if (!ehciHandle) + { + return kStatus_USB_InvalidHandle; + } + + USB_OSA_ENTER_CRITICAL(); + + message.buffer = NULL; + message.length = USB_UNINITIALIZED_VAL_32; + + /* Get the first dtd */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + + while (currentDtd) + { + currentDtd->reservedUnion.originalBufferInfo.dtdInvalid = 1U; + currentDtd = (usb_device_ehci_dtd_struct_t *)(currentDtd->nextDtdPointer & USB_DEVICE_ECHI_DTD_POINTER_MASK); + } + + /* Get the first dtd */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + while (currentDtd) + { + if (!currentDtd->reservedUnion.originalBufferInfo.dtdInvalid) + { + break; + } + else + { + if (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE) + { + /* Flush the endpoint to stop a transfer. */ + do + { + /* Set the corresponding bit(s) in the EPFLUSH register */ + ehciState->registerBase->EPFLUSH |= primeBit; + + /* Wait until all bits in the EPFLUSH register are cleared. */ + while (ehciState->registerBase->EPFLUSH & primeBit) + { + } + /* + * Read the EPSR register to ensure that for all endpoints + * commanded to be flushed, that the corresponding bits + * are now cleared. + */ + } while (ehciState->registerBase->EPSR & primeBit); + } + + /* Save the original buffer address. */ + if (NULL == message.buffer) + { + message.buffer = (uint8_t *)((currentDtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_MASK) | + (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest)); + } + + /* Remove the dtd from the dtd in-used queue. */ + if (ehciState->dtdHard[index] == ehciState->dtdTail[index]) + { + ehciState->dtdHard[index] = NULL; + ehciState->dtdTail[index] = NULL; + } + else + { + ehciState->dtdHard[index] = (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer; + } + + /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */ + if ((currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) || + (0 == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK))) + { + message.code = ep; + message.isSetup = 0U; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + message.buffer = NULL; + } + /* Clear the token field. */ + currentDtd->dtdTokenUnion.dtdToken = 0U; + /* Save the dtd to the free queue. */ + currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree; + ehciState->dtdFree = currentDtd; + ehciState->dtdCount++; + } + /* Get the next dtd. */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + } + if (!currentDtd) + { + /* Set the QH to empty. */ + ehciState->qh[index].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +/*! + * @brief Control the status of the selected item. + * + * The function is used to control the status of the selected item. + * + * @param ehciHandle Pointer of the device EHCI handle. + * @param type The selected item. Please refer to enumeration type usb_device_control_type_t. + * @param param The param type is determined by the selected item. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, usb_device_control_type_t type, void *param) +{ + usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle; + usb_status_t error = kStatus_USB_Error; + uint16_t *temp16; + uint8_t *temp8; +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + usb_device_dcd_state_struct_t *dcdHSState; + dcdHSState = + &s_UsbDeviceDcdHSState[ehciState->controllerId - kUSB_ControllerEhci0]; /*The hard code should be replaced*/ + usb_device_dcd_charging_time_t *deviceDcdTimingConfig = (usb_device_dcd_charging_time_t *)param; +#endif +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + usb_device_struct_t *deviceHandle; + uint64_t startTick; +#endif + + if (!ehciHandle) + { + return kStatus_USB_InvalidHandle; + } + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + deviceHandle = (usb_device_struct_t *)ehciState->deviceHandle; +#endif + + switch (type) + { + case kUSB_DeviceControlRun: + ehciState->registerBase->USBCMD |= USBHS_USBCMD_RS_MASK; + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlStop: + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_RS_MASK; + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlEndpointInit: + if (param) + { + error = USB_DeviceEhciEndpointInit(ehciState, (usb_device_endpoint_init_struct_t *)param); + } + break; + case kUSB_DeviceControlEndpointDeinit: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceEhciEndpointDeinit(ehciState, *temp8); + } + break; + case kUSB_DeviceControlEndpointStall: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceEhciEndpointStall(ehciState, *temp8); + } + break; + case kUSB_DeviceControlEndpointUnstall: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceEhciEndpointUnstall(ehciState, *temp8); + } + break; + case kUSB_DeviceControlGetDeviceStatus: + if (param) + { + temp16 = (uint16_t *)param; + *temp16 = (USB_DEVICE_CONFIG_SELF_POWER << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT)) +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + | (deviceHandle->remotewakeup << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT)) +#endif + ; + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetEndpointStatus: + if (param) + { + usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param; + uint8_t ep = (endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = + ((endpointStatus->endpointAddress) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + + if (ep < USB_DEVICE_CONFIG_ENDPOINTS) + { + if (ep) + { + endpointStatus->endpointStatus = (ehciState->registerBase->EPCR[ep - 1U] & + (direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK)) ? + kUSB_DeviceEndpointStateStalled : + kUSB_DeviceEndpointStateIdle; + } + else + { + endpointStatus->endpointStatus = + (ehciState->registerBase->EPCR0 & (direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK)) ? + kUSB_DeviceEndpointStateStalled : + kUSB_DeviceEndpointStateIdle; + } + error = kStatus_USB_Success; + } + } + break; + case kUSB_DeviceControlSetDeviceAddress: + if (param) + { + temp8 = (uint8_t *)param; + ehciState->registerBase->DEVICEADDR = (((uint32_t)(*temp8)) << USBHS_DEVICEADDR_USBADR_SHIFT); + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetSynchFrame: + break; +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U) + case kUSB_DeviceControlResume: +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK; +#else + ehciState->registerBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK; +#endif + ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; + ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; + startTick = deviceHandle->hwTick; + while ((deviceHandle->hwTick - startTick) < 10) + { + __ASM("nop"); + } + ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_FPR_MASK; + error = kStatus_USB_Success; + break; +#endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */ + case kUSB_DeviceControlSuspend: + ehciState->registerBase->OTGSC |= 0x007F0000U; + ehciState->registerPhyBase->PWD = 0xFFFFFFFF; + /* ehciState->registerBase->OTGCTL |= ((1U<<10) | (1U<<17) | (1U<<16)); */ + while (ehciState->registerPhyBase->CTRL & (USBPHY_CTRL_UTMI_SUSPENDM_MASK)) + { + __ASM("nop"); + } + /* ehciState->registerPhyBase->CTRL |= ((1U << 21) | (1U << 22) | (1U << 23)); */ + ehciState->registerBase->USBSTS |= USBHS_USBSTS_SRI_MASK; + ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK; +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK | USBPHY_CTRL_ENIDCHG_WKUP_MASK | + USBPHY_CTRL_ENDPDMCHG_WKUP_MASK | USBPHY_CTRL_ENIRQRESUMEDETECT_MASK; + ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK | + USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK | + USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK; + ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK; +#else + ehciState->registerBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK; +#endif + ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; + ehciState->isSuspending = 1U; + error = kStatus_USB_Success; + break; +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + case kUSB_DeviceControlSetDefaultStatus: + for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++) + { + USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_IN << 0x07U))); + USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_OUT << 0x07U))); + } + USB_DeviceEhciSetDefaultState(ehciState); + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlGetSpeed: + if (param) + { + temp8 = (uint8_t *)param; + *temp8 = ehciState->speed; + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetOtgStatus: + break; + case kUSB_DeviceControlSetOtgStatus: + break; +#if (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + case kUSB_DeviceControlSetTestMode: + if (param) + { + temp8 = (uint8_t *)param; + ehciState->registerBase->PORTSC1 |= ((uint32_t)(*temp8) << 16U); + error = kStatus_USB_Success; + } + break; +#endif +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + case kUSB_DeviceControlDcdInitModule: + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + dcdHSState->dcdRegisterBase->TIMER0 = USBDCD_TIMER0_TSEQ_INIT(deviceDcdTimingConfig->dcdSeqInitTime); + dcdHSState->dcdRegisterBase->TIMER1 = USBDCD_TIMER1_TDCD_DBNC(deviceDcdTimingConfig->dcdDbncTime); + dcdHSState->dcdRegisterBase->TIMER1 |= USBDCD_TIMER1_TVDPSRC_ON(deviceDcdTimingConfig->dcdDpSrcOnTime); + dcdHSState->dcdRegisterBase->TIMER2_BC12 = + USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD(deviceDcdTimingConfig->dcdTimeWaitAfterPrD); + dcdHSState->dcdRegisterBase->TIMER2_BC12 |= + USBDCD_TIMER2_BC12_TVDMSRC_ON(deviceDcdTimingConfig->dcdTimeDMSrcOn); + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_IE_MASK; + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_BC12_MASK; + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_START_MASK; + break; + case kUSB_DeviceControlDcdDeinitModule: + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + break; +#endif + + default: + break; + } + + return error; +} + +/*! + * @brief Handle the EHCI device interrupt. + * + * The function is used to handle the EHCI device interrupt. + * + * @param deviceHandle The device handle got from USB_DeviceInit. + * + */ +void USB_DeviceEhciIsrFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_ehci_state_struct_t *ehciState; + uint32_t status; + + if (NULL == deviceHandle) + { + return; + } + + ehciState = (usb_device_ehci_state_struct_t *)(handle->controllerHandle); + +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + + if (ehciState->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK) + { + if (ehciState->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIR_MASK) + { + ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; + ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK; + } + } + else + { + } + +#else + if (ehciState->registerBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK) + { + if (ehciState->registerBase->USBGENCTRL & (1U << 8)) + { + ehciState->registerBase->USBGENCTRL &= ~(1U << 8); + ehciState->registerBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK; + ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; + ehciState->registerBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK; + } + } + else + { + } +#endif + +#endif + +#if defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U) + if (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSVIS_MASK) + { + usb_device_callback_message_struct_t message; + + ehciState->registerBase->OTGSC |= USBHS_OTGSC_BSVIS_MASK; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + if (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK) + { + /* Device is connected to a host. */ + message.code = kUSB_DeviceNotifyAttach; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } + else + { + /* Device is disconnected from a host. */ + message.code = kUSB_DeviceNotifyDetach; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } + } +#endif /* USB_DEVICE_CONFIG_DETACH_ENABLE */ + + status = ehciState->registerBase->USBSTS; + status &= ehciState->registerBase->USBINTR; + + ehciState->registerBase->USBSTS = status; + +#if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U) + if (status & USBHS_USBSTS_UEI_MASK) + { + /* Error interrupt */ + USB_DeviceEhciInterruptError(ehciState); + } +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + + if (status & USBHS_USBSTS_URI_MASK) + { + /* Reset interrupt */ + USB_DeviceEhciInterruptReset(ehciState); + } + + if (status & USBHS_USBSTS_UI_MASK) + { + /* Token done interrupt */ + USB_DeviceEhciInterruptTokenDone(ehciState); + } + + if (status & USBHS_USBSTS_PCI_MASK) + { + /* Port status change interrupt */ + USB_DeviceEhciInterruptPortChange(ehciState); + } + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + if (status & USBHS_USBSTS_SLI_MASK) + { + /* Suspend interrupt */ + USB_DeviceEhciInterruptSuspend(ehciState); + } +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + + if (status & USBHS_USBSTS_SRI_MASK) + { + /* Sof interrupt */ + USB_DeviceEhciInterruptSof(ehciState); + } +} + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +void USB_DeviceDcdHSIsrFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_ehci_state_struct_t *ehciState; + usb_device_dcd_state_struct_t *dcdHSState; + uint32_t status; + uint32_t chargerType; + usb_device_callback_message_struct_t message; + + if (NULL == deviceHandle) + { + return; + } + + ehciState = (usb_device_ehci_state_struct_t *)(handle->controllerHandle); + + dcdHSState = &s_UsbDeviceDcdHSState[ehciState->controllerId - kUSB_ControllerEhci0]; + + status = dcdHSState->dcdRegisterBase->STATUS; + + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_IACK_MASK; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + + if (status & USBDCD_STATUS_ERR_MASK) + { + if (status & USBDCD_STATUS_TO_MASK) + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDcdTimeOut; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + else + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDcdUnknownPortType; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + } + else + { + switch (status & USBDCD_STATUS_SEQ_STAT_MASK) + { + case USBDCD_STATUS_SEQ_STAT(kUSB_DcdChargingPortDetectionCompleted): + chargerType = status & USBDCD_STATUS_SEQ_RES_MASK; + if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionStandardHost)) + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifySDPDetected; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + else if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionChargingPort)) + { + message.code = kUSB_DeviceNotifyChargingPortDetected; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + break; + case USBDCD_STATUS_SEQ_STAT(kUSB_DcdChargerTypeDetectionCompleted): + chargerType = status & USBDCD_STATUS_SEQ_RES_MASK; + if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionChargingPort)) + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyChargingHostDetected; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + else if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionDedicatedCharger)) + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDedicatedChargerDetected; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + break; + + default: + break; + } + } +} +#endif + +#endif /* USB_DEVICE_CONFIG_EHCI */ diff --git a/bsp/imxrt/libraries/drivers/usb/device/usb_device_ehci.h b/bsp/imxrt/libraries/drivers/usb/device/usb_device_ehci.h new file mode 100644 index 0000000000..869e063263 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/device/usb_device_ehci.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __USB_DEVICE_EHCI_H__ +#define __USB_DEVICE_EHCI_H__ + +#include + +/*! + * @addtogroup usb_device_controller_ehci_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief The maximum value of ISO type maximum packet size for HS in USB specification 2.0 */ +#define USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE (1024U) + +/*! @brief The maximum value of interrupt type maximum packet size for HS in USB specification 2.0 */ +#define USB_DEVICE_MAX_HS_INTERUPT_MAX_PACKET_SIZE (1024U) + +/*! @brief The maximum value of bulk type maximum packet size for HS in USB specification 2.0 */ +#define USB_DEVICE_MAX_HS_BULK_MAX_PACKET_SIZE (512U) + +/*! @brief The maximum value of control type maximum packet size for HS in USB specification 2.0 */ +#define USB_DEVICE_MAX_HS_CONTROL_MAX_PACKET_SIZE (64U) + +/*! @brief EHCI state structure */ +typedef struct _usb_device_ehci_state_struct +{ + usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object is belonged to */ + USBHS_Type *registerBase; /*!< The base address of the register */ +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + USBPHY_Type *registerPhyBase; /*!< The base address of the PHY register */ +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + USBNC_Type *registerNcBase; /*!< The base address of the USBNC register */ +#endif +#endif + usb_device_ehci_qh_struct_t *qh; /*!< The QH structure base address */ + usb_device_ehci_dtd_struct_t *dtd; /*!< The DTD structure base address */ + usb_device_ehci_dtd_struct_t *dtdFree; /*!< The idle DTD list head */ + usb_device_ehci_dtd_struct_t + *dtdHard[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< The transferring DTD list head for each endpoint */ + usb_device_ehci_dtd_struct_t + *dtdTail[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< The transferring DTD list tail for each endpoint */ + int8_t dtdCount; /*!< The idle DTD node count */ + uint8_t endpointCount; /*!< The endpoint number of EHCI */ + uint8_t isResetting; /*!< Whether a PORT reset is occurring or not */ + uint8_t controllerId; /*!< Controller ID */ + uint8_t speed; /*!< Current speed of EHCI */ + uint8_t isSuspending; /*!< Is suspending of the PORT */ +} usb_device_ehci_state_struct_t; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +typedef struct _usb_device_dcd_state_struct +{ + usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */ + USBHSDCD_Type *dcdRegisterBase; /*!< The base address of the dcd module */ + uint8_t controllerId; /*!< Controller ID */ +} usb_device_dcd_state_struct_t; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name USB device EHCI functions + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Initializes the USB device EHCI instance. + * + * This function initializes the USB device EHCI module specified by the controllerId. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t. + * @param[in] handle Pointer of the device handle used to identify the device object is belonged to. + * @param[out] ehciHandle An out parameter used to return the pointer of the device EHCI handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *ehciHandle); + +/*! + * @brief Deinitializes the USB device EHCI instance. + * + * This function deinitializes the USB device EHCI module. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciDeinit(usb_device_controller_handle ehciHandle); + +/*! + * @brief Sends data through a specified endpoint. + * + * This function sends data through a specified endpoint. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value means whether the sending request is successful or not. The transfer completion is indicated + * by the + * corresponding callback function. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is received through the + * endpoint + * callback). + */ +usb_status_t USB_DeviceEhciSend(usb_device_controller_handle ehciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Receive data through a specified endpoint. + * + * This function Receives data through a specified endpoint. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceEhciRecv(usb_device_controller_handle ehciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Cancels the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, 0U - OUT. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciCancel(usb_device_controller_handle ehciHandle, uint8_t ep); + +/*! + * @brief Controls the status of the selected item. + * + * The function is used to control the status of the selected item. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * @param[in] type The selected item. See enumeration type usb_device_control_type_t. + * @param[in,out] param The parameter type is determined by the selected item. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, + usb_device_control_type_t type, + void *param); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* __USB_DEVICE_EHCI_H__ */ diff --git a/bsp/imxrt/libraries/drivers/usb/host/usb_host.h b/bsp/imxrt/libraries/drivers/usb/host/usb_host.h new file mode 100644 index 0000000000..53be402cd3 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/host/usb_host.h @@ -0,0 +1,726 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _USB_HOST_H_ +#define _USB_HOST_H_ + +#include +#include +#include + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +struct _usb_host_transfer; /* for cross reference */ + +/*! + * @addtogroup usb_host_drv + * @{ + */ + +/*! @brief USB host class handle type define */ +typedef void *usb_host_class_handle; + +/*! @brief USB host controller handle type define */ +typedef void *usb_host_controller_handle; + +/*! @brief USB host configuration handle type define */ +typedef void *usb_host_configuration_handle; + +/*! @brief USB host interface handle type define */ +typedef void *usb_host_interface_handle; + +/*! @brief USB host pipe handle type define */ +typedef void *usb_host_pipe_handle; + +/*! @brief Event codes for device attach/detach */ +typedef enum _usb_host_event +{ + kUSB_HostEventAttach = 1U, /*!< Device is attached */ + kUSB_HostEventDetach, /*!< Device is detached */ + kUSB_HostEventEnumerationDone, /*!< Device's enumeration is done and the device is supported */ + kUSB_HostEventNotSupported, /*!< Device's enumeration is done and the device is not supported */ +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + kUSB_HostEventNotSuspended, /*!< Suspend failed */ + kUSB_HostEventSuspended, /*!< Suspend successful */ + kUSB_HostEventNotResumed, /*!< Resume failed */ + kUSB_HostEventDetectResume, /*!< Detect resume signal */ + kUSB_HostEventResumed, /*!< Resume successful */ + kUSB_HostEventL1Sleeped, /*!< L1 Sleep successful,state transition was successful (ACK) */ + kUSB_HostEventL1SleepNYET, /*!< Device was unable to enter the L1 state at this time (NYET) */ + kUSB_HostEventL1SleepNotSupport, /*!< Device does not support the L1 state (STALL) */ + kUSB_HostEventL1SleepError, /*!< Device failed to respond or an error occurred */ + kUSB_HostEventL1NotResumed, /*!< Resume failed */ + kUSB_HostEventL1DetectResume, /*!< Detect resume signal */ + kUSB_HostEventL1Resumed, /*!< Resume successful */ +#endif +} usb_host_event_t; + +/*! @brief USB host device information code */ +typedef enum _usb_host_dev_info +{ + kUSB_HostGetDeviceAddress = 1U, /*!< Device's address */ + kUSB_HostGetDeviceHubNumber, /*!< Device's first hub address */ + kUSB_HostGetDevicePortNumber, /*!< Device's first hub port number */ + kUSB_HostGetDeviceSpeed, /*!< Device's speed */ + kUSB_HostGetDeviceHSHubNumber, /*!< Device's first high-speed hub address */ + kUSB_HostGetDeviceHSHubPort, /*!< Device's first high-speed hub number */ + kUSB_HostGetDeviceLevel, /*!< Device's hub level */ + kUSB_HostGetHostHandle, /*!< Device's host handle */ + kUSB_HostGetDeviceControlPipe, /*!< Device's control pipe handle */ + kUSB_HostGetDevicePID, /*!< Device's PID */ + kUSB_HostGetDeviceVID, /*!< Device's VID */ + kUSB_HostGetHubThinkTime, /*!< Device's hub total think time */ + kUSB_HostGetDeviceConfigIndex, /*!< Device's running zero-based config index */ + kUSB_HostGetConfigurationDes, /*!< Device's configuration descriptor pointer */ + kUSB_HostGetConfigurationLength, /*!< Device's configuration descriptor pointer */ +} usb_host_dev_info_t; + +/*! + * @brief Host callback function typedef. + * + * This callback function is used to notify application device attach/detach event. + * This callback pointer is passed when initializing the host. + * + * @param deviceHandle The device handle, which indicates the attached device. + * @param configurationHandle The configuration handle contains the attached device's configuration information. + * @param event_code The callback event code; See the enumeration host_event_t. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Application handles the attached device successfully. + * @retval kStatus_USB_NotSupported Application don't support the attached device. + * @retval kStatus_USB_Error Application handles the attached device falsely. + */ +typedef usb_status_t (*host_callback_t)(usb_device_handle deviceHandle, + usb_host_configuration_handle configurationHandle, + uint32_t eventCode); + +/*! + * @brief Transfer callback function typedef. + * + * This callback function is used to notify the upper layer the result of the transfer. + * This callback pointer is passed when calling the send/receive APIs. + * + * @param param The parameter pointer, which is passed when calling the send/receive APIs. + * @param data The data buffer pointer. + * @param data_len The result data length. + * @param status A USB error code or kStatus_USB_Success. + */ +typedef void (*transfer_callback_t)(void *param, uint8_t *data, uint32_t dataLen, usb_status_t status); + +/*! + * @brief Host stack inner transfer callback function typedef. + * + * This callback function is used to notify the upper layer the result of a transfer. + * This callback pointer is passed when initializing the structure usb_host_transfer_t. + * + * @param param The parameter pointer, which is passed when calling the send/receive APIs. + * @param transfer The transfer information; See the structure usb_host_transfer_t. + * @param status A USB error code or kStatus_USB_Success. + */ +typedef void (*host_inner_transfer_callback_t)(void *param, struct _usb_host_transfer *transfer, usb_status_t status); + +/*! @brief USB host endpoint information structure */ +typedef struct _usb_host_ep +{ + usb_descriptor_endpoint_t *epDesc; /*!< Endpoint descriptor pointer*/ + uint8_t *epExtension; /*!< Endpoint extended descriptor pointer*/ + uint16_t epExtensionLength; /*!< Extended descriptor length*/ +} usb_host_ep_t; + +/*! @brief USB host interface information structure */ +typedef struct _usb_host_interface +{ + usb_host_ep_t epList[USB_HOST_CONFIG_INTERFACE_MAX_EP]; /*!< Endpoint array*/ + usb_descriptor_interface_t *interfaceDesc; /*!< Interface descriptor pointer*/ + uint8_t *interfaceExtension; /*!< Interface extended descriptor pointer*/ + uint16_t interfaceExtensionLength; /*!< Extended descriptor length*/ + uint8_t interfaceIndex; /*!< The interface index*/ + uint8_t alternateSettingNumber; /*!< The interface alternate setting value*/ + uint8_t epCount; /*!< Interface's endpoint number*/ +} usb_host_interface_t; + +/*! @brief USB host configuration information structure */ +typedef struct _usb_host_configuration +{ + usb_host_interface_t interfaceList[USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE]; /*!< Interface array*/ + usb_descriptor_configuration_t *configurationDesc; /*!< Configuration descriptor pointer*/ + uint8_t *configurationExtension; /*!< Configuration extended descriptor pointer*/ + uint16_t configurationExtensionLength; /*!< Extended descriptor length*/ + uint8_t interfaceCount; /*!< The configuration's interface number*/ +} usb_host_configuration_t; + +/*! @brief USB host pipe common structure */ +typedef struct _usb_host_pipe +{ + struct _usb_host_pipe *next; /*!< Link the idle pipes*/ + usb_device_handle deviceHandle; /*!< This pipe's device's handle*/ + uint16_t currentCount; /*!< For KHCI transfer*/ + uint16_t nakCount; /*!< Maximum NAK count*/ + uint16_t maxPacketSize; /*!< Maximum packet size*/ + uint16_t interval; /*!< FS/LS: frame unit; HS: micro-frame unit*/ + uint8_t open; /*!< 0 - closed, 1 - open*/ + uint8_t nextdata01; /*!< Data toggle*/ + uint8_t endpointAddress; /*!< Endpoint address*/ + uint8_t direction; /*!< Pipe direction*/ + uint8_t pipeType; /*!< Pipe type, for example USB_ENDPOINT_BULK*/ + uint8_t numberPerUframe; /*!< Transaction number per micro-frame*/ +} usb_host_pipe_t; + +/*! @brief USB host transfer structure */ +typedef struct _usb_host_transfer +{ + struct _usb_host_transfer *next; /*!< The next transfer structure*/ + uint8_t *transferBuffer; /*!< Transfer data buffer*/ + uint32_t transferLength; /*!< Transfer data length*/ + uint32_t transferSofar; /*!< Length transferred so far*/ + host_inner_transfer_callback_t callbackFn; /*!< Transfer callback function*/ + void *callbackParam; /*!< Transfer callback parameter*/ + usb_host_pipe_t *transferPipe; /*!< Transfer pipe pointer*/ + usb_setup_struct_t *setupPacket; /*!< Set up packet buffer*/ + uint8_t direction; /*!< Transfer direction; it's values are USB_OUT or USB_IN*/ + uint8_t setupStatus; /*!< Set up the transfer status*/ + union + { + uint32_t unitHead; /*!< xTD head for this transfer*/ + int32_t transferResult; /*!< KHCI transfer result */ + } union1; + + union + { + uint32_t unitTail; /*! 0U)) +/*! + * @brief Send a bus or device suspend request. + * + * This function is used to send a bus or device suspend request. + * + * @param[in] hostHandle The host handle. + * @param[in] deviceHandle The device handle. + * + * @retval kStatus_USB_Success Request successfully. + * @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Error There is no idle transfer. + * Or, the deviceHandle is invalid. + * Or, the request is invalid. + */ +extern usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle); + +/*! + * @brief Send a bus or device resume request. + * + * This function is used to send a bus or device resume request. + * + * @param[in] hostHandle The host handle. + * @param[in] deviceHandle The device handle. + * + * @retval kStatus_USB_Success Request successfully. + * @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Error There is no idle transfer. + * Or, the deviceHandle is invalid. + * Or, the request is invalid. + */ +extern usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle); +#if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U)) +/*! + * @brief Send a bus or device suspend request. + * + * This function is used to send a bus or device suspend request. + * + * @param[in] hostHandle The host handle. + * @param[in] deviceHandle The device handle. + *@param[in] sleeptype Bus suspend or single device suspend. + * + * @retval kStatus_USB_Success Request successfully. + * @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Error There is no idle transfer. + * Or, the deviceHandle is invalid. + * Or, the request is invalid. + */ +extern usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle, + usb_device_handle deviceHandle, + uint8_t sleeptype); + +/*! + * @brief Send a bus or device resume request. + * + * This function is used to send a bus or device resume request. + * + * @param[in] hostHandle The host handle. + * @param[in] deviceHandle The device handle. + * *@param[in] sleeptype Bus suspend or single device suspend. + * + * @retval kStatus_USB_Success Request successfully. + * @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Error There is no idle transfer. + * Or, the deviceHandle is invalid. + * Or, the request is invalid. + */ +extern usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle, + usb_device_handle deviceHandle, + uint8_t sleepType); +/*! + * @brief Update the lpm param. + * + * The function is used to configuure the lpm token. + * + * @param[in] hostHandle The host handle. + * @param[in] lpmParam HIRD vaule and whether enable remotewakeup. + * + */ +extern usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam); +#endif +/*! + * @brief Update the hardware tick. + * + * The function is used to update the hardware tick. + * + * @param[in] hostHandle The host handle. + * @param[in] tick Current hardware tick(uint is ms). + * + */ +extern usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t tick); + +#endif + +/*! @}*/ + +#ifdef __cplusplus +} +#endif + +/*! @}*/ + +#endif /* _USB_HOST_H_ */ diff --git a/bsp/imxrt/libraries/drivers/usb/host/usb_host_devices.c b/bsp/imxrt/libraries/drivers/usb/host/usb_host_devices.c new file mode 100644 index 0000000000..42b16e071e --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/host/usb_host_devices.c @@ -0,0 +1,1414 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "usb_host.h" +#include "usb_host_hci.h" +#include "usb_host_devices.h" + +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) +#include "usb_host_hub.h" +#endif /* USB_HOST_CONFIG_HUB */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief enumeration transfer callback function. + * + * @param param callback parameter. + * @param transfer the transfer. + * @param status transfer result status. + */ +static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status); + +/*! + * @brief process the new step state. + * + * @param deviceInstance device instance pointer. + * + * @return kStatus_USB_Success or error codes + */ +static usb_status_t USB_HostProcessState(usb_host_device_instance_t *deviceInstance); + +/*! + * @brief process the previous step transfer result. + * + * @param deviceInstance device instance pointer. + * + * @return kStatus_USB_Success or error codes + */ +static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance); + +/*! + * @brief notify the application event, the callback is registered when initializing host. + * + * @param deviceInstance device instance pointer. + * @param eventCode event code. + * + * @return kStatus_USB_Success or error codes + */ +static usb_status_t USB_HostNotifyDevice(usb_host_device_instance_t *deviceInstance, uint32_t eventCode); + +/*! + * @brief allocate one address. + * + * @param hostInstance host instance pointer. + * + * @return address, 0 is invalid. + */ +static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance); + +/*! + * @brief release one address. + * + * @param hostInstance host instance pointer. + * @param address releasing address. + */ +static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address); + +/*! + * @brief release device resource. + * + * @param hostInstance host instance pointer. + * @param deviceInstance device instance pointer. + */ +static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance, + usb_host_device_instance_t *deviceInstance); + +/*! + * @brief parse device configuration descriptor. + * + * @param deviceHandle device handle. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle); + +/*! + * @brief remove device instance from host device list. + * + * @param hostHandle host instance handle. + * @param deviceHandle device handle. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle); + +/*! + * @brief control the bus. + * + * This function control the host bus. + * + * @param[in] hostHandle the host handle. + * @param[in] controlType the control code, please reference to bus_event_t. + * + * @retval kStatus_USB_Success control successfully. + * @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer. + */ +static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType); + +extern usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance, + usb_host_transfer_t *transfer, + void *param); +extern usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance, + usb_host_transfer_t *transfer, + void *param); +extern usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance, + usb_host_transfer_t *transfer, + uint8_t *buffer, + uint32_t bufferLen); + +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + +extern usb_status_t USB_HostHubDeviceEvent(usb_host_handle hostHandle, + usb_device_handle deviceHandle, + usb_host_configuration_handle configurationHandle, + uint32_t eventCode); + +extern uint32_t USB_HostHubGetHsHubNumber(usb_host_handle hostHandle, uint8_t parentHubNo); + +extern uint32_t USB_HostHubGetHsHubPort(usb_host_handle hostHandle, uint8_t parentHubNo, uint8_t parentPortNo); + +extern usb_status_t USB_HostHubRemovePort(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber); + +#endif + +/******************************************************************************* + * Variables + ******************************************************************************/ + +extern usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST]; + +/*! @brief enumeration step process array */ +static const usb_host_enum_process_entry_t s_EnumEntries[] = \ +{ + /* kStatus_dev_initial */ + { + 0, 0, NULL, + }, + /* kStatus_DEV_GetDes8 */ + { + kStatus_DEV_SetAddress, kStatus_DEV_GetDes8, USB_HostProcessCallback, + }, + /* kStatus_DEV_SetAddress */ + { + kStatus_DEV_GetDes, kStatus_DEV_SetAddress, USB_HostProcessCallback, + }, + /* kStatus_DEV_GetDes */ + { + kStatus_DEV_GetCfg9, kStatus_DEV_GetDes, NULL, + }, + /* kStatus_DEV_GetCfg9 */ + { + kStatus_DEV_GetCfg, kStatus_DEV_GetCfg9, USB_HostProcessCallback, + }, + /* kStatus_DEV_GetCfg */ + { + kStatus_DEV_SetCfg, kStatus_DEV_GetCfg9, USB_HostProcessCallback, + }, + /* kStatus_DEV_SetCfg */ + { + kStatus_DEV_EnumDone, kStatus_DEV_SetCfg, NULL, + }, +}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status) +{ + uint8_t nextStep = 0; + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)param; + + USB_HostFreeTransfer(deviceInstance->hostHandle, transfer); /* free transfer */ + + if (status == kStatus_USB_Success) + { + nextStep = 1; + } + else if (status == kStatus_USB_TransferStall) + { +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) + usb_echo("no response from device\r\n"); +#endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */ + if (deviceInstance->stallRetries > 0) /* retry same transfer when stall */ + { + deviceInstance->stallRetries--; + } + else /* process next state when all retries stall */ + { + nextStep = 1; + } + } + else if (status == kStatus_USB_TransferCancel) + { + return; + } + else + { + if (deviceInstance->enumRetries > 0) /* next whole retry */ + { + deviceInstance->enumRetries--; + deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES; + deviceInstance->configurationValue = 0; + deviceInstance->state = kStatus_DEV_GetDes8; + } + else + { +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) + usb_echo("Device No Response\r\n"); +#endif + return; + } + } + + if (nextStep == 1) + { + deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES; + if (s_EnumEntries[deviceInstance->state - 1].process == NULL) + { + deviceInstance->state = s_EnumEntries[deviceInstance->state - 1].successState; /* next state */ + } + else + { + status = s_EnumEntries[deviceInstance->state - 1].process( + deviceInstance); /* process the previous state result */ + if (status == kStatus_USB_Success) /* process success */ + { + deviceInstance->state = s_EnumEntries[deviceInstance->state - 1].successState; + } + else if (status == kStatus_USB_Retry) /* need retry */ + { + deviceInstance->state = s_EnumEntries[deviceInstance->state - 1].retryState; + } + else if (status == kStatus_USB_NotSupported) /* device don't suport by the application */ + { + return; /* unrecoverable fail */ + } + else /* process error, next retry */ + { + if (deviceInstance->enumRetries > 0) /* next whole retry */ + { + deviceInstance->enumRetries--; + deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES; + deviceInstance->configurationValue = 0; + deviceInstance->state = kStatus_DEV_GetDes8; + } + else + { +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) + usb_echo("Device No Response\r\n"); +#endif + return; /* unrecoverable fail */ + } + } + } + } + + if (USB_HostProcessState(deviceInstance) != kStatus_USB_Success) /* process the new state */ + { +#ifdef HOST_ECHO + usb_echo("enumation setup error\r\n"); +#endif + return; + } +} + +static usb_status_t USB_HostProcessState(usb_host_device_instance_t *deviceInstance) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_process_descriptor_param_t getDescriptorParam; + usb_host_transfer_t *transfer; + + /* malloc transfer */ + if (deviceInstance->state != kStatus_DEV_EnumDone) + { + if (USB_HostMallocTransfer(deviceInstance->hostHandle, &transfer) != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("error to get transfer\r\n"); +#endif + return kStatus_USB_Error; + } + transfer->callbackFn = USB_HostEnumerationTransferCallback; + transfer->callbackParam = deviceInstance; + + /* reset transfer fields */ + transfer->setupPacket->bmRequestType = 0x00; + transfer->setupPacket->wIndex = 0; + transfer->setupPacket->wLength = 0; + transfer->setupPacket->wValue = 0; + } + + switch (deviceInstance->state) + { + case kStatus_DEV_GetDes8: + case kStatus_DEV_GetDes: /* get descriptor state */ + getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t); + if (deviceInstance->state == kStatus_DEV_GetDes8) + { + getDescriptorParam.descriptorLength = 8; + } + getDescriptorParam.descriptorBuffer = (uint8_t *)deviceInstance->deviceDescriptor; + getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE; + getDescriptorParam.descriptorIndex = 0; + getDescriptorParam.languageId = 0; + + transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN; + transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR; + status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam); + break; + case kStatus_DEV_SetAddress: /* set address state */ + transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_ADDRESS; + status = USB_HostStandardSetAddress(deviceInstance, transfer, &deviceInstance->allocatedAddress); + break; + + case kStatus_DEV_GetCfg9: /* get 9 bytes configuration state */ + getDescriptorParam.descriptorBuffer = deviceInstance->enumBuffer; + getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_CONFIGURE; + getDescriptorParam.descriptorIndex = deviceInstance->configurationValue; + getDescriptorParam.descriptorLength = 9; + getDescriptorParam.languageId = 0; + + transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN; + transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR; + status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam); + break; + + case kStatus_DEV_GetCfg: /* get configuration state */ + getDescriptorParam.descriptorBuffer = deviceInstance->configurationDesc; + getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_CONFIGURE; + getDescriptorParam.descriptorIndex = deviceInstance->configurationValue; + getDescriptorParam.descriptorLength = deviceInstance->configurationLen; + getDescriptorParam.languageId = 0; + + transfer->setupPacket->bmRequestType |= USB_REQUEST_TYPE_DIR_IN; + transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR; + status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam); + break; + + case kStatus_DEV_SetCfg: /* set configuration state */ + transfer->setupPacket->wValue = + USB_SHORT_TO_LITTLE_ENDIAN(deviceInstance->configuration.configurationDesc->bConfigurationValue); + transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_CONFIGURATION; + status = USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0); + break; + + case kStatus_DEV_EnumDone: /* enumeration done state */ + status = USB_HostNotifyDevice(deviceInstance, + kUSB_HostEventEnumerationDone); /* notify device enumeration done */ + if (status == kStatus_USB_Success) + { + deviceInstance->state = kStatus_DEV_AppUsed; + } + break; + + default: + break; + } + + return status; +} + +static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance) +{ + usb_host_pipe_t *pipe = (usb_host_pipe_t *)deviceInstance->controlPipe; + usb_status_t status = kStatus_USB_Success; + usb_descriptor_configuration_t *configureDesc; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle; + + switch (deviceInstance->state) + { + case kStatus_DEV_GetDes8: /* process get 8 bytes descriptor result */ + pipe->maxPacketSize = deviceInstance->deviceDescriptor->bMaxPacketSize0; + hostInstance->controllerTable->controllerIoctl( + hostInstance->controllerHandle, kUSB_HostUpdateControlPacketSize, deviceInstance->controlPipe); + break; + + case kStatus_DEV_SetAddress: /* process set address result */ + deviceInstance->setAddress = deviceInstance->allocatedAddress; + hostInstance->controllerTable->controllerIoctl( + hostInstance->controllerHandle, kUSB_HostUpdateControlEndpointAddress, deviceInstance->controlPipe); + break; + + case kStatus_DEV_GetDes: /* process set address result */ + /* NULL */ + break; + + case kStatus_DEV_GetCfg9: /* process get 9 bytes configuration result */ + configureDesc = (usb_descriptor_configuration_t *)&deviceInstance->enumBuffer[0]; + + deviceInstance->configurationLen = USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(configureDesc->wTotalLength); + if (deviceInstance->configurationDesc != NULL) + { +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + SDK_Free(deviceInstance->configurationDesc); +#else + USB_OsaMemoryFree(deviceInstance->configurationDesc); +#endif + deviceInstance->configurationDesc = NULL; + } + /* for KHCI, the start address and the length should be 4 byte align */ + if ((deviceInstance->configurationLen & 0x03) != 0) + { +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + deviceInstance->configurationDesc = + (uint8_t *)SDK_Malloc((deviceInstance->configurationLen & 0xFFFFFFFCu) + 4, USB_CACHE_LINESIZE); +#else + deviceInstance->configurationDesc = + (uint8_t *)USB_OsaMemoryAllocate((deviceInstance->configurationLen & 0xFFFFFFFCu) + 4); +#endif + } + else + { +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + deviceInstance->configurationDesc = + (uint8_t *)SDK_Malloc(deviceInstance->configurationLen, USB_CACHE_LINESIZE); +#else + deviceInstance->configurationDesc = (uint8_t *)USB_OsaMemoryAllocate(deviceInstance->configurationLen); +#endif + } + if (deviceInstance->configurationDesc == NULL) + { + return kStatus_USB_Error; + } + break; + + case kStatus_DEV_GetCfg: /* process get cofiguration result */ + if (((usb_descriptor_configuration_t *)deviceInstance->configurationDesc)->bMaxPower > + USB_HOST_CONFIG_MAX_POWER) + { + return kStatus_USB_Error; + } + deviceInstance->configurationValue++; + if (USB_HostParseDeviceConfigurationDescriptor(deviceInstance) != + kStatus_USB_Success) /* parse configuration descriptor */ + { + return kStatus_USB_Error; + } + + status = USB_HostNotifyDevice(deviceInstance, kUSB_HostEventAttach); + + if (status != kStatus_USB_Success) + { + /* next configuration */ + if (deviceInstance->configurationValue < deviceInstance->deviceDescriptor->bNumConfigurations) + { + return kStatus_USB_Retry; + } + else + { + USB_HostNotifyDevice(deviceInstance, + kUSB_HostEventNotSupported); /* notify application device is not supported */ + return kStatus_USB_NotSupported; + } + } + break; + + case kStatus_DEV_SetCfg: + /* NULL */ + break; + + default: + break; + } + + return status; +} + +static usb_status_t USB_HostNotifyDevice(usb_host_device_instance_t *deviceInstance, uint32_t eventCode) +{ + usb_host_instance_t *hostInstance; + usb_status_t status1 = kStatus_USB_Error; +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + usb_status_t status2 = kStatus_USB_Error; + uint8_t haveHub; + uint8_t haveNoHub; + uint8_t interfaceIndex; +#endif /* USB_HOST_CONFIG_HUB */ + + if (deviceInstance == NULL) + { + return kStatus_USB_InvalidHandle; + } + hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle; + +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + haveHub = 0; + haveNoHub = 0; + for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex) + { + if (((usb_descriptor_interface_t *)deviceInstance->configuration.interfaceList[interfaceIndex].interfaceDesc) + ->bInterfaceClass == USB_HOST_HUB_CLASS_CODE) + { + haveHub = 1; + } + else + { + haveNoHub = 1; + } + } + + if ((haveNoHub == 1) && (hostInstance->deviceCallback != NULL)) + { + status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, + eventCode); /* notify application event */ + } + if (haveHub) + { + status2 = USB_HostHubDeviceEvent(hostInstance, deviceInstance, &deviceInstance->configuration, + eventCode); /* notify hub event */ + } + + if ((status1 == kStatus_USB_Success) || (status2 == kStatus_USB_Success)) /* the device is supported */ + { + return kStatus_USB_Success; + } + else if (eventCode == kUSB_HostEventAttach) /* attach event */ + { + status1 = kStatus_USB_NotSupported; + } + else + { + status1 = kStatus_USB_Error; + } +#else + if (hostInstance->deviceCallback != NULL) + { + status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration, + eventCode); /* call host callback function */ + } +#endif + return status1; +} + +static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance) +{ + uint8_t address = 0; + uint8_t addressIndex; + uint8_t addressBitIndex; + for (addressIndex = 0; addressIndex < 8; ++addressIndex) /* find the idle address postion byte */ + { + if (hostInstance->addressBitMap[addressIndex] != 0xFF) + { + break; + } + } + if (addressIndex < 8) + { + for (addressBitIndex = 0; addressBitIndex < 8; ++addressBitIndex) /* find the idle address position bit */ + { + if (!(hostInstance->addressBitMap[addressIndex] & (0x01u << addressBitIndex))) + { + hostInstance->addressBitMap[addressIndex] |= (0x01u << addressBitIndex); /* set the allocated bit */ + address = addressIndex * 8 + addressBitIndex + 1; /* the address minimum is 1 */ + break; + } + } + } + return address; +} + +static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address) +{ + USB_HostLock(); + hostInstance->addressBitMap[(uint32_t)(address - 1) >> 3] &= + (~(0x01u << (((uint32_t)address - 1) & 0x07U))); /* reset the allocated bit */ + USB_HostUnlock(); +} + +static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle) +{ + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + usb_host_device_instance_t *currentInstance; + usb_host_device_instance_t *prevInstance; + if ((hostHandle == NULL) || (deviceHandle == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + /* search and remove device instance */ + prevInstance = (usb_host_device_instance_t *)hostInstance->deviceList; + if (prevInstance == deviceHandle) + { + hostInstance->deviceList = prevInstance->next; + return kStatus_USB_Success; + } + else + { + currentInstance = prevInstance->next; + } + + while (currentInstance != NULL) + { + if (currentInstance == deviceHandle) + { + prevInstance->next = currentInstance->next; + return kStatus_USB_Success; + } + prevInstance = currentInstance; + currentInstance = currentInstance->next; + } + + return kStatus_USB_Success; +} + +static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance, usb_host_device_instance_t *deviceInstance) +{ +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + uint8_t level = 0; +#endif + +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + if (deviceInstance == hostInstance->suspendedDevice) + { + hostInstance->suspendedDevice = NULL; + } +#endif + /* release device's address */ + if (deviceInstance->setAddress != 0) + { + USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->setAddress); + } + else + { + if (deviceInstance->allocatedAddress != 0) + { + USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->allocatedAddress); + } + } + + /* close control pipe */ + if (deviceInstance->controlPipe != NULL) + { + USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL); + if (USB_HostClosePipe(hostInstance, deviceInstance->controlPipe) != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("error when close pipe\r\n"); +#endif + } + deviceInstance->controlPipe = NULL; + } + + /* free configuration buffer */ + if (deviceInstance->configurationDesc != NULL) + { +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + SDK_Free(deviceInstance->configurationDesc); +#else + USB_OsaMemoryFree(deviceInstance->configurationDesc); +#endif + } + +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + level = deviceInstance->level; +#endif +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + SDK_Free(deviceInstance->deviceDescriptor); +#else + USB_OsaMemoryFree(deviceInstance->deviceDescriptor); +#endif + /* free device instance buffer */ + USB_OsaMemoryFree(deviceInstance); + +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + /* enable controller attach if root hub */ + if (level == 1) + { + USB_HostControlBus(hostInstance, kUSB_HostBusEnableAttach); + } +#else + /* enable controller attach */ + USB_HostControlBus(hostInstance, kUSB_HostBusEnableAttach); +#endif +} + +static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle) +{ + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + uint32_t endPos; + usb_descriptor_union_t *unionDes; + usb_host_interface_t *interfaceParse = NULL; + usb_host_ep_t *epParse; + uint8_t *buffer; + + if (deviceHandle == NULL) + { + return kStatus_USB_InvalidParameter; + } + + buffer = (uint8_t *)&deviceInstance->configuration; + /* clear the previous parse result, note: end_pos means buffer index here*/ + for (endPos = 0; endPos < sizeof(usb_host_configuration_t); endPos++) + { + buffer[endPos] = 0; + } + for (endPos = 0; endPos < USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE; ++endPos) + { + deviceInstance->interfaceStatus[endPos] = 0; + } + + /* parse configuration descriptor */ + unionDes = (usb_descriptor_union_t *)deviceInstance->configurationDesc; + endPos = (uint32_t)(deviceInstance->configurationDesc + deviceInstance->configurationLen); + + if ((unionDes->common.bLength == USB_DESCRIPTOR_LENGTH_CONFIGURE) && + (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_CONFIGURE)) + { + /* configuration descriptor */ + deviceInstance->configuration.configurationDesc = (usb_descriptor_configuration_t *)unionDes; + deviceInstance->configuration.configurationExtensionLength = 0; + deviceInstance->configuration.configurationExtension = NULL; + deviceInstance->configuration.interfaceCount = 0; + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + while ((uint32_t)unionDes < endPos) + { + if (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) + { + if (deviceInstance->configuration.configurationExtension == NULL) + { + deviceInstance->configuration.configurationExtension = (uint8_t *)unionDes; + } + if ((unionDes->common.bDescriptorType == 0x00) || + (unionDes->common.bLength == 0x00)) /* the descriptor data is wrong */ + { + return kStatus_USB_Error; + } + deviceInstance->configuration.configurationExtensionLength += unionDes->common.bLength; + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + } + else + { + break; + } + } + + /* interface descriptor */ + deviceInstance->configuration.interfaceCount = 0; + while ((uint32_t)unionDes < endPos) + { + if (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE) + { + if (unionDes->interface.bAlternateSetting == 0x00) + { + if (deviceInstance->configuration.interfaceCount >= USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE) + { +#ifdef HOST_ECHO + usb_echo( + "Unsupported Device attached\r\n too many interfaces in one configuration, please increase " + "the USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE value\n"); +#endif + return kStatus_USB_Error; + } + interfaceParse = + &deviceInstance->configuration.interfaceList[deviceInstance->configuration.interfaceCount]; + deviceInstance->configuration.interfaceCount++; + interfaceParse->alternateSettingNumber = 0; + interfaceParse->epCount = 0; + interfaceParse->interfaceDesc = &unionDes->interface; + interfaceParse->interfaceExtensionLength = 0; + interfaceParse->interfaceExtension = NULL; + interfaceParse->interfaceIndex = unionDes->interface.bInterfaceNumber; + if (unionDes->common.bLength == 0x00) /* the descriptor data is wrong */ + { + return kStatus_USB_Error; + } + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + while ((uint32_t)unionDes < endPos) + { + if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) && + (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT)) + { + if (interfaceParse->interfaceExtension == NULL) + { + interfaceParse->interfaceExtension = (uint8_t *)unionDes; + } + if ((unionDes->common.bDescriptorType == 0x00) || + (unionDes->common.bLength == 0x00)) /* the descriptor data is wrong */ + { + return kStatus_USB_Error; + } + interfaceParse->interfaceExtensionLength += unionDes->common.bLength; + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + } + else + { + break; + } + } + + /* endpoint descriptor */ + if (interfaceParse->interfaceDesc->bNumEndpoints != 0) + { + if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) || + (interfaceParse->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP)) + { +#ifdef HOST_ECHO + usb_echo("interface descriptor error\n"); +#endif + return kStatus_USB_Error; + } + for (; interfaceParse->epCount < interfaceParse->interfaceDesc->bNumEndpoints; + (interfaceParse->epCount)++) + { + if (((uint32_t)unionDes >= endPos) || + (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT)) + { +#ifdef HOST_ECHO + usb_echo("endpoint descriptor error\n"); +#endif + return kStatus_USB_Error; + } + epParse = (usb_host_ep_t *)&interfaceParse->epList[interfaceParse->epCount]; + epParse->epDesc = (usb_descriptor_endpoint_t *)unionDes; + epParse->epExtensionLength = 0; + epParse->epExtension = NULL; + if (unionDes->common.bLength == 0x00) /* the descriptor data is wrong */ + { + return kStatus_USB_Error; + } + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + while ((uint32_t)unionDes < endPos) + { + if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) && + (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE)) + { + if (epParse->epExtension == NULL) + { + epParse->epExtension = (uint8_t *)unionDes; + } + if ((unionDes->common.bDescriptorType == 0x00) || + (unionDes->common.bLength == 0x00)) /* the descriptor data is wrong */ + { + return kStatus_USB_Error; + } + epParse->epExtensionLength += unionDes->common.bLength; + unionDes = + (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + } + else + { + break; + } + } + } + } + } + else + { + if (interfaceParse == NULL) + { + return kStatus_USB_Error; /* in normal situation this cannot reach */ + } + interfaceParse->alternateSettingNumber++; + if (interfaceParse->interfaceExtension == NULL) + { + interfaceParse->interfaceExtension = (uint8_t *)unionDes; + } + if (unionDes->common.bLength == 0x00) /* the descriptor data is wrong */ + { + return kStatus_USB_Error; + } + interfaceParse->interfaceExtensionLength += unionDes->common.bLength; + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + while ((uint32_t)unionDes < endPos) + { + if (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) + { + if ((unionDes->common.bDescriptorType == 0x00) || + (unionDes->common.bLength == 0x00)) /* the descriptor data is wrong */ + { + return kStatus_USB_Error; + } + interfaceParse->interfaceExtensionLength += unionDes->common.bLength; + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + } + else + { + break; + } + } + } + } + else + { + return kStatus_USB_Error; + } + } + } + + for (endPos = 0; endPos < deviceInstance->configuration.interfaceCount; ++endPos) + { + deviceInstance->interfaceStatus[endPos] = kStatus_interface_Attached; + } + + return kStatus_USB_Success; +} + +usb_status_t USB_HostAttachDevice(usb_host_handle hostHandle, + uint8_t speed, + uint8_t hubNumber, + uint8_t portNumber, + uint8_t level, + usb_device_handle *deviceHandle) +{ + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + usb_host_device_instance_t *newInstance; +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + usb_host_device_instance_t *currentInstance; +#endif + uint8_t address; + usb_host_pipe_init_t pipeInit; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + +/* check whether is the device attached? */ +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + currentInstance = (usb_host_device_instance_t *)hostInstance->deviceList; + while (currentInstance != NULL) + { + if ((currentInstance->hubNumber == hubNumber) && (currentInstance->portNumber == portNumber)) + { + *deviceHandle = NULL; +#ifdef HOST_ECHO + usb_echo("device has attached\r\n"); +#endif + return kStatus_USB_Busy; + } + else + { + currentInstance = currentInstance->next; + } + } +#else + if (hostInstance->deviceList != NULL) + { + *deviceHandle = NULL; + usb_echo("device has attached\r\n"); + return kStatus_USB_Busy; + } +#endif + + /* Allocate new device instance */ + newInstance = (usb_host_device_instance_t *)USB_OsaMemoryAllocate(sizeof(usb_host_device_instance_t)); + if (newInstance == NULL) + { +#ifdef HOST_ECHO + usb_echo("allocate dev instance fail\r\n"); +#endif + return kStatus_USB_AllocFail; + } + + /* new instance fields init */ + newInstance->hostHandle = hostHandle; + newInstance->speed = speed; + newInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES; + newInstance->enumRetries = USB_HOST_CONFIG_ENUMERATION_MAX_RETRIES; + newInstance->setAddress = 0; + newInstance->deviceAttachState = kStatus_device_Attached; +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + newInstance->deviceDescriptor = + (usb_descriptor_device_t *)SDK_Malloc(sizeof(usb_descriptor_device_t) + 9, USB_CACHE_LINESIZE); +#else + newInstance->deviceDescriptor = + (usb_descriptor_device_t *)USB_OsaMemoryAllocate(sizeof(usb_descriptor_device_t) + 9); +#endif + if (newInstance->deviceDescriptor == NULL) + { +#ifdef HOST_ECHO + usb_echo("allocate newInstance->deviceDescriptor fail\r\n"); +#endif +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + SDK_Free(newInstance->deviceDescriptor); +#else + USB_OsaMemoryFree(newInstance->deviceDescriptor); +#endif + USB_OsaMemoryFree(newInstance); + return kStatus_USB_AllocFail; + } + newInstance->enumBuffer = (uint8_t *)((uint8_t *)newInstance->deviceDescriptor + sizeof(usb_descriptor_device_t)); +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + newInstance->hubNumber = hubNumber; + newInstance->portNumber = portNumber; + newInstance->level = level; + + if ((speed != USB_SPEED_HIGH) && (level > 1)) + { + newInstance->hsHubNumber = USB_HostHubGetHsHubNumber(hostHandle, hubNumber); + newInstance->hsHubPort = USB_HostHubGetHsHubPort(hostHandle, hubNumber, portNumber); + } + else + { + newInstance->hsHubNumber = hubNumber; + newInstance->hsHubPort = portNumber; + } +#endif /* USB_HOST_CONFIG_HUB */ + + USB_HostLock(); + /* allocate address && insert to the dev list */ + address = USB_HostAllocateDeviceAddress(hostInstance); + if (address == 0) + { +#ifdef HOST_ECHO + usb_echo("allocate address fail\r\n"); +#endif + USB_HostUnlock(); +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + SDK_Free(newInstance->deviceDescriptor); +#else + USB_OsaMemoryFree(newInstance->deviceDescriptor); +#endif + USB_OsaMemoryFree(newInstance); + return kStatus_USB_Error; + } + newInstance->allocatedAddress = address; + + newInstance->next = (usb_host_device_instance_t *)hostInstance->deviceList; + hostInstance->deviceList = newInstance; + newInstance->state = kStatus_DEV_Initial; + USB_HostUnlock(); + + /* open control pipe */ + pipeInit.devInstance = newInstance; + pipeInit.pipeType = USB_ENDPOINT_CONTROL; + pipeInit.direction = 0; + pipeInit.endpointAddress = 0; + pipeInit.interval = 0; + pipeInit.maxPacketSize = 8; + pipeInit.numberPerUframe = 0; + pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK; + if (USB_HostOpenPipe(hostHandle, &newInstance->controlPipe, &pipeInit) != kStatus_USB_Success) + { + /* don't need release resource, resource is released when detach */ + *deviceHandle = newInstance; +#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + SDK_Free(newInstance->deviceDescriptor); +#else + USB_OsaMemoryFree(newInstance->deviceDescriptor); +#endif + USB_OsaMemoryFree(newInstance); + return kStatus_USB_Error; + } + + /* start enumeration */ + newInstance->state = kStatus_DEV_GetDes8; + USB_HostProcessState(newInstance); /* process enumeration state machine */ + + *deviceHandle = newInstance; + return kStatus_USB_Success; +} + +usb_status_t USB_HostDetachDevice(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber) +{ + usb_host_device_instance_t *deviceInstance; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + USB_HostLock(); +/* search for device instance handle */ +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList; + while (deviceInstance != NULL) + { + if ((deviceInstance->hubNumber == hubNumber) && (deviceInstance->portNumber == portNumber)) + { + break; + } + deviceInstance = deviceInstance->next; + } +#else + deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList; +#endif + USB_HostUnlock(); + if (deviceInstance != NULL) + { + return USB_HostDetachDeviceInternal(hostHandle, deviceInstance); /* device instance detach */ + } + return kStatus_USB_Success; +} + +usb_status_t USB_HostDetachDeviceInternal(usb_host_handle hostHandle, usb_device_handle deviceHandle) +{ + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + if ((hostHandle == NULL) || (deviceHandle == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + deviceInstance->deviceAttachState = kStatus_device_Detached; /* mark the device is detached from host */ + + if (deviceInstance->state >= kStatus_DEV_Initial) /* device instance is valid */ + { + /* detach internally */ + if (deviceInstance->state < kStatus_DEV_AppUsed) /* enumeration is not done */ + { + if (deviceInstance->controlPipe != NULL) + { + USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL); + } + + /* remove device instance from host */ + USB_HostRemoveDeviceInstance(hostInstance, deviceInstance); + USB_HostReleaseDeviceResource(hostInstance, deviceInstance); + } + else /* enumeration has be done and notifed application */ + { + USB_HostNotifyDevice(deviceInstance, kUSB_HostEventDetach); /* notify application device detach */ + } + } + + return kStatus_USB_Success; +} + +uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle) +{ + return deviceHandle ? ((usb_host_device_instance_t *)deviceHandle)->deviceAttachState : 0x0; +} + +usb_status_t USB_HostValidateDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle) +{ + usb_host_device_instance_t *searchDev; + + if (deviceHandle == NULL) + { + return kStatus_USB_InvalidParameter; + } + /* search for the device */ + searchDev = (usb_host_device_instance_t *)((usb_host_instance_t *)hostHandle)->deviceList; + while ((searchDev != NULL) && ((usb_device_handle)searchDev != deviceHandle)) + { + searchDev = searchDev->next; + } + + if (searchDev) + { + return kStatus_USB_Success; + } + return kStatus_USB_Error; +} + +static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, + &controlType); + + return status; +} + +usb_status_t USB_HostOpenDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle) +{ + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + usb_host_instance_t *hostInstance = NULL; + uint8_t interfaceIndex; + uint8_t index = 0; + + if ((deviceHandle == NULL) || (interfaceHandle == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle; + USB_HostLock(); + /* check host_instance valid? */ + for (; index < USB_HOST_CONFIG_MAX_HOST; ++index) + { + if ((g_UsbHostInstance[index].occupied == 1) && + ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance))) + { + break; + } + } + if (index >= USB_HOST_CONFIG_MAX_HOST) + { + USB_HostUnlock(); + return kStatus_USB_Error; + } + + /* check deviceHandle valid? */ + if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success) + { + USB_HostUnlock(); + return kStatus_USB_Error; + } + + /* search interface and set the interface as opened */ + for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex) + { + if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle) + { + deviceInstance->interfaceStatus[interfaceIndex] = kStatus_interface_Opened; + break; + } + } + USB_HostUnlock(); + + return kStatus_USB_Success; +} + +usb_status_t USB_HostCloseDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle) +{ + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + usb_host_instance_t *hostInstance = NULL; + uint8_t interfaceIndex; + uint8_t removeLabel = 1; + uint8_t index = 0; + + if (deviceHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle; + USB_HostLock(); + /* check host_instance valid? */ + for (; index < USB_HOST_CONFIG_MAX_HOST; ++index) + { + if ((g_UsbHostInstance[index].occupied == 1) && + ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance))) + { + break; + } + } + if (index >= USB_HOST_CONFIG_MAX_HOST) + { + USB_HostUnlock(); + return kStatus_USB_Error; + } + + /* check deviceHandle valid? */ + if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success) + { + USB_HostUnlock(); + return kStatus_USB_Error; + } + + if (interfaceHandle != NULL) + { + /* search interface and set the interface as detached */ + for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex) + { + if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle) + { + deviceInstance->interfaceStatus[interfaceIndex] = kStatus_interface_Detached; + break; + } + } + } + + if (deviceInstance->deviceAttachState == kStatus_device_Detached) /* device is removed from host */ + { + removeLabel = 1; + /* check all the interfaces of the device are not opened */ + for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex) + { + if (deviceInstance->interfaceStatus[interfaceIndex] == kStatus_interface_Opened) + { + removeLabel = 0; + break; + } + } + if (removeLabel == 1) + { + /* remove device instance from host */ + USB_HostRemoveDeviceInstance(hostInstance, deviceInstance); + } + USB_HostUnlock(); + + if (removeLabel == 1) + { + USB_HostReleaseDeviceResource((usb_host_instance_t *)deviceInstance->hostHandle, + deviceInstance); /* release device resource */ + } + } + else + { + USB_HostUnlock(); + } + + return kStatus_USB_Success; +} + +usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle) +{ + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + uint8_t interfaceIndex = 0; +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + uint8_t level = 0; + uint8_t devHubNo; + uint8_t devPortNo; +#endif + + if ((hostHandle == NULL) || (deviceHandle == NULL)) + { + return kStatus_USB_InvalidHandle; + } + if (deviceInstance->hostHandle != hostHandle) + { + return kStatus_USB_InvalidParameter; + } + + if (USB_HostValidateDevice(hostInstance, deviceInstance) == kStatus_USB_Success) /* device is valid */ + { +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + devHubNo = deviceInstance->hubNumber; + devPortNo = deviceInstance->portNumber; + level = deviceInstance->level; +#endif + + deviceInstance->deviceAttachState = kStatus_device_Detached; + if (deviceInstance->state >= kStatus_DEV_Initial) /* device is valid */ + { + if (deviceInstance->state < kStatus_DEV_AppUsed) /* enumeraion is not done or application don't use */ + { + /* detach internally */ + USB_HostDetachDeviceInternal(hostHandle, deviceHandle); + } + else /* application use the device */ + { + for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; + ++interfaceIndex) + { + if (deviceInstance->interfaceStatus[interfaceIndex] == kStatus_interface_Opened) + { +#ifdef HOST_ECHO + usb_echo("error: there is class instance that is not deinited\r\n"); +#endif + break; + } + } + /* remove device instance from host */ + USB_HostRemoveDeviceInstance(hostInstance, deviceInstance); + USB_HostReleaseDeviceResource(hostInstance, deviceInstance); /* release resource */ + } + } + +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + if (level == 1) + { + USB_HostControlBus(hostHandle, kUSB_HostBusReset); /* reset controller port */ + USB_HostControlBus(hostHandle, kUSB_HostBusRestart); /* restart controller port */ + } + else + { + USB_HostHubRemovePort(hostHandle, devHubNo, devPortNo); /* reset hub port */ + } +#else + USB_HostControlBus(hostHandle, kUSB_HostBusReset); /* reset controller port */ + USB_HostControlBus(hostHandle, kUSB_HostBusRestart); /* restart controller port */ +#endif /* USB_HOST_CONFIG_HUB */ + } + + return kStatus_USB_Success; +} diff --git a/bsp/imxrt/libraries/drivers/usb/host/usb_host_devices.h b/bsp/imxrt/libraries/drivers/usb/host/usb_host_devices.h new file mode 100644 index 0000000000..422e876a12 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/host/usb_host_devices.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _USB_HOST_DEV_MNG_H_ +#define _USB_HOST_DEV_MNG_H_ + +#include "usb_host.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @addtogroup usb_host_drv + * @{ + */ +/*! @brief States of device instances enumeration */ +typedef enum _usb_host_device_enumeration_status +{ + kStatus_DEV_Notinit = 0, /*!< Device is invalid */ + kStatus_DEV_Initial, /*!< Device has been processed by host driver */ + kStatus_DEV_GetDes8, /*!< Enumeration process: get 8 bytes' device descriptor */ + kStatus_DEV_SetAddress, /*!< Enumeration process: set device address */ + kStatus_DEV_GetDes, /*!< Enumeration process: get device descriptor */ + kStatus_DEV_GetCfg9, /*!< Enumeration process: get 9 bytes' configuration descriptor */ + kStatus_DEV_GetCfg, /*!< Enumeration process: get configuration descriptor */ + kStatus_DEV_SetCfg, /*!< Enumeration process: set configuration */ + kStatus_DEV_EnumDone, /*!< Enumeration is done */ + kStatus_DEV_AppUsed, /*!< This device has been used by application */ +} usb_host_device_enumeration_status_t; + +/*! @brief States of device's interface */ +typedef enum _usb_host_interface_state +{ + kStatus_interface_Attached = 1, /*!< Interface's default status */ + kStatus_interface_Opened, /*!< Interface is used by application */ + kStatus_interface_Detached, /*!< Interface is not used by application */ +} usb_host_interface_state_t; + +/*! @brief States of device */ +typedef enum _usb_host_device_state +{ + kStatus_device_Detached = 0, /*!< Device is used by application */ + kStatus_device_Attached, /*!< Device's default status */ +} usb_host_device_state_t; + +/*! @brief Device instance */ +typedef struct _usb_host_device_instance +{ + struct _usb_host_device_instance *next; /*!< Next device, or NULL */ + usb_host_handle hostHandle; /*!< Host handle */ + usb_host_configuration_t configuration; /*!< Parsed configuration information for the device */ + usb_descriptor_device_t *deviceDescriptor; /*!< Standard device descriptor */ + usb_host_pipe_handle controlPipe; /*!< Device's control pipe */ + uint8_t *configurationDesc; /*!< Configuration descriptor pointer */ + uint16_t configurationLen; /*!< Configuration descriptor length */ + uint16_t configurationValue; /*!< Configuration index */ + uint8_t interfaceStatus[USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE]; /*!< Interfaces' status, please reference to + #usb_host_interface_state_t */ + uint8_t *enumBuffer; /*!< Buffer for enumeration */ + uint8_t state; /*!< Device state for enumeration */ + uint8_t enumRetries; /*!< Re-enumeration when error in control transfer */ + uint8_t stallRetries; /*!< Re-transfer when stall */ + uint8_t speed; /*!< Device speed */ + uint8_t allocatedAddress; /*!< Temporary address for the device. When set address request succeeds, setAddress is + a value, 1 - 127 */ + uint8_t setAddress; /*!< The address has been set to the device successfully, 1 - 127 */ + uint8_t deviceAttachState; /*!< See the usb_host_device_state_t */ +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + /* hub related */ + uint8_t hubNumber; /*!< Device's first connected hub address (root hub = 0) */ + uint8_t portNumber; /*!< Device's first connected hub's port no (1 - 8) */ + uint8_t hsHubNumber; /*!< Device's first connected high-speed hub's address (1 - 8) */ + uint8_t hsHubPort; /*!< Device's first connected high-speed hub's port no (1 - 8) */ + uint8_t level; /*!< Device's level (root device = 0) */ +#endif +} usb_host_device_instance_t; + +typedef struct _usb_host_enum_process_entry +{ + uint8_t successState; /*!< When the last step is successful, the next state value */ + uint8_t retryState; /*!< When the last step need retry, the next state value */ + usb_status_t (*process)(usb_host_device_instance_t *deviceInstance); /*!< When the last step transfer is done, the + function is used to process the transfer + data */ +} usb_host_enum_process_entry_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Calls this function when device attach. + * + * @param hostHandle Host instance handle. + * @param speed Device speed. + * @param hubNumber Device hub no. root device's hub no. is 0. + * @param portNumber Device port no. root device's port no. is 0. + * @param level Device level. root device's level is 1. + * @param deviceHandle Return device handle. + * + * @return kStatus_USB_Success or error codes. + */ +extern usb_status_t USB_HostAttachDevice(usb_host_handle hostHandle, + uint8_t speed, + uint8_t hubNumber, + uint8_t portNumber, + uint8_t level, + usb_device_handle *deviceHandle); + +/*! + * @brief Call this function when device detaches. + * + * @param hostHandle Host instance handle. + * @param hubNumber Device hub no. root device's hub no. is 0. + * @param portNumber Device port no. root device's port no. is 0. + * + * @return kStatus_USB_Success or error codes. + */ +extern usb_status_t USB_HostDetachDevice(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber); + +/*! + * @brief Call this function when device detaches. + * + * @param hostHandle Host instance handle. + * @param deviceHandle Device handle. + * + * @return kStatus_USB_Success or error codes. + */ +extern usb_status_t USB_HostDetachDeviceInternal(usb_host_handle hostHandle, usb_device_handle deviceHandle); + +/*! + * @brief Gets the device attach/detach state. + * + * @param deviceHandle Device handle. + * + * @return 0x01 - attached; 0x00 - detached. + */ +extern uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle); + +/*! + * @brief Determine whether the device is attached. + * + * @param hostHandle Host instance pointer. + * @param deviceHandle Device handle. + * + * @return kStatus_USB_Success or error codes. + */ +extern usb_status_t USB_HostValidateDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle); + +/*! @}*/ +#endif /* _USB_HOST_DEV_MNG_H_ */ diff --git a/bsp/imxrt/libraries/drivers/usb/host/usb_host_ehci.c b/bsp/imxrt/libraries/drivers/usb/host/usb_host_ehci.c new file mode 100644 index 0000000000..8a31514b3a --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/host/usb_host_ehci.c @@ -0,0 +1,4747 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI > 0U)) +#include "usb_host.h" +#include "usb_host_hci.h" +#include "usb_host_devices.h" +#include "fsl_device_registers.h" +#include "usb_host_ehci.h" +#include "usb_phy.h" +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) +#include "usb_host.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U) + +#error The SOC does not suppoort dedicated RAM case. + +#endif + +#define USB_HOST_EHCI_BANDWIDTH_DELAY (3500U) +#define USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP (333U) +#define USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME (900U) + +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) +#define USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH (18U) +#define USB_HOST_EHCI_PORTSC_PTC_J_STATE (0x01U) +#define USB_HOST_EHCI_PORTSC_PTC_K_STATE (0x02U) +#define USB_HOST_EHCI_PORTSC_PTC_SE0_NAK (0x03U) +#define USB_HOST_EHCI_PORTSC_PTC_PACKET (0x04U) +#define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS (0x05U) +#define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_FS (0x06U) +#define USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_LS (0x07U) +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief compute data bandwidth time. + * + * @param speed data speed. + * @param pipeType data type. + * @param direction data direction. + * @param dataLength data length. + * + *@return time value. + */ +static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength); + +/*! + * @brief compute current allocated bandwidth when ehci work as full-speed or low-speed host. + * + * @param ehciInstance ehci instance pointer. + * @param frameIndex frame index. + * @param frameBandwidths return frame bandwidth data. + */ +static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance, + uint16_t frameIndex, + uint16_t *frameBandwidth); + +/*! + * @brief compute current hub's allocated FS/LS bandwidth when ehci work as hi-speed host. + * + * @param ehciInstance ehci instance pointer. + * @param hubNumber hub address. + * @param frameIndex frame index. + * @param frameBandwidths return frame bandwidth data. + */ +static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance, + uint32_t hubNumber, + uint16_t frameIndex, + uint8_t frameBandwidths[8]); + +/*! + * @brief compute current allocated HS bandwidth when ehci work as hi-speed host. + * + * @param ehciInstance ehci instance pointer. + * @param frameIndex frame index. + * @param frameBandwidths return frame bandwidth data. + */ +static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance, + uint16_t frameIndex, + uint8_t frameBandwidths[8]); + +/*! + * @brief allocate HS bandwidth when host work as high-speed host. + * + * @param ehciInstance ehci instance pointer. + * @param uframeInterval micro-frame interval. + * @param timeData time for allocating. + * @param uframe_index_out return start uframe index. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance, + uint16_t uframeInterval, + uint16_t timeData, + uint16_t *uframeIndexOut); + +/*! + * @brief allocate HS interrupt bandwidth when host work as high-speed host. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief allocate bandwidth when host work as full-speed or low-speed host. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief get the 2 power value of uint8_t. + * + * @param value input uint8_t value. + */ +static uint8_t USB_HostEhciGet2PowerValue(uint8_t value); + +/*! + * @brief memory zero. + * + * @param buffer buffer pointer. + * @param length buffer length. + */ +static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length); + +/*! + * @brief host ehci delay. + * + * @param ehciIpBase ehci ip base address. + * @param ms millisecond. + */ +static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms); + +/*! + * @brief host ehci start async schedule. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief host ehci stop async schedule. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief host ehci start periodic schedule. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief host ehci stop periodic schedule. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief initialize the qtd for one transfer. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * @param transfer transfer information. + * + *@return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer); + +/*! + * @brief release the qtd list. + * + * @param ehciInstance ehci instance pointer. + * @param ehciQtdStart qtd list start pointer. + * @param ehciQtdEnd qtd list end pointer. + * + *@return the transfer's length. + */ +static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_qtd_t *ehciQtdStart, + usb_host_ehci_qtd_t *ehciQtdEnd); + +/*! + * @brief de-initialize qh's linking qtd list. + * 1. remove qtd from qh; 2. remove transfer from qh; 3. release qtd; 4. transfer callback. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe. + * + *@return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief de-initialize transfer's linking qtd list. + * 1. stop this qh schedule; 2. remove qtd from qh; 3. remove transfer from qh; 4. release qtd; 5. transfer callback; 6. + *start this qh schedule. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * @param transfer transfer information. + * + *@return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer); + +/*! + * @brief initialize QH when opening one control, bulk or interrupt pipe. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief de-initialize QH when closing one control, bulk or interrupt pipe. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief add qh to one frame entry. + * + * @param ehciInstance ehci instance pointer. + * @param entryPointerValue entry pointer value. + * @param framePos frame index. + * @param uframeInterval micro-frame interval. + */ +static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance, + uint32_t entryPointerValue, + uint16_t framePos, + uint16_t uframeInterval); + +/*! + * @brief remove entry from frame list. + * + * @param ehciInstance ehci instance pointer. + * @param entryPointerValue entry pointer value. + * @param framePos frame index. + */ +static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance, + uint32_t entryPointerValue, + uint16_t framePos); + +#if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)) +/*! + * @brief add sitd array to the frame list. + * + * @param ehciInstance ehci instance pointer. + * @param entryPointerValue entry pointer value. + * @param startEntryPointer sitd entry pointer. + */ +static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + void *startEntryPointer); + +/*! + * @brief initialize sitd array for one transfer. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * @param transfer transfer information. + */ +static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer); + +/*! + * @brief release sitd list. + * + * @param ehciInstance ehci instance pointer. + * @param startSitdPointer start sitd pointer. + * @param endSitdPointer end sitd pointer. + * + * @return transfer's result length. + */ +static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_sitd_t *startSitdPointer, + usb_host_ehci_sitd_t *endSitdPointer); + +/*! + * @brief de-initialize sitd list. + * 1. remove transfer; 2. remove sitd from frame list and release sitd; 3. transfer callback + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); +#endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */ + +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) +/*! + * @brief compute the frame index when inserting itd. + * + * @param ehciInstance ehci instance pointer. + * @param lastLinkUframe last inserted micro-frame. + * @param startUframe start micro-frame. + * @param uframeInterval micro-frame interval. + * + * @return frame index + */ +static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance, + uint32_t lastLinkUframe, + uint16_t startUframe, + uint16_t uframeInterval); + +/*! + * @brief initialize itd list for one transfer. + * 1. initialize itd list; 2. insert itd to frame list. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * @param transfer transfer information. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer); + +/*! + * @brief release itd list. + * + * @param ehciInstance ehci instance pointer. + * @param startItdPointer start itd pointer. + * @param endItdPointer end itd pointer. + * + * @return transfer's result length. + */ +static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_itd_t *startItdPointer, + usb_host_ehci_itd_t *endItdPointer); + +/*! + * @brief de-initialize itd list. + * 1. remove transfer; 2. remove itd from frame list and release itd; 3. transfer callback + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); +#endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */ + +/*! + * @brief open control or bulk pipe. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief close control or bulk pipe. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief open interrupt pipe. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief close interrupt pipe. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); + +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) +/*! + * @brief open iso pipe. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief close iso pipe. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer); + +/*! + * @brief allocate HS iso bandwidth when host work as high-speed host. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer); + +#endif + +/*! + * @brief reset ehci ip. + * + * @param ehciInstance ehci instance pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief start ehci ip. + * + * @param ehciInstance ehci instance pointer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief cancel pipe's transfers. + * + * @param ehciInstance ehci instance pointer. + * @param ehciPipePointer ehci pipe pointer. + * @param transfer the canceling transfer. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer); + +/*! + * @brief control ehci bus. + * + * @param ehciInstance ehci instance pointer. + * @param bus_control control code. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl); + +/*! + * @brief ehci transaction done process function. + * + * @param ehciInstance ehci instance pointer. + */ +void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief ehci port change interrupt process function. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief ehci timer0 interrupt process function. + * cancel control/bulk transfer that time out. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance); + +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) +/*! + * @brief ehci timer1 interrupt process function. + * cancel control/bulk transfer that time out. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance); +#endif + +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) +/*! + * @brief suspend bus. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance); + +/*! + * @brief resume bus. + * + * @param ehciInstance ehci instance pointer. + */ +static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance); + +extern usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance, + usb_host_transfer_t *transfer, + void *param); +#endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* EHCI controller driver instances. */ +#if (USB_HOST_CONFIG_EHCI == 1U) +USB_RAM_ADDRESS_ALIGNMENT(4096) +USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4]; + +#define USB_HOST_EHCI_FRAME_LIST_ARRAY \ + { \ + &s_UsbHostEhciFrameList1[0] \ + } + +USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1; +#define USB_HOST_EHCI_DATA_ARRAY \ + { \ + &s_UsbHostEhciData1 \ + } +#elif(USB_HOST_CONFIG_EHCI == 2U) +USB_RAM_ADDRESS_ALIGNMENT(4096) +USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4]; +USB_RAM_ADDRESS_ALIGNMENT(4096) +USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList2[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4]; +#define USB_HOST_EHCI_FRAME_LIST_ARRAY \ + { \ + &s_UsbHostEhciFrameList1[0], &s_UsbHostEhciFrameList2[0] \ + } + +USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1; +USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData2; +#define USB_HOST_EHCI_DATA_ARRAY \ + { \ + &s_UsbHostEhciData1, &s_UsbHostEhciData2 \ + } +#else +#error "Please increase the instance count." +#endif + +static uint8_t s_SlotMaxBandwidth[8] = {125, 125, 125, 125, 125, 125, 50, 0}; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! +* @brief EHCI NC get USB NC bass address. +* +* This function is used to get USB NC bass address. +* +* @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t. +* +* @retval USB NC bass address. +*/ +#if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) +void *USB_EhciNCGetBase(uint8_t controllerId) +{ + void *usbNCBase = NULL; +#if ((defined FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + uint32_t instance; + uint32_t newinstance = 0; + uint32_t usbnc_base_temp[] = USBNC_BASE_ADDRS; + uint32_t usbnc_base[] = USBNC_BASE_ADDRS; + + if (controllerId < kUSB_ControllerEhci0) + { + return NULL; + } + + controllerId = controllerId - kUSB_ControllerEhci0; + + for (instance = 0; instance < (sizeof(usbnc_base_temp) / sizeof(usbnc_base_temp[0])); instance++) + { + if (usbnc_base_temp[instance]) + { + usbnc_base[newinstance++] = usbnc_base_temp[instance]; + } + } + if (controllerId > newinstance) + { + return NULL; + } + + usbNCBase = (void *)usbnc_base[controllerId]; +#endif + return usbNCBase; +} +#endif +#endif + +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) + +usb_status_t USB_HostEhciTestSetMode(usb_host_ehci_instance_t *ehciInstance, uint32_t testMode) +{ + uint32_t ehciPortSC; + + ehciPortSC = ehciInstance->ehciIpBase->PORTSC1; + ehciPortSC &= ~((uint32_t)USBHS_PORTSC1_PTC_MASK); /* clear test mode bits */ + ehciPortSC |= (testMode << USBHS_PORTSC1_PTC_SHIFT); /* set test mode bits */ + ehciInstance->ehciIpBase->PORTSC1 = ehciPortSC; + return kStatus_USB_Success; +} + +static void USB_HostEhciTestSuspendResume(usb_host_ehci_instance_t *ehciInstance) +{ + uint8_t timeCount; + timeCount = 15; /* 15s */ + while (timeCount--) + { + USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U); + } + USB_HostEhciSuspendBus(ehciInstance); + timeCount = 15; /* 15s */ + while (timeCount--) + { + USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U); + } + + USB_HostEhciResumeBus(ehciInstance); +} + +static void USB_HostEhciTestCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status) +{ + USB_HostFreeTransfer(param, transfer); +} + +static void USB_HostEhciTestSingleStepGetDeviceDesc(usb_host_ehci_instance_t *ehciInstance, + usb_device_handle deviceHandle) +{ + usb_host_process_descriptor_param_t getDescriptorParam; + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + usb_host_transfer_t *transfer; + uint8_t timeCount; + + /* disable periodic shedule */ + USB_HostEhciStopPeriodic(ehciInstance); + + timeCount = 15; /* 15s */ + while (timeCount--) + { + USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U); + } + + /* malloc one transfer */ + if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("allocate transfer error\r\n"); +#endif + return; + } + + getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t); + getDescriptorParam.descriptorLength = 18; + getDescriptorParam.descriptorBuffer = (uint8_t *)&deviceInstance->deviceDescriptor; + getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE; + getDescriptorParam.descriptorIndex = 0; + getDescriptorParam.languageId = 0; + transfer->callbackFn = USB_HostEhciTestCallback; + transfer->callbackParam = ehciInstance->hostHandle; + transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN; + transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR; + transfer->setupPacket->wIndex = 0; + transfer->setupPacket->wLength = 0; + transfer->setupPacket->wValue = 0; + USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam); +} + +static usb_status_t USB_HostEhciSingleStepQtdListInit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer, + uint8_t setupPhase) +{ + volatile usb_host_ehci_qh_t *vltQhPointer; + usb_host_ehci_qtd_t *qtdPointer = NULL; + volatile uint32_t *entryPointer; + uint32_t qtdNumber; + uint32_t dataLength; + uint32_t dataAddress; + uint8_t index; + + /* compute the qtd number */ + qtdNumber = 1; + + vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + /* get qtd list */ + USB_HostEhciLock(); + if (qtdNumber <= ehciInstance->ehciQtdNumber) + { + ehciInstance->ehciQtdNumber -= qtdNumber; + qtdPointer = NULL; + do + { + if (qtdPointer != NULL) + { + qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead; + } + qtdPointer = ehciInstance->ehciQtdHead; + ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer; + qtdPointer->nextQtdPointer = 0; + } while (--qtdNumber); + } + else + { + USB_HostEhciUnlock(); + return kStatus_USB_Error; + } + USB_HostEhciUnlock(); + + /* int qTD */ + if (setupPhase == 1) /* setup transaction qtd init */ + { + qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */ + qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0; + qtdPointer->transferResults[0] = + ((0x00000000 << EHCI_HOST_QTD_DT_SHIFT) | (8 << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) | + (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + dataAddress = (uint32_t)(transfer->setupPacket); + qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */ + /* set buffer pointer no matter data length */ + for (index = 0; index < 4; ++index) + { + qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000); + } + } + else if (setupPhase == 2) /* data transaction qtd */ + { + dataLength = transfer->transferLength; + if (dataLength != 0) + { + qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */ + qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0; + + qtdPointer->transferResults[0] = + ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) | + (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + + dataAddress = (uint32_t)(transfer->transferBuffer); + qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */ + /* set buffer pointer no matter data length */ + for (index = 0; index < 4; ++index) + { + qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000); + } + } + } + else if (setupPhase == 3) + { + /* status transaction qtd */ + qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */ + qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0; + + qtdPointer->transferResults[0] = + ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | + (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + + qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE; + } + qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE; + qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* set IOC */ + + /* save qtd to transfer */ + transfer->union1.unitHead = (uint32_t)qtdPointer; + transfer->union2.unitTail = (uint32_t)qtdPointer; + /* link transfer to qh */ + transfer->next = NULL; + if (vltQhPointer->ehciTransferHead == NULL) + { + transfer->next = NULL; + vltQhPointer->ehciTransferHead = vltQhPointer->ehciTransferTail = transfer; + } + else + { + transfer->next = NULL; + vltQhPointer->ehciTransferTail->next = transfer; + vltQhPointer->ehciTransferTail = transfer; + } + + USB_HostEhciLock(); + /* link qtd to qh (link to end) */ + entryPointer = &(vltQhPointer->nextQtdPointer); + dataAddress = *entryPointer; /* dataAddress variable means entry value here */ + while ((dataAddress) && (!(dataAddress & EHCI_HOST_T_INVALID_VALUE))) + { + entryPointer = (volatile uint32_t *)dataAddress; + dataAddress = *entryPointer; + } + *entryPointer = (uint32_t)qtdPointer; + USB_HostEhciUnlock(); + USB_HostEhciStartAsync(ehciInstance); + + return kStatus_USB_Success; +} + +static void USB_HostEhciTestSingleStepGetDeviceDescData(usb_host_ehci_instance_t *ehciInstance, + usb_device_handle deviceHandle) +{ + static uint8_t buffer[USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH]; + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + usb_host_transfer_t *transfer; + uint8_t timeCount; + + USB_HostEhciStopPeriodic(ehciInstance); + + if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success) + { + return; + } + transfer->callbackFn = USB_HostEhciTestCallback; + transfer->callbackParam = ehciInstance->hostHandle; + transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_DIR_IN; + transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR; + transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH); + transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN((uint16_t)((uint16_t)USB_DESCRIPTOR_TYPE_DEVICE << 8)); + transfer->setupPacket->wIndex = 0; + USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 1); + + timeCount = 15; /* 15s */ + while (timeCount--) + { + USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U); + } + + if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success) + { + return; + } + transfer->callbackFn = USB_HostEhciTestCallback; + transfer->callbackParam = ehciInstance->hostHandle; + transfer->transferBuffer = buffer; + transfer->transferLength = USB_HOST_EHCI_TEST_DESCRIPTOR_LENGTH; + USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 2); + + if (USB_HostMallocTransfer(ehciInstance->hostHandle, &transfer) != kStatus_USB_Success) + { + return; + } + transfer->callbackFn = USB_HostEhciTestCallback; + transfer->callbackParam = ehciInstance->hostHandle; + transfer->transferBuffer = NULL; + transfer->transferLength = 0; + USB_HostEhciSingleStepQtdListInit(ehciInstance, (usb_host_ehci_pipe_t *)(deviceInstance->controlPipe), transfer, 3); + + timeCount = 15; /* 15s */ + while (timeCount--) + { + USB_HostEhciDelay(ehciInstance->ehciIpBase, 1000U); + } + + usb_echo("test_single_step_get_dev_desc_data finished\r\n"); + + return; +} + +void USB_HostEhciTestModeInit(usb_device_handle deviceHandle) +{ + uint32_t productId; + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + usb_host_ehci_instance_t *ehciInstance = + (usb_host_ehci_instance_t *)(((usb_host_instance_t *)(deviceInstance->hostHandle))->controllerHandle); + + USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId); + + usb_echo("usb host ehci test mode init product id:0x%x\r\n", productId); + + switch (productId) + { + case 0x0101U: + USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_SE0_NAK); + break; + case 0x0102U: + USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_J_STATE); + break; + case 0x0103U: + USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_K_STATE); + break; + case 0x0104U: + USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_PACKET); + break; + case 0x0105U: + usb_echo("set test mode FORCE_ENALBE_HS\r\n"); + USB_HostEhciTestSetMode(ehciInstance, USB_HOST_EHCI_PORTSC_PTC_FORCE_ENABLE_HS); + break; + case 0x0106U: + USB_HostEhciTestSuspendResume(ehciInstance); + break; + case 0x0107U: + usb_echo("start test SINGLE_STEP_GET_DEV_DESC\r\n"); + USB_HostEhciTestSingleStepGetDeviceDesc(ehciInstance, deviceHandle); + break; + case 0x0108U: + usb_echo("start test SINGLE_STEP_GET_DEV_DESC_DATA\r\n"); + USB_HostEhciTestSingleStepGetDeviceDescData(ehciInstance, deviceHandle); + break; + default: + break; + } + + return; +} + +static void USB_HostEhciSuspendBus(usb_host_ehci_instance_t *ehciInstance) +{ + uint32_t ehciPortSC; + + USB_HostEhciLock(); + ehciPortSC = ehciInstance->ehciIpBase->PORTSC1; + if (ehciPortSC & USBHS_PORTSC1_PE_MASK) + { + ehciPortSC = ehciInstance->ehciIpBase->PORTSC1; + ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS); + ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_SUSP_MASK); + } + USB_HostEhciUnlock(); +} + +static void USB_HostEhciResumeBus(usb_host_ehci_instance_t *ehciInstance) +{ + uint32_t ehciPortSC; + + USB_HostEhciLock(); + /* Resume port */ + ehciPortSC = ehciInstance->ehciIpBase->PORTSC1; + if (ehciPortSC & USBHS_PORTSC1_PE_MASK) + { + ehciPortSC &= (uint32_t)(~EHCI_PORTSC1_W1_BITS); + ehciInstance->ehciIpBase->PORTSC1 = (ehciPortSC | USBHS_PORTSC1_FPR_MASK); + } + USB_HostEhciUnlock(); +} +#endif + +static uint32_t USB_HostBandwidthComputeTime(uint8_t speed, uint8_t pipeType, uint8_t direction, uint32_t dataLength) +{ + uint32_t result = (3167 + ((1000 * dataLength) * 7U * 8U / 6U)) / 1000; + + if (pipeType == USB_ENDPOINT_ISOCHRONOUS) /* iso */ + { + if (speed == USB_SPEED_HIGH) + { + result = 38 * 8 * 2083 + 2083 * result + USB_HOST_EHCI_BANDWIDTH_DELAY; + } + else if (speed == USB_SPEED_FULL) + { + if (direction == USB_IN) + { + result = 7268000 + 83540 * result + USB_HOST_EHCI_BANDWIDTH_DELAY; + } + else + { + result = 6265000 + 83540 * result + USB_HOST_EHCI_BANDWIDTH_DELAY; + } + } + else + { + } + } + else /* interrupt */ + { + if (speed == USB_SPEED_HIGH) + { + result = 55 * 8 * 2083 + 2083 * result + USB_HOST_EHCI_BANDWIDTH_DELAY; + } + else if (speed == USB_SPEED_FULL) + { + result = 9107000 + 83540 * result + USB_HOST_EHCI_BANDWIDTH_DELAY; + } + else if (speed == USB_SPEED_LOW) + { + if (direction == USB_IN) + { + result = 64060000 + 2000 * USB_HOST_EHCI_BANDWIDTH_HUB_LS_SETUP + 676670 * result + + USB_HOST_EHCI_BANDWIDTH_DELAY; + } + else + { + result = 6265000 + 83540 * result + USB_HOST_EHCI_BANDWIDTH_DELAY; + } + } + else + { + } + } + + result /= 1000000; + if (result == 0) + { + result = 1; + } + + return result; +} + +static void USB_HostBandwidthFslsHostComputeCurrent(usb_host_ehci_instance_t *ehciInstance, + uint16_t frameIndex, + uint16_t *frameBandwidth) +{ + usb_host_ehci_pipe_t *ehciPipePointer; + + /* clear the bandwidth */ + *frameBandwidth = 0; + + ehciPipePointer = ehciInstance->ehciRunningPipeList; + while (ehciPipePointer != NULL) + { + /* only compute iso and interrupt pipe */ + if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) || + (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)) + { + /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */ + if ((frameIndex >= ehciPipePointer->startFrame) && + (!((uint32_t)(frameIndex - ehciPipePointer->startFrame) & + (uint32_t)(ehciPipePointer->pipeCommon.interval - 1)))) + { + *frameBandwidth += ehciPipePointer->dataTime; + } + } + ehciPipePointer = (usb_host_ehci_pipe_t *)ehciPipePointer->pipeCommon.next; + } +} + +static void USB_HostBandwidthHsHostComputeCurrentFsls(usb_host_ehci_instance_t *ehciInstance, + uint32_t hubNumber, + uint16_t frameIndex, + uint8_t frameBandwidths[8]) +{ + usb_host_ehci_pipe_t *ehciPipePointer; + uint8_t index; + uint32_t deviceInfo; + + for (index = 0; index < 8; ++index) + { + frameBandwidths[index] = 0; + } + + ehciPipePointer = ehciInstance->ehciRunningPipeList; + while (ehciPipePointer != NULL) + { + /* only compute iso and interrupt pipe */ + if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) || + (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)) + { + /* compute FS/LS bandwidth that blong to same high-speed hub, because FS/LS bandwidth is allocated from + * first parent high-speed hub */ + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, + kUSB_HostGetDeviceHSHubNumber, &deviceInfo); + if (deviceInfo != hubNumber) + { + ehciPipePointer = (usb_host_ehci_pipe_t *)ehciPipePointer->pipeCommon.next; + continue; + } + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, + &deviceInfo); + if (deviceInfo == USB_SPEED_HIGH) + { + ehciPipePointer = (usb_host_ehci_pipe_t *)ehciPipePointer->pipeCommon.next; + continue; + } + + /* does pipe allocate bandwidth in frameIndex frame? note: interval is power of 2. */ + if ((frameIndex >= ehciPipePointer->startFrame) && + (!((uint32_t)(frameIndex - ehciPipePointer->startFrame) & + (uint32_t)(ehciPipePointer->pipeCommon.interval - 1)))) + { + if (ehciPipePointer->pipeCommon.pipeType == + USB_ENDPOINT_ISOCHRONOUS) /* iso bandwidth is allocated once */ + { + frameBandwidths[ehciPipePointer->startUframe + 1] += ehciPipePointer->dataTime; + } + else /* iso bandwidth is allocated three times */ + { + frameBandwidths[ehciPipePointer->startUframe + 1] += ehciPipePointer->dataTime; + frameBandwidths[ehciPipePointer->startUframe + 2] += ehciPipePointer->dataTime; + frameBandwidths[ehciPipePointer->startUframe + 3] += ehciPipePointer->dataTime; + } + } + } + ehciPipePointer = (usb_host_ehci_pipe_t *)ehciPipePointer->pipeCommon.next; + } + + for (index = 0; index < 7; ++index) /* */ + { + if (frameBandwidths[index] > s_SlotMaxBandwidth[index]) + { + frameBandwidths[index + 1] += (frameBandwidths[index] - s_SlotMaxBandwidth[index]); + frameBandwidths[index] = s_SlotMaxBandwidth[index]; + } + } +} + +static void USB_HostBandwidthHsHostComputeCurrentHsAll(usb_host_ehci_instance_t *ehciInstance, + uint16_t frameIndex, + uint8_t frameBandwidths[8]) +{ + usb_host_ehci_pipe_t *ehciPipePointer; + uint8_t index; + uint32_t deviceInfo; + uint16_t frameInterval; + + for (index = 0; index < 8; ++index) + { + frameBandwidths[index] = 0; + } + + ehciPipePointer = ehciInstance->ehciRunningPipeList; + while (ehciPipePointer != NULL) + { + /* only compute iso and interrupt pipe */ + if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) || + (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT)) + { + frameInterval = ehciPipePointer->pipeCommon.interval; + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, + &deviceInfo); + if (deviceInfo == USB_SPEED_HIGH) /* high-speed data bandwidth */ + { + /* frameInterval means micro-frame here */ + if (frameIndex >= ehciPipePointer->startFrame) + { + if ((frameInterval > 8) && + (frameIndex * 8 - ehciPipePointer->startFrame * 8 >= ehciPipePointer->startUframe)) + { + if (!((uint32_t)(frameIndex * 8 - ehciPipePointer->startFrame * 8 - + ehciPipePointer->startUframe) & + (uint32_t)(frameInterval - 1))) + { + frameBandwidths[ehciPipePointer->startUframe] += ehciPipePointer->dataTime; + } + } + else + { + for (index = ehciPipePointer->startUframe; index < 8; index += frameInterval) + { + frameBandwidths[index] += ehciPipePointer->dataTime; + } + } + } + } + else /* full-speed split bandwidth */ + { + if ((frameIndex >= ehciPipePointer->startFrame) && + (!((uint32_t)(frameIndex - ehciPipePointer->startFrame) & (uint32_t)(frameInterval - 1)))) + { + for (index = 0; index < 8; ++index) + { + if ((uint32_t)(ehciPipePointer->uframeSmask) & + (uint32_t)(0x01 << index)) /* start-split micro-frames */ + { + frameBandwidths[index] += ehciPipePointer->startSplitTime; + } + if ((uint32_t)(ehciPipePointer->uframeCmask) & + (uint32_t)(0x01 << index)) /* complete-split micro-frames */ + { + frameBandwidths[index] += ehciPipePointer->completeSplitTime; + } + } + } + } + } + ehciPipePointer = (usb_host_ehci_pipe_t *)ehciPipePointer->pipeCommon.next; + } + + for (index = 0; index < 7; ++index) /* */ + { + if (frameBandwidths[index] > s_SlotMaxBandwidth[index]) + { + frameBandwidths[index + 1] += (frameBandwidths[index] - s_SlotMaxBandwidth[index]); + frameBandwidths[index] = s_SlotMaxBandwidth[index]; + } + } +} + +/*! + * @brief allocate HS bandwidth when host work as high-speed host. + * + * @param ehciInstance ehci instance pointer. + * @param uframeInterval micro-frame interval. + * @param timeData time for allocating. + * @param uframeIndexOut return start uframe index. + * + * @return kStatus_USB_Success or error codes. + */ +static usb_status_t USB_HostBandwidthHsHostAllocateHsCommon(usb_host_ehci_instance_t *ehciInstance, + uint16_t uframeInterval, + uint16_t timeData, + uint16_t *uframeIndexOut) +{ + uint16_t uframeIntervalIndex; + uint16_t uframeIndex; + uint16_t frameIndex; + uint8_t frameTimes[8]; + + frameIndex = 0; + USB_HostBandwidthHsHostComputeCurrentHsAll( + ehciInstance, frameIndex, frameTimes); /* compute the allocated bandwidths in the frameIndex frame */ + for (uframeIntervalIndex = 0; (uframeIntervalIndex < uframeInterval); ++uframeIntervalIndex) /* start micro-frame */ + { + /* for all the micro-frame in interval uframeInterval */ + for (uframeIndex = uframeIntervalIndex; uframeIndex < (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8); + uframeIndex += uframeInterval) + { + if (frameIndex != (uframeIndex >> 3)) + { + frameIndex = (uframeIndex >> 3); + USB_HostBandwidthHsHostComputeCurrentHsAll( + ehciInstance, frameIndex, + frameTimes); /* compute the allocated bandwidths in the new frameIndex frame */ + } + if (frameTimes[uframeIndex & 0x0007] + timeData > + s_SlotMaxBandwidth[(uframeIndex & 0x0007)]) /* micro-frame has enough idle bandwidth? */ + { + break; /* fail */ + } + } + if (uframeIndex >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 8)) /* success? */ + { + break; + } + } + + if (uframeIntervalIndex < uframeInterval) + { + *uframeIndexOut = (uframeIntervalIndex); + return kStatus_USB_Success; + } + else + { + return kStatus_USB_Error; + } +} + +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + +static usb_status_t USB_HostBandwidthHsHostAllocateIso(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_status_t status; + uint32_t deviceInfo; + uint32_t hubNumber; + uint16_t uframeIntervalIndex = 0; + uint16_t frameIntervalIndex = 0; + uint16_t frameIndex; + uint16_t timeCompleteSplit; + uint16_t timeStartSplit; + uint32_t timeData; + uint8_t SsCsNumber = 0; + uint16_t frameInterval; + uint8_t frameTimes[8]; + uint8_t allocateOk = 1; + uint8_t index; + + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, + &deviceInfo); + + timeData = USB_HostBandwidthComputeTime( + deviceInfo, USB_ENDPOINT_ISOCHRONOUS, ehciPipePointer->pipeCommon.direction, + ehciPipePointer->pipeCommon.maxPacketSize * ehciPipePointer->pipeCommon.numberPerUframe); + /* pipe is high-speed */ + if (deviceInfo == USB_SPEED_HIGH) + { + uframeIntervalIndex = 0; + status = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval, timeData, + &uframeIntervalIndex); + if (status == kStatus_USB_Success) + { + ehciPipePointer->startFrame = (uframeIntervalIndex / 8); + ehciPipePointer->startUframe = (uframeIntervalIndex & 0x0007); + ehciPipePointer->dataTime = timeData; + + return kStatus_USB_Success; + } + } + else /* pipe is full-speed or low-speed */ + { + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetHubThinkTime, + &deviceInfo); /* deviceInfo variable means hub think time */ + timeData += (deviceInfo * 7 / (6 * 12)); + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceHSHubNumber, + &hubNumber); + frameInterval = ehciPipePointer->pipeCommon.interval; + + /* compute start-split and complete-split bandwidth */ + if (ehciPipePointer->pipeCommon.direction == USB_OUT) + { + timeStartSplit = USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_OUT, + ehciPipePointer->pipeCommon.maxPacketSize); + timeCompleteSplit = 0; + } + else + { + timeStartSplit = USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN, 1); + timeCompleteSplit = USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_ISOCHRONOUS, USB_IN, + ehciPipePointer->pipeCommon.maxPacketSize); + } + /* note: bandwidth must put in one frame */ + for (uframeIntervalIndex = 0; uframeIntervalIndex <= 5; ++uframeIntervalIndex) /* uframe interval */ + { + for (frameIntervalIndex = 0; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */ + { + allocateOk = 1; + for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; + frameIndex += frameInterval) /* check all the frames */ + { + /* compute start-split and complete-split number */ + SsCsNumber = (ehciPipePointer->pipeCommon.maxPacketSize + 187) / + 188; /* ss number for iso out; cs number for iso in */ + if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */ + { + if (uframeIntervalIndex + SsCsNumber > 8) + { + allocateOk = 0; + } + } + else + { + if (uframeIntervalIndex + 2 + SsCsNumber > + 8) /* ISO IN: there are two micro-frame interval between start-split and complete-split */ + { + allocateOk = 0; + } + } + if (allocateOk) + { + /* allocate start-split and complete-split bandwidth */ + USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes); + if (ehciPipePointer->pipeCommon.direction == USB_OUT) /* ISO OUT */ + { + index = uframeIntervalIndex; + for (; index < (uframeIntervalIndex + SsCsNumber); ++index) + { + if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidth[index]) + { + allocateOk = 0; + break; + } + } + } + else /* ISO IN */ + { + index = uframeIntervalIndex; + if (frameTimes[index] + timeStartSplit > s_SlotMaxBandwidth[index]) + { + allocateOk = 0; + } + if (allocateOk) + { + index = + uframeIntervalIndex + + 2; /* there are two micro-frames interval between start-split and complete-split */ + for (; index < (uframeIntervalIndex + 2 + SsCsNumber); ++index) + { + if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidth[index]) + { + allocateOk = 0; + break; + } + } + } + } + } + + /* allocate data bandwidth */ + if (allocateOk) + { + USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes); + index = uframeIntervalIndex + 1; /* timeData bandwidth start position */ + /* iso must occupy all the uframe bandwidth */ + { + deviceInfo = timeData; /* note: deviceInfo variable means bandwidth here */ + while ((index < 8) && (deviceInfo > s_SlotMaxBandwidth[index])) + { + if (frameTimes[index] > 0) + { + allocateOk = 0; + break; + } + else + { + deviceInfo -= s_SlotMaxBandwidth[index]; + } + ++index; + } + } + } + if (allocateOk) + { + /* data bandwidth can be put in the frame? */ + index = uframeIntervalIndex + 1; /* timeData bandwidth start position */ + frameTimes[index] += timeData; + for (; index < 7; ++index) + { + if (frameTimes[index] > s_SlotMaxBandwidth[index]) + { + frameTimes[index + 1] += (frameTimes[index] - s_SlotMaxBandwidth[index]); + frameTimes[index] = s_SlotMaxBandwidth[index]; + } + else + { + break; + } + } + if (frameTimes[index] > s_SlotMaxBandwidth[index]) + { + allocateOk = 0; + } + } + + if (allocateOk) + { + break; + } + } + if (allocateOk) + { + break; + } + } + if (allocateOk) + { + break; + } + } + + if (allocateOk) + { + ehciPipePointer->startFrame = frameIntervalIndex; + ehciPipePointer->startUframe = uframeIntervalIndex; + ehciPipePointer->dataTime = timeData; + ehciPipePointer->startSplitTime = timeStartSplit; + ehciPipePointer->completeSplitTime = timeCompleteSplit; + if (ehciPipePointer->pipeCommon.direction == USB_OUT) + { + index = uframeIntervalIndex; + for (; index < (uframeIntervalIndex + SsCsNumber); ++index) + { + ehciPipePointer->uframeSmask = (uint32_t)ehciPipePointer->uframeSmask | (uint32_t)(0x01 << index); + } + } + else + { + index = uframeIntervalIndex; + ehciPipePointer->uframeSmask = (uint32_t)ehciPipePointer->uframeSmask | (uint32_t)(0x01 << index); + index = uframeIntervalIndex + 2; + for (; index < (uframeIntervalIndex + 2 + SsCsNumber); ++index) + { + ehciPipePointer->uframeCmask = (uint32_t)ehciPipePointer->uframeCmask | (uint32_t)(0x01 << index); + } + } + + return kStatus_USB_Success; + } + } + + return kStatus_USB_Error; +} + +#endif + +static usb_status_t USB_HostBandwidthHsHostAllocateInterrupt(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_status_t status; + uint32_t deviceInfo; + uint32_t hubNumber; + uint16_t uframeIntervalIndex = 0; + uint16_t frameIntervalIndex = 0; + uint16_t frameIndex; + uint16_t timeCompleteSplit; + uint16_t timeStartSplit; + uint32_t timeData; + uint8_t SsCsNumber; + uint16_t frameInterval; + uint8_t frameTimes[8]; + uint8_t allocateOk = 1; + uint8_t index; + + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, + &deviceInfo); + + timeData = USB_HostBandwidthComputeTime( + deviceInfo, USB_ENDPOINT_INTERRUPT, ehciPipePointer->pipeCommon.direction, + ehciPipePointer->pipeCommon.maxPacketSize * ehciPipePointer->pipeCommon.numberPerUframe); + /* pipe is high-speed */ + if (deviceInfo == USB_SPEED_HIGH) + { + uframeIntervalIndex = 0; + status = USB_HostBandwidthHsHostAllocateHsCommon(ehciInstance, ehciPipePointer->uframeInterval, timeData, + &uframeIntervalIndex); + if (status == kStatus_USB_Success) + { + ehciPipePointer->startFrame = (uframeIntervalIndex / 8); + ehciPipePointer->startUframe = (uframeIntervalIndex & 0x0007); + /* for HS interrupt start transaction position */ + if (ehciPipePointer->uframeInterval >= 8) + { + ehciPipePointer->uframeSmask = (0x01 << ehciPipePointer->startUframe); + } + else + { + ehciPipePointer->uframeSmask = 0x00u; + for (index = ehciPipePointer->startUframe; index < 8; index += ehciPipePointer->uframeInterval) + { + ehciPipePointer->uframeSmask |= (0x01U << index); + } + } + ehciPipePointer->dataTime = timeData; + + return kStatus_USB_Success; + } + } + else /* pipe is full-speed or low-speed */ + { + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetHubThinkTime, + &deviceInfo); + timeData += (deviceInfo * 7 / (6 * 12)); + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceHSHubNumber, + &hubNumber); + frameInterval = ehciPipePointer->pipeCommon.interval; + SsCsNumber = 3; /* complete split number */ + + /* compute start-split and complete-split bandwidth */ + if (ehciPipePointer->pipeCommon.direction == USB_OUT) + { + timeStartSplit = USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, + ehciPipePointer->pipeCommon.maxPacketSize) + + USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 1); + timeCompleteSplit = USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_OUT, 0); + } + else + { + timeStartSplit = USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 1); + timeCompleteSplit = USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, + ehciPipePointer->pipeCommon.maxPacketSize) + + USB_HostBandwidthComputeTime(USB_SPEED_HIGH, USB_ENDPOINT_INTERRUPT, USB_IN, 0); + } + /* note: bandwidth must put in one frame */ + for (uframeIntervalIndex = 0; uframeIntervalIndex <= 4; ++uframeIntervalIndex) /* uframe interval */ + { + for (frameIntervalIndex = 0; frameIntervalIndex < frameInterval; ++frameIntervalIndex) /* frame interval */ + { + allocateOk = 1; + for (frameIndex = frameIntervalIndex; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; + frameIndex += frameInterval) /* check all the frames */ + { + /* allocate data bandwidth */ + USB_HostBandwidthHsHostComputeCurrentFsls(ehciInstance, hubNumber, frameIndex, frameTimes); + index = uframeIntervalIndex + 1; + for (; index <= (uframeIntervalIndex + 3); ++index) /* data bandwidth number is 3. + uframeIntervalIndex don't exceed 4, so + index cannot exceed 7 */ + { + if (frameTimes[index] + timeData > s_SlotMaxBandwidth[index]) + { + allocateOk = 0; + break; + } + } + + if (allocateOk) + { + USB_HostBandwidthHsHostComputeCurrentHsAll(ehciInstance, frameIndex, frameTimes); + /* allocate start_split bandwidth */ + if (frameTimes[uframeIntervalIndex] + timeStartSplit > s_SlotMaxBandwidth[uframeIntervalIndex]) + { + allocateOk = 0; + } + if (allocateOk) + { + /* allocate complete_split bandwidth */ + index = uframeIntervalIndex + 2; + /* complete-split number is normal 3. When uframeIntervalIndex is 4, complete-split number + * is 2. */ + for (; (index <= (uframeIntervalIndex + 1 + SsCsNumber)) && (index < 8); ++index) + { + if (frameTimes[index] + timeCompleteSplit > s_SlotMaxBandwidth[index]) + { + allocateOk = 0; + break; + } + } + } + } + + if (!allocateOk) + { + break; /* allocate fail */ + } + } + if (allocateOk) + { + break; + } + } + if (allocateOk) + { + break; + } + } + + if (allocateOk) + { + ehciPipePointer->startFrame = frameIntervalIndex; + ehciPipePointer->startUframe = uframeIntervalIndex; + ehciPipePointer->uframeSmask = (0x01 << ehciPipePointer->startUframe); + ehciPipePointer->uframeCmask = 0; + index = uframeIntervalIndex + 2; + for (; (index <= (uframeIntervalIndex + 1 + SsCsNumber)) && (index < 8); ++index) + { + ehciPipePointer->uframeCmask = (uint32_t)ehciPipePointer->uframeCmask | (uint32_t)(0x01 << index); + } + ehciPipePointer->dataTime = timeData; + ehciPipePointer->startSplitTime = timeStartSplit; + ehciPipePointer->completeSplitTime = timeCompleteSplit; + + return kStatus_USB_Success; + } + } + + return kStatus_USB_BandwidthFail; +} + +static usb_status_t USB_HostBandwidthFslsHostAllocate(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + uint32_t FslsTime = 0; + uint32_t speed = 0; + uint16_t uframeIntervalIndex; + uint16_t frameIndex; + uint16_t frameInterval; + uint16_t frameTime; + + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetHubThinkTime, + &FslsTime); + FslsTime += (FslsTime * 7 / (6 * 12)); + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, &speed); + FslsTime = FslsTime + USB_HostBandwidthComputeTime(speed, ehciPipePointer->pipeCommon.pipeType, + ehciPipePointer->pipeCommon.direction, + ehciPipePointer->pipeCommon.maxPacketSize); + + frameInterval = ehciPipePointer->pipeCommon.interval; + for (uframeIntervalIndex = 0; uframeIntervalIndex < ehciPipePointer->uframeInterval; + ++uframeIntervalIndex) /* uframeIntervalIndex can exceed 8 */ + { + for (frameIndex = (uframeIntervalIndex >> 3); frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; + frameIndex += frameInterval) + { + USB_HostBandwidthFslsHostComputeCurrent(ehciInstance, frameIndex, &frameTime); + if (frameTime + FslsTime > USB_HOST_EHCI_BANDWIDTH_FRAME_TOTOAL_TIME) + { + break; + } + } + if (frameIndex >= USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE) + { + break; + } + } + if (uframeIntervalIndex < ehciPipePointer->uframeInterval) + { + ehciPipePointer->startFrame = (uframeIntervalIndex >> 3); + ehciPipePointer->startUframe = (uframeIntervalIndex & 0x0007); + ehciPipePointer->uframeSmask = 0; /* useless */ + ehciPipePointer->uframeCmask = 0; + ehciPipePointer->dataTime = FslsTime; + + return kStatus_USB_Success; + } + + return kStatus_USB_BandwidthFail; +} + +static uint8_t USB_HostEhciGet2PowerValue(uint8_t value) +{ + if ((value == 0) || (value == 1)) + { + return value; + } + if (value & 0xf0) + { + if (value & 0x80) + { + return 128; + } + else if (value & 0x40) + { + return 64; + } + else if (value & 0x20) + { + return 32; + } + else + { + return 16; + } + } + else + { + if (value & 0x08) + { + return 8; + } + else if (value & 0x04) + { + return 4; + } + else if (value & 0x02) + { + return 2; + } + else + { + return 1; + } + } +} + +static void USB_HostEhciZeroMem(uint32_t *buffer, uint32_t length) +{ + /* note: the zero unit is uint32_t */ + while (length--) + { + *buffer = 0; + buffer++; + } +} + +static void USB_HostEhciDelay(USBHS_Type *ehciIpBase, uint32_t ms) +{ + /* note: the max delay time cannot exceed half of max value (0x4000) */ + int32_t sofStart; + int32_t SofEnd; + uint32_t distance; + + sofStart = (int32_t)(ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE); + + do + { + SofEnd = (int32_t)(ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE); + distance = (uint32_t)(SofEnd - sofStart + EHCI_MAX_UFRAME_VALUE + 1); + } while ((distance & EHCI_MAX_UFRAME_VALUE) < (ms * 8)); /* compute the distance between sofStart and SofEnd */ +} + +static void USB_HostEhciStartAsync(usb_host_ehci_instance_t *ehciInstance) +{ + uint32_t stateSync; + + if (!(ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK)) + { + /* the status must be same when change USBCMD->ASE */ + do + { + stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) | + (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK)); + } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK)); + + ehciInstance->ehciIpBase->ASYNCLISTADDR = (uint32_t)(ehciInstance->shedFirstQh); + ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_ASE_MASK; + while (!(ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK)) + { + } + } +} + +static void USB_HostEhciStopAsync(usb_host_ehci_instance_t *ehciInstance) +{ + uint32_t stateSync; + + /* the status must be same when change USBCMD->ASE */ + do + { + stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) | + (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_ASE_MASK)); + } while ((stateSync == USBHS_USBSTS_AS_MASK) || (stateSync == USBHS_USBCMD_ASE_MASK)); + + ehciInstance->ehciIpBase->USBCMD &= (uint32_t)(~(uint32_t)USBHS_USBCMD_ASE_MASK); /* disable async schedule */ + while (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) + { + } +} + +static void USB_HostEhciStartPeriodic(usb_host_ehci_instance_t *ehciInstance) +{ + uint32_t stateSync; + + if (!(ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK)) + { + /* the status must be same when change USBCMD->PSE */ + do + { + stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) | + (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK)); + } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK)); + ehciInstance->ehciIpBase->PERIODICLISTBASE = (uint32_t)(ehciInstance->ehciFrameList); + if (!(ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK)) + { + ehciInstance->ehciIpBase->USBCMD |= USBHS_USBCMD_PSE_MASK; /* start periodic schedule */ + } + while (!(ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK)) + { + } + } + return; +} + +static void USB_HostEhciStopPeriodic(usb_host_ehci_instance_t *ehciInstance) +{ + uint32_t stateSync; + + /* the status must be same when change USBCMD->PSE */ + do + { + stateSync = ((ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) | + (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_PSE_MASK)); + } while ((stateSync == USBHS_USBSTS_PS_MASK) || (stateSync == USBHS_USBCMD_PSE_MASK)); + + ehciInstance->ehciIpBase->USBCMD &= (~USBHS_USBCMD_PSE_MASK); /* stop periodic schedule */ + while (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_PS_MASK) + { + } +} + +static usb_status_t USB_HostEhciQhQtdListInit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer) +{ + volatile usb_host_ehci_qh_t *vltQhPointer; + usb_host_ehci_qtd_t *qtdPointer = NULL; + usb_host_ehci_qtd_t *BaseQtdPointer = NULL; + volatile uint32_t *entryPointer; + uint32_t qtdNumber; + uint32_t dataLength; + uint32_t dataAddress; + uint32_t endAddress; + uint8_t index; + + /* compute the qtd number */ + if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL) + { + /* assume setup data don't exceed one qtd data size, one qtd can transfer least 16k data */ + if (transfer->transferLength == 0) + { + qtdNumber = 2; + } + else + { + qtdNumber = 3; + } + } + else + { + qtdNumber = + (((transfer->transferLength) & 0xFFFFC000U) >> 14) + (((transfer->transferLength) & 0x00003FFF) ? 1 : 0); + } + + vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + /* get qtd list */ + USB_HostEhciLock(); + if (qtdNumber <= ehciInstance->ehciQtdNumber) + { + ehciInstance->ehciQtdNumber -= qtdNumber; + BaseQtdPointer = ehciInstance->ehciQtdHead; + qtdPointer = NULL; + do + { + if (qtdPointer != NULL) + { + qtdPointer->nextQtdPointer = (uint32_t)ehciInstance->ehciQtdHead; + } + qtdPointer = ehciInstance->ehciQtdHead; + ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer; + qtdPointer->nextQtdPointer = 0; + } while (--qtdNumber); + if (ehciInstance->ehciQtdNumber == 0) + { + ehciInstance->ehciQtdTail = NULL; + } + } + else + { + USB_HostEhciUnlock(); + return kStatus_USB_Error; + } + USB_HostEhciUnlock(); + + /* int qTD list */ + if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL) + { + /* setup transaction qtd */ + qtdPointer = BaseQtdPointer; + qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + /* dt: need set; ioc: 0; C_Page: 0; PID Code: SETUP; Status: Active */ + qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0; + qtdPointer->transferResults[0] = + ((0x00000000 << EHCI_HOST_QTD_DT_SHIFT) | (8 << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) | + (EHCI_HOST_PID_SETUP << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + dataAddress = ((uint32_t)transfer->setupPacket); + qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */ + /* set buffer pointer no matter data length */ + for (index = 0; index < 4; ++index) + { + qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000U); + } + + /* data transaction qtd */ + dataLength = transfer->transferLength; + if (dataLength != 0) + { + qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer); + + qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + /* dt: need set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */ + qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0; + if (transfer->direction == USB_OUT) + { + qtdPointer->transferResults[0] = + ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) | + (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + } + else + { + qtdPointer->transferResults[0] = + ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (dataLength << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) | + (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + } + + dataAddress = (uint32_t)transfer->transferBuffer; + qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */ + /* set buffer pointer no matter data length */ + for (index = 0; index < 4; ++index) + { + qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000U); + } + } + + /* status transaction qtd */ + qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer); + qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + /* dt: dont care; ioc: 1; C_Page: 0; PID Code: IN/OUT; Status: Active */ + qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0; + if ((dataLength == 0) || (transfer->direction == USB_OUT)) + { + qtdPointer->transferResults[0] = + ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | + (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + } + else + { + qtdPointer->transferResults[0] = + ((0x00000001U << EHCI_HOST_QTD_DT_SHIFT) | (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | + (EHCI_HOST_QTD_IOC_MASK) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + } + qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE; + } + else + { + dataLength = transfer->transferLength; + dataAddress = (uint32_t)transfer->transferBuffer; + qtdPointer = BaseQtdPointer; + while (1) + { + endAddress = dataAddress + (16 * 1024); + if (endAddress > (uint32_t)(transfer->transferBuffer + transfer->transferLength)) + { + endAddress = (uint32_t)(transfer->transferBuffer + transfer->transferLength); + } + + qtdPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + /* dt: set; ioc: 0; C_Page: 0; PID Code: IN/OUT; Status: Active */ + qtdPointer->transferResults[0] = qtdPointer->transferResults[1] = 0; + if (transfer->direction == USB_OUT) + { + qtdPointer->transferResults[0] = + (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) | + ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) | + (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) | + (EHCI_HOST_PID_OUT << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + } + else + { + qtdPointer->transferResults[0] = + (((endAddress - dataAddress) << EHCI_HOST_QTD_TOTAL_BYTES_SHIFT) | + ((uint32_t)ehciPipePointer->pipeCommon.nextdata01 << EHCI_HOST_QTD_DT_SHIFT) | + (EHCI_HOST_QTD_CERR_MAX_VALUE << EHCI_HOST_QTD_CERR_SHIFT) | + (EHCI_HOST_PID_IN << EHCI_HOST_QTD_PID_CODE_SHIFT) | (EHCI_HOST_QTD_STATUS_ACTIVE_MASK)); + } + qtdPointer->transferResults[1] = dataAddress; /* current offset is set too */ + /* set buffer pointer no matter data length */ + for (index = 0; index < 4; ++index) + { + qtdPointer->bufferPointers[index] = ((dataAddress + (index + 1) * 4 * 1024) & 0xFFFFF000U); + } + dataAddress = endAddress; /* for next qtd */ + + if (qtdPointer->nextQtdPointer == 0) + { + break; + } + qtdPointer = (usb_host_ehci_qtd_t *)(qtdPointer->nextQtdPointer); + } + + qtdPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE; + qtdPointer->transferResults[0] |= EHCI_HOST_QTD_IOC_MASK; /* last one set IOC */ + } + + /* save qtd to transfer */ + transfer->union1.unitHead = (uint32_t)BaseQtdPointer; + transfer->union2.unitTail = (uint32_t)qtdPointer; + /* link transfer to qh */ + transfer->next = NULL; + if (vltQhPointer->ehciTransferHead == NULL) + { + transfer->next = NULL; + vltQhPointer->ehciTransferHead = vltQhPointer->ehciTransferTail = transfer; + } + else + { + transfer->next = NULL; + vltQhPointer->ehciTransferTail->next = transfer; + vltQhPointer->ehciTransferTail = transfer; + } + + USB_HostEhciLock(); + /* link qtd to qh (link to end) */ + entryPointer = &(vltQhPointer->nextQtdPointer); + dataAddress = *entryPointer; /* dataAddress variable means entry value here */ + while ((dataAddress) && (!(dataAddress & EHCI_HOST_T_INVALID_VALUE))) + { + entryPointer = (volatile uint32_t *)dataAddress; + dataAddress = *entryPointer; + } + *entryPointer = (uint32_t)BaseQtdPointer; + USB_HostEhciUnlock(); + USB_HostEhciStartAsync(ehciInstance); + + return kStatus_USB_Success; +} + +static uint32_t USB_HostEhciQtdListRelease(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_qtd_t *ehciQtdStart, + usb_host_ehci_qtd_t *ehciQtdEnd) +{ + uint32_t length = 0; + usb_host_ehci_qtd_t *qtdPointer; + + ehciQtdEnd->nextQtdPointer = 0; + + /* compute remaining length */ + qtdPointer = ehciQtdStart; + while (qtdPointer != ehciQtdEnd) + { + length += + ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT); + qtdPointer = (usb_host_ehci_qtd_t *)qtdPointer->nextQtdPointer; + } + qtdPointer = ehciQtdEnd; + length += ((qtdPointer->transferResults[0] & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> EHCI_HOST_QTD_TOTAL_BYTES_SHIFT); + + /* put releasing qtd to idle qtd list */ + USB_HostEhciLock(); + if (ehciInstance->ehciQtdNumber == 0) + { + ehciInstance->ehciQtdHead = ehciQtdStart; + ehciInstance->ehciQtdTail = ehciQtdEnd; + } + else + { + ehciInstance->ehciQtdTail->nextQtdPointer = (uint32_t)ehciQtdStart; + ehciInstance->ehciQtdTail = ehciQtdEnd; + } + + while (ehciQtdStart != ehciQtdEnd) + { + ehciInstance->ehciQtdNumber++; + ehciQtdStart = (usb_host_ehci_qtd_t *)ehciQtdStart->nextQtdPointer; + } + ehciInstance->ehciQtdNumber++; + USB_HostEhciUnlock(); + + return length; +} + +static usb_status_t USB_HostEhciQhQtdListDeinit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + volatile usb_host_ehci_qh_t *vltQhPointer; + usb_host_transfer_t *transfer; + usb_host_transfer_t *nextTransfer; + uint8_t needStop = 0; + + vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + + USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */ + /* remove qtd from qh */ + if ((!((uint32_t)vltQhPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE)) || + (!((uint32_t)vltQhPointer->currentQtdPointer & EHCI_HOST_T_INVALID_VALUE))) + { + /* need stop async schedule */ + if ((!(vltQhPointer->horizontalLinkPointer & EHCI_HOST_T_INVALID_VALUE)) && + (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT)) + { + needStop = 1; + } + if (needStop) + { + USB_HostEhciStopAsync(ehciInstance); + } + vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */ + vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */ + vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */ + if (needStop) + { + USB_HostEhciStartAsync(ehciInstance); + } + } + + /* remove transfer from the QH transfer list */ + transfer = vltQhPointer->ehciTransferHead; + vltQhPointer->ehciTransferHead = vltQhPointer->ehciTransferTail = NULL; + USB_HostEhciUnlock(); + + /* release qtd and transfer callback*/ + while (transfer != NULL) + { + nextTransfer = transfer->next; /* the transfer is released when call back */ + transfer->transferSofar = + USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead), + (usb_host_ehci_qtd_t *)(transfer->union2.unitTail)); + transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ? + 0 : + (transfer->transferLength - transfer->transferSofar); + transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel); + transfer = nextTransfer; + } + + return kStatus_USB_Success; +} + +static usb_status_t USB_HostEhciTransferQtdListDeinit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer) +{ + volatile usb_host_ehci_qh_t *vltQhPointer; + usb_host_transfer_t *preSearchTransfer; + uint32_t qhNextQtdValue; + uint32_t qtdPointerEntry; + uint32_t *searchQtdEntryPointer; + + vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + + USB_HostEhciLock(); /* this API is called from APP, the host task may occupy to access the same resource */ + /* remove qtd from qh */ + qhNextQtdValue = (uint32_t)vltQhPointer->currentQtdPointer; + qtdPointerEntry = *((uint32_t *)qhNextQtdValue + 2); /* note: qtdPointerEntry means qtd status */ + if ((qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE) || (!(qtdPointerEntry & EHCI_HOST_QTD_STATUS_ACTIVE_MASK))) + { + qhNextQtdValue = (uint32_t)vltQhPointer->nextQtdPointer; + } + if (!(qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE)) /* there is pending qtd in the qh */ + { + /* this qh don't schedule temporarily */ + if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT) + { + USB_HostEhciStopAsync(ehciInstance); + } + vltQhPointer->currentQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid current qtd */ + vltQhPointer->nextQtdPointer |= EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */ + if (ehciPipePointer->pipeCommon.pipeType != USB_ENDPOINT_INTERRUPT) + { + USB_HostEhciStartAsync(ehciInstance); + } + + /* remove qtd from qh one by one */ + qtdPointerEntry = transfer->union1.unitHead; + while (1) + { + /* search qh's qtd list for qtdPointerEntry */ + searchQtdEntryPointer = &qhNextQtdValue; + while (!((*searchQtdEntryPointer) & EHCI_HOST_T_INVALID_VALUE)) + { + if ((*searchQtdEntryPointer) == qtdPointerEntry) + { + *searchQtdEntryPointer = *((uint32_t *)qtdPointerEntry); /* remove the qtd from qh */ + break; + } + else + { + searchQtdEntryPointer = (uint32_t *)(*searchQtdEntryPointer); + } + } + if (qtdPointerEntry == transfer->union2.unitTail) + { + break; + } + qtdPointerEntry = *((uint32_t *)qtdPointerEntry); + } + } + + /* remove transfer from the QH transfer list */ + preSearchTransfer = vltQhPointer->ehciTransferHead; + if (preSearchTransfer == transfer) + { + vltQhPointer->ehciTransferHead = preSearchTransfer->next; + } + else + { + while (preSearchTransfer != NULL) + { + if (preSearchTransfer->next == transfer) + { + preSearchTransfer->next = transfer->next; + break; + } + else + { + preSearchTransfer = preSearchTransfer->next; + } + } + } + USB_HostEhciUnlock(); + + /* release qtd and callback */ + transfer->transferSofar = + USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead), + (usb_host_ehci_qtd_t *)(transfer->union2.unitTail)); + transfer->transferSofar = + (transfer->transferLength < transfer->transferSofar) ? 0 : (transfer->transferLength - transfer->transferSofar); + transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel); + + /* start this qh schedule */ + vltQhPointer->transferOverlayResults[0] &= (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */ + if ((qhNextQtdValue != 0) && (!(qhNextQtdValue & EHCI_HOST_T_INVALID_VALUE))) + { + vltQhPointer->nextQtdPointer = qhNextQtdValue; + } + + return kStatus_USB_Success; +} + +static usb_status_t USB_HostEhciQhInit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_host_ehci_qh_t *qhPointer = NULL; + uint32_t address, speed, portNumber, hubNumber; + uint32_t controlBits1 = 0; + uint32_t controlBits2 = 0; + /* get qh */ + USB_HostEhciLock(); + if (ehciInstance->ehciQhList != NULL) + { + qhPointer = (usb_host_ehci_qh_t *)ehciInstance->ehciQhList; + ehciInstance->ehciQhList = + (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK); + } + USB_HostEhciUnlock(); + if (qhPointer == NULL) + { +#ifdef HOST_EHCO + usb_echo("get qh error\r\n"); +#endif + return kStatus_USB_Error; + } + ehciPipePointer->ehciQh = (void *)qhPointer; + + /* initialize qh */ + USB_HostEhciZeroMem((uint32_t *)qhPointer, sizeof(usb_host_ehci_qh_t) / 4); + qhPointer->horizontalLinkPointer = EHCI_HOST_T_INVALID_VALUE; + qhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE; + qhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + qhPointer->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + qhPointer->ehciPipePointer = ehciPipePointer; + qhPointer->timeOutLabel = 0; + qhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE; + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, &speed); + /* initialize staticEndpointStates[0] */ + if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT) + { + /* Software should set the RL field to zero if the queue head is an interrupt endpoint. */ + controlBits1 |= ((0U << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK); + } + else + { + if (ehciPipePointer->pipeCommon.nakCount >= 16) + { + controlBits1 |= ((15U << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK); + } + else + { + controlBits1 |= + (((uint32_t)ehciPipePointer->pipeCommon.nakCount << EHCI_HOST_QH_RL_SHIFT) & EHCI_HOST_QH_RL_MASK); + } + } + if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL) + { + if (speed != USB_SPEED_HIGH) + { + controlBits1 |= (1 << EHCI_HOST_QH_C_SHIFT); + } + controlBits1 |= (1 << EHCI_HOST_QH_DTC_SHIFT); + } + controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT); + controlBits1 |= (speed << EHCI_HOST_QH_EPS_SHIFT); + controlBits1 |= ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_QH_ENDPT_SHIFT); + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceAddress, + &address); + controlBits1 |= (address << EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT); + qhPointer->staticEndpointStates[0] = controlBits1; + if (speed == USB_SPEED_HIGH) + { + controlBits2 |= ((uint32_t)ehciPipePointer->pipeCommon.numberPerUframe << EHCI_HOST_QH_MULT_SHIFT); + } + else + { + controlBits2 |= (0x00000001U << EHCI_HOST_QH_MULT_SHIFT); + } + /*initialize staticEndpointStates[1] */ + if (speed != USB_SPEED_HIGH) + { + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceHSHubNumber, + &hubNumber); + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceHSHubPort, + &portNumber); + } + else + { + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceHubNumber, + &hubNumber); + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDevicePortNumber, + &portNumber); + } + controlBits2 |= (portNumber << EHCI_HOST_QH_PORT_NUMBER_SHIFT); + controlBits2 |= (hubNumber << EHCI_HOST_QH_HUB_ADDR_SHIFT); + controlBits2 |= ((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_QH_UFRAME_CMASK_SHIFT); + controlBits2 |= ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_QH_UFRAME_SMASK_SHIFT); + qhPointer->staticEndpointStates[1] = controlBits2; + + return kStatus_USB_Success; +} + +static usb_status_t USB_HostEhciQhDeinit(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_host_ehci_qh_t *qhPointer; + + qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + /* de-initialize qtd from qh */ + USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer); + + /* release QH */ + USB_HostEhciLock(); + qhPointer->horizontalLinkPointer = (uint32_t)ehciInstance->ehciQhList; + ehciInstance->ehciQhList = qhPointer; + USB_HostEhciUnlock(); + + return kStatus_USB_Success; +} + +static void USB_HostEhciAddQhToFrame(usb_host_ehci_instance_t *ehciInstance, + uint32_t entryPointerValue, + uint16_t framePos, + uint16_t uframeInterval) +{ + volatile uint32_t *frameEntryPointer; + uint32_t frameEntryValue; + + /* search for the inserting point by interval */ + frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)ehciInstance->ehciFrameList)[framePos]); + while (frameEntryPointer) + { + frameEntryValue = *frameEntryPointer; + if (frameEntryValue & EHCI_HOST_T_INVALID_VALUE) + { + /* insert into the end */ + *((uint32_t *)entryPointerValue) = EHCI_HOST_T_INVALID_VALUE; + *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH); + break; + } + + if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue) + { + return; /* has inserted */ + } + if (((frameEntryValue & EHCI_HOST_POINTER_TYPE_MASK) == EHCI_HOST_POINTER_TYPE_QH) && + (((usb_host_ehci_qh_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK)) + ->ehciPipePointer->uframeInterval <= uframeInterval)) + { + /* insert into this point */ + *((uint32_t *)entryPointerValue) = frameEntryValue; + *frameEntryPointer = (entryPointerValue | EHCI_HOST_POINTER_TYPE_QH); + return; + } + else + { + frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK); + } + } +} + +static void USB_HostEhciRemoveFromFrame(usb_host_ehci_instance_t *ehciInstance, + uint32_t entryPointerValue, + uint16_t framePos) +{ + volatile uint32_t *frameEntryPointer; + uint32_t frameEntryValue; + + /* search for the qh/itd/sitd entry */ + frameEntryPointer = (volatile uint32_t *)(&((uint32_t *)ehciInstance->ehciFrameList)[framePos]); + + while (frameEntryPointer) + { + frameEntryValue = *frameEntryPointer; + if (frameEntryValue & EHCI_HOST_T_INVALID_VALUE) + { + return; + } + + if ((frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK) == entryPointerValue) + { + /* remove the entry */ + *frameEntryPointer = *((uint32_t *)entryPointerValue); + break; + } + else + { + frameEntryPointer = (volatile uint32_t *)(frameEntryValue & EHCI_HOST_POINTER_ADDRESS_MASK); + } + } +} + +#if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)) +static void USB_HostEhciLinkSitd(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + void *startEntryPointer) +{ + usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; + usb_host_ehci_sitd_t *sitdPointer; + uint32_t distance; + uint32_t frameInterval; + int32_t shouldLinkFrame; + int32_t currentFrame; + + frameInterval = (ehciPipePointer->uframeInterval >> 3); + + if (isoPointer->lastLinkFrame == 0xFFFF) /* first link */ + { + currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE) >> 3); + currentFrame = ((uint32_t)(currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) & + (EHCI_MAX_UFRAME_VALUE >> 3)); /* add USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER */ + /* frame should align with interval */ + currentFrame -= ehciPipePointer->startFrame; + currentFrame = + ((uint32_t)(currentFrame + frameInterval - 1) & (~(frameInterval - 1))); /* frameInterval is power of 2 */ + currentFrame += ehciPipePointer->startFrame; + } + else + { + shouldLinkFrame = isoPointer->lastLinkFrame + frameInterval; /* continuous next should link frame */ + if (shouldLinkFrame > (int32_t)(EHCI_MAX_UFRAME_VALUE >> 3)) + { + shouldLinkFrame = shouldLinkFrame - ((EHCI_MAX_UFRAME_VALUE >> 3) + 1); + } + currentFrame = ((ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE) >> 3); + distance = ((shouldLinkFrame - currentFrame + (EHCI_MAX_UFRAME_VALUE >> 3) + 1) & + (EHCI_MAX_UFRAME_VALUE >> 3)); /* get the distance from shouldLinkFrame to currentFrame */ + /* shouldLinkFrame has add frameInterval, think about the align with interval, so here add (frameInterval * + * 2) */ + if ((distance <= (USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER + frameInterval * 2)) && (distance > 0)) + { + currentFrame = shouldLinkFrame; + } + else /* re-link */ + { + currentFrame = + ((uint32_t)(currentFrame + USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER) & (EHCI_MAX_UFRAME_VALUE >> 3)); + if (currentFrame > (int32_t)(EHCI_MAX_UFRAME_VALUE >> 3)) + { + currentFrame = currentFrame - ((EHCI_MAX_UFRAME_VALUE >> 3) + 1); + } + /* frame should align with interval */ + currentFrame -= ehciPipePointer->startFrame; + currentFrame = ((uint32_t)(currentFrame + frameInterval - 1) & (~(frameInterval - 1))); + currentFrame += ehciPipePointer->startFrame; + } + } + if (currentFrame >= (int32_t)USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE) /* frame turn around */ + { + shouldLinkFrame = + (currentFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE); /* shouldLinkFrame means inserted frame position */ + } + else + { + shouldLinkFrame = currentFrame; /* shouldLinkFrame means inserted frame position */ + } + + sitdPointer = (usb_host_ehci_sitd_t *)startEntryPointer; + while (sitdPointer) + { + sitdPointer->frameEntryIndex = shouldLinkFrame; + /* add to frame list head */ + sitdPointer->nextLinkPointer = ((uint32_t *)ehciInstance->ehciFrameList)[shouldLinkFrame]; + ((uint32_t *)ehciInstance->ehciFrameList)[shouldLinkFrame] = + ((uint32_t)sitdPointer | EHCI_HOST_POINTER_TYPE_SITD); + if (sitdPointer->nextSitdIndex == 0xFF) /* 0xFF is invalid value */ + { + break; + } + sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]); /* next sitd */ + + shouldLinkFrame += frameInterval; + currentFrame += frameInterval; + if (shouldLinkFrame >= (int32_t)USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE) + { + shouldLinkFrame = (shouldLinkFrame - USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE); + } + } + + if (currentFrame > (int32_t)(EHCI_MAX_UFRAME_VALUE >> 3)) + { + currentFrame = currentFrame - ((EHCI_MAX_UFRAME_VALUE >> 3) + 1); + } + isoPointer->lastLinkFrame = currentFrame; /* save the last link frame value */ +} + +static usb_status_t USB_HostEhciSitdArrayInit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer) +{ + usb_host_ehci_iso_t *isoPointer; + uint32_t sitdNumber = 0; + usb_host_ehci_sitd_t *sitdPointer; + uint32_t dataLength = 0; + uint32_t sitdLength = 0; + uint32_t dataBufferValue; + uint32_t hubNumber; + uint32_t portNumber; + uint32_t address; + uint32_t tmp; + uint8_t index; + + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceAddress, + &address); + + sitdNumber = ((transfer->transferLength - 1 + (ehciPipePointer->pipeCommon.maxPacketSize)) / + (ehciPipePointer->pipeCommon.maxPacketSize)); + /* get sitd array */ + tmp = ehciPipePointer - ehciInstance->ehciPipeIndexBase; /* pipe index */ + /* USB_HostEhciLock(); */ + if (ehciInstance->ehciSitdNumber >= sitdNumber) + { + sitdPointer = ehciInstance->ehciSitdList; + transfer->union1.unitHead = (uint32_t)sitdPointer; + for (index = 1; index < sitdNumber; ++index) + { + sitdPointer->nextSitdIndex = + (((usb_host_ehci_sitd_t *)sitdPointer->nextLinkPointer) - ehciInstance->ehciSitdIndexBase); + sitdPointer = (usb_host_ehci_sitd_t *)sitdPointer->nextLinkPointer; + } + sitdPointer->nextSitdIndex = 0xFF; + ehciInstance->ehciSitdList = (usb_host_ehci_sitd_t *)sitdPointer->nextLinkPointer; + ehciInstance->ehciSitdNumber -= sitdNumber; + } + else + { + /* USB_HostEhciUnlock(); */ + return kStatus_USB_Error; + } + /* USB_HostEhciUnlock(); */ + transfer->union2.unitTail = (uint32_t)sitdPointer; + /* initialize sitd array */ + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceHubNumber, + &hubNumber); + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDevicePortNumber, + &portNumber); + sitdPointer = (usb_host_ehci_sitd_t *)transfer->union1.unitHead; + dataLength = transfer->transferLength; + while (sitdNumber--) + { + USB_HostEhciZeroMem((uint32_t *)sitdPointer, 7); + sitdLength = dataLength; + if (sitdLength > ehciPipePointer->pipeCommon.maxPacketSize) + { + sitdLength = ehciPipePointer->pipeCommon.maxPacketSize; + } + dataBufferValue = (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength)); + dataLength -= sitdLength; /* update left data length */ + sitdPointer->transferResults[1] = dataBufferValue; + sitdPointer->transferResults[2] = ((dataBufferValue + 4 * 1024) & 0xFFFFF000U); + sitdPointer->endpointStates[0] = + (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_SITD_DIRECTION_SHIFT) | + (portNumber << EHCI_HOST_SITD_PORT_NUMBER_SHIFT) | (hubNumber << EHCI_HOST_SITD_HUB_ADDR_SHIFT) | + ((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_SITD_ENDPT_SHIFT) | + (address << EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT)); + sitdPointer->transferResults[0] = + ((sitdLength << EHCI_HOST_SITD_TOTAL_BYTES_SHIFT) | (EHCI_HOST_SITD_STATUS_ACTIVE_MASK)); + + if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH) + { + sitdPointer->endpointStates[1] = (((uint32_t)ehciPipePointer->uframeCmask << EHCI_HOST_SITD_CMASK_SHIFT) | + ((uint32_t)ehciPipePointer->uframeSmask << EHCI_HOST_SITD_SMASK_SHIFT)); + + tmp = (sitdLength + 187) / 188; + if (tmp > 1) + { + sitdPointer->transferResults[2] |= (0x01 << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */ + } + else + { + sitdPointer->transferResults[2] |= (0x00 << EHCI_HOST_SITD_TP_SHIFT); /* for iso split */ + } + sitdPointer->transferResults[2] |= (tmp << EHCI_HOST_SITD_TCOUNT_SHIFT); /* for iso split */ + } + + sitdPointer->backPointer = EHCI_HOST_T_INVALID_VALUE; + + sitdPointer = (ehciInstance->ehciSitdIndexBase + sitdPointer->nextSitdIndex); + } + sitdPointer = (usb_host_ehci_sitd_t *)transfer->union2.unitTail; + sitdPointer->transferResults[0] |= (1U << EHCI_HOST_SITD_IOC_SHIFT); /* last set IOC */ + + /* link transfer to usb_host_ehci_iso_t transfer list */ + isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; + USB_HostEhciLock(); + if (isoPointer->ehciTransferHead == NULL) + { + transfer->next = NULL; + isoPointer->ehciTransferHead = isoPointer->ehciTransferTail = transfer; + } + else + { + transfer->next = NULL; + isoPointer->ehciTransferTail->next = transfer; + isoPointer->ehciTransferTail = transfer; + } + USB_HostEhciUnlock(); + + /* link itd to frame list (note: initialize frameEntryIndex)*/ + USB_HostEhciLinkSitd(ehciInstance, ehciPipePointer, (void *)transfer->union1.unitHead); + + return kStatus_USB_Success; +} + +static uint32_t USB_HostEhciSitdArrayRelease(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_sitd_t *startSitdPointer, + usb_host_ehci_sitd_t *endSitdPointer) +{ + usb_host_ehci_sitd_t *sitdPointer = startSitdPointer; + uint32_t leftLength = 0; + /* remove itd from frame list */ + while (1) + { + /* record the transfer's result length */ + leftLength += + ((sitdPointer->transferResults[0] & EHCI_HOST_SITD_TOTAL_BYTES_MASK) >> EHCI_HOST_SITD_TOTAL_BYTES_SHIFT); + USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)sitdPointer, + sitdPointer->frameEntryIndex); /* remove from the inserted frame list */ + + /* release itd */ + /* USB_HostEhciLock(); */ + sitdPointer->nextLinkPointer = (uint32_t)ehciInstance->ehciSitdList; + ehciInstance->ehciSitdList = sitdPointer; + ehciInstance->ehciSitdNumber++; + /* USB_HostEhciUnlock(); */ + + if (sitdPointer == endSitdPointer) + { + break; + } + + sitdPointer = &(ehciInstance->ehciSitdIndexBase[sitdPointer->nextSitdIndex]); + } + + return leftLength; +} + +static usb_status_t USB_HostEhciSitdArrayDeinit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; + usb_host_transfer_t *transfer; + usb_host_transfer_t *nextTransfer; + + /* firstly remove the transfer (because host task may occupy to access the resource) */ + USB_HostEhciLock(); + transfer = isoPointer->ehciTransferHead; + isoPointer->ehciTransferHead = isoPointer->ehciTransferTail = NULL; + USB_HostEhciUnlock(); + + while (transfer != NULL) + { + nextTransfer = transfer->next; + /* remove sitd from frame list and release itd */ + transfer->transferSofar = + transfer->transferLength - USB_HostEhciSitdArrayRelease(ehciInstance, + (usb_host_ehci_sitd_t *)transfer->union1.unitHead, + (usb_host_ehci_sitd_t *)transfer->union2.unitTail); + /* transfer callback */ + transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel); + /* next transfer */ + transfer = nextTransfer; + } + + return kStatus_USB_Success; +} +#endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */ + +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) +static uint32_t USB_HostEhciGetItdLinkFrame(usb_host_ehci_instance_t *ehciInstance, + uint32_t lastLinkUframe, + uint16_t startUframe, + uint16_t uframeInterval) +{ + int32_t shouldLinkUframe; + int32_t currentUframe; + int32_t distance; + + if (lastLinkUframe != 0xFFFF) + { + shouldLinkUframe = lastLinkUframe + uframeInterval; + if (shouldLinkUframe > (int32_t)EHCI_MAX_UFRAME_VALUE) + { + shouldLinkUframe = shouldLinkUframe - (EHCI_MAX_UFRAME_VALUE + 1); + } + currentUframe = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE); + distance = ((shouldLinkUframe - currentUframe + EHCI_MAX_UFRAME_VALUE + 1) & + EHCI_MAX_UFRAME_VALUE); /* get the distance */ + /* shouldLinkUframe has add uframeInterval, think about the align with interval, so here add (uframeInterval + * * 2) */ + if ((distance <= (int32_t)(USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER + (uframeInterval * 2))) && (distance > 2)) + { + currentUframe = shouldLinkUframe; + } + else /* re-link */ + { + currentUframe = + ((uint32_t)(currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & EHCI_MAX_UFRAME_VALUE); + if (currentUframe > (int32_t)EHCI_MAX_UFRAME_VALUE) + { + currentUframe = currentUframe - (EHCI_MAX_UFRAME_VALUE + 1); + } + /* uframe should align with interval */ + currentUframe -= startUframe; + currentUframe = ((uint32_t)(currentUframe + uframeInterval - 1) & + (~((uint32_t)uframeInterval - 1))); /* uframeInterval is power of 2 */ + currentUframe += startUframe; + } + } + else + { + currentUframe = (ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE); + currentUframe = ((uint32_t)(currentUframe + USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER) & EHCI_MAX_UFRAME_VALUE); + /* uframe should align with interval */ + currentUframe -= startUframe; + currentUframe = ((uint32_t)(currentUframe + uframeInterval - 1) & + (~((uint32_t)uframeInterval - 1))); /* uframeInterval is power of 2 */ + currentUframe += startUframe; + } + + return currentUframe; +} + +static usb_status_t USB_HostEhciItdArrayInit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer) +{ + usb_host_ehci_iso_t *isoPointer; + usb_host_ehci_itd_t *itdPointer = NULL; + usb_host_ehci_itd_t *tmpItdPointer; + uint32_t dataLength; /* the remaining data for sending */ + uint32_t transactionLength; /* the initializing transaction descriptor data length */ + uint32_t itdBufferValue; + uint32_t itdBufferBaseValue; /* for calculating PG value */ + uint32_t address; + uint32_t lastShouldLinkUframe; + uint32_t linkUframe; + uint32_t minDataPerItd = ehciPipePointer->pipeCommon.numberPerUframe * ehciPipePointer->pipeCommon.maxPacketSize; + uint8_t maxItdNumber; + uint8_t index = 0; + + isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceAddress, + &address); + + /* max needed itd number, the actual needed number may be less because micro-frame interval may be less than 8 */ + maxItdNumber = ((transfer->transferLength - 1 + minDataPerItd) / minDataPerItd); + if (ehciPipePointer->uframeInterval < 8) + { + maxItdNumber = ((maxItdNumber * ehciPipePointer->uframeInterval + 7) / 8) + 1; + } + if (maxItdNumber > ehciInstance->ehciItdNumber) + { + return kStatus_USB_Error; + } + + /* link transfer to usb_host_ehci_iso_t transfer list */ + transfer->next = NULL; + /* USB_HostEhciLock(); */ + if (isoPointer->ehciTransferHead == NULL) + { + isoPointer->ehciTransferHead = isoPointer->ehciTransferTail = transfer; + } + else + { + isoPointer->ehciTransferTail->next = transfer; + isoPointer->ehciTransferTail = transfer; + } + /* USB_HostEhciUnlock(); */ + + dataLength = transfer->transferLength; + transfer->union1.unitHead = (uint32_t)NULL; + /* get the link micro-frame */ + lastShouldLinkUframe = USB_HostEhciGetItdLinkFrame( + ehciInstance, isoPointer->lastLinkFrame, + (uint16_t)((ehciPipePointer->startFrame << 3) + ehciPipePointer->startUframe), ehciPipePointer->uframeInterval); + if (lastShouldLinkUframe > EHCI_MAX_UFRAME_VALUE) + { + linkUframe = lastShouldLinkUframe - (EHCI_MAX_UFRAME_VALUE + 1); + } + else + { + linkUframe = lastShouldLinkUframe; + } + while (dataLength) + { + /* get one idle itd */ + tmpItdPointer = ehciInstance->ehciItdList; + ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)tmpItdPointer->nextLinkPointer; + ehciInstance->ehciItdNumber -= 1; + if (tmpItdPointer == NULL) + { + return kStatus_USB_Error; /* this should not reach */ + } + tmpItdPointer->nextItdPointer = NULL; + + /* use the itd */ + if (transfer->union1.unitHead == (uint32_t)NULL) /* first itd */ + { + transfer->union1.unitHead = (uint32_t)tmpItdPointer; + } + else /* link itd list */ + { + itdPointer->nextItdPointer = tmpItdPointer; + } + itdPointer = tmpItdPointer; + + /* itd has been set to all zero when releasing */ + itdBufferBaseValue = itdBufferValue = + (uint32_t)(transfer->transferBuffer + (transfer->transferLength - dataLength)); + for (index = 0; index < 7; ++index) + { + itdPointer->bufferPointers[index] = ((itdBufferBaseValue + (index * 4 * 1024)) & 0xFFFFF000U); + } + /* initialize iTD common fields */ + itdPointer->bufferPointers[0] |= + (((uint32_t)ehciPipePointer->pipeCommon.endpointAddress << EHCI_HOST_ITD_ENDPT_SHIFT) | + (address << EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT)); + itdPointer->bufferPointers[1] |= + (((uint32_t)ehciPipePointer->pipeCommon.direction << EHCI_HOST_ITD_DIRECTION_SHIFT) | + ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT)); + itdPointer->bufferPointers[2] |= (ehciPipePointer->pipeCommon.numberPerUframe); + /* initialize transaction descriptors */ + for (index = (linkUframe & 0x0007); index < 8; index += ehciPipePointer->uframeInterval) + { + transactionLength = ((dataLength > minDataPerItd) ? minDataPerItd : dataLength); + /* initialize the uframeIndex's transaction descriptor in itd */ + itdPointer->transactions[index] = + ((EHCI_HOST_ITD_STATUS_ACTIVE_MASK) | (transactionLength << EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT) | + ((((itdBufferValue & 0xFFFFF000U) - (itdBufferBaseValue & 0xFFFFF000U)) >> + EHCI_HOST_ITD_BUFFER_POINTER_SHIFT) + << EHCI_HOST_ITD_PG_SHIFT) | + (itdBufferValue & EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK)); + dataLength -= transactionLength; + itdBufferValue += transactionLength; + if (dataLength <= 0) + { + break; + } + } + } + + transfer->union2.unitTail = (uint32_t)itdPointer; + itdPointer->transactions[index] |= (1 << EHCI_HOST_ITD_IOC_SHIFT); /* last set IOC */ + + /* link itd to frame list (note: initialize frameEntryIndex)*/ + while (itdPointer) + { + itdPointer->frameEntryIndex = linkUframe; + /* add to frame head */ + itdPointer->nextLinkPointer = ((uint32_t *)ehciInstance->ehciFrameList)[linkUframe >> 3]; + *(uint32_t *)((uint32_t *)ehciInstance->ehciFrameList)[linkUframe >> 3] = + ((uint32_t)itdPointer | EHCI_HOST_POINTER_TYPE_ITD); + itdPointer = itdPointer->nextItdPointer; + if (itdPointer == NULL) + { + break; + } + + linkUframe += ehciPipePointer->uframeInterval; + lastShouldLinkUframe += ehciPipePointer->uframeInterval; + if (linkUframe >= (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3)) + { + linkUframe = (linkUframe - (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE << 3)); + } + } + + if (lastShouldLinkUframe > EHCI_MAX_UFRAME_VALUE) + { + lastShouldLinkUframe = lastShouldLinkUframe - (EHCI_MAX_UFRAME_VALUE + 1); + } + isoPointer->lastLinkFrame = lastShouldLinkUframe; + + return kStatus_USB_Success; +} + +static uint32_t USB_HostEhciItdArrayRelease(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_itd_t *startItdPointer, + usb_host_ehci_itd_t *endItdPointer) +{ + usb_host_ehci_itd_t *itdPointer = startItdPointer; + uint8_t index; + uint32_t doneLength = 0; + + /* remove itd from frame list */ + while (1) + { + /* record the transfer's result length */ + for (index = 0; index < 8; ++index) + { + doneLength += ((itdPointer->transactions[index] & EHCI_HOST_ITD_TRANSACTION_LEN_MASK) >> + EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT); + } + + USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)itdPointer, + itdPointer->frameEntryIndex); /* remove from the inserted frame list */ + + /* release itd */ + /* USB_HostEhciLock(); */ + USB_HostEhciZeroMem((uint32_t *)itdPointer, sizeof(usb_host_ehci_itd_t) >> 2); + itdPointer->nextLinkPointer = (uint32_t)ehciInstance->ehciItdList; + ehciInstance->ehciItdList = itdPointer; + ehciInstance->ehciItdNumber++; + /* USB_HostEhciUnlock(); */ + + if (itdPointer == endItdPointer) + { + break; + } + itdPointer = itdPointer->nextItdPointer; + } + + return doneLength; +} + +static usb_status_t USB_HostEhciItdArrayDeinit(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_host_ehci_iso_t *isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; + usb_host_transfer_t *transfer; + usb_host_transfer_t *nextTransfer; + uint32_t doneLength = 0; + + /* firstly remove the transfer (because host task may occupy to access the resource) */ + USB_HostEhciLock(); + transfer = isoPointer->ehciTransferHead; + isoPointer->ehciTransferHead = isoPointer->ehciTransferTail = NULL; + USB_HostEhciUnlock(); + + while (transfer != NULL) + { + nextTransfer = transfer->next; + doneLength = 0; + /* remove itd from frame list and release itd */ + doneLength = USB_HostEhciItdArrayRelease(ehciInstance, (usb_host_ehci_itd_t *)transfer->union1.unitHead, + (usb_host_ehci_itd_t *)transfer->union2.unitTail); + + /* transfer callback */ + if (ehciPipePointer->pipeCommon.direction == USB_OUT) + { + doneLength = transfer->transferLength; + } + transfer->transferSofar = doneLength; + transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferCancel); + + /* next transfer */ + transfer = nextTransfer; + } + + return kStatus_USB_Success; +} +#endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */ + +static usb_status_t USB_HostEhciOpenControlBulk(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_host_ehci_qh_t *qhPointer; + + if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success) /* initialize control/bulk qh */ + { + return kStatus_USB_Error; + } + + qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + + /* add qh to async */ + qhPointer->horizontalLinkPointer = ehciInstance->shedFirstQh->horizontalLinkPointer; + ehciInstance->shedFirstQh->horizontalLinkPointer = ((uint32_t)qhPointer | EHCI_HOST_POINTER_TYPE_QH); + + return kStatus_USB_Success; +} + +static usb_status_t USB_HostEhciCloseControlBulk(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + volatile usb_host_ehci_qh_t *vltPrevQhPointer; + uint32_t horizontalLinkValue; + + /* remove qh from async schedule */ + if ((ehciInstance->shedFirstQh->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK) == + (uint32_t)ehciPipePointer->ehciQh) /* the removing qh is the first qh in the async list */ + { + USB_HostEhciStopAsync(ehciInstance); + ehciInstance->shedFirstQh->horizontalLinkPointer = + ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer; + USB_HostEhciStartAsync(ehciInstance); + } + else + { + /* search for the removing qh from the async list */ + vltPrevQhPointer = ehciInstance->shedFirstQh; + while (vltPrevQhPointer != NULL) + { + horizontalLinkValue = vltPrevQhPointer->horizontalLinkPointer; + if ((horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE) || + ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)ehciPipePointer->ehciQh) || + ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)ehciInstance->shedFirstQh)) + { + break; + } + + vltPrevQhPointer = (volatile usb_host_ehci_qh_t *)(horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK); + } + + /* remove the qh from async list */ + if ((vltPrevQhPointer != NULL) && (!(horizontalLinkValue & EHCI_HOST_T_INVALID_VALUE)) && + ((horizontalLinkValue & EHCI_HOST_POINTER_ADDRESS_MASK) == (uint32_t)ehciPipePointer->ehciQh)) + { + USB_HostEhciStopAsync(ehciInstance); + vltPrevQhPointer->horizontalLinkPointer = + ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer; + USB_HostEhciStartAsync(ehciInstance); + } + } + ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer = + EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */ + return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initialize qh and release qh */ +} + +static usb_status_t USB_HostEhciOpenInterrupt(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_status_t status = kStatus_USB_Success; + uint32_t frameIndex; + + /* allocate bandwidth */ + if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH) + { + status = USB_HostBandwidthHsHostAllocateInterrupt(ehciInstance, ehciPipePointer); /* host works as high-speed */ + } + else + { + status = USB_HostBandwidthFslsHostAllocate(ehciInstance, + ehciPipePointer); /* host works as full-speed or low-speed */ + } + + if (status != kStatus_USB_Success) + { + return status; + } + if (USB_HostEhciQhInit(ehciInstance, ehciPipePointer) != kStatus_USB_Success) + { + return kStatus_USB_Error; + } + + /* insert QH to frame list */ + for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; + frameIndex += (ehciPipePointer->uframeInterval / 8)) + { + USB_HostEhciAddQhToFrame(ehciInstance, (uint32_t)ehciPipePointer->ehciQh, frameIndex, + ehciPipePointer->uframeInterval); + } + + return kStatus_USB_Success; +} + +static usb_status_t USB_HostEhciCloseInterrupt(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer) +{ + uint32_t frameIndex; + + /* remove from frame list */ + for (frameIndex = ehciPipePointer->startFrame; frameIndex < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; + frameIndex += (ehciPipePointer->uframeInterval / 8)) + { + USB_HostEhciRemoveFromFrame(ehciInstance, (uint32_t)ehciPipePointer->ehciQh, frameIndex); + } + ((usb_host_ehci_qh_t *)ehciPipePointer->ehciQh)->horizontalLinkPointer |= + EHCI_HOST_T_INVALID_VALUE; /* invalid next qh link */ + + return USB_HostEhciQhDeinit(ehciInstance, ehciPipePointer); /* de-initilaze qh and release qh */ +} + +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + +static usb_status_t USB_HostEhciOpenIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_host_ehci_iso_t *isoPointer; + usb_status_t status = kStatus_USB_Success; + + if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH) + { + status = USB_HostBandwidthHsHostAllocateIso( + ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as high-speed */ + } + else + { + status = USB_HostBandwidthFslsHostAllocate( + ehciInstance, ehciPipePointer); /* allocate iso bandwidth when host works as full-speed or low-speed */ + } + + if (status != kStatus_USB_Success) + { + return status; + } + + /* get usb_host_ehci_iso_t */ + if (ehciInstance->ehciIsoList == NULL) + { + return kStatus_USB_Error; + } + USB_HostEhciLock(); + isoPointer = ehciInstance->ehciIsoList; + ehciInstance->ehciIsoList = ehciInstance->ehciIsoList->next; + USB_HostEhciUnlock(); + isoPointer->lastLinkFrame = 0xFFFF; + ehciPipePointer->ehciQh = isoPointer; + + return status; +} + +static usb_status_t USB_HostEhciCloseIso(usb_host_ehci_instance_t *ehciInstance, usb_host_ehci_pipe_t *ehciPipePointer) +{ + usb_host_ehci_iso_t *isoPointer; + uint32_t speed; + + isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; + + if (isoPointer->ehciTransferHead != NULL) + { + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, + &speed); + if (speed == USB_SPEED_HIGH) + { +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) + USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd list and free them */ +#endif + } + else + { +#if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)) + USB_HostEhciSitdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize sitd list and free them */ +#endif + } + } + + /* release usb_host_ehci_iso_t */ + USB_HostEhciLock(); + isoPointer->next = ehciInstance->ehciIsoList; + ehciInstance->ehciIsoList = isoPointer; + USB_HostEhciUnlock(); + return kStatus_USB_Success; +} + +#endif + +static usb_status_t USB_HostEhciResetIP(usb_host_ehci_instance_t *ehciInstance) +{ + /* reset controller */ + ehciInstance->ehciIpBase->USBCMD = USBHS_USBCMD_RST_MASK; + while (ehciInstance->ehciIpBase->USBCMD & USBHS_USBCMD_RST_MASK) + { + } +/* set host mode */ +#if (ENDIANNESS == USB_LITTLE_ENDIAN) + ehciInstance->ehciIpBase->USBMODE |= 0x03; +#else + ehciInstance->ehciIpBase->USBMODE |= (0x03 | (0x01 << USBHS_USBMODE_ES_SHIFT)); +#endif + /* check frame list size */ + if (!(ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK)) + { +#if ((USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE < 8) || (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE > 1024)) + return kStatus_USB_Error; +#endif +#if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE & (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE - 1)) + return kStatus_USB_Error; /* frame size must be 1024/512/256/128/64/32/16/8 */ +#endif + } + return kStatus_USB_Success; +} + +static usb_status_t USB_HostEhciStartIP(usb_host_ehci_instance_t *ehciInstance) +{ + uint32_t tmp = 0; + + if (ehciInstance->ehciIpBase->HCSPARAMS & USBHS_HCSPARAMS_PPC_MASK) /* Ports have power port switches */ + { + /* only has one port */ + tmp = ehciInstance->ehciIpBase->PORTSC1; + tmp &= (~EHCI_PORTSC1_W1_BITS); + ehciInstance->ehciIpBase->PORTSC1 = (tmp | USBHS_PORTSC1_PP_MASK); /* turn on port power */ + } + + /* set frame list size */ + if (ehciInstance->ehciIpBase->HCCPARAMS & USBHS_HCCPARAMS_PFL_MASK) + { +#if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE <= 64) + ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_FS2_MASK); +#if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 64) + ehciInstance->ehciIpBase->USBCMD |= (0x00 << USBHS_USBCMD_FS_SHIFT); +#elif(USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 32) + ehciInstance->ehciIpBase->USBCMD |= (0x01 << USBHS_USBCMD_FS_SHIFT); +#elif(USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 16) + ehciInstance->ehciIpBase->USBCMD |= (0x02 << USBHS_USBCMD_FS_SHIFT); +#elif(USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 8) + ehciInstance->ehciIpBase->USBCMD |= (0x03 << USBHS_USBCMD_FS_SHIFT); +#endif +#else +#if (USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 1024) + ehciInstance->ehciIpBase->USBCMD |= (0x00 << USBHS_USBCMD_FS_SHIFT); +#elif(USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 512) + ehciInstance->ehciIpBase->USBCMD |= (0x01 << USBHS_USBCMD_FS_SHIFT); +#elif(USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 256) + ehciInstance->ehciIpBase->USBCMD |= (0x02 << USBHS_USBCMD_FS_SHIFT); +#elif(USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE == 128) + ehciInstance->ehciIpBase->USBCMD |= (0x03 << USBHS_USBCMD_FS_SHIFT); +#endif +#endif + } + + /* start the controller */ + ehciInstance->ehciIpBase->USBCMD = USBHS_USBCMD_RS_MASK; + + /* set timer0 */ + ehciInstance->ehciIpBase->GPTIMER0LD = (300 * 1000 - 1); /* 100ms */ + + /* enable interrupt (USB interrupt enable + USB error interrupt enable + port change detect enable + system error + * enable + interrupt on async advance enable) + general purpos Timer 0 Interrupt enable */ + ehciInstance->ehciIpBase->USBINTR |= (0x1000037); + + return kStatus_USB_Success; +} + +static usb_status_t USB_HostEhciCancelPipe(usb_host_ehci_instance_t *ehciInstance, + usb_host_ehci_pipe_t *ehciPipePointer, + usb_host_transfer_t *transfer) +{ + usb_host_ehci_qh_t *qhPointer; +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + usb_host_ehci_iso_t *isoPointer; + uint32_t speed; +#endif + uint8_t cancelPipe = 0; + + switch (ehciPipePointer->pipeCommon.pipeType) + { + case USB_ENDPOINT_BULK: + case USB_ENDPOINT_CONTROL: + case USB_ENDPOINT_INTERRUPT: + qhPointer = (usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + if (qhPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */ + { + return kStatus_USB_Success; + } + if (transfer != NULL) + { + if ((qhPointer->ehciTransferHead == transfer) && + (qhPointer->ehciTransferHead == qhPointer->ehciTransferTail)) /* only has this one transfer */ + { + cancelPipe = 1; + } + else + { + cancelPipe = 0; + } + } + else + { + cancelPipe = 1; + } + if (cancelPipe == 1) /* cancel all pipe */ + { + USB_HostEhciQhQtdListDeinit(ehciInstance, ehciPipePointer); /* release all the qtd */ + } + else /* cancel one transfer */ + { + USB_HostEhciTransferQtdListDeinit(ehciInstance, ehciPipePointer, transfer); + } + break; + +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + case USB_ENDPOINT_ISOCHRONOUS: + isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; + if (isoPointer->ehciTransferHead == NULL) /* there is no transfer to cancel */ + { + return kStatus_USB_Success; + } + /* cancel all pipe, don't implement canceling transfer for iso */ + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, + &speed); + if (speed == USB_SPEED_HIGH) + { +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) + USB_HostEhciItdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize itd */ +#endif + } + else + { +#if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)) + USB_HostEhciSitdArrayDeinit(ehciInstance, ehciPipePointer); /* de-initialize sitd */ +#endif + } + break; +#endif + + default: + break; + } + + return kStatus_USB_Success; +} + +static usb_status_t USB_HostEhciControlBus(usb_host_ehci_instance_t *ehciInstance, uint8_t busControl) +{ + usb_status_t status = kStatus_USB_Success; + uint32_t portScRegister; + + switch (busControl) + { + case kUSB_HostBusReset: + /* reset port */ + portScRegister = ehciInstance->ehciIpBase->PORTSC1; + portScRegister &= (~EHCI_PORTSC1_W1_BITS); + ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK); + while (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK) + { + } + break; + + case kUSB_HostBusRestart: + ehciInstance->deviceAttached = kEHCIDeviceDetached; + ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */ + break; + + case kUSB_HostBusEnableAttach: /* enable device attach */ + if (ehciInstance->deviceAttached == kEHCIDeviceDetached) + { + ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_PCE_MASK); /* enable ehci port change interrupt */ + } + break; + + case kUSB_HostBusDisableAttach: /* disable device attach */ + ehciInstance->ehciIpBase->USBINTR &= (~USBHS_USBINTR_PCE_MASK); /* disable ehci port change interrupt */ + break; +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + case kUSB_HostBusSuspend: + if (ehciInstance->ehciIpBase->PORTSC1 && USBHS_PORTSC1_CCS_MASK) + { + /* set timer1 */ + ehciInstance->ehciIpBase->GPTIMER1LD = (1 * 1000); /* 1ms */ + ehciInstance->ehciIpBase->GPTIMER1CTL |= + (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK); + + USB_HostEhciStopAsync(ehciInstance); + USB_HostEhciStopPeriodic(ehciInstance); + while (ehciInstance->ehciIpBase->USBSTS & (USBHS_USBSTS_PS_MASK | USBHS_USBSTS_AS_MASK)) + { + __ASM("nop"); + } + ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKCN_MASK; + ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_WKDS_MASK; + ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_SUSP_MASK); /* Suspend the device */ + + ehciInstance->matchTick = 0U; + ehciInstance->ehciIpBase->USBINTR |= (USBHS_USBINTR_TIE1_MASK); + ehciInstance->busSuspendStatus = kBus_EhciStartSuspend; + } + else + { + status = kStatus_USB_Error; + } + break; + case kUSB_HostBusResume: + ehciInstance->ehciIpBase->PORTSC1 &= ~(USBHS_PORTSC1_SUSP_MASK); /* Clear Suspend bit */ + ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; + if (ehciInstance->deviceAttached != kEHCIDeviceDetached) + { + ehciInstance->busSuspendStatus = kBus_EhciStartResume; +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK; +#else + ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK; +#endif + ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK); + ehciInstance->ehciIpBase->PORTSC1 |= (USBHS_PORTSC1_FPR_MASK); /* Resume the device */ + } + else + { + status = kStatus_USB_Error; + } + break; +#endif + default: + status = kStatus_USB_Error; + break; + } + return status; +} + +void USB_HostEhciTransactionDone(usb_host_ehci_instance_t *ehciInstance) +{ + /* process async QH */ + usb_host_ehci_pipe_t *ehciPipePointer; + usb_host_ehci_pipe_t *ehciClearPipePointer = NULL; + volatile usb_host_ehci_qh_t *vltQhPointer; + volatile usb_host_ehci_qtd_t *vltQtdPointer; + usb_host_transfer_t *transfer; + usb_host_transfer_t *nextTransfer; + uint32_t qtdStatus = 0; +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) + volatile usb_host_ehci_itd_t *vltItdPointer; + uint8_t index = 0; +#endif +#if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)) + volatile usb_host_ehci_sitd_t *vltSitdPointer; +#endif +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + usb_host_ehci_iso_t *isoPointer; + uint32_t dataLength; + uint32_t speed; +#endif + + ehciPipePointer = ehciInstance->ehciRunningPipeList; /* check all the running pipes */ + while (ehciPipePointer != NULL) + { + switch (ehciPipePointer->pipeCommon.pipeType) + { + case USB_ENDPOINT_BULK: + case USB_ENDPOINT_INTERRUPT: + case USB_ENDPOINT_CONTROL: + vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */ + transfer = vltQhPointer->ehciTransferHead; /* qh's transfer */ + while (transfer != NULL) + { + nextTransfer = transfer->next; + /* normal case */ + vltQtdPointer = (volatile usb_host_ehci_qtd_t *)transfer->union2.unitTail; + if ((vltQtdPointer->transferResults[0] & (EHCI_HOST_QTD_IOC_MASK)) && + (!(vltQtdPointer->transferResults[0] & + EHCI_HOST_QTD_STATUS_ACTIVE_MASK))) /* transfer is done */ + { + qtdStatus = (vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_STATUS_ERROR_MASK); + transfer->transferSofar = + USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead), + (usb_host_ehci_qtd_t *)(transfer->union2.unitTail)); + transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ? + 0 : + (transfer->transferLength - transfer->transferSofar); + + vltQhPointer->ehciTransferHead = transfer->next; + vltQhPointer->timeOutLabel = 0; + vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE; + if (qtdStatus) /* has errors */ + { + if (!(vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)) + { + vltQhPointer->transferOverlayResults[0] &= + (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */ + } + if (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK) + { + transfer->callbackFn(transfer->callbackParam, transfer, + kStatus_USB_TransferFailed); /* transfer fail */ + } + else + { + transfer->callbackFn(transfer->callbackParam, transfer, + kStatus_USB_TransferStall); /* transfer stall */ + } + } + else + { + if ((ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_CONTROL) && + (transfer->setupPacket->bRequest == USB_REQUEST_STANDARD_CLEAR_FEATURE) && + (transfer->setupPacket->bmRequestType == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) && + ((USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wValue) & 0x00FFu) == + USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT)) + { + ehciClearPipePointer = ehciInstance->ehciRunningPipeList; + while (ehciClearPipePointer != NULL) + { + /* only compute bulk and interrupt pipe */ + if (((ehciClearPipePointer->pipeCommon.endpointAddress | + (ehciClearPipePointer->pipeCommon.direction + << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) == + (uint8_t)(USB_SHORT_FROM_LITTLE_ENDIAN(transfer->setupPacket->wIndex))) && + (ehciClearPipePointer->pipeCommon.deviceHandle == + ehciPipePointer->pipeCommon.deviceHandle)) + { + break; + } + ehciClearPipePointer = + (usb_host_ehci_pipe_t *)ehciClearPipePointer->pipeCommon.next; + } + + if ((ehciClearPipePointer != NULL) && + ((ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT) || + (ehciClearPipePointer->pipeCommon.pipeType == USB_ENDPOINT_BULK))) + { + ((volatile usb_host_ehci_qh_t *)(ehciClearPipePointer->ehciQh)) + ->transferOverlayResults[0] &= (~EHCI_HOST_QTD_DT_MASK); + } + } + transfer->callbackFn(transfer->callbackParam, transfer, + kStatus_USB_Success); /* transfer success */ + } + } + else if ((!(vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QTD_STATUS_ACTIVE_MASK)) && + (vltQhPointer->transferOverlayResults[0] & + EHCI_HOST_QH_STATUS_ERROR_MASK)) /* there is error and transfer is done */ + { + qtdStatus = (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QH_STATUS_ERROR_MASK); + vltQtdPointer = (volatile usb_host_ehci_qtd_t *)(vltQhPointer->currentQtdPointer); + + if (((uint32_t)vltQtdPointer & EHCI_HOST_T_INVALID_VALUE) || + (vltQtdPointer == NULL)) /* the error status is unreasonable */ + { + vltQhPointer->transferOverlayResults[0] &= + (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */ + } + else + { + /* remove qtd from qh */ + while ((vltQtdPointer != NULL) && (!(vltQtdPointer->transferResults[0] & + EHCI_HOST_QTD_IOC_MASK))) /* find the IOC qtd */ + { + vltQtdPointer = (volatile usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer; + } + + vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + vltQhPointer->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE; + vltQhPointer->transferOverlayResults[0] &= + (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */ + if (vltQtdPointer != NULL) + { + vltQhPointer->nextQtdPointer = vltQtdPointer->nextQtdPointer; + } + + transfer->transferSofar = USB_HostEhciQtdListRelease( + ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead), + (usb_host_ehci_qtd_t *)(transfer->union2.unitTail)); + transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ? + 0 : + (transfer->transferLength - transfer->transferSofar); + vltQhPointer->ehciTransferHead = transfer->next; + vltQhPointer->timeOutLabel = 0; + vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE; + if (qtdStatus & EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK) + { + transfer->callbackFn(transfer->callbackParam, transfer, + kStatus_USB_TransferFailed); /* transfer fail */ + } + else + { + transfer->callbackFn(transfer->callbackParam, transfer, + kStatus_USB_TransferStall); /* transfer stall */ + } + } + } + else + { + break; + } + transfer = nextTransfer; + } + break; +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + case USB_ENDPOINT_ISOCHRONOUS: + qtdStatus = 0; /* qtdStatus means break here, because there is only one break in while for misra */ + isoPointer = (usb_host_ehci_iso_t *)ehciPipePointer->ehciQh; /* pipe's usb_host_ehci_iso_t */ + transfer = isoPointer->ehciTransferHead; /* usb_host_ehci_iso_t's transfer */ + while (transfer != NULL) + { + nextTransfer = transfer->next; + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, + kUSB_HostGetDeviceSpeed, &speed); + if (speed == USB_SPEED_HIGH) + { +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) + vltItdPointer = + (volatile usb_host_ehci_itd_t *)(transfer->union2.unitTail); /* transfer's last itd */ + for (index = 0; index < 8; ++index) + { + if (vltItdPointer->transactions[index] & EHCI_HOST_ITD_STATUS_ACTIVE_MASK) + { + break; + } + } + if (index == 8) /* transfer is done */ + { + /* remove itd from frame list and release itd */ + dataLength = USB_HostEhciItdArrayRelease(ehciInstance, + (usb_host_ehci_itd_t *)transfer->union1.unitHead, + (usb_host_ehci_itd_t *)transfer->union2.unitTail); + transfer->transferSofar = dataLength; + isoPointer->ehciTransferHead = transfer->next; + transfer->callbackFn(transfer->callbackParam, transfer, + kStatus_USB_Success); /* transfer callback success */ + /* TODO: iso callback error */ + } + else + { + qtdStatus = 1; /* break */ + } +#endif + } + else + { +#if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)) + vltSitdPointer = + (volatile usb_host_ehci_sitd_t *)(transfer->union2.unitTail); /* transfer's last sitd */ + if (!(vltSitdPointer->transferResults[0] & + EHCI_HOST_SITD_STATUS_ACTIVE_MASK)) /* transfer is done */ + { + /* remove sitd from frame list and release itd */ + dataLength = USB_HostEhciSitdArrayRelease( + ehciInstance, (usb_host_ehci_sitd_t *)transfer->union1.unitHead, + (usb_host_ehci_sitd_t *)transfer->union2.unitTail); + transfer->transferSofar = dataLength; + isoPointer->ehciTransferHead = transfer->next; + transfer->callbackFn(transfer->callbackParam, transfer, + kStatus_USB_Success); /* transfer callback success */ + /* TODO: iso callback error */ + } + else + { + qtdStatus = 1; /* break */ + } +#endif + } + if (qtdStatus == 1) + { + break; + } + transfer = nextTransfer; + } + break; +#endif + + default: + break; + } + ehciPipePointer = (usb_host_ehci_pipe_t *)ehciPipePointer->pipeCommon.next; + } +} + +static void USB_HostEhciPortChange(usb_host_ehci_instance_t *ehciInstance) +{ + /* note: only has one port */ + uint32_t portScRegister = ehciInstance->ehciIpBase->PORTSC1; + int32_t sofStart = 0; + int32_t sofCount = 0; + uint32_t index; + + if (portScRegister & USBHS_PORTSC1_CSC_MASK) /* connection status change */ + { + sofStart = (int32_t)(ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE); + + /* process CSC bit */ + while (1) + { + portScRegister = ehciInstance->ehciIpBase->PORTSC1; + if (portScRegister & USBHS_PORTSC1_CSC_MASK) + { + /* clear csc bit */ + portScRegister = ehciInstance->ehciIpBase->PORTSC1; + portScRegister &= (~EHCI_PORTSC1_W1_BITS); + ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_CSC_MASK); + } + sofCount = (int32_t)(ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE); + if (((sofCount - sofStart + EHCI_MAX_UFRAME_VALUE + 1) & EHCI_MAX_UFRAME_VALUE) > + (1 * 8)) /* delay 1ms to clear CSC */ + { + break; + } + } + } + + /* process CCS bit */ + portScRegister = ehciInstance->ehciIpBase->PORTSC1; + if (portScRegister & USBHS_PORTSC1_CCS_MASK) /* process attach */ + { + if ((ehciInstance->deviceAttached == kEHCIDevicePhyAttached) || + (ehciInstance->deviceAttached == kEHCIDeviceAttached)) + { + return; + } +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + ehciInstance->busSuspendStatus = kBus_EhciIdle; + ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK); +#endif + for (index = 0; index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY; ++index) + { + USB_HostEhciDelay(ehciInstance->ehciIpBase, 1); + if (!(ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK)) + { + break; + } + } + if (index < USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY) /* CCS is cleared */ + { + ehciInstance->deviceAttached = kEHCIDeviceDetached; + return; + } + /* reset port */ + portScRegister = ehciInstance->ehciIpBase->PORTSC1; + portScRegister &= (~EHCI_PORTSC1_W1_BITS); + ehciInstance->ehciIpBase->PORTSC1 = (portScRegister | USBHS_PORTSC1_PR_MASK); + while (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PR_MASK) + { + } + ehciInstance->firstDeviceSpeed = + ((ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_PSPD_MASK) >> USBHS_PORTSC1_PSPD_SHIFT); + /* enable ehci phy disconnection */ + if (ehciInstance->firstDeviceSpeed == USB_SPEED_HIGH) + { + USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 1); + } + + /* wait for reset */ + USB_HostEhciDelay(ehciInstance->ehciIpBase, USB_HOST_EHCI_PORT_RESET_DELAY); + /* process attach */ + USB_OsaEventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_ATTACH); + /* gpt timer start */ + ehciInstance->ehciIpBase->GPTIMER0CTL |= + (USBHS_GPTIMER0CTL_RUN_MASK | USBHS_GPTIMER0CTL_MODE_MASK | USBHS_GPTIMER0CTL_RST_MASK); + ehciInstance->deviceAttached = kEHCIDevicePhyAttached; + } + else + { + if ((ehciInstance->deviceAttached == kEHCIDevicePhyAttached) || + (ehciInstance->deviceAttached == kEHCIDeviceAttached)) + { +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + ehciInstance->busSuspendStatus = kBus_EhciIdle; + ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK); +#endif + /* disable ehci phy disconnection */ + USB_EhcihostPhyDisconnectDetectCmd(ehciInstance->controllerId, 0); + /* disable async and periodic */ + USB_HostEhciStopAsync(ehciInstance); + USB_HostEhciStopPeriodic(ehciInstance); + USB_OsaEventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_DEVICE_DETACH); + } + } +} + +static void USB_HostEhciTimer0(usb_host_ehci_instance_t *ehciInstance) +{ + volatile usb_host_ehci_qh_t *vltQhPointer; + volatile usb_host_ehci_qtd_t *vltQtdPointer; + usb_host_transfer_t *transfer; + uint32_t backValue; + volatile uint32_t *totalBytesAddress = NULL; + usb_host_ehci_pipe_t *ehciPipePointer = ehciInstance->ehciRunningPipeList; + uint8_t timeoutLabel; + + while (ehciPipePointer != NULL) + { + switch (ehciPipePointer->pipeCommon.pipeType) + { + case USB_ENDPOINT_BULK: + case USB_ENDPOINT_CONTROL: + vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; /* pipe's qh */ + transfer = vltQhPointer->ehciTransferHead; /* qh's transfer */ + if ((transfer != NULL)) /* there is transfering data */ + { + timeoutLabel = 0; + if (ehciInstance->deviceAttached != kEHCIDeviceAttached) + { + vltQtdPointer = (volatile usb_host_ehci_qtd_t *)transfer->union2.unitTail; + + vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */ + vltQhPointer->transferOverlayResults[0] &= + (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */ + timeoutLabel = 1; + } + else + { + if (vltQhPointer->transferOverlayResults[0] & EHCI_HOST_QTD_STATUS_ACTIVE_MASK) + { + vltQtdPointer = (volatile usb_host_ehci_qtd_t *)vltQhPointer->currentQtdPointer; + totalBytesAddress = &(vltQhPointer->transferOverlayResults[0]); + } + else + { + vltQtdPointer = (volatile usb_host_ehci_qtd_t *)transfer->union2.unitTail; + totalBytesAddress = ((uint32_t *)vltQtdPointer + 2); + } + + backValue = + (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> + EHCI_HOST_QTD_TOTAL_BYTES_SHIFT); /* backValue is used for total bytes to transfer */ + if (vltQhPointer->timeOutLabel != backValue) /* use total bytes to reflect the time out */ + { + vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE; + vltQhPointer->timeOutLabel = backValue; + } + else + { + /* time out when the total bytes don't change for the duration + * USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE + */ + (vltQhPointer->timeOutValue)--; + if (vltQhPointer->timeOutValue == 0) + { + /* stop the qh schedule */ + USB_HostEhciStopAsync(ehciInstance); + if (backValue != (((*totalBytesAddress) & EHCI_HOST_QTD_TOTAL_BYTES_MASK) >> + EHCI_HOST_QTD_TOTAL_BYTES_SHIFT)) + { + USB_HostEhciStartAsync(ehciInstance); + } + else + { + vltQhPointer->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; /* invalid next qtd */ + vltQhPointer->transferOverlayResults[0] &= + (~EHCI_HOST_QTD_STATUS_MASK); /* clear error status */ + USB_HostEhciStartAsync(ehciInstance); + timeoutLabel = 1; + } + } + } + } + + if (timeoutLabel == 1) + { + /* remove qtd from qh */ + while ((vltQtdPointer != NULL) && + (!(vltQtdPointer->transferResults[0] & EHCI_HOST_QTD_IOC_MASK)) && + (vltQtdPointer != (usb_host_ehci_qtd_t *)vltQhPointer->ehciTransferTail)) + { + vltQtdPointer = (volatile usb_host_ehci_qtd_t *)vltQtdPointer->nextQtdPointer; + } + if ((vltQtdPointer != NULL) && (!(vltQtdPointer->nextQtdPointer & EHCI_HOST_T_INVALID_VALUE))) + { + vltQhPointer->nextQtdPointer = + vltQtdPointer->nextQtdPointer; /* start qh if there are other qtd that don't belong to + the transfer */ + } + transfer->transferSofar = + USB_HostEhciQtdListRelease(ehciInstance, (usb_host_ehci_qtd_t *)(transfer->union1.unitHead), + (usb_host_ehci_qtd_t *)(transfer->union2.unitTail)); + transfer->transferSofar = (transfer->transferLength < transfer->transferSofar) ? + 0 : + (transfer->transferLength - transfer->transferSofar); + + vltQhPointer->ehciTransferHead = transfer->next; + vltQhPointer->timeOutValue = USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE; + transfer->callbackFn(transfer->callbackParam, transfer, kStatus_USB_TransferFailed); + } + } + break; + default: + break; + } + ehciPipePointer = (usb_host_ehci_pipe_t *)ehciPipePointer->pipeCommon.next; + } +} + +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) +static void USB_HostEhciTimer1(usb_host_ehci_instance_t *ehciInstance) +{ + if (ehciInstance->deviceAttached != kEHCIDeviceDetached) + { + if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus) + { + usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle; + + if (0 == ehciInstance->matchTick) + { + ehciInstance->matchTick = hostPointer->hwTick; + } + else + { + if ((hostPointer->hwTick - ehciInstance->matchTick) >= 5) + { + ehciInstance->ehciIpBase->USBCMD &= ~USBHS_USBCMD_RS_MASK; + ehciInstance->ehciIpBase->USBSTS |= USBHS_USBSTS_SRI_MASK; +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) +#if 0 + ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK + | USBPHY_CTRL_ENIDCHG_WKUP_MASK + | USBPHY_CTRL_ENDPDMCHG_WKUP_MASK + | USBPHY_CTRL_ENIRQRESUMEDETECT_MASK + ; +#endif +#endif + ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK; + + ehciInstance->registerPhyBase->PWD = 0xFFFFFFFFU; + + while (ehciInstance->registerPhyBase->CTRL & (USBPHY_CTRL_UTMI_SUSPENDM_MASK)) + { + __ASM("nop"); + } + +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK | + USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK | + USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK; + ehciInstance->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK; +#else + ehciInstance->ehciIpBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK; +#endif + ehciInstance->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; + hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL, + kUSB_HostEventSuspended); /* call host callback function */ + ehciInstance->busSuspendStatus = kBus_EhciSuspended; + } + } + } + else if (kBus_EhciStartResume == ehciInstance->busSuspendStatus) + { + usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle; + if (!(ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK)) + { + ehciInstance->ehciIpBase->PORTSC1 &= ~USBHS_PORTSC1_WKDS_MASK; + if (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK) + { + USB_HostEhciStartAsync(ehciInstance); + USB_HostEhciStartPeriodic(ehciInstance); + } + hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL, + kUSB_HostEventResumed); /* call host callback function */ + hostPointer->suspendedDevice = NULL; + ehciInstance->busSuspendStatus = kBus_EhciIdle; + ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK); + } + } + else + { + } + } + else + { + ehciInstance->busSuspendStatus = kBus_EhciIdle; + ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK); + } +} +#endif + +usb_status_t USB_HostEhciCreate(uint8_t controllerId, + usb_host_handle upperLayerHandle, + usb_host_controller_handle *controllerHandle) +{ + uint32_t index = 0; + usb_osa_status_t osaStatus; + usb_host_ehci_instance_t *ehciInstance; + uint32_t usbhsBaseAddrs[] = USBHS_BASE_ADDRS; + usb_host_ehci_data_t *usbHostEhciData[] = USB_HOST_EHCI_DATA_ARRAY; + uint8_t *usbHostEhciFrameList[] = USB_HOST_EHCI_FRAME_LIST_ARRAY; + uint32_t *framePointer; + + if ((uint32_t)(controllerId - kUSB_ControllerEhci0) >= (sizeof(usbhsBaseAddrs) / sizeof(usbhsBaseAddrs[0]))) + { + return kStatus_USB_ControllerNotFound; + } + + *controllerHandle = NULL; + ehciInstance = (usb_host_ehci_instance_t *)USB_OsaMemoryAllocate( + sizeof(usb_host_ehci_instance_t)); /* malloc host ehci instance */ + if (ehciInstance == NULL) + { + return kStatus_USB_AllocFail; + } + ehciInstance->controllerId = controllerId; + ehciInstance->hostHandle = upperLayerHandle; + ehciInstance->deviceAttached = kEHCIDeviceDetached; + ehciInstance->ehciIpBase = (USBHS_Type *) + usbhsBaseAddrs[controllerId - kUSB_ControllerEhci0]; /* operate ehci ip through the base address */ +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + ehciInstance->busSuspendStatus = kBus_EhciIdle; + +#if (defined(USB_HOST_CONFIG_LOW_POWER_MODE) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + ehciInstance->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciInstance->registerNcBase = (USBNC_Type *)USB_EhciNCGetBase(controllerId); +#endif + +#endif + +#endif + + if (USB_HostEhciResetIP(ehciInstance) != kStatus_USB_Success) /* reset ehci ip */ + { + USB_OsaMemoryFree(ehciInstance); + return kStatus_USB_Error; + } + + /* initialize ehci frame list */ + ehciInstance->ehciFrameList = usbHostEhciFrameList[ehciInstance->controllerId - kUSB_ControllerEhci0]; + + /* initialize ehci units */ + ehciInstance->ehciUnitBase = (uint32_t *)(usbHostEhciData[ehciInstance->controllerId - kUSB_ControllerEhci0]); + /* initialize qh/qtd/itd/sitd/iso list */ + ehciInstance->ehciQhList = (usb_host_ehci_qh_t *)((uint32_t)(ehciInstance->ehciUnitBase)); + ehciInstance->ehciQtdHead = (usb_host_ehci_qtd_t *)((uint32_t)ehciInstance->ehciQhList + + (sizeof(usb_host_ehci_qh_t) * USB_HOST_CONFIG_EHCI_MAX_QH)); + ehciInstance->ehciItdList = (usb_host_ehci_itd_t *)((uint32_t)ehciInstance->ehciQtdHead + + (sizeof(usb_host_ehci_qtd_t) * USB_HOST_CONFIG_EHCI_MAX_QTD)); + ehciInstance->ehciSitdList = ehciInstance->ehciSitdIndexBase = + (usb_host_ehci_sitd_t *)((uint32_t)ehciInstance->ehciItdList + + (sizeof(usb_host_ehci_itd_t) * USB_HOST_CONFIG_EHCI_MAX_ITD)); + ehciInstance->ehciIsoList = (usb_host_ehci_iso_t *)((uint32_t)ehciInstance->ehciSitdList + + (sizeof(usb_host_ehci_sitd_t) * USB_HOST_CONFIG_EHCI_MAX_SITD)); + ehciInstance->ehciPipeIndexBase = + (usb_host_ehci_pipe_t *)((uint32_t)ehciInstance->ehciIsoList + + (sizeof(usb_host_ehci_iso_t) * USB_HOST_EHCI_ISO_NUMBER)); + for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_QH; ++index) + { + ehciInstance->ehciQhList[index - 1].horizontalLinkPointer = (uint32_t)(&ehciInstance->ehciQhList[index]); + } + ehciInstance->ehciQhList[USB_HOST_CONFIG_EHCI_MAX_QH - 1].horizontalLinkPointer = (uint32_t)NULL; + for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_QTD; ++index) + { + ehciInstance->ehciQtdHead[index - 1].nextQtdPointer = (uint32_t)(&ehciInstance->ehciQtdHead[index]); + } + ehciInstance->ehciQtdNumber = USB_HOST_CONFIG_EHCI_MAX_QTD; + ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1].nextQtdPointer = (uint32_t)NULL; + ehciInstance->ehciQtdTail = &ehciInstance->ehciQtdHead[USB_HOST_CONFIG_EHCI_MAX_QTD - 1]; + +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) + for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_ITD; ++index) + { + ehciInstance->ehciItdList[index - 1].nextLinkPointer = (uint32_t)(&ehciInstance->ehciItdList[index]); + } + ehciInstance->ehciItdNumber = USB_HOST_CONFIG_EHCI_MAX_ITD; + ehciInstance->ehciItdList[USB_HOST_CONFIG_EHCI_MAX_ITD - 1].nextLinkPointer = (uint32_t)NULL; +#endif /* USB_HOST_CONFIG_EHCI_MAX_ITD */ + +#if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)) + for (index = 1; index < USB_HOST_CONFIG_EHCI_MAX_SITD; ++index) + { + ehciInstance->ehciSitdList[index - 1].nextLinkPointer = (uint32_t)(&ehciInstance->ehciSitdList[index]); + } + ehciInstance->ehciSitdNumber = USB_HOST_CONFIG_EHCI_MAX_SITD; + ehciInstance->ehciSitdList[USB_HOST_CONFIG_EHCI_MAX_SITD - 1].nextLinkPointer = (uint32_t)NULL; +#endif /* USB_HOST_CONFIG_EHCI_MAX_SITD */ + +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) + for (index = 1; index < USB_HOST_EHCI_ISO_NUMBER; ++index) + { + ehciInstance->ehciIsoList[index - 1].next = &ehciInstance->ehciIsoList[index]; + } + ehciInstance->ehciIsoList[USB_HOST_EHCI_ISO_NUMBER - 1].next = NULL; +#endif + + /* initialize pipes */ + ehciInstance->ehciPipeList = ehciInstance->ehciPipeIndexBase; + for (index = 1; index < USB_HOST_CONFIG_MAX_PIPES; ++index) + { + ehciInstance->ehciPipeList[index - 1].pipeCommon.next = (usb_host_pipe_t *)&ehciInstance->ehciPipeList[index]; + } + /* initialize mutext */ + osaStatus = USB_OsaMutexCreate(&ehciInstance->ehciMutex); + if (osaStatus != kStatus_USB_OSA_Success) + { +#ifdef HOST_ECHO + usb_echo("ehci mutex init fail\r\n"); +#endif + USB_OsaMemoryFree(ehciInstance); + return kStatus_USB_Error; + } + /* initialize task event */ + osaStatus = USB_OsaEventCreate(&ehciInstance->taskEventHandle, 1); + if (osaStatus != kStatus_USB_OSA_Success) + { +#ifdef HOST_ECHO + usb_echo("ehci event init fail\r\n"); +#endif + USB_OsaMutexDestroy(ehciInstance->ehciMutex); + USB_OsaMemoryFree(ehciInstance); + return kStatus_USB_Error; + } + + /* initialize first qh */ + ehciInstance->shedFirstQh = ehciInstance->ehciQhList; + ehciInstance->ehciQhList = + (usb_host_ehci_qh_t *)(ehciInstance->ehciQhList->horizontalLinkPointer & EHCI_HOST_POINTER_ADDRESS_MASK); + ehciInstance->shedFirstQh->staticEndpointStates[0] |= (1 << EHCI_HOST_QH_H_SHIFT); /* first qh */ + ehciInstance->shedFirstQh->horizontalLinkPointer = EHCI_HOST_T_INVALID_VALUE; + ehciInstance->shedFirstQh->currentQtdPointer = EHCI_HOST_T_INVALID_VALUE; + ehciInstance->shedFirstQh->nextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + ehciInstance->shedFirstQh->alternateNextQtdPointer = EHCI_HOST_T_INVALID_VALUE; + ehciInstance->shedFirstQh->horizontalLinkPointer = + (uint32_t)((uint32_t)(ehciInstance->shedFirstQh) | EHCI_HOST_POINTER_TYPE_QH); + + /* initialize periodic list */ + framePointer = (uint32_t *)ehciInstance->ehciFrameList; + for (index = 0; index < USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE; ++index) + { + framePointer[index] = EHCI_HOST_T_INVALID_VALUE; + } + + USB_HostEhciStartIP(ehciInstance); /* start ehci ip */ + + *controllerHandle = ehciInstance; + + return kStatus_USB_Success; +} + +usb_status_t USB_HostEhciDestory(usb_host_controller_handle controllerHandle) +{ + usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle; + + /* disable all interrupts */ + ehciInstance->ehciIpBase->USBINTR = 0; + /* stop the controller */ + ehciInstance->ehciIpBase->USBCMD = 0; + /* free memory */ + USB_OsaMutexDestroy(ehciInstance->ehciMutex); + USB_OsaEventDestroy(ehciInstance->taskEventHandle); + USB_OsaMemoryFree(ehciInstance); + + return kStatus_USB_Success; +} + +usb_status_t USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle *pipeHandle, + usb_host_pipe_init_t *pipeInit) +{ + usb_host_ehci_pipe_t *ehciPipePointer = NULL; + usb_status_t status; + uint32_t speed; + usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle; + + /* get one pipe */ + USB_HostEhciLock(); + if (ehciInstance->ehciPipeList != NULL) + { + ehciPipePointer = ehciInstance->ehciPipeList; + ehciInstance->ehciPipeList = (usb_host_ehci_pipe_t *)ehciPipePointer->pipeCommon.next; + } + USB_HostEhciUnlock(); + if (ehciPipePointer == NULL) + { +#ifdef HOST_ECHO + usb_echo("ehci open pipe failed\r\n"); +#endif + return kStatus_USB_Busy; + } + + /* initialize pipe informations */ + USB_HostEhciZeroMem((uint32_t *)ehciPipePointer, sizeof(usb_host_ehci_pipe_t) / 4); + ehciPipePointer->pipeCommon.deviceHandle = pipeInit->devInstance; + ehciPipePointer->pipeCommon.endpointAddress = pipeInit->endpointAddress; + ehciPipePointer->pipeCommon.direction = pipeInit->direction; + ehciPipePointer->pipeCommon.interval = pipeInit->interval; + ehciPipePointer->pipeCommon.maxPacketSize = pipeInit->maxPacketSize; + ehciPipePointer->pipeCommon.pipeType = pipeInit->pipeType; + ehciPipePointer->pipeCommon.numberPerUframe = pipeInit->numberPerUframe; + if (ehciPipePointer->pipeCommon.numberPerUframe == 0) + { + ehciPipePointer->pipeCommon.numberPerUframe = 1; + } + ehciPipePointer->pipeCommon.nakCount = pipeInit->nakCount; + ehciPipePointer->pipeCommon.nextdata01 = 0; + ehciPipePointer->ehciQh = NULL; + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, &speed); + if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_ISOCHRONOUS) + { + ehciPipePointer->pipeCommon.interval = + (1 << (ehciPipePointer->pipeCommon.interval - 1)); /* iso interval is the power of 2 */ + } + else if (ehciPipePointer->pipeCommon.pipeType == USB_ENDPOINT_INTERRUPT) + { + if (speed == USB_SPEED_HIGH) + { + ehciPipePointer->pipeCommon.interval = + (1 << (ehciPipePointer->pipeCommon.interval - 1)); /* HS interrupt interval is the power of 2 */ + } + else + { + ehciPipePointer->pipeCommon.interval = USB_HostEhciGet2PowerValue( + ehciPipePointer->pipeCommon + .interval); /* FS/LS interrupt interval should be the power of 2, it is used for ehci bandwidth */ + } + } + else + { + } + + /* save the micro-frame interval, it is convenient for the interval process */ + if (speed == USB_SPEED_HIGH) + { + ehciPipePointer->uframeInterval = ehciPipePointer->pipeCommon.interval; + } + else + { + ehciPipePointer->uframeInterval = 8 * ehciPipePointer->pipeCommon.interval; + } + + /* open pipe */ + switch (ehciPipePointer->pipeCommon.pipeType) + { + case USB_ENDPOINT_CONTROL: + case USB_ENDPOINT_BULK: + status = USB_HostEhciOpenControlBulk(ehciInstance, ehciPipePointer); + break; + +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + case USB_ENDPOINT_ISOCHRONOUS: + status = USB_HostEhciOpenIso(ehciInstance, ehciPipePointer); + break; +#endif + + case USB_ENDPOINT_INTERRUPT: + status = USB_HostEhciOpenInterrupt(ehciInstance, ehciPipePointer); + break; + + default: + status = kStatus_USB_Error; + break; + } + + if (status != kStatus_USB_Success) + { + /* release pipe */ + USB_HostEhciLock(); + ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)ehciInstance->ehciPipeList; + ehciInstance->ehciPipeList = ehciPipePointer; + USB_HostEhciUnlock(); + return status; + } + + /* add pipe to run pipe list */ + USB_HostEhciLock(); + ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)ehciInstance->ehciRunningPipeList; + ehciInstance->ehciRunningPipeList = ehciPipePointer; + USB_HostEhciUnlock(); + + *pipeHandle = ehciPipePointer; + return status; +} + +usb_status_t USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle) +{ + usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle; + usb_host_ehci_pipe_t *ehciPipePointer = (usb_host_ehci_pipe_t *)pipeHandle; + usb_host_pipe_t *prevPointer = NULL; + + switch (ehciPipePointer->pipeCommon.pipeType) + { + case USB_ENDPOINT_BULK: + case USB_ENDPOINT_CONTROL: + USB_HostEhciCloseControlBulk(ehciInstance, ehciPipePointer); + break; + + case USB_ENDPOINT_INTERRUPT: + USB_HostEhciCloseInterrupt(ehciInstance, ehciPipePointer); + break; + +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + case USB_ENDPOINT_ISOCHRONOUS: + USB_HostEhciCloseIso(ehciInstance, ehciPipePointer); + break; +#endif + + default: + break; + } + + /* delete pipe from run pipe list */ + USB_HostEhciLock(); + prevPointer = (usb_host_pipe_t *)ehciInstance->ehciRunningPipeList; + if (prevPointer == (usb_host_pipe_t *)ehciPipePointer) + { + ehciInstance->ehciRunningPipeList = (usb_host_ehci_pipe_t *)(prevPointer->next); + } + else + { + while (prevPointer != NULL) + { + if (prevPointer->next == (usb_host_pipe_t *)ehciPipePointer) + { + prevPointer->next = ehciPipePointer->pipeCommon.next; + break; + } + else + { + prevPointer = prevPointer->next; + } + } + } + USB_HostEhciUnlock(); + + /* release pipe */ + USB_HostEhciLock(); + ehciPipePointer->pipeCommon.next = (usb_host_pipe_t *)ehciInstance->ehciPipeList; + ehciInstance->ehciPipeList = ehciPipePointer; + USB_HostEhciUnlock(); + + return kStatus_USB_Success; +} + +usb_status_t USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle pipeHandle, + usb_host_transfer_t *transfer) +{ + usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle; + usb_host_ehci_pipe_t *ehciPipePointer = (usb_host_ehci_pipe_t *)pipeHandle; + usb_status_t status = kStatus_USB_Success; +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + uint32_t speed; +#endif + + switch (ehciPipePointer->pipeCommon.pipeType) + { + case USB_ENDPOINT_BULK: + case USB_ENDPOINT_CONTROL: + case USB_ENDPOINT_INTERRUPT: + status = USB_HostEhciQhQtdListInit(ehciInstance, ehciPipePointer, + transfer); /* initialize qtd for control/bulk transfer */ + break; + +#if (((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) || \ + ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD))) + case USB_ENDPOINT_ISOCHRONOUS: + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceSpeed, + &speed); + if (speed == USB_SPEED_HIGH) + { +#if ((defined USB_HOST_CONFIG_EHCI_MAX_ITD) && (USB_HOST_CONFIG_EHCI_MAX_ITD)) + status = USB_HostEhciItdArrayInit(ehciInstance, ehciPipePointer, + transfer); /* initialize itd for iso transfer */ +#endif + } + else + { +#if ((defined USB_HOST_CONFIG_EHCI_MAX_SITD) && (USB_HOST_CONFIG_EHCI_MAX_SITD)) + status = USB_HostEhciSitdArrayInit(ehciInstance, ehciPipePointer, + transfer); /* initialize sitd for iso transfer */ +#endif + } + break; +#endif + + default: + break; + } + return status; +} + +usb_status_t USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle pipeHandle, + usb_host_transfer_t *transfer) +{ + return USB_HostEhciWritePipe(controllerHandle, pipeHandle, transfer); /* same as write */ +} + +usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandle, uint32_t ioctlEvent, void *ioctlParam) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_ehci_instance_t *ehciInstance = (usb_host_ehci_instance_t *)controllerHandle; + usb_host_cancel_param_t *param; + usb_host_ehci_pipe_t *ehciPipePointer; + volatile usb_host_ehci_qh_t *vltQhPointer; + uint32_t deviceAddress; + + if (controllerHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + switch (ioctlEvent) + { + case kUSB_HostCancelTransfer: /* cancel pipe or one transfer */ + param = (usb_host_cancel_param_t *)ioctlParam; + status = USB_HostEhciCancelPipe(ehciInstance, (usb_host_ehci_pipe_t *)param->pipeHandle, param->transfer); + break; + + case kUSB_HostBusControl: /* bus control */ + status = USB_HostEhciControlBus(ehciInstance, *((uint8_t *)ioctlParam)); + break; + + case kUSB_HostGetFrameNumber: /* get frame number */ + *((uint32_t *)ioctlParam) = ((ehciInstance->ehciIpBase->FRINDEX & EHCI_MAX_UFRAME_VALUE) >> 3); + break; + + case kUSB_HostUpdateControlEndpointAddress: + ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam; + vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + /* update address */ + USB_HostHelperGetPeripheralInformation(ehciPipePointer->pipeCommon.deviceHandle, kUSB_HostGetDeviceAddress, + &deviceAddress); + vltQhPointer->staticEndpointStates[0] |= deviceAddress; + break; + + case kUSB_HostUpdateControlPacketSize: + ehciPipePointer = (usb_host_ehci_pipe_t *)ioctlParam; + vltQhPointer = (volatile usb_host_ehci_qh_t *)ehciPipePointer->ehciQh; + USB_HostEhciLock(); + if (ehciInstance->ehciIpBase->USBSTS & USBHS_USBSTS_AS_MASK) + { + USB_HostEhciStopAsync(ehciInstance); + /* update max packet size */ + vltQhPointer->staticEndpointStates[0] = + (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) | + ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT)); + USB_HostEhciStartAsync(ehciInstance); + } + else + { + /* update max packet size */ + vltQhPointer->staticEndpointStates[0] = + (((vltQhPointer->staticEndpointStates[0]) & (~EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK)) | + ((uint32_t)ehciPipePointer->pipeCommon.maxPacketSize << EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT)); + } + USB_HostEhciUnlock(); + break; + + default: + break; + } + return status; +} + +void USB_HostEhciTaskFunction(void *hostHandle) +{ + usb_host_ehci_instance_t *ehciInstance; + uint32_t bitSet; + usb_device_handle deviceHandle; + + if (hostHandle == NULL) + { + return; + } + ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle; + + if (USB_OsaEventWait(ehciInstance->taskEventHandle, 0xFF, 0, 0, &bitSet) == + kStatus_USB_OSA_Success) /* wait all event */ + { + if (bitSet & EHCI_TASK_EVENT_PORT_CHANGE) /* port change */ + { + USB_HostEhciPortChange(ehciInstance); + } + + if (bitSet & EHCI_TASK_EVENT_TIMER0) /* timer0 */ + { + USB_HostEhciTimer0(ehciInstance); + } + +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + if (bitSet & EHCI_TASK_EVENT_TIMER1) /* timer1 */ + { + USB_HostEhciTimer1(ehciInstance); + } +#endif + + if (ehciInstance->deviceAttached == kEHCIDeviceAttached) + { + if (bitSet & EHCI_TASK_EVENT_TRANSACTION_DONE) /* transaction done */ + { + USB_HostEhciTransactionDone(ehciInstance); + } + + if (bitSet & EHCI_TASK_EVENT_DEVICE_DETACH) /* device detach */ + { + ehciInstance->ehciIpBase->USBINTR &= + (~USBHS_USBINTR_PCE_MASK); /* disable attach, enable when the detach process is done */ + ehciInstance->deviceAttached = kEHCIDeviceDetached; + USB_HostDetachDevice(ehciInstance->hostHandle, 0, 0); + } + } + else if (ehciInstance->deviceAttached != kEHCIDeviceAttached) + { + if (bitSet & EHCI_TASK_EVENT_DEVICE_ATTACH) /* device is attached */ + { + USB_HostEhciStartAsync(ehciInstance); + USB_HostEhciStartPeriodic(ehciInstance); + + if (USB_HostAttachDevice(ehciInstance->hostHandle, ehciInstance->firstDeviceSpeed, 0, 0, 1, + &deviceHandle) == kStatus_USB_Success) + { + ehciInstance->deviceAttached = kEHCIDeviceAttached; + } + } + } + else + { + } + } +} + +void USB_HostEhciIsrFunction(void *hostHandle) +{ + usb_host_ehci_instance_t *ehciInstance; + static uint32_t interruptStatus = 0; + + if (hostHandle == NULL) + { + return; + } + + ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle; + +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + if (ehciInstance->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK) + { + usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle; + ehciInstance->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK; + hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL, + kUSB_HostEventDetectResume); /* call host callback function */ + + while (!(ehciInstance->registerNcBase->USB_OTGn_PHY_CTRL_0 & USBNC_USB_OTGn_PHY_CTRL_0_UTMI_CLK_VLD_MASK)) + { + } + + if (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK) + { + USB_HostEhciStartAsync(ehciInstance); + USB_HostEhciStartPeriodic(ehciInstance); + } + ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK); + if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus)) + { + /* ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */ + ehciInstance->busSuspendStatus = kBus_EhciStartResume; + } + else + { + } + } + else + { + } +#else + if (ehciInstance->ehciIpBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK) + { + usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle; + + hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL, + kUSB_HostEventDetectResume); /* call host callback function */ + + while (!(USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK)) + { + } + ehciInstance->ehciIpBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK; + ehciInstance->ehciIpBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK; + if (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK) + { + USB_HostEhciStartAsync(ehciInstance); + USB_HostEhciStartPeriodic(ehciInstance); + } + ehciInstance->ehciIpBase->USBCMD |= (USBHS_USBCMD_RS_MASK); + if ((kBus_EhciSuspended == ehciInstance->busSuspendStatus)) + { + ehciInstance->busSuspendStatus = kBus_EhciStartResume; + /*ehciInstance->ehciIpBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; */ + } + else + { + } + } + else + { + } +#endif /* FSL_FEATURE_SOC_USBNC_COUNT */ + +#endif /* USB_HOST_CONFIG_LOW_POWER_MODE */ + + interruptStatus = ehciInstance->ehciIpBase->USBSTS; + interruptStatus &= ehciInstance->ehciIpBase->USBINTR; + while (interruptStatus) /* there are usb interrupts */ + { + ehciInstance->ehciIpBase->USBSTS = interruptStatus; /* clear interrupt */ + + if (interruptStatus & USBHS_USBSTS_SRI_MASK) /* SOF interrupt */ + { + } + + if (interruptStatus & USBHS_USBSTS_SEI_MASK) /* system error interrupt */ + { + } + + if ((interruptStatus & USBHS_USBSTS_UI_MASK) || + (interruptStatus & USBHS_USBSTS_UEI_MASK)) /* USB interrupt or USB error interrupt */ + { + USB_OsaEventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TRANSACTION_DONE); + } + + if (interruptStatus & USBHS_USBSTS_PCI_MASK) /* port change detect interrupt */ + { +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + usb_host_instance_t *hostPointer = (usb_host_instance_t *)ehciInstance->hostHandle; + if (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_FPR_MASK) + { + if (kBus_EhciStartSuspend == ehciInstance->busSuspendStatus) + { + if (ehciInstance->ehciIpBase->PORTSC1 & USBHS_PORTSC1_CCS_MASK) + { + USB_HostEhciStartAsync(ehciInstance); + USB_HostEhciStartPeriodic(ehciInstance); + } + hostPointer->deviceCallback(hostPointer->suspendedDevice, NULL, + kUSB_HostEventNotSuspended); /* call host callback function */ + hostPointer->suspendedDevice = NULL; + ehciInstance->busSuspendStatus = kBus_EhciIdle; + ehciInstance->ehciIpBase->USBINTR &= ~(USBHS_USBINTR_TIE1_MASK); + } + else + { + } + } +#endif + USB_OsaEventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_PORT_CHANGE); + } + + if (interruptStatus & USBHS_USBSTS_TI0_MASK) /* timer 0 interrupt */ + { + USB_OsaEventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER0); + } + +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + if (interruptStatus & USBHS_USBSTS_TI1_MASK) /* timer 1 interrupt */ + { + USB_OsaEventSet(ehciInstance->taskEventHandle, EHCI_TASK_EVENT_TIMER1); + } +#endif + + interruptStatus = ehciInstance->ehciIpBase->USBSTS; + interruptStatus &= ehciInstance->ehciIpBase->USBINTR; + } +} + +#endif /* USB_HOST_CONFIG_EHCI */ diff --git a/bsp/imxrt/libraries/drivers/usb/host/usb_host_ehci.h b/bsp/imxrt/libraries/drivers/usb/host/usb_host_ehci.h new file mode 100644 index 0000000000..162d6576cd --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/host/usb_host_ehci.h @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _USB_HOST_CONTROLLER_EHCI_H_ +#define _USB_HOST_CONTROLLER_EHCI_H_ + +/******************************************************************************* + * KHCI private public structures, enumerations, macros, functions + ******************************************************************************/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* EHCI host macros */ +#define EHCI_HOST_T_INVALID_VALUE (1U) +#define EHCI_HOST_POINTER_TYPE_ITD (0x00U) +#define EHCI_HOST_POINTER_TYPE_QH (0x00000002U) +#define EHCI_HOST_POINTER_TYPE_SITD (0x00000004U) +#define EHCI_HOST_POINTER_TYPE_FSTN (0x00000006U) +#define EHCI_HOST_POINTER_TYPE_MASK (0x00000006U) +#define EHCI_HOST_POINTER_ADDRESS_MASK (0xFFFFFFE0U) +#define EHCI_HOST_PID_OUT (0U) +#define EHCI_HOST_PID_IN (1U) +#define EHCI_HOST_PID_SETUP (2U) + +#define EHCI_HOST_QH_RL_SHIFT (28U) +#define EHCI_HOST_QH_RL_MASK (0xF0000000U) +#define EHCI_HOST_QH_C_SHIFT (27U) +#define EHCI_HOST_QH_MAX_PACKET_LENGTH_SHIFT (16U) +#define EHCI_HOST_QH_MAX_PACKET_LENGTH_MASK (0x07FF0000U) +#define EHCI_HOST_QH_H_SHIFT (15U) +#define EHCI_HOST_QH_DTC_SHIFT (14U) +#define EHCI_HOST_QH_EPS_SHIFT (12U) +#define EHCI_HOST_QH_ENDPT_SHIFT (8U) +#define EHCI_HOST_QH_I_SHIFT (7U) +#define EHCI_HOST_QH_DEVICE_ADDRESS_SHIFT (0U) +#define EHCI_HOST_QH_MULT_SHIFT (30U) +#define EHCI_HOST_QH_PORT_NUMBER_SHIFT (23U) +#define EHCI_HOST_QH_HUB_ADDR_SHIFT (16U) +#define EHCI_HOST_QH_UFRAME_CMASK_SHIFT (8U) +#define EHCI_HOST_QH_UFRAME_SMASK_SHIFT (0U) +#define EHCI_HOST_QH_STATUS_ERROR_MASK (0x0000007EU) +#define EHCI_HOST_QH_STATUS_NOSTALL_ERROR_MASK (0x0000003EU) + +#define EHCI_HOST_QTD_DT_SHIFT (31U) +#define EHCI_HOST_QTD_DT_MASK (0x80000000U) +#define EHCI_HOST_QTD_TOTAL_BYTES_SHIFT (16U) +#define EHCI_HOST_QTD_TOTAL_BYTES_MASK (0x7FFF0000U) +#define EHCI_HOST_QTD_IOC_MASK (0x00008000U) +#define EHCI_HOST_QTD_C_PAGE_SHIFT (12U) +#define EHCI_HOST_QTD_CERR_SHIFT (10U) +#define EHCI_HOST_QTD_CERR_MAX_VALUE (0x00000003U) +#define EHCI_HOST_QTD_PID_CODE_SHIFT (8U) +#define EHCI_HOST_QTD_STATUS_SHIFT (0U) +#define EHCI_HOST_QTD_CURRENT_OFFSET_MASK (0x00000FFFU) +#define EHCI_HOST_QTD_BUFFER_POINTER_SHIFT (12U) +#define EHCI_HOST_QTD_STATUS_ACTIVE_MASK (0x00000080U) +#define EHCI_HOST_QTD_STATUS_MASK (0x000000ffU) +#define EHCI_HOST_QTD_STATUS_ERROR_MASK (0x0000007EU) +#define EHCI_HOST_QTD_STATUS_STALL_ERROR_MASK (0x00000040U) + +#define EHCI_HOST_ITD_STATUS_ACTIVE_MASK (0x80000000U) +#define EHCI_HOST_ITD_TRANSACTION_LEN_SHIFT (16U) +#define EHCI_HOST_ITD_TRANSACTION_LEN_MASK (0x0FFF0000U) +#define EHCI_HOST_ITD_IOC_SHIFT (15U) +#define EHCI_HOST_ITD_PG_SHIFT (12U) +#define EHCI_HOST_ITD_TRANSACTION_OFFSET_SHIFT (0U) +#define EHCI_HOST_ITD_TRANSACTION_OFFSET_MASK (0x00000FFFU) +#define EHCI_HOST_ITD_BUFFER_POINTER_SHIFT (12U) +#define EHCI_HOST_ITD_ENDPT_SHIFT (8U) +#define EHCI_HOST_ITD_DEVICE_ADDRESS_SHIFT (0U) +#define EHCI_HOST_ITD_MAX_PACKET_SIZE_SHIFT (0U) +#define EHCI_HOST_ITD_MULT_SHIFT (0U) +#define EHCI_HOST_ITD_DIRECTION_SHIFT (11U) + +#define EHCI_HOST_SITD_STATUS_ACTIVE_MASK (0x00000080U) +#define EHCI_HOST_SITD_DIRECTION_SHIFT (31U) +#define EHCI_HOST_SITD_PORT_NUMBER_SHIFT (24U) +#define EHCI_HOST_SITD_HUB_ADDR_SHIFT (16U) +#define EHCI_HOST_SITD_ENDPT_SHIFT (8U) +#define EHCI_HOST_SITD_DEVICE_ADDRESS_SHIFT (0U) +#define EHCI_HOST_SITD_CMASK_SHIFT (8U) +#define EHCI_HOST_SITD_SMASK_SHIFT (0U) +#define EHCI_HOST_SITD_TOTAL_BYTES_SHIFT (16U) +#define EHCI_HOST_SITD_TOTAL_BYTES_MASK (0x03FF0000U) +#define EHCI_HOST_SITD_TP_SHIFT (3U) +#define EHCI_HOST_SITD_TCOUNT_SHIFT (0U) +#define EHCI_HOST_SITD_IOC_SHIFT (31U) + +/* register related MACROs */ +#define EHCI_PORTSC1_W1_BITS (0x0000002AU) +#define EHCI_MAX_UFRAME_VALUE (0x00003FFFU) + +/* task event */ +#define EHCI_TASK_EVENT_DEVICE_ATTACH (0x01U) +#define EHCI_TASK_EVENT_TRANSACTION_DONE (0x02U) +#define EHCI_TASK_EVENT_DEVICE_DETACH (0x04U) +#define EHCI_TASK_EVENT_PORT_CHANGE (0x08U) +#define EHCI_TASK_EVENT_TIMER0 (0x10U) +#define EHCI_TASK_EVENT_TIMER1 (0x20U) + +#define USB_HostEhciLock() USB_OsaMutexLock(ehciInstance->ehciMutex) +#define USB_HostEhciUnlock() USB_OsaMutexUnlock(ehciInstance->ehciMutex) + +/******************************************************************************* + * KHCI driver public structures, enumerations, macros, functions + ******************************************************************************/ + +/*! + * @addtogroup usb_host_controller_ehci + * @{ + */ + +/*! @brief The maximum supported ISO pipe number */ +#define USB_HOST_EHCI_ISO_NUMBER USB_HOST_CONFIG_EHCI_MAX_ITD +/*! @brief Check the port connect state delay if the state is unstable */ +#define USB_HOST_EHCI_PORT_CONNECT_DEBOUNCE_DELAY (101U) +/*! @brief Delay for port reset */ +#define USB_HOST_EHCI_PORT_RESET_DELAY (11U) +/*! @brief The SITD inserts a frame interval for putting more SITD continuously. + * There is an interval when an application sends two FS/LS ISO transfers. + * When the interval is less than the macro, the two transfers are continuous in the frame list. Otherwise, the two + * transfers + * are not continuous. + * For example: + * - Use case 1: when inserting the SITD first, the inserted frame = the current frame value + this MACRO value. + * - Use case 2: when inserting SITD is not first, choose between the last inserted frame value and the + * current frame value according to the following criteria: + * If the interval is less than the MACRO value, the new SITD is continuous with the last SITD. + * If not, the new SITD inserting frame = the current frame value + this MACRO value. + */ +#define USB_HOST_EHCI_ISO_BOUNCE_FRAME_NUMBER (2U) +/*! @brief The ITD inserts a micro-frame interval for putting more ITD continuously. + * There is an interval when an application sends two HS ISO transfers. + * When the interval is less than the macro, the two transfers are continuous in the frame list. Otherwise, the two + * transfers + * are not continuous. + * For example: + * - Use case 1: when inserting ITD first, the inserted micro-frame = the current micro-frame value + this MACRO value. + * - Use case 2: when inserting ITD is not first, choose between the last inserted micro-frame value and the + * current micro-frame value according to the following criteria: + * If the interval is less than this MACRO value, the new ITD is continuous with the last ITD. + * If not, the new ITD inserting micro-frame = the current micro-frame value + this MACRO value. + */ +#define USB_HOST_EHCI_ISO_BOUNCE_UFRAME_NUMBER (16U) +/*! @brief Control or bulk transaction timeout value (unit: 100 ms) */ +#define USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE (20U) + +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) +typedef enum _bus_ehci_suspend_request_state +{ + kBus_EhciIdle = 0U, + kBus_EhciStartSuspend, + kBus_EhciSuspended, + kBus_EhciStartResume, +} bus_ehci_suspend_request_state_t; +#endif + +/*! @brief EHCI state for device attachment/detachment. */ +typedef enum _host_ehci_device_state_ +{ + kEHCIDevicePhyAttached = 1, /*!< Device is physically attached */ + kEHCIDeviceAttached, /*!< Device is attached and initialized */ + kEHCIDeviceDetached, /*!< Device is detached and de-initialized */ +} host_ehci_device_state_t; + +/*! @brief EHCI pipe structure */ +typedef struct _usb_host_ehci_pipe +{ + usb_host_pipe_t pipeCommon; /*!< Common pipe information */ + void *ehciQh; /*!< Control/bulk/interrupt: QH; ISO: usb_host_ehci_iso_t*/ + + /* bandwidth */ + uint16_t uframeInterval; /*!< Micro-frame interval value */ + uint16_t startFrame; /*!< + Bandwidth start frame: its value is from 0 to frame_list. + */ + uint16_t dataTime; /*!< + Bandwidth time value: + - When the host works as HS: it's the data bandwidth value. + - When the host works as FS/LS: + - For FS/LS device, it's the data bandwidth value when transferring the data by FS/LS. + - For HS device, it's the data bandwidth value when transferring the data by HS. + */ + uint16_t startSplitTime; /*!< + Start splitting the bandwidth time value: + - When the host works as HS, it is the start split bandwidth value. + */ + uint16_t completeSplitTime; /*!< + Complete splitting the bandwidth time value: + - When host works as HS, it is the complete split bandwidth value. + */ + uint8_t startUframe; /*!< + Bandwidth start micro-frame: its value is from 0 to 7. + */ + uint8_t uframeSmask; /*!< + Start micro-frame. + - When host works as an HS: + - For FS/LS device, it's the interrupt or ISO transfer start-split mask. + - For HS device, it's the interrupt transfer start micro-frame mask. + - When host works as FS/LS, it's the interrupt and ISO start micro-frame mask + */ + uint8_t uframeCmask; /*!< + Complete micro-frame + - When host works as HS: + - For FS/LS device, it's the interrupt or ISO transfer complete-split mask. + */ +} usb_host_ehci_pipe_t; + +/*! @brief EHCI QH structure. See the USB EHCI specification */ +typedef struct _usb_host_ehci_qh +{ + uint32_t horizontalLinkPointer; /*!< QH specification filed, queue head a horizontal link pointer */ + uint32_t + staticEndpointStates[2]; /*!< QH specification filed, static endpoint state and configuration information */ + uint32_t currentQtdPointer; /*!< QH specification filed, current qTD pointer */ + uint32_t nextQtdPointer; /*!< QH specification filed, next qTD pointer */ + uint32_t alternateNextQtdPointer; /*!< QH specification filed, alternate next qTD pointer */ + uint32_t + transferOverlayResults[6]; /*!< QH specification filed, transfer overlay configuration and transfer results */ + + /* reserved space */ + usb_host_ehci_pipe_t *ehciPipePointer; /*!< EHCI pipe pointer */ + usb_host_transfer_t *ehciTransferHead; /*!< Transfer list head on this QH */ + usb_host_transfer_t *ehciTransferTail; /*!< Transfer list tail on this QH */ + uint16_t timeOutValue; /*!< Its maximum value is USB_HOST_EHCI_CONTROL_BULK_TIME_OUT_VALUE. When the value is + zero, the transfer times out. */ + uint16_t timeOutLabel; /*!< It's used to judge the transfer timeout. The EHCI driver maintain the value */ +} usb_host_ehci_qh_t; + +/*! @brief EHCI QTD structure. See the USB EHCI specification. */ +typedef struct _usb_host_ehci_qtd +{ + uint32_t nextQtdPointer; /*!< QTD specification filed, the next QTD pointer */ + uint32_t alternateNextQtdPointer; /*!< QTD specification filed, alternate next QTD pointer */ + uint32_t transferResults[2]; /*!< QTD specification filed, transfer results fields */ + uint32_t bufferPointers[4]; /*!< QTD specification filed, transfer buffer fields */ +} usb_host_ehci_qtd_t; + +/*! @brief EHCI ITD structure. See the USB EHCI specification. */ +typedef struct _usb_host_ehci_itd +{ + uint32_t nextLinkPointer; /*!< ITD specification filed, the next linker pointer */ + uint32_t transactions[8]; /*!< ITD specification filed, transactions information */ + uint32_t bufferPointers[7]; /*!< ITD specification filed, transfer buffer fields */ + + /* add space */ + struct _usb_host_ehci_itd *nextItdPointer; /*!< Next ITD pointer */ + uint32_t frameEntryIndex; /*!< The ITD inserted frame value */ + uint32_t reserved[6]; /*!< Reserved fields for 32 bytes align */ +} usb_host_ehci_itd_t; + +/*! @brief EHCI SITD structure. See the USB EHCI specification. */ +typedef struct _usb_host_ehci_sitd +{ + uint32_t nextLinkPointer; /*!< SITD specification filed, the next linker pointer */ + uint32_t endpointStates[2]; /*!< SITD specification filed, endpoint configuration information */ + uint32_t transferResults[3]; /*!< SITD specification filed, transfer result fields */ + uint32_t backPointer; /*!< SITD specification filed, back pointer */ + + /* reserved space */ + uint16_t frameEntryIndex; /*!< The SITD inserted frame value */ + uint8_t nextSitdIndex; /*!< The next SITD index; Get the next SITD pointer through adding base address with the + index. 0xFF means invalid. */ + uint8_t reserved; /*!< Reserved fields for 32 bytes align */ +} usb_host_ehci_sitd_t; + +/*! @brief EHCI ISO structure; An ISO pipe has an instance of this structure to keep the ISO pipe-specific information. + */ +typedef struct _usb_host_ehci_iso +{ + struct _usb_host_ehci_iso *next; /*!< Next instance pointer */ + usb_host_pipe_t *ehciPipePointer; /*!< This ISO's EHCI pipe pointer */ + usb_host_transfer_t *ehciTransferHead; /*!< Transfer list head on this ISO pipe */ + usb_host_transfer_t *ehciTransferTail; /*!< Transfer list head on this ISO pipe */ + + uint16_t lastLinkFrame; /*!< It means that the inserted frame for ISO ITD/SITD. 0xFFFF is invalid. For ITD, it is a + micro-frame value. For SITD, it is a frame value */ +} usb_host_ehci_iso_t; + +/*! @brief EHCI instance structure */ +typedef struct _usb_host_ehci_instance +{ + usb_host_handle hostHandle; /*!< Related host handle*/ + uint32_t *ehciUnitBase; /*!< Keep the QH/QTD/ITD/SITD buffer pointer for release*/ + uint8_t *ehciFrameList; /*!< The frame list of the current ehci instance*/ + usb_host_ehci_qh_t *ehciQhList; /*!< Idle QH list pointer */ + usb_host_ehci_qtd_t *ehciQtdHead; /*!< Idle QTD list pointer head */ + usb_host_ehci_qtd_t *ehciQtdTail; /*!< Idle QTD list pointer tail (recently used qTD will be used)*/ + usb_host_ehci_itd_t *ehciItdList; /*!< Idle ITD list pointer*/ + usb_host_ehci_sitd_t *ehciSitdIndexBase; /*!< SITD buffer's start pointer*/ + usb_host_ehci_sitd_t *ehciSitdList; /*!< Idle SITD list pointer*/ + usb_host_ehci_iso_t *ehciIsoList; /*!< Idle ISO list pointer*/ + USBHS_Type *ehciIpBase; /*!< EHCI IP base address*/ + usb_host_ehci_qh_t *shedFirstQh; /*!< First async QH*/ + usb_host_ehci_pipe_t *ehciPipeIndexBase; /*!< Pipe buffer's start pointer*/ + usb_host_ehci_pipe_t *ehciPipeList; /*!< Idle pipe list pointer*/ + usb_host_ehci_pipe_t *ehciRunningPipeList; /*!< Running pipe list pointer*/ + usb_osa_mutex_handle ehciMutex; /*!< EHCI mutex*/ + usb_osa_event_handle taskEventHandle; /*!< EHCI task event*/ +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + uint64_t matchTick; + USBPHY_Type *registerPhyBase; /*!< The base address of the PHY register */ +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + USBNC_Type *registerNcBase; /*!< The base address of the USBNC register */ +#endif + +#endif + uint8_t controllerId; /*!< EHCI controller ID*/ + uint8_t deviceAttached; /*!< Device attach/detach state, see #host_ehci_device_state_t */ + uint8_t firstDeviceSpeed; /*!< The first device's speed, the controller's work speed*/ + uint8_t ehciItdNumber; /*!< Idle ITD number*/ + uint8_t ehciSitdNumber; /*!< Idle SITD number*/ + uint8_t ehciQtdNumber; /*!< Idle QTD number*/ +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + bus_ehci_suspend_request_state_t busSuspendStatus; /*!< Bus Suspend Status*/ +#endif +} usb_host_ehci_instance_t; + +/*! @brief EHCI data structure */ +typedef struct _usb_host_ehci_data +{ +#if ((defined(USB_HOST_CONFIG_EHCI_MAX_QH)) && (USB_HOST_CONFIG_EHCI_MAX_QH > 0U)) + usb_host_ehci_qh_t ehciQh[USB_HOST_CONFIG_EHCI_MAX_QH]; /*!< Idle QH list array*/ +#endif +#if ((defined(USB_HOST_CONFIG_EHCI_MAX_QTD)) && (USB_HOST_CONFIG_EHCI_MAX_QTD > 0U)) + usb_host_ehci_qtd_t ehciQtd[USB_HOST_CONFIG_EHCI_MAX_QTD]; /*!< Idle QTD list array*/ +#endif +#if ((defined(USB_HOST_CONFIG_EHCI_MAX_ITD)) && (USB_HOST_CONFIG_EHCI_MAX_ITD > 0U)) + usb_host_ehci_itd_t ehciItd[USB_HOST_CONFIG_EHCI_MAX_ITD]; /*!< Idle ITD list array*/ +#endif +#if ((defined(USB_HOST_CONFIG_EHCI_MAX_SITD)) && (USB_HOST_CONFIG_EHCI_MAX_SITD > 0U)) + usb_host_ehci_sitd_t ehciSitd[USB_HOST_CONFIG_EHCI_MAX_SITD]; /*!< Idle SITD list array*/ +#endif +#if ((defined(USB_HOST_EHCI_ISO_NUMBER)) && (USB_HOST_EHCI_ISO_NUMBER > 0U)) + usb_host_ehci_iso_t ehciIso[USB_HOST_EHCI_ISO_NUMBER]; /*!< Idle ISO list array*/ +#endif +#if ((defined(USB_HOST_CONFIG_MAX_PIPES)) && (USB_HOST_CONFIG_MAX_PIPES > 0U)) + usb_host_ehci_pipe_t ehciPipe[USB_HOST_CONFIG_MAX_PIPES]; /*!< Idle pipe list array*/ +#endif +} usb_host_ehci_data_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif +/*! + * @name USB host EHCI APIs + * @{ + */ + +/*! + * @brief Creates the USB host EHCI instance. + * + * This function initializes the USB host EHCI controller driver. + * + * @param[in] controllerId The controller ID of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param[in] upperLayerHandle The host level handle. + * @param[out] controllerHandle return the controller instance handle. + * + * @retval kStatus_USB_Success The host is initialized successfully. + * @retval kStatus_USB_AllocFail Allocating memory failed. + * @retval kStatus_USB_Error Host mutex create fail, KHCI/EHCI mutex or KHCI/EHCI event create fail. + * Or, KHCI/EHCI IP initialize fail. + */ +extern usb_status_t USB_HostEhciCreate(uint8_t controllerId, + usb_host_handle upperLayerHandle, + usb_host_controller_handle *controllerHandle); + +/*! + * @brief Destroys the USB host EHCI instance. + * + * This function de-initializes The USB host EHCI controller driver. + * + * @param[in] controllerHandle The controller handle. + * + * @retval kStatus_USB_Success The host is initialized successfully. + */ +extern usb_status_t USB_HostEhciDestory(usb_host_controller_handle controllerHandle); + +/*! + * @brief Opens the USB host pipe. + * + * This function opens a pipe according to the pipe_init_ptr parameter. + * + * @param[in] controllerHandle The controller handle. + * @param[out] pipeHandle The pipe handle pointer, it is used to return the pipe handle. + * @param[in] pipeInit It is used to initialize the pipe. + * + * @retval kStatus_USB_Success The host is initialized successfully. + * @retval kStatus_USB_Error There is no idle pipe. + * Or, there is no idle QH for EHCI. + * Or, bandwidth allocate fail for EHCI. + */ +extern usb_status_t USB_HostEhciOpenPipe(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle *pipeHandle, + usb_host_pipe_init_t *pipeInit); + +/*! + * @brief Closes the USB host pipe. + * + * This function closes a pipe and releases related resources. + * + * @param[in] controllerHandle The controller handle. + * @param[in] pipeHandle The closing pipe handle. + * + * @retval kStatus_USB_Success The host is initialized successfully. + */ +extern usb_status_t USB_HostEhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle); + +/*! + * @brief Sends data to the pipe. + * + * This function requests to send the transfer to the specified pipe. + * + * @param[in] controllerHandle The controller handle. + * @param[in] pipeHandle The sending pipe handle. + * @param[in] transfer The transfer information. + * + * @retval kStatus_USB_Success Sent successfully. + * @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI. + * @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI. + */ +extern usb_status_t USB_HostEhciWritePipe(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle pipeHandle, + usb_host_transfer_t *transfer); + +/*! + * @brief Receives data from the pipe. + * + * This function requests to receive the transfer from the specified pipe. + * + * @param[in] controllerHandle The controller handle. + * @param[in] pipeHandle The receiving pipe handle. + * @param[in] transfer The transfer information. + + * @retval kStatus_USB_Success Send successfully. + * @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI. + * @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI. + */ +extern usb_status_t USB_HostEhciReadpipe(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle pipeHandle, + usb_host_transfer_t *transfer); + +/*! + * @brief Controls the EHCI. + * + * This function controls the EHCI. + * + * @param[in] controllerHandle The controller handle. + * @param[in] ioctlEvent See enumeration host_bus_control_t. + * @param[in] ioctlParam The control parameter. + * + * @retval kStatus_USB_Success Cancel successfully. + * @retval kStatus_USB_InvalidHandle The controllerHandle is a NULL pointer. + */ +extern usb_status_t USB_HostEhciIoctl(usb_host_controller_handle controllerHandle, + uint32_t ioctlEvent, + void *ioctlParam); + +/*! @}*/ + +#ifdef __cplusplus +} +#endif + +/*! @}*/ + +#endif /* _USB_HOST_CONTROLLER_EHCI_H_ */ diff --git a/bsp/imxrt/libraries/drivers/usb/host/usb_host_hci.c b/bsp/imxrt/libraries/drivers/usb/host/usb_host_hci.c new file mode 100644 index 0000000000..927bf8bd9c --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/host/usb_host_hci.c @@ -0,0 +1,1052 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "fsl_common.h" +#include "usb_host.h" +#include "usb_host_hci.h" +#include "usb_host_devices.h" +#include "fsl_device_registers.h" +#if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#include "fsl_cache.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + +extern uint32_t USB_HostHubGetTotalThinkTime(usb_host_handle hostHandle, uint8_t parentHubNo); + +extern usb_status_t USB_HostHubSuspendDevice(usb_host_handle hostHandle); + +extern usb_status_t USB_HostHubResumeDevice(usb_host_handle hostHandle); +#endif + +/*! + * @brief get the idle host instance. + * + * @return host instance pointer. + */ +static usb_host_instance_t *USB_HostGetInstance(void); + +/*! + * @brief release host instance. + * + * @param hostInstance host instance pointer. + */ +static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance); + +/*! + * @brief get the khci/ehci interface. + * + * @param controllerId controller id. + * @param controllerTable return controller interface structure. + */ +static void USB_HostGetControllerInterface(uint8_t controllerId, + const usb_host_controller_interface_t **controllerTable); + +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) +#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) +extern void USB_HostEhciTestModeInit(usb_device_handle devHandle); +#endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */ +#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS)) +extern void USB_HostIp3516HsTestModeInit(usb_device_handle devHandle); +#endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */ +#endif /* USB_HOST_CONFIG_EHCI */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief USB host instance resource */ +usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST]; + +#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) +#include "usb_host_ehci.h" +static const usb_host_controller_interface_t s_EhciInterface = \ +{ + USB_HostEhciCreate, USB_HostEhciDestory, USB_HostEhciOpenPipe, USB_HostEhciClosePipe, + USB_HostEhciWritePipe, USB_HostEhciReadpipe, USB_HostEhciIoctl, +}; +#endif /* USB_HOST_CONFIG_EHCI */ + +#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI)) +#include "usb_host_khci.h" +static const usb_host_controller_interface_t s_KhciInterface = \ +{ + USB_HostKhciCreate, USB_HostKhciDestory, USB_HostKhciOpenPipe, USB_HostKhciClosePipe, + USB_HostKhciWritePipe, USB_HostKhciReadpipe, USB_HostKciIoctl, +}; +#endif /* USB_HOST_CONFIG_KHCI */ + +#if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U)) +#include "usb_host_ohci.h" +static const usb_host_controller_interface_t s_OhciInterface = \ +{ + USB_HostOhciCreate, USB_HostOhciDestory, USB_HostOhciOpenPipe, USB_HostOhciClosePipe, + USB_HostOhciWritePipe, USB_HostOhciReadPipe, USB_HostOhciIoctl, +}; +#endif /* USB_HOST_CONFIG_OHCI */ + +#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U)) +#include "usb_host_ip3516hs.h" +static const usb_host_controller_interface_t s_Ip3516HsInterface = \ +{ + USB_HostIp3516HsCreate, USB_HostIp3516HsDestory, USB_HostIp3516HsOpenPipe, USB_HostIp3516HsClosePipe, + USB_HostIp3516HsWritePipe, USB_HostIp3516HsReadPipe, USB_HostIp3516HsIoctl, +}; +#endif /* USB_HOST_CONFIG_IP3516HS */ + +USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_Setupbuffer[USB_HOST_CONFIG_MAX_HOST][USB_HOST_CONFIG_MAX_TRANSFERS][USB_DATA_ALIGN_SIZE_MULTIPLE(8)]; +/******************************************************************************* +* Code +******************************************************************************/ + +#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST)) +/*FUNCTION*---------------------------------------------------------------- +* +* Function Name : usb_test_mode_init +* Returned Value : None +* Comments : +* This function is called by common class to initialize the class driver. It +* is called in response to a select interface call by application +* +*END*--------------------------------------------------------------------*/ +usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle) +{ +#if (((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) || \ + ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))) + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle; +#endif + uint32_t productId; + uint32_t vendorId; + + usb_echo("usb host test init\r\n"); + USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId); + USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceVID, &vendorId); + usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId); + + if ((productId != 0x0200U) && (productId != 0x0101) && (productId != 0x0102) && (productId != 0x0103) && + (productId != 0x0104) && (productId != 0x0105) && (productId != 0x0106) && (productId != 0x0107) && + (productId != 0x0108)) + { + usb_echo("Unsupported Device\r\n"); + } + + if (productId == 0x0200U) + { + usb_echo("PET test device attached\r\n"); + } + else + { +#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) + if (hostInstance->controllerTable == &s_EhciInterface) + { + USB_HostEhciTestModeInit(deviceHandle); + } +#elif((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS)) + if (hostInstance->controllerTable == &s_Ip3516HsInterface) + { + USB_HostIp3516HsTestModeInit(deviceHandle); + } +#endif + } + + return kStatus_USB_Success; +} +#endif + +static usb_host_instance_t *USB_HostGetInstance(void) +{ + uint8_t i = 0; + uint32_t index = 0; + USB_OSA_SR_ALLOC(); + USB_OSA_ENTER_CRITICAL(); + for (; i < USB_HOST_CONFIG_MAX_HOST; i++) + { + if (g_UsbHostInstance[i].occupied != 1) + { + uint8_t *buffer = (uint8_t *)&g_UsbHostInstance[i]; + for (uint32_t j = 0U; j < sizeof(usb_host_instance_t); j++) + { + buffer[j] = 0x00U; + } + g_UsbHostInstance[i].occupied = 1; + USB_OSA_EXIT_CRITICAL(); + for (index = 0; index < USB_HOST_CONFIG_MAX_TRANSFERS; ++index) + { + g_UsbHostInstance[i].transferList[index].setupPacket = + (usb_setup_struct_t *)&(s_Setupbuffer[i][index][0]); + } + return &g_UsbHostInstance[i]; + } + } + USB_OSA_EXIT_CRITICAL(); + return NULL; +} + +static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance) +{ + USB_OSA_SR_ALLOC(); + USB_OSA_ENTER_CRITICAL(); + hostInstance->occupied = 0; + USB_OSA_EXIT_CRITICAL(); +} + +static void USB_HostGetControllerInterface(uint8_t controllerId, + const usb_host_controller_interface_t **controllerTable) +{ +#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI)) + if (controllerId == kUSB_ControllerKhci0) + { + *controllerTable = &s_KhciInterface; + } +#endif /* USB_HOST_CONFIG_KHCI */ + +#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI)) + if ((controllerId == kUSB_ControllerEhci0) || (controllerId == kUSB_ControllerEhci1)) + { + *controllerTable = &s_EhciInterface; + } +#endif /* USB_HOST_CONFIG_EHCI */ + +#if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI > 0U)) + if (controllerId == kUSB_ControllerOhci0) + { + *controllerTable = &s_OhciInterface; + } +#endif /* USB_HOST_CONFIG_OHCI */ + +#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS > 0U)) + if (controllerId == kUSB_ControllerIp3516Hs0) + { + *controllerTable = &s_Ip3516HsInterface; + } +#endif /* USB_HOST_CONFIG_IP3516HS */ +} + +usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = NULL; + usb_host_transfer_t *transferPrev = NULL; + uint8_t i = 0; + + hostInstance = USB_HostGetInstance(); /* get one host instance */ + if (hostInstance == NULL) + { + return kStatus_USB_InvalidHandle; + } + + /* get khci/ehci API table */ + USB_HostGetControllerInterface(controllerId, &hostInstance->controllerTable); + if (hostInstance->controllerTable == NULL) + { + USB_HostReleaseInstance(hostInstance); + return kStatus_USB_ControllerNotFound; + } + + /* judge the controller interface one time at here */ + if ((hostInstance->controllerTable->controllerCreate == NULL) || + (hostInstance->controllerTable->controllerDestory == NULL) || + (hostInstance->controllerTable->controllerOpenPipe == NULL) || + (hostInstance->controllerTable->controllerClosePipe == NULL) || + (hostInstance->controllerTable->controllerWritePipe == NULL) || + (hostInstance->controllerTable->controllerReadPipe == NULL) || + (hostInstance->controllerTable->controllerIoctl == NULL)) + { + return kStatus_USB_Error; + } + + /* HOST instance init*/ + hostInstance->controllerId = controllerId; + hostInstance->deviceCallback = callbackFn; + hostInstance->deviceList = NULL; + if (kStatus_USB_OSA_Success != USB_OsaMutexCreate(&hostInstance->hostMutex)) + { + USB_HostReleaseInstance(hostInstance); +#ifdef HOST_ECHO + usb_echo("host init: create host mutex fail\r\n"); +#endif + return kStatus_USB_Error; + } + + /* initialize transfer list */ + + hostInstance->transferHead = &hostInstance->transferList[0]; + transferPrev = hostInstance->transferHead; + for (i = 1; i < USB_HOST_CONFIG_MAX_TRANSFERS; ++i) + { + transferPrev->next = &hostInstance->transferList[i]; + transferPrev = transferPrev->next; + } + + /* controller create */ + status = + hostInstance->controllerTable->controllerCreate(controllerId, hostInstance, &(hostInstance->controllerHandle)); + if ((status != kStatus_USB_Success) || (hostInstance->controllerHandle == NULL)) + { + USB_OsaMutexDestroy(hostInstance->hostMutex); + USB_HostReleaseInstance(hostInstance); +#ifdef HOST_ECHO + usb_echo("host init: controller init fail\r\n"); +#endif + return kStatus_USB_Error; + } + + *hostHandle = hostInstance; + return kStatus_USB_Success; +} + +usb_status_t USB_HostDeinit(usb_host_handle hostHandle) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + usb_host_device_instance_t *deviceInstance = NULL; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + /* device list detach */ + deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList; + while (deviceInstance != NULL) + { + deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList; + USB_HostDetachDeviceInternal(hostHandle, deviceInstance); + } + + /* controller instance destory */ + status = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle); + hostInstance->controllerHandle = NULL; + if (status != kStatus_USB_Success) + { +#ifdef HOST_ECHO + usb_echo("host controller destory fail\r\n"); +#endif + } + + /* resource release */ + if (hostInstance->hostMutex) + { + USB_OsaMutexDestroy(hostInstance->hostMutex); + hostInstance->hostMutex = NULL; + } + USB_HostReleaseInstance(hostInstance); + + return status; +} + +usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle, + usb_host_pipe_handle *pipeHandle, + usb_host_pipe_init_t *pipeInit) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if ((hostHandle == NULL) || (pipeInit == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + /* call controller open pipe interface */ + status = hostInstance->controllerTable->controllerOpenPipe(hostInstance->controllerHandle, pipeHandle, pipeInit); + + return status; +} + +usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if ((hostHandle == NULL) || (pipeHandle == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + /* call controller close pipe interface */ + status = hostInstance->controllerTable->controllerClosePipe(hostInstance->controllerHandle, pipeHandle); + + return status; +} + +usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + /* initialize transfer */ + transfer->transferSofar = 0; + transfer->direction = USB_OUT; + + USB_HostLock(); /* This api can be called by host task and app task */ +/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function + */ +#if 0 + if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle)))) + { + USB_HostUnlock(); + return status; + } +#endif +/* call controller write pipe interface */ +#if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + if (transfer->transferLength > 0) + { + DCACHE_CleanByRange((uint32_t)transfer->transferBuffer, transfer->transferLength); + } +#endif + status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer); + + USB_HostUnlock(); + return status; +} + +usb_status_t USB_HostSendSetup(usb_host_handle hostHandle, + usb_host_pipe_handle pipeHandle, + usb_host_transfer_t *transfer) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + /* initialize transfer */ + transfer->transferSofar = 0; + transfer->next = NULL; + transfer->setupStatus = 0; + if ((transfer->setupPacket->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN) + { + transfer->direction = USB_IN; + } + else + { + transfer->direction = USB_OUT; + } + + USB_HostLock(); /* This API can be called by host task and application task */ +/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function + */ +#if 0 + if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle)))) + { + USB_HostUnlock(); + return status; + } +#endif +/* call controller write pipe interface */ +#if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + DCACHE_CleanByRange((uint32_t)&transfer->setupPacket->bmRequestType, sizeof(usb_setup_struct_t)); + if (transfer->transferLength > 0) + { + DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength); + } +#endif + status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer); + + USB_HostUnlock(); + return status; +} + +usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + /* initialize transfer */ + transfer->transferSofar = 0; + transfer->direction = USB_IN; + + USB_HostLock(); /* This API can be called by host task and application task */ +/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function + */ +#if 0 + if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle)))) + { + USB_HostUnlock(); + return status; + } +#endif + +#if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + if (transfer->transferLength > 0) + { + DCACHE_CleanInvalidateByRange((uint32_t)transfer->transferBuffer, transfer->transferLength); + } +#endif + status = hostInstance->controllerTable->controllerReadPipe(hostInstance->controllerHandle, pipeHandle, transfer); + + USB_HostUnlock(); + return status; +} + +usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle, + usb_host_pipe_handle pipeHandle, + usb_host_transfer_t *transfer) +{ + usb_status_t status = kStatus_USB_Success; + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + usb_host_cancel_param_t cancelParam; + + if ((hostHandle == NULL) || (pipeHandle == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + /* initialize cancel parameter */ + cancelParam.pipeHandle = pipeHandle; + cancelParam.transfer = transfer; + + /* USB_HostLock(); This api can be called by host task and app task */ + status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostCancelTransfer, + &cancelParam); + /* USB_HostUnlock(); */ + + return status; +} + +usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfer_t **transfer) +{ + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if ((hostHandle == NULL) || (transfer == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + /* get one from the transfer_head */ + USB_HostLock(); + if (hostInstance->transferHead != NULL) + { + *transfer = hostInstance->transferHead; + hostInstance->transferHead = hostInstance->transferHead->next; + USB_HostUnlock(); + return kStatus_USB_Success; + } + else + { + *transfer = NULL; + USB_HostUnlock(); + return kStatus_USB_Error; + } +} + +usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_t *transfer) +{ + usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + if (transfer == NULL) + { + return kStatus_USB_Success; + } + + /* release one to the transfer_head */ + USB_HostLock(); + transfer->next = hostInstance->transferHead; + hostInstance->transferHead = transfer; + USB_HostUnlock(); + return kStatus_USB_Success; +} + +usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle, + uint32_t infoCode, + uint32_t *infoValue) +{ + usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle; + if ((deviceHandle == NULL) || (infoValue == NULL)) + { + return kStatus_USB_InvalidParameter; + } + + switch (infoCode) + { + case kUSB_HostGetDeviceAddress: /* device address */ + *infoValue = (uint32_t)deviceInstance->setAddress; + break; + + case kUSB_HostGetDeviceControlPipe: /* device control pipe */ + *infoValue = (uint32_t)deviceInstance->controlPipe; + break; + + case kUSB_HostGetHostHandle: /* device host handle */ + *infoValue = (uint32_t)deviceInstance->hostHandle; + break; + +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + case kUSB_HostGetDeviceHubNumber: /* device hub address */ + *infoValue = (uint32_t)deviceInstance->hubNumber; + break; + + case kUSB_HostGetDevicePortNumber: /* device port no */ + *infoValue = (uint32_t)deviceInstance->portNumber; + break; + + case kUSB_HostGetDeviceLevel: /* device level */ + *infoValue = (uint32_t)deviceInstance->level; + break; + + case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */ + *infoValue = (uint32_t)deviceInstance->hsHubNumber; + break; + + case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */ + *infoValue = (uint32_t)deviceInstance->hsHubPort; + break; + + case kUSB_HostGetHubThinkTime: /* device hub think time */ + *infoValue = USB_HostHubGetTotalThinkTime(deviceInstance->hostHandle, deviceInstance->hubNumber); + break; +#else + case kUSB_HostGetDeviceHubNumber: /* device hub address */ + case kUSB_HostGetDevicePortNumber: /* device port no */ + case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */ + case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */ + case kUSB_HostGetHubThinkTime: /* device hub think time */ + *infoValue = 0; + break; + case kUSB_HostGetDeviceLevel: /* device level */ + *infoValue = 1; + break; +#endif /* USB_HOST_CONFIG_HUB */ + + case kUSB_HostGetDeviceSpeed: /* device speed */ + *infoValue = (uint32_t)deviceInstance->speed; + break; + + case kUSB_HostGetDevicePID: /* device pid */ + *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idProduct); + break; + + case kUSB_HostGetDeviceVID: /* device vid */ + *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor->idVendor); + break; + + case kUSB_HostGetDeviceConfigIndex: /* device config index */ + *infoValue = (uint32_t)deviceInstance->configurationValue - 1U; + break; + + case kUSB_HostGetConfigurationDes: /* configuration descriptor pointer */ + *infoValue = (uint32_t)deviceInstance->configurationDesc; + break; + + case kUSB_HostGetConfigurationLength: /* configuration descriptor length */ + *infoValue = (uint32_t)deviceInstance->configurationLen; + break; + + default: + return kStatus_USB_Error; + } + + return kStatus_USB_Success; +} + +usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle, + uint8_t alternateSetting, + usb_host_interface_t *interface) +{ + uint32_t endPosition; + usb_descriptor_union_t *unionDes; + usb_host_ep_t *epParse; + + if (interfaceHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + if (alternateSetting == 0) + { + return kStatus_USB_InvalidParameter; + } + + /* parse configuration descriptor */ + unionDes = (usb_descriptor_union_t *)((usb_host_interface_t *)interfaceHandle) + ->interfaceDesc; /* interface extend descriptor start */ + endPosition = + (uint32_t)unionDes + + ((usb_host_interface_t *)interfaceHandle)->interfaceExtensionLength; /* interface extend descriptor end */ + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + + /* search for the alternate setting interface descritpor */ + while ((uint32_t)unionDes < endPosition) + { + if (unionDes->interface.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE) + { + if (unionDes->interface.bAlternateSetting == alternateSetting) + { + break; + } + else + { + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + } + } + else + { + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + } + } + if ((uint32_t)unionDes >= endPosition) + { + return kStatus_USB_Error; + } + + /* initialize interface handle structure instance */ + interface->interfaceDesc = &unionDes->interface; + interface->alternateSettingNumber = 0; + interface->epCount = 0; + interface->interfaceExtension = NULL; + interface->interfaceExtensionLength = 0; + interface->interfaceIndex = unionDes->interface.bInterfaceNumber; + + /* search for endpoint descriptor start position */ + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + while ((uint32_t)unionDes < endPosition) + { + if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) && + (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT)) + { + if (interface->interfaceExtension == NULL) + { + interface->interfaceExtension = (uint8_t *)unionDes; + } + interface->interfaceExtensionLength += unionDes->common.bLength; + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + } + else + { + break; + } + } + + /* parse endpoint descriptor */ + if (interface->interfaceDesc->bNumEndpoints != 0) + { + if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) || + (interface->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP)) + { +#ifdef HOST_ECHO + usb_echo("interface descriptor error\n"); +#endif + return kStatus_USB_Error; + } + for (; interface->epCount < interface->interfaceDesc->bNumEndpoints; (interface->epCount)++) + { + if (((uint32_t)unionDes >= endPosition) || + (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT)) + { +#ifdef HOST_ECHO + usb_echo("endpoint descriptor error\n"); +#endif + return kStatus_USB_Error; + } + epParse = (usb_host_ep_t *)&interface->epList[interface->epCount]; + epParse->epDesc = (usb_descriptor_endpoint_t *)unionDes; + epParse->epExtensionLength = 0; + epParse->epExtension = NULL; + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + while ((uint32_t)unionDes < endPosition) + { + if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) && + (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE)) + { + if (epParse->epExtension == NULL) + { + epParse->epExtension = (uint8_t *)unionDes; + } + epParse->epExtensionLength += unionDes->common.bLength; + unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength); + } + else + { + break; + } + } + } + } + + return kStatus_USB_Success; +} + +void USB_HostGetVersion(uint32_t *version) +{ + if (version) + { + *version = + (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX); + } +} + +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) +/* Send BUS or specific device suepend request */ +usb_status_t USB_HostSuspendDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle) +{ + usb_host_instance_t *hostInstance; + usb_host_device_instance_t *deviceInstance; + usb_status_t status = kStatus_USB_Error; + usb_host_bus_control_t type = kUSB_HostBusSuspend; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + hostInstance = (usb_host_instance_t *)hostHandle; + + hostInstance->suspendedDevice = (void *)deviceHandle; + + if (NULL == deviceHandle) + { +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + status = USB_HostHubSuspendDevice(hostInstance); +#else + status = + hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type); +#endif + } + else + { +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + deviceInstance = (usb_host_device_instance_t *)deviceHandle; + if (0 == deviceInstance->hubNumber) + { +#endif + if (hostInstance->deviceList == deviceHandle) + { + status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, + kUSB_HostBusControl, &type); + } +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + } + else + { + if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle)) + { + status = USB_HostHubSuspendDevice(hostInstance); + } + } +#endif + } + if (kStatus_USB_Error == status) + { + hostInstance->suspendedDevice = NULL; + } + return status; +} + +/* Send BUS or specific device resume request */ +usb_status_t USB_HostResumeDeviceResquest(usb_host_handle hostHandle, usb_device_handle deviceHandle) +{ + usb_host_instance_t *hostInstance; + usb_host_device_instance_t *deviceInstance; + usb_status_t status = kStatus_USB_Error; + usb_host_bus_control_t type = kUSB_HostBusResume; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + hostInstance = (usb_host_instance_t *)hostHandle; + + if (hostInstance->suspendedDevice != deviceHandle) + { + return kStatus_USB_InvalidParameter; + } + hostInstance->suspendedDevice = (void *)deviceHandle; + + if (NULL == deviceHandle) + { + status = + hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type); + } + else + { +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + deviceInstance = (usb_host_device_instance_t *)deviceHandle; + if (0 == deviceInstance->hubNumber) + { +#endif + if (hostInstance->deviceList == deviceHandle) + { + status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, + kUSB_HostBusControl, &type); + } +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) + } + else + { + if (kStatus_USB_Success == USB_HostValidateDevice(hostInstance, deviceHandle)) + { + status = USB_HostHubResumeDevice(hostInstance); + } + } +#endif + } + + return status; +} +#if ((defined(USB_HOST_CONFIG_LPM_L1)) && (USB_HOST_CONFIG_LPM_L1 > 0U)) +/* Send BUS or specific device suepend request */ +usb_status_t USB_HostL1SleepDeviceResquest(usb_host_handle hostHandle, + usb_device_handle deviceHandle, + uint8_t sleepType) +{ + usb_host_instance_t *hostInstance; + usb_status_t status = kStatus_USB_Error; + usb_host_bus_control_t type = kUSB_HostBusL1Sleep; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + hostInstance = (usb_host_instance_t *)hostHandle; + + hostInstance->suspendedDevice = (void *)deviceHandle; + + if (1U == sleepType) + { + /*#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))*/ + /*To do, implete hub L1 suspend device*/ + /*#else*/ + status = + hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type); + /*#endif*/ + } + else + { +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) +/*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/ +#endif + if (hostInstance->deviceList == deviceHandle) + { + status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, + &type); + } + } + if (kStatus_USB_Error == status) + { + hostInstance->suspendedDevice = NULL; + } + return status; +} +/* Send BUS or specific device suepend request */ +usb_status_t USB_HostL1SleepDeviceResquestConfig(usb_host_handle hostHandle, uint8_t *lpmParam) +{ + usb_host_instance_t *hostInstance; + usb_status_t status = kStatus_USB_Error; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + hostInstance = (usb_host_instance_t *)hostHandle; + + status = + hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostL1Config, lpmParam); + + return status; +} + +/* Send BUS or specific device resume request */ +usb_status_t USB_HostL1ResumeDeviceResquest(usb_host_handle hostHandle, + usb_device_handle deviceHandle, + uint8_t sleepType) +{ + usb_host_instance_t *hostInstance; + + usb_status_t status = kStatus_USB_Error; + usb_host_bus_control_t type = kUSB_HostBusL1Resume; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + hostInstance = (usb_host_instance_t *)hostHandle; + + if (1U == sleepType) + { + status = + hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, &type); + } + else + { +#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB)) +/*To do, if device hub number is 0, need suspend the bus ,else suspend the corresponding device*/ + +#endif + if (hostInstance->deviceList == deviceHandle) + { + status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl, + &type); + } + } + + return status; +} +#endif +/* Update HW tick(unit is ms) */ +usb_status_t USB_HostUpdateHwTick(usb_host_handle hostHandle, uint64_t tick) +{ + usb_host_instance_t *hostInstance; + usb_status_t status = kStatus_USB_Success; + + if (hostHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + hostInstance = (usb_host_instance_t *)hostHandle; + + hostInstance->hwTick = tick; + + return status; +} +#endif diff --git a/bsp/imxrt/libraries/drivers/usb/host/usb_host_hci.h b/bsp/imxrt/libraries/drivers/usb/host/usb_host_hci.h new file mode 100644 index 0000000000..26b6d4a9c5 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/host/usb_host_hci.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _USB_HOST_HCI_H_ +#define _USB_HOST_HCI_H_ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief USB host lock */ +#define USB_HostLock() USB_OsaMutexLock(hostInstance->hostMutex) +/*! @brief USB host unlock */ +#define USB_HostUnlock() USB_OsaMutexUnlock(hostInstance->hostMutex) + +/*! + * @addtogroup usb_host_controller_driver + * @{ + */ + +/*! @brief USB host controller control code */ +typedef enum _usb_host_controller_control +{ + kUSB_HostCancelTransfer = 1U, /*!< Cancel transfer code */ + kUSB_HostBusControl, /*!< Bus control code */ + kUSB_HostGetFrameNumber, /*!< Get frame number code */ + kUSB_HostUpdateControlEndpointAddress, /*!< Update control endpoint address */ + kUSB_HostUpdateControlPacketSize, /*!< Update control endpoint maximum packet size */ + kUSB_HostPortAttachDisable, /*!< Disable the port attach event */ + kUSB_HostPortAttachEnable, /*!< Enable the port attach event */ + kUSB_HostL1Config, /*!< L1 suspend Bus control code */ +} usb_host_controller_control_t; + +/*! @brief USB host controller bus control code */ +typedef enum _usb_host_bus_control +{ + kUSB_HostBusReset = 1U, /*!< Reset bus */ + kUSB_HostBusRestart, /*!< Restart bus */ + kUSB_HostBusEnableAttach, /*!< Enable attach */ + kUSB_HostBusDisableAttach, /*!< Disable attach */ + kUSB_HostBusSuspend, /*!< Suspend BUS */ + kUSB_HostBusResume, /*!< Resume BUS */ + kUSB_HostBusL1SuspendInit, /*!< L1 Suspend BUS */ + kUSB_HostBusL1Sleep, /*!< L1 Suspend BUS */ + kUSB_HostBusL1Resume, /*!< L1 Resume BUS */ +} usb_host_bus_control_t; + +/*! @brief USB host controller interface structure */ +typedef struct _usb_host_controller_interface +{ + usb_status_t (*controllerCreate)( + uint8_t controllerId, + usb_host_handle upperLayerHandle, + usb_host_controller_handle *controllerHandle); /*!< Create a controller instance function prototype*/ + usb_status_t (*controllerDestory)( + usb_host_controller_handle controllerHandle); /*!< Destroy a controller instance function prototype*/ + usb_status_t (*controllerOpenPipe)(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle *pipeHandle, + usb_host_pipe_init_t *pipeInit); /*!< Open a controller pipe function prototype*/ + usb_status_t (*controllerClosePipe)( + usb_host_controller_handle controllerHandle, + usb_host_pipe_handle pipeHandle); /*!< Close a controller pipe function prototype*/ + usb_status_t (*controllerWritePipe)(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle pipeHandle, + usb_host_transfer_t *transfer); /*!< Write data to a pipe function prototype*/ + usb_status_t (*controllerReadPipe)(usb_host_controller_handle controllerHandle, + usb_host_pipe_handle pipeHandle, + usb_host_transfer_t *transfer); /*!< Read data from a pipe function prototype*/ + usb_status_t (*controllerIoctl)(usb_host_controller_handle controllerHandle, + uint32_t ioctlEvent, + void *ioctlParam); /*!< Control a controller function prototype*/ +} usb_host_controller_interface_t; + +/*! @}*/ + +/*! + * @addtogroup usb_host_drv + * @{ + */ + +/*! @brief USB host instance structure */ +typedef struct _usb_host_instance +{ + void *controllerHandle; /*!< The low level controller handle*/ + host_callback_t deviceCallback; /*!< Device attach/detach callback*/ + usb_osa_mutex_handle hostMutex; /*!< Host layer mutex*/ + usb_host_transfer_t transferList[USB_HOST_CONFIG_MAX_TRANSFERS]; /*!< Transfer resource*/ + usb_host_transfer_t *transferHead; /*!< Idle transfer head*/ + const usb_host_controller_interface_t *controllerTable; /*!< KHCI/EHCI interface*/ + void *deviceList; /*!< Device list*/ +#if ((defined(USB_HOST_CONFIG_LOW_POWER_MODE)) && (USB_HOST_CONFIG_LOW_POWER_MODE > 0U)) + void *suspendedDevice; /*!< Suspended device handle*/ + volatile uint64_t hwTick; /*!< Current hw tick(ms)*/ + uint8_t sleepType; /*!< L1 LPM device handle*/ +#endif + uint8_t addressBitMap[16]; /*!< Used for address allocation. The first bit is the address 1, second bit is the + address 2*/ + uint8_t occupied; /*!< 0 - the instance is not occupied; 1 - the instance is occupied*/ + uint8_t controllerId; /*!< The controller ID*/ +} usb_host_instance_t; + +/*! @}*/ + +#endif /* _USB_HOST_HCI_H_ */ diff --git a/bsp/imxrt/libraries/drivers/usb/include/usb.h b/bsp/imxrt/libraries/drivers/usb/include/usb.h new file mode 100644 index 0000000000..256896b472 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/include/usb.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __USB_H__ +#define __USB_H__ + +#include +#include +#include +#include "usb_misc.h" +#include "usb_spec.h" + +/*! + * @addtogroup usb_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Defines USB stack major version */ +#define USB_STACK_VERSION_MAJOR (1U) +/*! @brief Defines USB stack minor version */ +#define USB_STACK_VERSION_MINOR (6U) +/*! @brief Defines USB stack bugfix version */ +#define USB_STACK_VERSION_BUGFIX (3U) + +/*! @brief USB stack version definition */ +#define USB_MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +/*! @brief USB error code */ +typedef enum _usb_status +{ + kStatus_USB_Success = 0x00U, /*!< Success */ + kStatus_USB_Error, /*!< Failed */ + + kStatus_USB_Busy, /*!< Busy */ + kStatus_USB_InvalidHandle, /*!< Invalid handle */ + kStatus_USB_InvalidParameter, /*!< Invalid parameter */ + kStatus_USB_InvalidRequest, /*!< Invalid request */ + kStatus_USB_ControllerNotFound, /*!< Controller cannot be found */ + kStatus_USB_InvalidControllerInterface, /*!< Invalid controller interface */ + + kStatus_USB_NotSupported, /*!< Configuration is not supported */ + kStatus_USB_Retry, /*!< Enumeration get configuration retry */ + kStatus_USB_TransferStall, /*!< Transfer stalled */ + kStatus_USB_TransferFailed, /*!< Transfer failed */ + kStatus_USB_AllocFail, /*!< Allocation failed */ + kStatus_USB_LackSwapBuffer, /*!< Insufficient swap buffer for KHCI */ + kStatus_USB_TransferCancel, /*!< The transfer cancelled */ + kStatus_USB_BandwidthFail, /*!< Allocate bandwidth failed */ + kStatus_USB_MSDStatusFail, /*!< For MSD, the CSW status means fail */ + kStatus_USB_EHCIAttached, + kStatus_USB_EHCIDetached, +} usb_status_t; + +/*! @brief USB host handle type define */ +typedef void *usb_host_handle; + +/*! @brief USB device handle type define. For device stack it is the whole device handle; for host stack it is the + * attached device instance handle*/ +typedef void *usb_device_handle; + +/*! @brief USB OTG handle type define */ +typedef void *usb_otg_handle; + +/*! @brief USB controller ID */ +typedef enum _usb_controller_index +{ + kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */ + kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved + to be used in the future. */ + kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */ + kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */ + kUSB_ControllerLpcIp3511Fs1 = + 5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which have two IP3511 IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */ + kUSB_ControllerLpcIp3511Hs1 = + 7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which have two IP3511 IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerOhci0 = 8U, /*!< OHCI 0U */ + kUSB_ControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */ + kUSB_ControllerIp3516Hs1 = + 11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two IP3516HS IPs, this is reserved + to be used in the future. */ +} usb_controller_index_t; + +/** +* @brief USB stack version fields +*/ +typedef struct _usb_version +{ + uint8_t major; /*!< Major */ + uint8_t minor; /*!< Minor */ + uint8_t bugfix; /*!< Bug fix */ +} usb_version_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! @} */ + +#endif /* __USB_H__ */ diff --git a/bsp/imxrt/libraries/drivers/usb/include/usb_device_config.h b/bsp/imxrt/libraries/drivers/usb/include/usb_device_config.h new file mode 100644 index 0000000000..551d92edc7 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/include/usb_device_config.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _USB_DEVICE_CONFIG_H_ +#define _USB_DEVICE_CONFIG_H_ + +/******************************************************************************* +* Definitions +******************************************************************************/ +/*! + * @addtogroup usb_device_configuration + * @{ + */ + +/*! + * @name Hardware instance define + * @{ + */ + +/*! @brief KHCI instance count */ +#define USB_DEVICE_CONFIG_KHCI (0U) + +/*! @brief EHCI instance count */ +#define USB_DEVICE_CONFIG_EHCI (2U) + +/*! @brief LPC USB IP3511 FS instance count */ +#define USB_DEVICE_CONFIG_LPCIP3511FS (0U) + +/*! @brief LPC USB IP3511 HS instance count */ +#define USB_DEVICE_CONFIG_LPCIP3511HS (0U) + +/*! @brief Device instance count, the sum of KHCI and EHCI instance counts*/ +#define USB_DEVICE_CONFIG_NUM \ + (USB_DEVICE_CONFIG_KHCI + USB_DEVICE_CONFIG_EHCI + USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) + +/* @} */ + +/*! + * @name class instance define + * @{ + */ + +/*! @brief HID instance count */ +#define USB_DEVICE_CONFIG_HID (0U) + +/*! @brief CDC ACM instance count */ +#define USB_DEVICE_CONFIG_CDC_ACM (1U) + +/*! @brief MSC instance count */ +#define USB_DEVICE_CONFIG_MSC (0U) + +/*! @brief Audio instance count */ +#define USB_DEVICE_CONFIG_AUDIO (0U) + +/*! @brief PHDC instance count */ +#define USB_DEVICE_CONFIG_PHDC (0U) + +/*! @brief Video instance count */ +#define USB_DEVICE_CONFIG_VIDEO (0U) + +/*! @brief CCID instance count */ +#define USB_DEVICE_CONFIG_CCID (0U) + +/*! @brief Printer instance count */ +#define USB_DEVICE_CONFIG_PRINTER (0U) + +/*! @brief DFU instance count */ +#define USB_DEVICE_CONFIG_DFU (0U) + +/* @} */ + +/*! @brief Whether device is self power. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_SELF_POWER (1U) + +/*! @brief How many endpoints are supported in the stack. */ +#define USB_DEVICE_CONFIG_ENDPOINTS (4U) + +/*! @brief Whether the device task is enabled. */ +#define USB_DEVICE_CONFIG_USE_TASK (0U) + +/*! @brief How many the notification message are supported when the device task is enabled. */ +#define USB_DEVICE_CONFIG_MAX_MESSAGES (8U) + +/*! @brief Whether test mode enabled. */ +#define USB_DEVICE_CONFIG_USB20_TEST_MODE (0U) + +/*! @brief Whether device CV test is enabled. */ +#define USB_DEVICE_CONFIG_CV_TEST (0U) + +/*! @brief Whether device compliance test is enabled. If the macro is enabled, + the test mode and CV test macroes will be set.*/ +#define USB_DEVICE_CONFIG_COMPLIANCE_TEST (0U) + +#if ((defined(USB_DEVICE_CONFIG_COMPLIANCE_TEST)) && (USB_DEVICE_CONFIG_COMPLIANCE_TEST > 0U)) + +/*! @brief Undefine the marco USB_DEVICE_CONFIG_USB20_TEST_MODE. */ +#undef USB_DEVICE_CONFIG_USB20_TEST_MODE +/*! @brief Undefine the marco USB_DEVICE_CONFIG_CV_TEST. */ +#undef USB_DEVICE_CONFIG_CV_TEST + +/*! @brief enable the test mode. */ +#define USB_DEVICE_CONFIG_USB20_TEST_MODE (1U) + +/*! @brief enable the CV test */ +#define USB_DEVICE_CONFIG_CV_TEST (1U) + +#endif + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) + +/*! @brief The MAX buffer length for the KHCI DMA workaround.*/ +#define USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH (64U) +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/*! @brief How many the DTD are supported. */ +#define USB_DEVICE_CONFIG_EHCI_MAX_DTD (16U) + +/*! @brief Whether the EHCI ID pin detect feature enabled. */ +#define USB_DEVICE_CONFIG_EHCI_ID_PIN_DETECT (0U) +#endif + +/*! @brief Whether the keep alive feature enabled. */ +#define USB_DEVICE_CONFIG_KEEP_ALIVE_MODE (0U) + +/*! @brief Whether the transfer buffer is cache-enabled or not. */ +#define USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE (1U) + +/*! @brief Whether the low power mode is enabled or not. */ +#define USB_DEVICE_CONFIG_LOW_POWER_MODE (0U) + +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! @brief Whether device remote wakeup supported. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U) + +/*! @brief Whether LPM is supported. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_LPM_L1 (0U) +#else +/*! @brief The device remote wakeup is unsupported. */ +#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U) +#endif + +/*! @brief Whether the device detached feature is enabled or not. */ +#define USB_DEVICE_CONFIG_DETACH_ENABLE (0U) + +/*! @brief Whether handle the USB bus error. */ +#define USB_DEVICE_CONFIG_ERROR_HANDLING (0U) + +/* @} */ +/*! @brief rt-thread port alloc */ +#include +#define USB_OSA_SR_ALLOC(...) +/*! @brief rt-thread port enter critical */ +#define USB_OSA_ENTER_CRITICAL rt_enter_critical +/*! @brief rt-thread port exit critical */ +#define USB_OSA_EXIT_CRITICAL rt_exit_critical + +#endif /* _USB_DEVICE_CONFIG_H_ */ diff --git a/bsp/imxrt/libraries/drivers/usb/include/usb_ehci.h b/bsp/imxrt/libraries/drivers/usb/include/usb_ehci.h new file mode 100644 index 0000000000..edc3496643 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/include/usb_ehci.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __USB_EHCI_H__ +#define __USB_EHCI_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Device QH */ +#define USB_DEVICE_EHCI_QH_POINTER_MASK (0xFFFFFFC0U) +#define USB_DEVICE_EHCI_QH_MULT_MASK (0xC0000000U) +#define USB_DEVICE_EHCI_QH_ZLT_MASK (0x20000000U) +#define USB_DEVICE_EHCI_QH_MAX_PACKET_SIZE_MASK (0x07FF0000U) +#define USB_DEVICE_EHCI_QH_MAX_PACKET_SIZE (0x00000800U) +#define USB_DEVICE_EHCI_QH_IOS_MASK (0x00008000U) + +/* Device DTD */ +#define USB_DEVICE_ECHI_DTD_POINTER_MASK (0xFFFFFFE0U) +#define USB_DEVICE_ECHI_DTD_TERMINATE_MASK (0x00000001U) +#define USB_DEVICE_ECHI_DTD_PAGE_MASK (0xFFFFF000U) +#define USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK (0x00000FFFU) +#define USB_DEVICE_ECHI_DTD_PAGE_BLOCK (0x00001000U) +#define USB_DEVICE_ECHI_DTD_TOTAL_BYTES_MASK (0x7FFF0000U) +#define USB_DEVICE_ECHI_DTD_TOTAL_BYTES (0x00004000U) +#define USB_DEVICE_ECHI_DTD_IOC_MASK (0x00008000U) +#define USB_DEVICE_ECHI_DTD_MULTIO_MASK (0x00000C00U) +#define USB_DEVICE_ECHI_DTD_STATUS_MASK (0x000000FFU) +#define USB_DEVICE_EHCI_DTD_STATUS_ERROR_MASK (0x00000068U) +#define USB_DEVICE_ECHI_DTD_STATUS_ACTIVE (0x00000080U) +#define USB_DEVICE_ECHI_DTD_STATUS_HALTED (0x00000040U) +#define USB_DEVICE_ECHI_DTD_STATUS_DATA_BUFFER_ERROR (0x00000020U) +#define USB_DEVICE_ECHI_DTD_STATUS_TRANSACTION_ERROR (0x00000008U) + +typedef struct _usb_device_ehci_qh_struct +{ + union + { + volatile uint32_t capabilttiesCharacteristics; + struct + { + volatile uint32_t reserved1 : 15; + volatile uint32_t ios : 1; + volatile uint32_t maxPacketSize : 11; + volatile uint32_t reserved2 : 2; + volatile uint32_t zlt : 1; + volatile uint32_t mult : 2; + } capabilttiesCharacteristicsBitmap; + } capabilttiesCharacteristicsUnion; + volatile uint32_t currentDtdPointer; + volatile uint32_t nextDtdPointer; + union + { + volatile uint32_t dtdToken; + struct + { + volatile uint32_t status : 8; + volatile uint32_t reserved1 : 2; + volatile uint32_t multiplierOverride : 2; + volatile uint32_t reserved2 : 3; + volatile uint32_t ioc : 1; + volatile uint32_t totalBytes : 15; + volatile uint32_t reserved3 : 1; + } dtdTokenBitmap; + } dtdTokenUnion; + volatile uint32_t bufferPointerPage[5]; + volatile uint32_t reserved1; + uint32_t setupBuffer[2]; + uint32_t setupBufferBack[2]; + union + { + uint32_t endpointStatus; + struct + { + uint32_t isOpened : 1; + uint32_t : 31; + } endpointStatusBitmap; + } endpointStatusUnion; + uint32_t reserved2; +} usb_device_ehci_qh_struct_t; + +typedef struct _usb_device_ehci_dtd_struct +{ + volatile uint32_t nextDtdPointer; + union + { + volatile uint32_t dtdToken; + struct + { + volatile uint32_t status : 8; + volatile uint32_t reserved1 : 2; + volatile uint32_t multiplierOverride : 2; + volatile uint32_t reserved2 : 3; + volatile uint32_t ioc : 1; + volatile uint32_t totalBytes : 15; + volatile uint32_t reserved3 : 1; + } dtdTokenBitmap; + } dtdTokenUnion; + volatile uint32_t bufferPointerPage[5]; + union + { + volatile uint32_t reserved; + struct + { + uint32_t originalBufferOffest : 12; + uint32_t originalBufferLength : 19; + uint32_t dtdInvalid : 1; + } originalBufferInfo; + } reservedUnion; +} usb_device_ehci_dtd_struct_t; + +#endif /* __USB_EHCI_H__ */ diff --git a/bsp/imxrt/libraries/drivers/usb/include/usb_misc.h b/bsp/imxrt/libraries/drivers/usb/include/usb_misc.h new file mode 100644 index 0000000000..4e65cfa94b --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/include/usb_misc.h @@ -0,0 +1,452 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __USB_MISC_H__ +#define __USB_MISC_H__ + +#ifndef ENDIANNESS + +#error ENDIANNESS should be defined, and then rebulid the project. + +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Define USB printf */ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +extern int DbgConsole_Printf(const char *fmt_s, ...); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#if defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE < 1) +#define usb_echo printf +#else +#define usb_echo DbgConsole_Printf +#endif + +#if defined(__ICCARM__) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED __packed +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED +#endif + +#elif defined(__GNUC__) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED __attribute__((__packed__)) +#endif + +#elif defined(__CC_ARM) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED _Pragma("pack(1U)") +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED _Pragma("pack()") +#endif + +#endif + +#define USB_SHORT_GET_LOW(x) (((uint16_t)x) & 0xFFU) +#define USB_SHORT_GET_HIGH(x) ((uint8_t)(((uint16_t)x) >> 8U) & 0xFFU) + +#define USB_LONG_GET_BYTE0(x) ((uint8_t)(((uint32_t)(x))) & 0xFFU) +#define USB_LONG_GET_BYTE1(x) ((uint8_t)(((uint32_t)(x)) >> 8U) & 0xFFU) +#define USB_LONG_GET_BYTE2(x) ((uint8_t)(((uint32_t)(x)) >> 16U) & 0xFFU) +#define USB_LONG_GET_BYTE3(x) ((uint8_t)(((uint32_t)(x)) >> 24U) & 0xFFU) + +#define USB_MEM4_ALIGN_MASK (0x03U) + +/* accessory macro */ +#define USB_MEM4_ALIGN(n) ((n + 3U) & (0xFFFFFFFCu)) +#define USB_MEM32_ALIGN(n) ((n + 31U) & (0xFFFFFFE0u)) +#define USB_MEM64_ALIGN(n) ((n + 63U) & (0xFFFFFFC0u)) + +/* big/little endian */ +#define SWAP2BYTE_CONST(n) ((((n)&0x00FFU) << 8U) | (((n)&0xFF00U) >> 8U)) +#define SWAP4BYTE_CONST(n) \ + ((((n)&0x000000FFU) << 24U) | (((n)&0x0000FF00U) << 8U) | (((n)&0x00FF0000U) >> 8U) | (((n)&0xFF000000U) >> 24U)) + +#define USB_ASSIGN_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = *((uint8_t *)&(m)); \ + *((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \ + *((uint8_t *)&(n) + 2) = *((uint8_t *)&(m) + 2); \ + *((uint8_t *)&(n) + 3) = *((uint8_t *)&(m) + 3); \ + } + +#define USB_ASSIGN_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = *((uint8_t *)&(m)); \ + *((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \ + } + +#define USB_ASSIGN_MACRO_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = (uint8_t)m; \ + *((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \ + *((uint8_t *)&(n) + 2) = (uint8_t)(m >> 16); \ + *((uint8_t *)&(n) + 3) = (uint8_t)(m >> 24); \ + } + +#define USB_ASSIGN_MACRO_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = (uint8_t)m; \ + *((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \ + } + +#if (ENDIANNESS == USB_BIG_ENDIAN) + +#define USB_SHORT_TO_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_TO_LITTLE_ENDIAN(n) SWAP4BYTE_CONST(n) +#define USB_SHORT_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) + +#define USB_SHORT_TO_BIG_ENDIAN(n) (n) +#define USB_LONG_TO_BIG_ENDIAN(n) (n) +#define USB_SHORT_FROM_BIG_ENDIAN(n) (n) +#define USB_LONG_FROM_BIG_ENDIAN(n) (n) + +#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[3] = ((n >> 24U) & 0xFFU); \ + m[2] = ((n >> 16U) & 0xFFU); \ + m[1] = ((n >> 8U) & 0xFFU); \ + m[0] = (n & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \ + (((uint8_t)n[0]) << 0U))) + +#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((n >> 24U) & 0xFFU); \ + m[1] = ((n >> 16U) & 0xFFU); \ + m[2] = ((n >> 8U) & 0xFFU); \ + m[3] = (n & 0xFFU); \ + } + +#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \ + (((uint8_t)n[3]) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[1] = ((n >> 8U) & 0xFFU); \ + m[0] = (n & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U))) + +#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((n >> 8U) & 0xFFU); \ + m[1] = (n & 0xFFU); \ + } + +#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U))) + +#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 3) = ((n >> 24U) & 0xFFU); \ + *((uint8_t *)&(m) + 2) = ((n >> 16U) & 0xFFU); \ + *((uint8_t *)&(m) + 1) = ((n >> 8U) & 0xFFU); \ + *((uint8_t *)&(m) + 0) = (n & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \ + ((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \ + ((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 1) = ((n >> 8U) & 0xFFU); \ + *((uint8_t *)&(m)) = ((n)&0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n)))))) + +#else + +#define USB_SHORT_TO_LITTLE_ENDIAN(n) (n) +#define USB_LONG_TO_LITTLE_ENDIAN(n) (n) +#define USB_SHORT_FROM_LITTLE_ENDIAN(n) (n) +#define USB_LONG_FROM_LITTLE_ENDIAN(n) (n) + +#define USB_SHORT_TO_BIG_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_TO_BIG_ENDIAN(n) SWAP4BYTE_CONST(n) +#define USB_SHORT_FROM_BIG_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_FROM_BIG_ENDIAN(n) SWAP4BYTE_CONST(n) + +#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[3] = ((n >> 24U) & 0xFFU); \ + m[2] = ((n >> 16U) & 0xFFU); \ + m[1] = ((n >> 8U) & 0xFFU); \ + m[0] = (n & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \ + (((uint8_t)n[0]) << 0U))) + +#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((n >> 24U) & 0xFFU); \ + m[1] = ((n >> 16U) & 0xFFU); \ + m[2] = ((n >> 8U) & 0xFFU); \ + m[3] = (n & 0xFFU); \ + } + +#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \ + (((uint8_t)n[3]) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[1] = ((n >> 8U) & 0xFFU); \ + m[0] = (n & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U))) + +#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((n >> 8U) & 0xFFU); \ + m[1] = (n & 0xFFU); \ + } + +#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U))) + +#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 3) = ((n >> 24U) & 0xFFU); \ + *((uint8_t *)&(m) + 2) = ((n >> 16U) & 0xFFU); \ + *((uint8_t *)&(m) + 1) = ((n >> 8U) & 0xFFU); \ + *((uint8_t *)&(m) + 0) = (n & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \ + ((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \ + ((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 1) = ((n >> 8U) & 0xFFU); \ + *((uint8_t *)&(m)) = ((n)&0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n)))))) + +#endif + +/* + * The following MACROs (USB_GLOBAL, USB_BDT, USB_RAM_ADDRESS_ALIGNMENT, etc) are only used for USB device stack. + * The USB device global variables are put into the section m_usb_global and m_usb_bdt or the section + * .bss.m_usb_global and .bss.m_usb_bdt by using the MACRO USB_GLOBAL and USB_BDT. In this way, the USB device + * global variables can be linked into USB dedicated RAM by USB_STACK_USE_DEDICATED_RAM. + * The MACRO USB_STACK_USE_DEDICATED_RAM is used to decide the USB stack uses dedicated RAM or not. The value of + * the marco can be set as 0, USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL, or USB_STACK_DEDICATED_RAM_TYPE_BDT. + * The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL means USB device global variables, including USB_BDT and + * USB_GLOBAL, are put into the USB dedicated RAM. This feature can only be enabled when the USB dedicated RAM + * is not less than 2K Bytes. + * The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT means USB device global variables, only including USB_BDT, are put + * into the USB dedicated RAM, the USB_GLOBAL will be put into .bss section. This feature is used for some SOCs, + * the USB dedicated RAM size is not more than 512 Bytes. + */ +#define USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL 1 +#define USB_STACK_DEDICATED_RAM_TYPE_BDT 2 + +#if defined(__ICCARM__) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +/* disable misra 19.13 */ +_Pragma("diag_suppress=Pm120") +#define USB_ALIGN_PRAGMA(x) _Pragma(#x) + _Pragma("diag_default=Pm120") + +#define USB_RAM_ADDRESS_ALIGNMENT(n) USB_ALIGN_PRAGMA(data_alignment = n) + _Pragma("diag_suppress=Pm120") +#define USB_LINK_SECTION_PART(str) _Pragma(#str) +#define USB_LINK_SECTION_SUB(sec) USB_LINK_SECTION_PART(location = #sec) +#define USB_LINK_USB_GLOBAL _Pragma("location = \"m_usb_global\"") +#define USB_LINK_USB_BDT _Pragma("location = \"m_usb_bdt\"") +#define USB_LINK_USB_GLOBAL_BSS _Pragma("location = \".bss.m_usb_global\"") +#define USB_LINK_USB_BDT_BSS _Pragma("location = \".bss.m_usb_bdt\"") + _Pragma("diag_default=Pm120") +#define USB_LINK_DMA_NONINIT_DATA _Pragma("location = \"m_usb_dma_noninit_data\"") +#define USB_LINK_NONCACHE_NONINIT_DATA _Pragma("location = \"NonCacheable\"") +#elif defined(__CC_ARM) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __weak +#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n))) +#define USB_LINK_SECTION_SUB(sec) __attribute__((section(#sec))) +#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global"))) __attribute__((zero_init)) +#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt"))) __attribute__((zero_init)) +#define USB_LINK_USB_GLOBAL_BSS __attribute__((section(".bss.m_usb_global"))) __attribute__((zero_init)) +#define USB_LINK_USB_BDT_BSS __attribute__((section(".bss.m_usb_bdt"))) __attribute__((zero_init)) +#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data"))) __attribute__((zero_init)) +#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable"))) __attribute__((zero_init)) + +#elif defined(__GNUC__) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n))) +#define USB_LINK_SECTION_SUB(sec) __attribute__((section(#sec))) +#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global, \"aw\", %nobits @"))) +#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt, \"aw\", %nobits @"))) +#define USB_LINK_USB_GLOBAL_BSS __attribute__((section(".bss.m_usb_global, \"aw\", %nobits @"))) +#define USB_LINK_USB_BDT_BSS __attribute__((section(".bss.m_usb_bdt, \"aw\", %nobits @"))) +#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data, \"aw\", %nobits @"))) +#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable, \"aw\", %nobits @"))) + +#else +#error The tool-chain is not supported. +#endif + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + +#if ((defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) && (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) +#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#elif(defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) +#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, 0) +#elif(defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)) +#define USB_CACHE_LINESIZE MAX(0, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#else +#define USB_CACHE_LINESIZE 4 +#endif + +#else +#define USB_CACHE_LINESIZE 4 +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#define USB_DATA_ALIGN 64 +#else +#define USB_DATA_ALIGN 4 +#endif + +#define USB_DATA_ALIGN_SIZE MAX(USB_CACHE_LINESIZE, USB_DATA_ALIGN) + +#define USB_DATA_ALIGN_SIZE_MULTIPLE(n) ((n + USB_DATA_ALIGN_SIZE - 1) & (~(USB_DATA_ALIGN_SIZE - 1))) + +#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL) + +#define USB_GLOBAL USB_LINK_USB_GLOBAL +#define USB_BDT USB_LINK_USB_BDT + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_SECTION_SUB(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA USB_LINK_USB_GLOBAL +#endif + +#elif defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT) + +#define USB_BDT USB_LINK_USB_BDT + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_SECTION_SUB(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA +#endif + +#else + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + +#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA +#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_SECTION_SUB(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA + +#else +#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS +#define USB_BDT USB_LINK_USB_BDT_BSS +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA +#endif + +#endif + +#define USB_DMA_NONINIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_INIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_INIT_SUB + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_DMA_DATA_NONCACHEABLE USB_LINK_NONCACHE_NONINIT_DATA + +#else +#define USB_DMA_DATA_NONCACHEABLE +#endif + +#define USB_GLOBAL_DEDICATED_RAM USB_LINK_USB_GLOBAL + +/* #define USB_RAM_ADDRESS_NONCACHEREG_ALIGNMENT(n, var) AT_NONCACHEABLE_SECTION_ALIGN(var, n) */ +/* #define USB_RAM_ADDRESS_NONCACHEREG(var) AT_NONCACHEABLE_SECTION(var) */ + +#endif /* __USB_MISC_H__ */ diff --git a/bsp/imxrt/libraries/drivers/usb/include/usb_spec.h b/bsp/imxrt/libraries/drivers/usb/include/usb_spec.h new file mode 100644 index 0000000000..d77b7d3598 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/include/usb_spec.h @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __USB_SPEC_H__ +#define __USB_SPEC_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* USB speed (the value cannot be changed because EHCI QH use the value directly)*/ +#define USB_SPEED_FULL (0x00U) +#define USB_SPEED_LOW (0x01U) +#define USB_SPEED_HIGH (0x02U) + +/* Set up packet structure */ +typedef struct _usb_setup_struct +{ + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} usb_setup_struct_t; + +/* USB standard descriptor endpoint type */ +#define USB_ENDPOINT_CONTROL (0x00U) +#define USB_ENDPOINT_ISOCHRONOUS (0x01U) +#define USB_ENDPOINT_BULK (0x02U) +#define USB_ENDPOINT_INTERRUPT (0x03U) + +/* USB standard descriptor transfer direction (cannot change the value because iTD use the value directly) */ +#define USB_OUT (0U) +#define USB_IN (1U) + +/* USB standard descriptor length */ +#define USB_DESCRIPTOR_LENGTH_DEVICE (0x12U) +#define USB_DESCRIPTOR_LENGTH_CONFIGURE (0x09U) +#define USB_DESCRIPTOR_LENGTH_INTERFACE (0x09U) +#define USB_DESCRIPTOR_LENGTH_ENDPOINT (0x07U) +#define USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER (0x0AU) +#define USB_DESCRIPTOR_LENGTH_OTG_DESCRIPTOR (5U) +#define USB_DESCRIPTOR_LENGTH_BOS_DESCRIPTOR (5U) + +/* USB Device Capability Type Codes */ +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_WIRELESS (0x01U) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_USB20_EXTENSION (0x02U) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_SUPERSPEED (0x03U) + +/* USB standard descriptor type */ +#define USB_DESCRIPTOR_TYPE_DEVICE (0x01U) +#define USB_DESCRIPTOR_TYPE_CONFIGURE (0x02U) +#define USB_DESCRIPTOR_TYPE_STRING (0x03U) +#define USB_DESCRIPTOR_TYPE_INTERFACE (0x04U) +#define USB_DESCRIPTOR_TYPE_ENDPOINT (0x05U) +#define USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER (0x06U) +#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION (0x07U) +#define USB_DESCRIPTOR_TYPE_INTERFAACE_POWER (0x08U) +#define USB_DESCRIPTOR_TYPE_OTG (0x09U) +#define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION (0x0BU) +#define USB_DESCRIPTOR_TYPE_BOS (0x0F) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY (0x10) + +#define USB_DESCRIPTOR_TYPE_HID (0x21U) +#define USB_DESCRIPTOR_TYPE_HID_REPORT (0x22U) +#define USB_DESCRIPTOR_TYPE_HID_PHYSICAL (0x23U) + +/* USB standard request type */ +#define USB_REQUEST_TYPE_DIR_MASK (0x80U) +#define USB_REQUEST_TYPE_DIR_SHIFT (7U) +#define USB_REQUEST_TYPE_DIR_OUT (0x00U) +#define USB_REQUEST_TYPE_DIR_IN (0x80U) + +#define USB_REQUEST_TYPE_TYPE_MASK (0x60U) +#define USB_REQUEST_TYPE_TYPE_SHIFT (5U) +#define USB_REQUEST_TYPE_TYPE_STANDARD (0U) +#define USB_REQUEST_TYPE_TYPE_CLASS (0x20U) +#define USB_REQUEST_TYPE_TYPE_VENDOR (0x40U) + +#define USB_REQUEST_TYPE_RECIPIENT_MASK (0x1FU) +#define USB_REQUEST_TYPE_RECIPIENT_SHIFT (0U) +#define USB_REQUEST_TYPE_RECIPIENT_DEVICE (0x00U) +#define USB_REQUEST_TYPE_RECIPIENT_INTERFACE (0x01U) +#define USB_REQUEST_TYPE_RECIPIENT_ENDPOINT (0x02U) +#define USB_REQUEST_TYPE_RECIPIENT_OTHER (0x03U) + +/* USB standard request */ +#define USB_REQUEST_STANDARD_GET_STATUS (0x00U) +#define USB_REQUEST_STANDARD_CLEAR_FEATURE (0x01U) +#define USB_REQUEST_STANDARD_SET_FEATURE (0x03U) +#define USB_REQUEST_STANDARD_SET_ADDRESS (0x05U) +#define USB_REQUEST_STANDARD_GET_DESCRIPTOR (0x06U) +#define USB_REQUEST_STANDARD_SET_DESCRIPTOR (0x07U) +#define USB_REQUEST_STANDARD_GET_CONFIGURATION (0x08U) +#define USB_REQUEST_STANDARD_SET_CONFIGURATION (0x09U) +#define USB_REQUEST_STANDARD_GET_INTERFACE (0x0AU) +#define USB_REQUEST_STANDARD_SET_INTERFACE (0x0BU) +#define USB_REQUEST_STANDARD_SYNCH_FRAME (0x0CU) + +/* USB standard request GET Status */ +#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT (0U) +#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT (1U) + +#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_MASK (0x01U) +#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_SHIFT (0U) + +#define USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR (0xF000U) + +/* USB standard request CLEAR/SET feature */ +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT (0U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP (1U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE (2U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE (3U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_HNP_SUPPORT (4U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_ALT_HNP_SUPPORT (5U) + +/* USB standard descriptor configure bmAttributes */ +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK (0x80U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_SHIFT (7U) + +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK (0x40U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT (6U) + +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_MASK (0x20U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT (5U) + +/* USB standard descriptor endpoint bmAttributes */ +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK (0x80U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT (7U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT (0U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN (0x80U) + +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK (0x0FU) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_SHFIT (0U) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK (0x03U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_NUMBER_SHFIT (0U) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_MASK (0x0CU) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SHFIT (2U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_NO_SYNC (0x00U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ASYNC (0x04U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ADAPTIVE (0x08U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SYNC (0x0CU) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_MASK (0x30U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_SHFIT (4U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_DATA_ENDPOINT (0x00U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_FEEDBACK_ENDPOINT (0x10U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_IMPLICIT_FEEDBACK_DATA_ENDPOINT (0x20U) + +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK (0x07FFu) +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK (0x1800u) +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT (11U) + +/* USB standard descriptor otg bmAttributes */ +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_SRP_MASK (0x01u) +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_HNP_MASK (0x02u) +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_ADP_MASK (0x04u) + +/* USB standard descriptor device capability usb20 extension bmAttributes */ +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_MASK (0x02U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_SHIFT (1U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_MASK (0x04U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_SHIFT (2U) + + +/* Language structure */ +typedef struct _usb_language +{ + uint8_t **string; /* The Strings descriptor array */ + uint32_t *length; /* The strings descriptor length array */ + uint16_t languageId; /* The language id of current language */ +} usb_language_t; + +typedef struct _usb_language_list +{ + uint8_t *languageString; /* The String 0U pointer */ + uint32_t stringLength; /* The String 0U Length */ + usb_language_t *languageList; /* The language list */ + uint8_t count; /* The language count */ +} usb_language_list_t; + +typedef struct _usb_descriptor_common +{ + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* DEVICE Descriptor Type */ + uint8_t bData[1]; /* Data */ +} usb_descriptor_common_t; + +typedef struct _usb_descriptor_device +{ + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* DEVICE Descriptor Type */ + uint8_t bcdUSB[2]; /* UUSB Specification Release Number in Binary-Coded Decimal, e.g. 0x0200U */ + uint8_t bDeviceClass; /* Class code */ + uint8_t bDeviceSubClass; /* Sub-Class code */ + uint8_t bDeviceProtocol; /* Protocol code */ + uint8_t bMaxPacketSize0; /* Maximum packet size for endpoint zero */ + uint8_t idVendor[2]; /* Vendor ID (assigned by the USB-IF) */ + uint8_t idProduct[2]; /* Product ID (assigned by the manufacturer) */ + uint8_t bcdDevice[2]; /* Device release number in binary-coded decimal */ + uint8_t iManufacturer; /* Index of string descriptor describing manufacturer */ + uint8_t iProduct; /* Index of string descriptor describing product */ + uint8_t iSerialNumber; /* Index of string descriptor describing the device serial number */ + uint8_t bNumConfigurations; /* Number of possible configurations */ +} usb_descriptor_device_t; + +typedef struct _usb_descriptor_configuration +{ + uint8_t bLength; /* Descriptor size in bytes = 9U */ + uint8_t bDescriptorType; /* CONFIGURATION type = 2U or 7U */ + uint8_t wTotalLength[2]; /* Length of concatenated descriptors */ + uint8_t bNumInterfaces; /* Number of interfaces, this configuration. */ + uint8_t bConfigurationValue; /* Value to set this configuration. */ + uint8_t iConfiguration; /* Index to configuration string */ + uint8_t bmAttributes; /* Configuration characteristics */ + uint8_t bMaxPower; /* Maximum power from bus, 2 mA units */ +} usb_descriptor_configuration_t; + +typedef struct _usb_descriptor_interface +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_descriptor_interface_t; + +typedef struct _usb_descriptor_endpoint +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint8_t wMaxPacketSize[2]; + uint8_t bInterval; +} usb_descriptor_endpoint_t; + +typedef struct _usb_descriptor_binary_device_object_store +{ + uint8_t bLength; /* Descriptor size in bytes = 5U */ + uint8_t bDescriptorType; /* BOS Descriptor type = 0FU*/ + uint8_t wTotalLength[2]; /*Length of this descriptor and all of its sub descriptors*/ + uint8_t bNumDeviceCaps; /*The number of separate device capability descriptors in the BOS*/ +} usb_descriptor_bos_t; + +typedef struct _usb_descriptor_usb20_extension +{ + uint8_t bLength; /* Descriptor size in bytes = 7U */ + uint8_t bDescriptorType; /* DEVICE CAPABILITY Descriptor type = 0x10U*/ + uint8_t bDevCapabilityType; /*Length of this descriptor and all of its sub descriptors*/ + uint8_t bmAttributes[4]; /*Bitmap encoding of supported device level features.*/ +} usb_descriptor_usb20_extension_t; + +typedef union _usb_descriptor_union +{ + usb_descriptor_common_t common; /* Common descriptor */ + usb_descriptor_device_t device; /* Device descriptor */ + usb_descriptor_configuration_t configuration; /* Configuration descriptor */ + usb_descriptor_interface_t interface; /* Interface descriptor */ + usb_descriptor_endpoint_t endpoint; /* Endpoint descriptor */ +} usb_descriptor_union_t; + +#endif /* __USB_SPEC_H__ */ diff --git a/bsp/imxrt/libraries/drivers/usb/phy/usb_phy.c b/bsp/imxrt/libraries/drivers/usb/phy/usb_phy.c new file mode 100644 index 0000000000..70537b97dc --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/phy/usb_phy.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "fsl_device_registers.h" + +#include + +void *USB_EhciPhyGetBase(uint8_t controllerId) +{ + void *usbPhyBase = NULL; +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + uint32_t instance; + uint32_t newinstance = 0; + uint32_t usbphy_base_temp[] = USBPHY_BASE_ADDRS; + uint32_t usbphy_base[] = USBPHY_BASE_ADDRS; + + if (controllerId < kUSB_ControllerEhci0) + { + return NULL; + } + + controllerId = controllerId - kUSB_ControllerEhci0; + + for (instance = 0; instance < (sizeof(usbphy_base_temp) / sizeof(usbphy_base_temp[0])); instance++) + { + if (usbphy_base_temp[instance]) + { + usbphy_base[newinstance++] = usbphy_base_temp[instance]; + } + } + if (controllerId > newinstance) + { + return NULL; + } + + usbPhyBase = (void *)usbphy_base[controllerId]; +#endif + return usbPhyBase; +} + +/*! + * @brief ehci phy initialization. + * + * This function initialize ehci phy IP. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + * @param[in] freq the external input clock. + * for example: if the external input clock is 16M, the parameter freq should be 16000000. + * + * @retval kStatus_USB_Success cancel successfully. + * @retval kStatus_USB_Error the freq value is incorrect. + */ +uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig) +{ +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + USBPHY_Type *usbPhyBase; + + usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + if (NULL == usbPhyBase) + { + return kStatus_USB_Error; + } + +#if ((defined FSL_FEATURE_SOC_ANATOP_COUNT) && (FSL_FEATURE_SOC_ANATOP_COUNT > 0U)) + ANATOP->HW_ANADIG_REG_3P0.RW = + (ANATOP->HW_ANADIG_REG_3P0.RW & + (~(ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x1F) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_ILIMIT_MASK))) | + ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x17) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_LINREG_MASK; + ANATOP->HW_ANADIG_USB2_CHRG_DETECT.SET = + ANATOP_HW_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B_MASK | ANATOP_HW_ANADIG_USB2_CHRG_DETECT_EN_B_MASK; +#endif + +#if (defined USB_ANALOG) + USB_ANALOG->INSTANCE[controllerId - kUSB_ControllerEhci0].CHRG_DETECT_SET = USB_ANALOG_CHRG_DETECT_CHK_CHRG_B(1) | USB_ANALOG_CHRG_DETECT_EN_B(1); +#endif + +#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) + + usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */ +#endif + usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */ + usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */ + /* PWD register provides overall control of the PHY power state */ + usbPhyBase->PWD = 0U; + + /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */ + usbPhyBase->TX = + ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) | + (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) | + USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM))); +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief ehci phy initialization for suspend and resume. + * + * This function initialize ehci phy IP for suspend and resume. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + * @param[in] freq the external input clock. + * for example: if the external input clock is 16M, the parameter freq should be 16000000. + * + * @retval kStatus_USB_Success cancel successfully. + * @retval kStatus_USB_Error the freq value is incorrect. + */ +uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig) +{ +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + USBPHY_Type *usbPhyBase; + + usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + if (NULL == usbPhyBase) + { + return kStatus_USB_Error; + } + +#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) + usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */ +#endif + +#if ((defined USBPHY_CTRL_AUTORESUME_EN_MASK) && (USBPHY_CTRL_AUTORESUME_EN_MASK > 0U)) + usbPhyBase->CTRL |= USBPHY_CTRL_AUTORESUME_EN_MASK; +#else + usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTO_PWRON_PLL_MASK; +#endif + usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK; + usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */ + usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */ + /* PWD register provides overall control of the PHY power state */ + usbPhyBase->PWD = 0U; +#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) + /* now the 480MHz USB clock is up, then configure fractional divider after PLL with PFD + * pfd clock = 480MHz*18/N, where N=18~35 + * Please note that USB1PFDCLK has to be less than 180MHz for RUN or HSRUN mode + */ + usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_FRAC(24); /* N=24 */ + usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_CLK_SEL(1); /* div by 4 */ + + usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_DEV_PULLDOWN_MASK; + usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK; + while (!(usbPhyBase->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK)) + { + } +#endif + /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */ + usbPhyBase->TX = + ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) | + (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) | + USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM))); +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief ehci phy de-initialization. + * + * This function de-initialize ehci phy IP. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + */ +void USB_EhciPhyDeinit(uint8_t controllerId) +{ +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + USBPHY_Type *usbPhyBase; + + usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + if (NULL == usbPhyBase) + { + return; + } +#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) + usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* power down PLL */ + usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* disable USB clock output from USB PHY PLL */ +#endif + usbPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* set to 1U to gate clocks */ +#endif +} + +/*! + * @brief ehci phy disconnect detection enable or disable. + * + * This function enable/disable host ehci disconnect detection. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + * @param[in] enable + * 1U - enable; + * 0U - disable; + */ +void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable) +{ +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + USBPHY_Type *usbPhyBase; + + usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + if (NULL == usbPhyBase) + { + return; + } + + if (enable) + { + usbPhyBase->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; + } + else + { + usbPhyBase->CTRL &= (~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK); + } +#endif +} diff --git a/bsp/imxrt/libraries/drivers/usb/phy/usb_phy.h b/bsp/imxrt/libraries/drivers/usb/phy/usb_phy.h new file mode 100644 index 0000000000..0409f9c8b9 --- /dev/null +++ b/bsp/imxrt/libraries/drivers/usb/phy/usb_phy.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __USB_PHY_H__ +#define __USB_PHY_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +typedef struct _usb_phy_config_struct +{ + uint8_t D_CAL; /* Decode to trim the nominal 17.78mA current source */ + uint8_t TXCAL45DP; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DP output pin */ + uint8_t TXCAL45DM; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DM output pin */ +} usb_phy_config_struct_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ +/*! + * @brief EHCI PHY get USB phy bass address. + * + * This function is used to get USB phy bass address. + * + * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t. + * + * @retval USB phy bass address. + */ +extern void *USB_EhciPhyGetBase(uint8_t controllerId); + +/*! + * @brief EHCI PHY initialization. + * + * This function initializes the EHCI PHY IP. + * + * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t. + * @param[in] freq The external input clock. + * + * @retval kStatus_USB_Success Cancel successfully. + * @retval kStatus_USB_Error The freq value is incorrect. + */ +extern uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig); + +/*! + * @brief ehci phy initialization for suspend and resume. + * + * This function initialize ehci phy IP for suspend and resume. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + * @param[in] freq the external input clock. + * for example: if the external input clock is 16M, the parameter freq should be 16000000. + * + * @retval kStatus_USB_Success cancel successfully. + * @retval kStatus_USB_Error the freq value is incorrect. + */ +extern uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig); + +/*! + * @brief EHCI PHY deinitialization. + * + * This function deinitializes the EHCI PHY IP. + * + * @param[in] controllerId EHCI controller ID; See #usb_controller_index_t. + */ +extern void USB_EhciPhyDeinit(uint8_t controllerId); + +/*! + * @brief EHCI PHY disconnect detection enable or disable. + * + * This function enable/disable the host EHCI disconnect detection. + * + * @param[in] controllerId EHCI controller ID; See #usb_controller_index_t. + * @param[in] enable + * 1U - enable; + * 0U - disable; + */ +extern void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable); + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_PHY_H__ */ -- Gitee From ae90273b68aeb25dfff2065116d01cf6feb8670f Mon Sep 17 00:00:00 2001 From: chao_king <37656088+ChazJin@users.noreply.github.com> Date: Thu, 26 Dec 2019 19:03:46 +0800 Subject: [PATCH 013/110] Fix bug for drv_enet.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 源文件主要存在以下问题: 1> rt_hw_gd32_eth_init函数中对MAC初始化完成后并没有修改PHY的连接状态,这会导致测试TCP例程时无法建立TCP链接,应在初始化完成后将PHY的连接状态修改成linkup; 已在GD32450Z-EVAL开发板上测试,修改后没有再出现以上问题。 --- bsp/gd32450z-eval/drivers/drv_enet.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bsp/gd32450z-eval/drivers/drv_enet.c b/bsp/gd32450z-eval/drivers/drv_enet.c index 0f8ce72db6..b1bf632f54 100644 --- a/bsp/gd32450z-eval/drivers/drv_enet.c +++ b/bsp/gd32450z-eval/drivers/drv_enet.c @@ -652,7 +652,10 @@ int rt_hw_gd32_eth_init(void) /* init tx buffer free semaphore */ rt_sem_init(&gd32_emac_device0.tx_buf_free, "tx_buf0", EMAC_TXBUFNB, RT_IPC_FLAG_FIFO); eth_device_init(&(gd32_emac_device0.parent), "e0"); - + + /* change device link status */ + eth_device_linkchange(&(gd32_emac_device0.parent), RT_TRUE); + return 0; } INIT_DEVICE_EXPORT(rt_hw_gd32_eth_init); -- Gitee From b8c13d494c166c3126392234340e596e02daa892 Mon Sep 17 00:00:00 2001 From: tyustli <1225613647@qq.com> Date: Fri, 27 Dec 2019 12:57:25 +0800 Subject: [PATCH 014/110] remote host config --- bsp/imxrt/imxrt1052-atk-commander/board/Kconfig | 15 --------------- bsp/imxrt/libraries/drivers/SConscript | 8 -------- 2 files changed, 23 deletions(-) diff --git a/bsp/imxrt/imxrt1052-atk-commander/board/Kconfig b/bsp/imxrt/imxrt1052-atk-commander/board/Kconfig index 67ca41ca13..b4beef948d 100644 --- a/bsp/imxrt/imxrt1052-atk-commander/board/Kconfig +++ b/bsp/imxrt/imxrt1052-atk-commander/board/Kconfig @@ -124,21 +124,6 @@ menu "Onboard Peripheral Drivers" bool "Enable SDRAM" default n - menuconfig BSP_USING_USB_HOST - bool "Enable USB Host" - select RT_USING_USB_HOST - default n - if BSP_USING_USB_HOST - menuconfig RT_USBH_MSTORAGE - bool "Enable Udisk Drivers" - default n - if RT_USBH_MSTORAGE - config UDISK_MOUNTPOINT - string "Udisk mount dir" - default "/" - endif - endif - config BSP_USING_USB_DEVICE bool "Enable USB Device" select RT_USING_USB_DEVICE diff --git a/bsp/imxrt/libraries/drivers/SConscript b/bsp/imxrt/libraries/drivers/SConscript index 940ff5eb6e..c806dada25 100644 --- a/bsp/imxrt/libraries/drivers/SConscript +++ b/bsp/imxrt/libraries/drivers/SConscript @@ -53,14 +53,6 @@ if GetDepend('BSP_USING_USB_DEVICE'): src += Glob('usb/phy/*.c') CPPDEFINES += ['ENDIANNESS'] -if GetDepend('BSP_USING_USB_HOST'): - src += ['drv_usbh.c'] - src += Glob('usb/host/*.c') - -if GetDepend('BSP_USING_USB_HOST'): - src += Glob('usb/phy/*.c') - CPPDEFINES += ['ENDIANNESS'] - path = [cwd,cwd + '/config'] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES=CPPDEFINES) -- Gitee From d910372010f92c9c0b836a035aaa556dd3818198 Mon Sep 17 00:00:00 2001 From: tonyzheng-rockchip Date: Thu, 26 Dec 2019 11:03:51 +0800 Subject: [PATCH 015/110] Fix dlmodule must depends on file system issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 解决dlmodule只能依赖于文件系统的问题; 增加dlmodule扩展接口,以适应更多需求; --- components/libc/Kconfig | 10 ++ components/libc/libdl/dlmodule.c | 190 ++++++++++++++++++++++++++++++- components/libc/libdl/dlmodule.h | 12 ++ 3 files changed, 211 insertions(+), 1 deletion(-) diff --git a/components/libc/Kconfig b/components/libc/Kconfig index 2d1e9315f1..26e156522b 100644 --- a/components/libc/Kconfig +++ b/components/libc/Kconfig @@ -34,9 +34,19 @@ if RT_USING_LIBC && RT_USING_DFS default n endif +endif + +if RT_USING_LIBC config RT_USING_MODULE bool "Enable dynamic module with dlopen/dlsym/dlclose feature" default n + + if RT_USING_MODULE + config RT_USING_CUSTOM_DLMODULE + bool "Enable load dynamic module by custom" + default n + endif + endif if RT_USING_LIBC != y diff --git a/components/libc/libdl/dlmodule.c b/components/libc/libdl/dlmodule.c index dbebfc8961..2829b7df7d 100644 --- a/components/libc/libdl/dlmodule.c +++ b/components/libc/libdl/dlmodule.c @@ -14,7 +14,9 @@ #include "dlmodule.h" #include "dlelf.h" +#if defined(RT_USING_POSIX) #include +#endif #define DBG_TAG "DLMD" #define DBG_LVL DBG_INFO @@ -419,11 +421,14 @@ struct rt_dlmodule *rt_module_self(void) struct rt_dlmodule* dlmodule_load(const char* filename) { - int fd, length = 0; +#if defined(RT_USING_POSIX) + int fd = -1, length = 0; +#endif rt_err_t ret = RT_EOK; rt_uint8_t *module_ptr = RT_NULL; struct rt_dlmodule *module = RT_NULL; +#if defined(RT_USING_POSIX) fd = open(filename, O_RDONLY, 0); if (fd >= 0) { @@ -446,6 +451,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename) { goto __exit; } +#endif + + if (!module_ptr) goto __exit; /* check ELF header */ if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 && @@ -512,7 +520,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename) return module; __exit: +#if defined(RT_USING_POSIX) if (fd >= 0) close(fd); +#endif if (module_ptr) rt_free(module_ptr); if (module) dlmodule_destroy(module); @@ -558,6 +568,184 @@ struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_s return module; } +#if defined(RT_USING_CUSTOM_DLMODULE) +struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops) +{ +#if defined(RT_USING_POSIX) + int fd = -1, length = 0; +#endif + rt_err_t ret = RT_EOK; + rt_uint8_t *module_ptr = RT_NULL; + struct rt_dlmodule *module = RT_NULL; + + if (ops) + { + RT_ASSERT(ops->load); + RT_ASSERT(ops->unload); + module_ptr = ops->load(filename); + } +#if defined(RT_USING_POSIX) + else + { + fd = open(filename, O_RDONLY, 0); + if (fd >= 0) + { + length = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + + if (length == 0) goto __exit; + + module_ptr = (uint8_t*) rt_malloc (length); + if (!module_ptr) goto __exit; + + if (read(fd, module_ptr, length) != length) + goto __exit; + + /* close file and release fd */ + close(fd); + fd = -1; + } + else + { + goto __exit; + } + } +#endif + + if (!module_ptr) goto __exit; + + /* check ELF header */ + if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 && + rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0) + { + rt_kprintf("Module: magic error\n"); + goto __exit; + } + + /* check ELF class */ + if (elf_module->e_ident[EI_CLASS] != ELFCLASS32) + { + rt_kprintf("Module: ELF class error\n"); + goto __exit; + } + + module = dlmodule_create(); + if (!module) goto __exit; + + /* set the name of module */ + _dlmodule_set_name(module, filename); + + LOG_D("rt_module_load: %.*s", RT_NAME_MAX, module->parent.name); + + if (elf_module->e_type == ET_REL) + { + ret = dlmodule_load_relocated_object(module, module_ptr); + } + else if (elf_module->e_type == ET_DYN) + { + ret = dlmodule_load_shared_object(module, module_ptr); + } + else + { + rt_kprintf("Module: unsupported elf type\n"); + goto __exit; + } + + /* check return value */ + if (ret != RT_EOK) goto __exit; + + /* release module data */ + if (ops) + { + ops->unload(module_ptr); + } + else + { + rt_free(module_ptr); + } + + /* increase module reference count */ + module->nref ++; + + /* deal with cache */ +#ifdef RT_USING_CACHE + rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, module->mem_space, module->mem_size); + rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, module->mem_space, module->mem_size); +#endif + + /* set module initialization and cleanup function */ + module->init_func = dlsym(module, "module_init"); + module->cleanup_func = dlsym(module, "module_cleanup"); + module->stat = RT_DLMODULE_STAT_INIT; + /* do module initialization */ + if (module->init_func) + { + module->init_func(module); + } + + return module; + +__exit: +#if defined(RT_USING_POSIX) + if (fd >= 0) close(fd); +#endif + if (module_ptr) + { + if (ops) + { + ops->unload(module_ptr); + } + else + { + rt_free(module_ptr); + } + } + + if (module) dlmodule_destroy(module); + + return RT_NULL; +} + +struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops) +{ + struct rt_dlmodule *module = RT_NULL; + + module = dlmodule_load_custom(pgname, ops); + if (module) + { + if (module->entry_addr) + { + /* exec this module */ + rt_thread_t tid; + + module->cmd_line = rt_strdup(cmd); + + /* check stack size and priority */ + if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1; + if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048; + + tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module, + module->stack_size, module->priority, 10); + if (tid) + { + tid->module_id = module; + module->main_thread = tid; + + rt_thread_startup(tid); + } + else + { + /* destory dl module */ + dlmodule_destroy(module); + module = RT_NULL; + } + } + } + + return module; +} +#endif + void dlmodule_exit(int ret_code) { rt_thread_t thread; diff --git a/components/libc/libdl/dlmodule.h b/components/libc/libdl/dlmodule.h index 4a4ead3303..b366c7603e 100644 --- a/components/libc/libdl/dlmodule.h +++ b/components/libc/libdl/dlmodule.h @@ -59,6 +59,12 @@ struct rt_dlmodule struct rt_module_symtab *symtab; /* module symbol table */ }; +struct rt_dlmodule_ops +{ + rt_uint8_t *(*load)(const char* filename); /* load dlmodule file data */ + rt_err_t (*unload)(rt_uint8_t *param); /* unload dlmodule file data */ +}; + struct rt_dlmodule *dlmodule_create(void); rt_err_t dlmodule_destroy(struct rt_dlmodule* module); @@ -66,6 +72,12 @@ struct rt_dlmodule *dlmodule_self(void); struct rt_dlmodule *dlmodule_load(const char* pgname); struct rt_dlmodule *dlmodule_exec(const char* pgname, const char* cmd, int cmd_size); + +#if defined(RT_USING_CUSTOM_DLMODULE) +struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops); +struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops); +#endif + void dlmodule_exit(int ret_code); struct rt_dlmodule *dlmodule_find(const char *name); -- Gitee From ff445708874117471d569e0eec368dded0747741 Mon Sep 17 00:00:00 2001 From: zhaoshaowei Date: Fri, 27 Dec 2019 16:41:47 +0800 Subject: [PATCH 016/110] [Kernel] fix typo in rt_thread_delay_util --- src/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread.c b/src/thread.c index 3a3c97d0b6..74a573b78f 100644 --- a/src/thread.c +++ b/src/thread.c @@ -585,7 +585,7 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) return RT_EOK; } -RTM_EXPORT(rt_thread_delay_util); +RTM_EXPORT(rt_thread_delay_until); /** * This function will let current thread delay for some milliseconds. -- Gitee From 3ad6b30e18f9b0c8197178f32571ffd18183506d Mon Sep 17 00:00:00 2001 From: zhaoshaowei Date: Fri, 27 Dec 2019 16:52:52 +0800 Subject: [PATCH 017/110] =?UTF-8?q?[componects]=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E5=8F=91=E7=8E=B0=E7=A6=81=E6=AD=A2=E5=86=99?= =?UTF-8?q?spi=20flash=E5=A4=B1=E8=B4=A5=E7=9A=84=E6=83=85=E5=BD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `(register_status & SFUD_STATUS_REGISTER_WEL) == 1` 这个表达式始终为假 SFUD_STATUS_REGISTER_WEL = (1 << 1) --- components/drivers/spi/sfud/src/sfud.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/drivers/spi/sfud/src/sfud.c b/components/drivers/spi/sfud/src/sfud.c index f666b06806..e5b03131ff 100644 --- a/components/drivers/spi/sfud/src/sfud.c +++ b/components/drivers/spi/sfud/src/sfud.c @@ -897,7 +897,7 @@ static sfud_err set_write_enabled(const sfud_flash *flash, bool enabled) { if (enabled && (register_status & SFUD_STATUS_REGISTER_WEL) == 0) { SFUD_INFO("Error: Can't enable write status."); return SFUD_ERR_WRITE; - } else if (!enabled && (register_status & SFUD_STATUS_REGISTER_WEL) == 1) { + } else if (!enabled && (register_status & SFUD_STATUS_REGISTER_WEL) != 0) { SFUD_INFO("Error: Can't disable write status."); return SFUD_ERR_WRITE; } -- Gitee From a0e62f665f5063991b43bebda51057a2286e07ad Mon Sep 17 00:00:00 2001 From: liuxinaliang Date: Sun, 29 Dec 2019 15:32:27 +0800 Subject: [PATCH 018/110] [net][lwip] fix assert in the sys_arch_mbox_fetch function when close socket --- components/net/lwip-1.4.1/src/arch/sys_arch.c | 12 ++++-------- components/net/lwip-2.0.2/src/arch/sys_arch.c | 13 +++++-------- components/net/lwip-2.1.0/src/arch/sys_arch.c | 15 ++++++--------- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/components/net/lwip-1.4.1/src/arch/sys_arch.c b/components/net/lwip-1.4.1/src/arch/sys_arch.c index c31bd59c1d..2392dde2fa 100644 --- a/components/net/lwip-1.4.1/src/arch/sys_arch.c +++ b/components/net/lwip-1.4.1/src/arch/sys_arch.c @@ -27,7 +27,7 @@ * Change Logs: * Date Author Notes * 2012-12-8 Bernard add file header - * export bsd socket symbol for RT-Thread Application Module + * export bsd socket symbol for RT-Thread Application Module * 2017-11-15 Bernard add lock for init_done callback. */ @@ -259,7 +259,7 @@ void sys_sem_signal(sys_sem_t *sem) * * @return If the timeout argument is non-zero, it will return the number of milliseconds * spent waiting for the semaphore to be signaled; If the semaphore isn't signaled - * within the specified time, it will return SYS_ARCH_TIMEOUT; If the thread doesn't + * within the specified time, it will return SYS_ARCH_TIMEOUT; If the thread doesn't * wait for the semaphore, it will return zero */ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) @@ -498,14 +498,10 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) } ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, t); - if(ret == -RT_ETIMEOUT) + if(ret != RT_EOK) { return SYS_ARCH_TIMEOUT; } - else - { - LWIP_ASSERT("rt_mb_recv returned with error!", ret == RT_EOK); - } /* get elapse msecond */ tick = rt_tick_get() - tick; @@ -536,7 +532,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) } else { - if (ret == RT_EOK) + if (ret == RT_EOK) ret = 1; } diff --git a/components/net/lwip-2.0.2/src/arch/sys_arch.c b/components/net/lwip-2.0.2/src/arch/sys_arch.c index b2abaeab54..f7ed6eedec 100644 --- a/components/net/lwip-2.0.2/src/arch/sys_arch.c +++ b/components/net/lwip-2.0.2/src/arch/sys_arch.c @@ -27,7 +27,7 @@ * Change Logs: * Date Author Notes * 2012-12-8 Bernard add file header - * export bsd socket symbol for RT-Thread Application Module + * export bsd socket symbol for RT-Thread Application Module * 2017-11-15 Bernard add lock for init_done callback. */ @@ -270,7 +270,7 @@ void sys_sem_signal(sys_sem_t *sem) * * @return If the timeout argument is non-zero, it will return the number of milliseconds * spent waiting for the semaphore to be signaled; If the semaphore isn't signaled - * within the specified time, it will return SYS_ARCH_TIMEOUT; If the thread doesn't + * within the specified time, it will return SYS_ARCH_TIMEOUT; If the thread doesn't * wait for the semaphore, it will return zero */ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) @@ -509,12 +509,9 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) } ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, t); - - if(ret == -RT_ETIMEOUT) - return SYS_ARCH_TIMEOUT; - else + if(ret != RT_EOK) { - LWIP_ASSERT("rt_mb_recv returned with error!", ret == RT_EOK); + return SYS_ARCH_TIMEOUT; } /* get elapse msecond */ @@ -545,7 +542,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) return SYS_ARCH_TIMEOUT; else { - if (ret == RT_EOK) + if (ret == RT_EOK) ret = 1; } diff --git a/components/net/lwip-2.1.0/src/arch/sys_arch.c b/components/net/lwip-2.1.0/src/arch/sys_arch.c index dc08715ecc..0633501bb6 100755 --- a/components/net/lwip-2.1.0/src/arch/sys_arch.c +++ b/components/net/lwip-2.1.0/src/arch/sys_arch.c @@ -27,7 +27,7 @@ * Change Logs: * Date Author Notes * 2012-12-8 Bernard add file header - * export bsd socket symbol for RT-Thread Application Module + * export bsd socket symbol for RT-Thread Application Module * 2017-11-15 Bernard add lock for init_done callback. * 2018-11-02 MurphyZhao port to lwip2.1.0 */ @@ -78,7 +78,7 @@ static err_t netif_device_init(struct netif *netif) /* copy device flags to netif flags */ netif->flags = ethif->flags; netif->mtu = ETHERNET_MTU; - + /* set output */ netif->output = etharp_output; @@ -278,7 +278,7 @@ void sys_sem_signal(sys_sem_t *sem) * * @return If the timeout argument is non-zero, it will return the number of milliseconds * spent waiting for the semaphore to be signaled; If the semaphore isn't signaled - * within the specified time, it will return SYS_ARCH_TIMEOUT; If the thread doesn't + * within the specified time, it will return SYS_ARCH_TIMEOUT; If the thread doesn't * wait for the semaphore, it will return zero */ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) @@ -523,12 +523,9 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) } ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, t); - - if(ret == -RT_ETIMEOUT) - return SYS_ARCH_TIMEOUT; - else + if(ret != RT_EOK) { - LWIP_ASSERT("rt_mb_recv returned with error!", ret == RT_EOK); + return SYS_ARCH_TIMEOUT; } /* get elapse msecond */ @@ -559,7 +556,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) return SYS_ARCH_TIMEOUT; else { - if (ret == RT_EOK) + if (ret == RT_EOK) ret = 1; } -- Gitee From 83b290c2897e0e8c319e2f0ab0b52d3276bfe0c5 Mon Sep 17 00:00:00 2001 From: liuxinaliang Date: Sun, 29 Dec 2019 15:35:22 +0800 Subject: [PATCH 019/110] [net][lwip] fix lwIP 2.1.0 personalized sign bug --- components/net/lwip-2.1.0/src/netif/ethernetif.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/components/net/lwip-2.1.0/src/netif/ethernetif.c b/components/net/lwip-2.1.0/src/netif/ethernetif.c index f73ed635a1..55ffaa89df 100755 --- a/components/net/lwip-2.1.0/src/netif/ethernetif.c +++ b/components/net/lwip-2.1.0/src/netif/ethernetif.c @@ -487,8 +487,13 @@ static err_t eth_netif_device_init(struct netif *netif) rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flags) { struct netif* netif; - +#if LWIP_NETIF_HOSTNAME +#define LWIP_HOSTNAME_LEN 16 + char *hostname = RT_NULL; + netif = (struct netif*) rt_malloc (sizeof(struct netif) + LWIP_HOSTNAME_LEN); +#else netif = (struct netif*) rt_malloc (sizeof(struct netif)); +#endif if (netif == RT_NULL) { rt_kprintf("malloc netif failed\n"); -- Gitee From e473ad5606550362fbc53bf7afb81497751d8187 Mon Sep 17 00:00:00 2001 From: liuxinaliang Date: Mon, 30 Dec 2019 18:13:21 +0800 Subject: [PATCH 020/110] =?UTF-8?q?[bsp][stm32]=20bsp/stm32/stm32f407-atk-?= =?UTF-8?q?explorer=20=E5=A2=9E=E5=8A=A0=20USB=20Device=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/stm32/stm32f407-atk-explorer/README.md | 4 +- .../board/CubeMX_Config/.mxproject | 10 ++-- .../board/CubeMX_Config/CubeMX_Config.ioc | 21 ++++--- .../CubeMX_Config/Inc/stm32f4xx_hal_conf.h | 54 ++++++++--------- .../board/CubeMX_Config/Src/main.c | 59 +++++++++++-------- .../CubeMX_Config/Src/stm32f4xx_hal_msp.c | 44 +++----------- .../board/CubeMX_Config/Src/stm32f4xx_it.c | 6 +- .../stm32f407-atk-explorer/board/Kconfig | 5 ++ 8 files changed, 89 insertions(+), 114 deletions(-) diff --git a/bsp/stm32/stm32f407-atk-explorer/README.md b/bsp/stm32/stm32f407-atk-explorer/README.md index 5e8432e01f..6a10371701 100644 --- a/bsp/stm32/stm32f407-atk-explorer/README.md +++ b/bsp/stm32/stm32f407-atk-explorer/README.md @@ -57,8 +57,8 @@ | WDT | 支持 | | | FLASH | 支持 | 已适配 [FAL](https://github.com/RT-Thread-packages/fal) | | PWM | 支持 | | -| USB Device | 暂不支持 | 即将支持 | -| USB Host | 暂不支持 | 即将支持 | +| USB Device | 支持 | | +| USB Host | 支持 | | | **扩展模块** | **支持情况** | **备注** | | ATK-ESP8266 模块 | 暂不支持 | 即将支持 | diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/.mxproject index 3c0602b619..d10dfb5d6a 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/.mxproject +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/.mxproject @@ -1,14 +1,14 @@ [PreviousGenFiles] -HeaderPath=F:/rt-thread/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc +HeaderPath=E:/rt-thread/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc HeaderFiles=stm32f4xx_it.h;stm32f4xx_hal_conf.h;main.h; -SourcePath=F:/rt-thread/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src +SourcePath=E:/rt-thread/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src SourceFiles=stm32f4xx_it.c;stm32f4xx_hal_msp.c;main.c; [PreviousLibFiles] -LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f407xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h; +LibFiles=Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h;Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h;Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f407xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h;Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; [PreviousUsedKeilFiles] -SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;../\Src/system_stm32f4xx.c;../Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;null; +SourceFiles=..\Src\main.c;..\Src\stm32f4xx_it.c;..\Src\stm32f4xx_hal_msp.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;..\\Src/system_stm32f4xx.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c;..\Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c;..\\Src/system_stm32f4xx.c;..\Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c;; HeaderPath=..\Drivers\STM32F4xx_HAL_Driver\Inc;..\Drivers\STM32F4xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F4xx\Include;..\Drivers\CMSIS\Include;..\Inc; -CDefines=USE_HAL_DRIVER;STM32F407xx;USE_HAL_DRIVER;STM32F407xx; +CDefines=USE_HAL_DRIVER;STM32F407xx;USE_HAL_DRIVER;USE_HAL_DRIVER; diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/CubeMX_Config.ioc index 52c20c220f..5952039d02 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/CubeMX_Config.ioc +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/CubeMX_Config.ioc @@ -79,10 +79,11 @@ Mcu.PinsNb=44 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F407ZGTx -MxCube.Version=5.0.0 -MxDb.Version=DB.5.0.0 +MxCube.Version=5.4.0 +MxDb.Version=DB.5.0.40 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false @@ -98,9 +99,9 @@ PA1.Mode=RMII PA1.Signal=ETH_REF_CLK PA10.Mode=Asynchronous PA10.Signal=USART1_RX -PA11.Mode=Host_Only +PA11.Mode=Device_Only PA11.Signal=USB_OTG_FS_DM -PA12.Mode=Host_Only +PA12.Mode=Device_Only PA12.Signal=USB_OTG_FS_DP PA13.Mode=Serial_Wire PA13.Signal=SYS_JTMS-SWDIO @@ -191,7 +192,7 @@ ProjectManager.CustomerFirmwarePackage= ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32F407ZGTx -ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.22.0 +ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.24.2 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 @@ -208,7 +209,7 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=MDK-ARM V5 ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_SPI1_Init-SPI1-false-HAL-true,5-MX_ETH_Init-ETH-false-HAL-true,6-MX_USART3_UART_Init-USART3-false-HAL-true,7-MX_ADC1_Init-ADC1-false-HAL-true,8-MX_RTC_Init-RTC-false-HAL-true,9-MX_IWDG_Init-IWDG-false-HAL-true,10-MX_TIM14_Init-TIM14-false-HAL-true,11-MX_TIM13_Init-TIM13-false-HAL-true,12-MX_TIM11_Init-TIM11-false-HAL-true,13-MX_SDIO_SD_Init-SDIO-false-HAL-true,14-MX_TIM2_Init-TIM2-false-HAL-true,15-MX_SPI2_Init-SPI2-false-HAL-true,16-MX_TIM4_Init-TIM4-false-HAL-true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_SPI1_Init-SPI1-false-HAL-true,5-MX_ETH_Init-ETH-false-HAL-true,6-MX_USART3_UART_Init-USART3-false-HAL-true,7-MX_ADC1_Init-ADC1-false-HAL-true,8-MX_RTC_Init-RTC-false-HAL-true,9-MX_IWDG_Init-IWDG-false-HAL-true,10-MX_TIM14_Init-TIM14-false-HAL-true,11-MX_TIM13_Init-TIM13-false-HAL-true,12-MX_TIM11_Init-TIM11-false-HAL-true,13-MX_SDIO_SD_Init-SDIO-false-HAL-true,14-MX_TIM2_Init-TIM2-false-HAL-true,15-MX_SPI2_Init-SPI2-false-HAL-true,16-MX_TIM4_Init-TIM4-false-HAL-true,17-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true RCC.48MHZClocksFreq_Value=48000000 RCC.AHBFreq_Value=168000000 RCC.APB1CLKDivider=RCC_HCLK_DIV4 @@ -225,7 +226,7 @@ RCC.HCLKFreq_Value=168000000 RCC.HSE_VALUE=8000000 RCC.HSI_VALUE=16000000 RCC.I2SClocksFreq_Value=192000000 -RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,PLLSourceVirtual,RCC_RTC_Clock_Source,RCC_RTC_Clock_SourceVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S +RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,RCC_RTC_Clock_Source,RCC_RTC_Clock_SourceVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S RCC.LSI_VALUE=32000 RCC.MCO2PinFreq_Value=168000000 RCC.PLLCLKFreq_Value=168000000 @@ -233,7 +234,6 @@ RCC.PLLM=4 RCC.PLLN=168 RCC.PLLQ=7 RCC.PLLQCLKFreq_Value=48000000 -RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE RCC.RCC_RTC_Clock_Source=RCC_RTCCLKSOURCE_LSE RCC.RCC_RTC_Clock_SourceVirtual=RCC_RTCCLKSOURCE_LSE RCC.RTCFreq_Value=32768 @@ -268,9 +268,8 @@ USART1.IPParameters=VirtualMode USART1.VirtualMode=VM_ASYNC USART3.IPParameters=VirtualMode USART3.VirtualMode=VM_ASYNC -USB_OTG_FS.IPParameters=VirtualMode,phy_itface -USB_OTG_FS.VirtualMode=Host_Only -USB_OTG_FS.phy_itface=HCD_PHY_EMBEDDED +USB_OTG_FS.IPParameters=VirtualMode +USB_OTG_FS.VirtualMode=Device_Only VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h index dc0a83626e..bcc1012811 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h @@ -1,33 +1,20 @@ /** ****************************************************************************** - * @file stm32f4xx_hal_conf.h - * @brief HAL configuration file. + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32f4xx_hal_conf.h. ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2019 STMicroelectronics

+ *

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

* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ @@ -49,7 +36,7 @@ */ #define HAL_MODULE_ENABLED -#define HAL_ADC_MODULE_ENABLED + #define HAL_ADC_MODULE_ENABLED /* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_CAN_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */ @@ -79,8 +66,9 @@ /* #define HAL_USART_MODULE_ENABLED */ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ -/* #define HAL_PCD_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED #define HAL_HCD_MODULE_ENABLED /* #define HAL_DSI_MODULE_ENABLED */ /* #define HAL_QSPI_MODULE_ENABLED */ @@ -90,8 +78,8 @@ /* #define HAL_SPDIFRX_MODULE_ENABLED */ /* #define HAL_DFSDM_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ -/* #define HAL_EXTI_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED @@ -221,12 +209,12 @@ #define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ /* Section 4: Extended PHY Registers */ -#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ +#define PHY_SR ((uint16_t)0x1FU) /*!< PHY status register Offset */ -#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ -#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0004U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010U) /*!< PHY Duplex mask */ -#define PHY_ISFR ((uint16_t)0x000BU) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR ((uint16_t)0x001DU) /*!< PHY Interrupt Source Flag register Offset */ #define PHY_ISFR_INT4 ((uint16_t)0x000BU) /*!< PHY Link down inturrupt */ /* ################## SPI peripheral configuration ########################## */ @@ -279,6 +267,10 @@ #include "stm32f4xx_hal_cryp.h" #endif /* HAL_CRYP_MODULE_ENABLED */ +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + #ifdef HAL_DMA2D_MODULE_ENABLED #include "stm32f4xx_hal_dma2d.h" #endif /* HAL_DMA2D_MODULE_ENABLED */ diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/main.c index 2c69b3dfa3..6d1ddd0123 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/main.c @@ -84,7 +84,7 @@ TIM_HandleTypeDef htim14; UART_HandleTypeDef huart1; UART_HandleTypeDef huart3; -HCD_HandleTypeDef hhcd_USB_OTG_FS; +PCD_HandleTypeDef hpcd_USB_OTG_FS; /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ @@ -108,7 +108,7 @@ static void MX_SDIO_SD_Init(void); static void MX_TIM2_Init(void); static void MX_SPI2_Init(void); static void MX_TIM4_Init(void); -static void MX_USB_OTG_FS_HCD_Init(void); +static void MX_USB_OTG_FS_PCD_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ @@ -128,6 +128,7 @@ int main(void) /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ + /* MCU Configuration--------------------------------------------------------*/ @@ -161,7 +162,7 @@ int main(void) MX_TIM2_Init(); MX_SPI2_Init(); MX_TIM4_Init(); - MX_USB_OTG_FS_HCD_Init(); + MX_USB_OTG_FS_PCD_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -189,11 +190,11 @@ void SystemClock_Config(void) RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - /**Configure the main internal regulator output voltage + /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); - /**Initializes the CPU, AHB and APB busses clocks + /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE |RCC_OSCILLATORTYPE_LSE; @@ -210,7 +211,7 @@ void SystemClock_Config(void) { Error_Handler(); } - /**Initializes the CPU, AHB and APB busses clocks + /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; @@ -248,7 +249,7 @@ static void MX_ADC1_Init(void) /* USER CODE BEGIN ADC1_Init 1 */ /* USER CODE END ADC1_Init 1 */ - /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; @@ -266,7 +267,7 @@ static void MX_ADC1_Init(void) { Error_Handler(); } - /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_5; sConfig.Rank = 1; @@ -293,21 +294,18 @@ static void MX_ETH_Init(void) /* USER CODE END ETH_Init 0 */ - uint8_t MACAddr[6] ; - /* USER CODE BEGIN ETH_Init 1 */ /* USER CODE END ETH_Init 1 */ heth.Instance = ETH; heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; heth.Init.PhyAddress = LAN8742A_PHY_ADDRESS; - MACAddr[0] = 0x00; - MACAddr[1] = 0x80; - MACAddr[2] = 0xE1; - MACAddr[3] = 0x00; - MACAddr[4] = 0x00; - MACAddr[5] = 0x00; - heth.Init.MACAddr = &MACAddr[0]; + heth.Init.MACAddr[0] = 0x00; + heth.Init.MACAddr[1] = 0x80; + heth.Init.MACAddr[2] = 0xE1; + heth.Init.MACAddr[3] = 0x00; + heth.Init.MACAddr[4] = 0x00; + heth.Init.MACAddr[5] = 0x00; heth.Init.RxMode = ETH_RXPOLLING_MODE; heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE; heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; @@ -369,7 +367,7 @@ static void MX_RTC_Init(void) /* USER CODE BEGIN RTC_Init 1 */ /* USER CODE END RTC_Init 1 */ - /**Initialize RTC Only + /** Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; @@ -524,6 +522,7 @@ static void MX_TIM2_Init(void) htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 0; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); @@ -581,6 +580,7 @@ static void MX_TIM4_Init(void) htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 0; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; sConfig.EncoderMode = TIM_ENCODERMODE_TI1; sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; @@ -626,6 +626,7 @@ static void MX_TIM11_Init(void) htim11.Init.CounterMode = TIM_COUNTERMODE_UP; htim11.Init.Period = 0; htim11.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim11.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim11) != HAL_OK) { Error_Handler(); @@ -656,6 +657,7 @@ static void MX_TIM13_Init(void) htim13.Init.CounterMode = TIM_COUNTERMODE_UP; htim13.Init.Period = 0; htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim13.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim13) != HAL_OK) { Error_Handler(); @@ -686,6 +688,7 @@ static void MX_TIM14_Init(void) htim14.Init.CounterMode = TIM_COUNTERMODE_UP; htim14.Init.Period = 0; htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim14) != HAL_OK) { Error_Handler(); @@ -767,7 +770,7 @@ static void MX_USART3_UART_Init(void) * @param None * @retval None */ -static void MX_USB_OTG_FS_HCD_Init(void) +static void MX_USB_OTG_FS_PCD_Init(void) { /* USER CODE BEGIN USB_OTG_FS_Init 0 */ @@ -777,13 +780,17 @@ static void MX_USB_OTG_FS_HCD_Init(void) /* USER CODE BEGIN USB_OTG_FS_Init 1 */ /* USER CODE END USB_OTG_FS_Init 1 */ - hhcd_USB_OTG_FS.Instance = USB_OTG_FS; - hhcd_USB_OTG_FS.Init.Host_channels = 8; - hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL; - hhcd_USB_OTG_FS.Init.dma_enable = DISABLE; - hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED; - hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE; - if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK) + hpcd_USB_OTG_FS.Instance = USB_OTG_FS; + hpcd_USB_OTG_FS.Init.dev_endpoints = 4; + hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL; + hpcd_USB_OTG_FS.Init.dma_enable = DISABLE; + hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED; + hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE; + hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE; + hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE; + hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE; + hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE; + if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK) { Error_Handler(); } diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c index 1597ab0ec0..c7a8ac1f1d 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c @@ -107,7 +107,6 @@ void HAL_MspInit(void) */ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hadc->Instance==ADC1) { @@ -139,10 +138,8 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) * @param hadc: ADC handle pointer * @retval None */ - void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) { - if(hadc->Instance==ADC1) { /* USER CODE BEGIN ADC1_MspDeInit 0 */ @@ -171,7 +168,6 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) */ void HAL_ETH_MspInit(ETH_HandleTypeDef* heth) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; if(heth->Instance==ETH) { @@ -229,10 +225,8 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef* heth) * @param heth: ETH handle pointer * @retval None */ - void HAL_ETH_MspDeInit(ETH_HandleTypeDef* heth) { - if(heth->Instance==ETH) { /* USER CODE BEGIN ETH_MspDeInit 0 */ @@ -273,7 +267,6 @@ void HAL_ETH_MspDeInit(ETH_HandleTypeDef* heth) */ void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) { - if(hrtc->Instance==RTC) { /* USER CODE BEGIN RTC_MspInit 0 */ @@ -294,10 +287,8 @@ void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) * @param hrtc: RTC handle pointer * @retval None */ - void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc) { - if(hrtc->Instance==RTC) { /* USER CODE BEGIN RTC_MspDeInit 0 */ @@ -320,7 +311,6 @@ void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc) */ void HAL_SD_MspInit(SD_HandleTypeDef* hsd) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hsd->Instance==SDIO) { @@ -368,10 +358,8 @@ void HAL_SD_MspInit(SD_HandleTypeDef* hsd) * @param hsd: SD handle pointer * @retval None */ - void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd) { - if(hsd->Instance==SDIO) { /* USER CODE BEGIN SDIO_MspDeInit 0 */ @@ -408,7 +396,6 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd) */ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hspi->Instance==SPI1) { @@ -480,10 +467,8 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) * @param hspi: SPI handle pointer * @retval None */ - void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) { - if(hspi->Instance==SPI1) { /* USER CODE BEGIN SPI1_MspDeInit 0 */ @@ -537,7 +522,6 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) */ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM2) { /* USER CODE BEGIN TIM2_MspInit 0 */ @@ -593,7 +577,6 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) */ void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; if(htim_encoder->Instance==TIM4) { @@ -624,7 +607,6 @@ void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder) void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; if(htim->Instance==TIM2) { @@ -655,10 +637,8 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) * @param htim_base: TIM_Base handle pointer * @retval None */ - void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM2) { /* USER CODE BEGIN TIM2_MspDeInit 0 */ @@ -712,10 +692,8 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) * @param htim_encoder: TIM_Encoder handle pointer * @retval None */ - void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef* htim_encoder) { - if(htim_encoder->Instance==TIM4) { /* USER CODE BEGIN TIM4_MspDeInit 0 */ @@ -745,7 +723,6 @@ void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef* htim_encoder) */ void HAL_UART_MspInit(UART_HandleTypeDef* huart) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; if(huart->Instance==USART1) { @@ -807,10 +784,8 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart) * @param huart: UART handle pointer * @retval None */ - void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) { - if(huart->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ @@ -853,16 +828,15 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) } /** -* @brief HCD MSP Initialization +* @brief PCD MSP Initialization * This function configures the hardware resources used in this example -* @param hhcd: HCD handle pointer +* @param hpcd: PCD handle pointer * @retval None */ -void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) +void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(hhcd->Instance==USB_OTG_FS) + if(hpcd->Instance==USB_OTG_FS) { /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */ @@ -893,16 +867,14 @@ void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) } /** -* @brief HCD MSP De-Initialization +* @brief PCD MSP De-Initialization * This function freeze the hardware resources used in this example -* @param hhcd: HCD handle pointer +* @param hpcd: PCD handle pointer * @retval None */ - -void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hhcd) +void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd) { - - if(hhcd->Instance==USB_OTG_FS) + if(hpcd->Instance==USB_OTG_FS) { /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */ diff --git a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_it.c b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_it.c index b512c4ef42..9832ed60e3 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_it.c +++ b/bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_it.c @@ -73,7 +73,7 @@ /* External variables --------------------------------------------------------*/ extern SPI_HandleTypeDef hspi1; extern UART_HandleTypeDef huart1; -extern HCD_HandleTypeDef hhcd_USB_OTG_FS; +extern PCD_HandleTypeDef hpcd_USB_OTG_FS; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -248,9 +248,9 @@ void USART1_IRQHandler(void) void OTG_FS_IRQHandler(void) { /* USER CODE BEGIN OTG_FS_IRQn 0 */ - + //You can open usb device or usb host, but open both of them is fatal error. /* USER CODE END OTG_FS_IRQn 0 */ - HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS); + HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); /* USER CODE BEGIN OTG_FS_IRQn 1 */ /* USER CODE END OTG_FS_IRQn 1 */ diff --git a/bsp/stm32/stm32f407-atk-explorer/board/Kconfig b/bsp/stm32/stm32f407-atk-explorer/board/Kconfig index 624f55b7f8..12a10a31da 100644 --- a/bsp/stm32/stm32f407-atk-explorer/board/Kconfig +++ b/bsp/stm32/stm32f407-atk-explorer/board/Kconfig @@ -296,6 +296,11 @@ menu "On-chip Peripheral Drivers" select RT_USING_DFS default n + config BSP_USING_USBD + bool "Enable USB Device" + select RT_USING_USB_DEVICE + default n + menuconfig BSP_USING_USBH bool "Enable USB Host" select RT_USING_USB_HOST -- Gitee From 0d0d0d37dcdc7eba53e964445f5006db04462fb3 Mon Sep 17 00:00:00 2001 From: ZYH Date: Mon, 30 Dec 2019 23:45:14 +0800 Subject: [PATCH 021/110] [BSP][STM32][STM32F469-DISCO]fix build error with qspi --- bsp/stm32/stm32f469-st-disco/board/SConscript | 3 --- 1 file changed, 3 deletions(-) diff --git a/bsp/stm32/stm32f469-st-disco/board/SConscript b/bsp/stm32/stm32f469-st-disco/board/SConscript index 3c07ee8dbc..9521cc5907 100644 --- a/bsp/stm32/stm32f469-st-disco/board/SConscript +++ b/bsp/stm32/stm32f469-st-disco/board/SConscript @@ -26,9 +26,6 @@ if GetDepend(['BSP_USING_TOUCH']): if GetDepend(['BSP_USING_SDCARD']): src += ['ports/drv_sdcard.c'] - -if GetDepend(['BSP_USING_QSPI']): - src += ['ports/drv_qspi_flash.c'] path = [cwd] path += [cwd + '/CubeMX_Config/Inc'] -- Gitee From b87f493f2ba9a27fb6f387d5e7a1170365192a2b Mon Sep 17 00:00:00 2001 From: shangjinlong Date: Tue, 31 Dec 2019 16:16:15 +0800 Subject: [PATCH 022/110] :bug: fix compile warning, undefine var --- components/drivers/audio/audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/drivers/audio/audio.c b/components/drivers/audio/audio.c index 28ddf0fe56..4cec8a4a9c 100644 --- a/components/drivers/audio/audio.c +++ b/components/drivers/audio/audio.c @@ -33,7 +33,7 @@ static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio) rt_err_t result = RT_EOK; rt_uint8_t *data; rt_size_t dst_size, src_size; - rt_uint16_t position, remain_bytes, index = 0; + rt_uint16_t position, remain_bytes = 0, index = 0; struct rt_audio_buf_info *buf_info; RT_ASSERT(audio != RT_NULL); -- Gitee From 00338fd2ac9c9dc976ea46db27a7d99c679a77a8 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Thu, 2 Jan 2020 08:17:32 +0800 Subject: [PATCH 023/110] [BSP] fix the lpc55 issue under Linux/GCC --- bsp/lpc55sxx/lpc55s69_nxp_evk/.config | 58 +++++++++++++++++++-- bsp/lpc55sxx/lpc55s69_nxp_evk/Kconfig | 2 +- bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.h | 7 +-- bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.h | 2 +- bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.py | 2 +- 5 files changed, 61 insertions(+), 10 deletions(-) diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/.config b/bsp/lpc55sxx/lpc55s69_nxp_evk/.config index fe6c720132..5a5d4619b8 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/.config +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/.config @@ -133,7 +133,9 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64 CONFIG_RT_USING_HWTIMER=y # CONFIG_RT_USING_CPUTIME is not set CONFIG_RT_USING_I2C=y +# CONFIG_RT_I2C_DEBUG is not set CONFIG_RT_USING_I2C_BITOPS=y +# CONFIG_RT_I2C_BITOPS_DEBUG is not set CONFIG_RT_USING_PIN=y CONFIG_RT_USING_ADC=y CONFIG_RT_USING_PWM=y @@ -229,10 +231,12 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_WEBCLIENT is not set # CONFIG_PKG_USING_WEBNET is not set # CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set # CONFIG_PKG_USING_WEBTERMINAL is not set # CONFIG_PKG_USING_CJSON is not set # CONFIG_PKG_USING_JSMN is not set # CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set @@ -254,7 +258,9 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_COAP is not set # CONFIG_PKG_USING_NOPOLL is not set # CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set # CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set # CONFIG_PKG_USING_WIZNET is not set # @@ -264,9 +270,23 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_GAGENT_CLOUD is not set # CONFIG_PKG_USING_ALI_IOTKIT is not set # CONFIG_PKG_USING_AZURE is not set -# CONFIG_PKG_USING_TENCENT_IOTKIT is not set +# CONFIG_PKG_USING_TENCENT_IOTHUB is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set # CONFIG_PKG_USING_NIMBLE is not set # CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set # # security packages @@ -288,6 +308,8 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_OPENMV is not set # CONFIG_PKG_USING_MUPDF is not set # CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set # # tools packages @@ -300,6 +322,12 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_QRCODE is not set # CONFIG_PKG_USING_ULOG_EASYFLASH is not set # CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set # # system packages @@ -317,6 +345,8 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_DFS_YAFFS is not set # CONFIG_PKG_USING_LITTLEFS is not set # CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set # # peripheral libraries and drivers @@ -324,21 +354,31 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_SENSORS_DRIVERS is not set # CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_SHT2X is not set -# CONFIG_PKG_USING_AHT10 is not set -# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_SHT3X is not set # CONFIG_PKG_USING_STM32_SDIO is not set # CONFIG_PKG_USING_ICM20608 is not set # CONFIG_PKG_USING_U8G2 is not set # CONFIG_PKG_USING_BUTTON is not set -# CONFIG_PKG_USING_MPU6XXX is not set # CONFIG_PKG_USING_PCF8574 is not set # CONFIG_PKG_USING_SX12XX is not set # CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set # CONFIG_PKG_USING_WM_LIBRARIES is not set # CONFIG_PKG_USING_KENDRYTE_SDK is not set # CONFIG_PKG_USING_INFRARED is not set # CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set # CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set # # miscellaneous packages @@ -349,11 +389,15 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_MINILZO is not set # CONFIG_PKG_USING_QUICKLZ is not set # CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set # CONFIG_PKG_USING_CANFESTIVAL is not set # CONFIG_PKG_USING_ZLIB is not set # CONFIG_PKG_USING_DSTR is not set # CONFIG_PKG_USING_TINYFRAME is not set # CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set # # samples: kernel and components samples @@ -365,6 +409,12 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_HELLO is not set # CONFIG_PKG_USING_VI is not set # CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_UKAL is not set CONFIG_SOC_LPC55S6X_SERIES=y # diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/Kconfig b/bsp/lpc55sxx/lpc55s69_nxp_evk/Kconfig index 39775bd315..b609832139 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/Kconfig +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/Kconfig @@ -22,5 +22,5 @@ config SOC_LPC55S6x source "$RTT_DIR/Kconfig" source "$PKGS_DIR/Kconfig" -source "../libraries/Kconfig" +source "../Libraries/Kconfig" source "board/Kconfig" diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.h b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.h index f2fce5c093..32afed7da3 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.h +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.h @@ -36,10 +36,11 @@ extern int Image$$ARM_LIB_HEAP$$ZI$$Base; #pragma section="HEAP" #define HEAP_BEGIN (__segment_end("HEAP")) #elif defined(__GNUC__) -extern int __bss_end; -#define HEAP_BEGIN ((void *)&__bss_end) +extern int __HeapBase; +extern int __HeapLimit; +#define HEAP_BEGIN ((void *)&__HeapBase) #endif -#define HEAP_END (void*)(0x20000000 + 0x40000) +#define HEAP_END ((void*)&__HeapLimit) void rt_hw_board_init(void); diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.h b/bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.h index b46ecc715d..fcf35369dd 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.h +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.h @@ -16,7 +16,7 @@ #define RT_USING_OVERFLOW_CHECK #define RT_USING_HOOK #define RT_USING_IDLE_HOOK -#define RT_IDEL_HOOK_LIST_SIZE 4 +#define RT_IDLE_HOOK_LIST_SIZE 4 #define IDLE_THREAD_STACK_SIZE 256 #define RT_USING_TIMER_SOFT #define RT_TIMER_THREAD_PRIO 4 diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.py b/bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.py index 25d2373c38..70c4c80b61 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.py +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/rtconfig.py @@ -46,7 +46,7 @@ if PLATFORM == 'gcc': DEVICE = ' -mcpu=' + CPU + ' -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections' CFLAGS = DEVICE + ' -Wall -D__FPU_PRESENT -eentry' AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb -D__START=entry' - LFLAGS = DEVICE + ' -lm -lgcc -lc' + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds' + LFLAGS = DEVICE + ' -lm -lgcc -lc' + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T board/linker_scripts/LPC55S69_cm33_core0_flash.ld' CPATH = '' LPATH = '' -- Gitee From f38b5a9f9f96ace22c68c747a9895c4e83416788 Mon Sep 17 00:00:00 2001 From: tonyzheng-rockchip Date: Thu, 2 Jan 2020 08:54:48 +0800 Subject: [PATCH 024/110] Add priority & stack_size parameters for dlmodule custom --- components/libc/libdl/dlmodule.c | 6 +++++- components/libc/libdl/dlmodule.h | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/components/libc/libdl/dlmodule.c b/components/libc/libdl/dlmodule.c index 2829b7df7d..ee50427605 100644 --- a/components/libc/libdl/dlmodule.c +++ b/components/libc/libdl/dlmodule.c @@ -709,6 +709,7 @@ __exit: struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops) { struct rt_dlmodule *module = RT_NULL; + rt_uint32_t tick = 10; module = dlmodule_load_custom(pgname, ops); if (module) @@ -721,11 +722,14 @@ struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, in module->cmd_line = rt_strdup(cmd); /* check stack size and priority */ + if (ops->priority) module->priority = ops->priority; + if (ops->stack_size) module->stack_size = ops->stack_size; + if (ops->tick) tick = ops->tick; if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1; if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048; tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module, - module->stack_size, module->priority, 10); + module->stack_size, module->priority, tick); if (tid) { tid->module_id = module; diff --git a/components/libc/libdl/dlmodule.h b/components/libc/libdl/dlmodule.h index b366c7603e..28677b06a7 100644 --- a/components/libc/libdl/dlmodule.h +++ b/components/libc/libdl/dlmodule.h @@ -63,6 +63,10 @@ struct rt_dlmodule_ops { rt_uint8_t *(*load)(const char* filename); /* load dlmodule file data */ rt_err_t (*unload)(rt_uint8_t *param); /* unload dlmodule file data */ + + rt_uint16_t priority; + rt_uint32_t stack_size; + rt_uint32_t tick; }; struct rt_dlmodule *dlmodule_create(void); -- Gitee From edfe6d5b282e4278b2b64466f736a47b75399d47 Mon Sep 17 00:00:00 2001 From: tyustli <1225613647@qq.com> Date: Thu, 2 Jan 2020 18:35:22 +0800 Subject: [PATCH 025/110] [src] [components] avoid compiler optimize --- src/components.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components.c b/src/components.c index df3e0f0fb3..362cf3203f 100644 --- a/src/components.c +++ b/src/components.c @@ -92,7 +92,7 @@ void rt_components_board_init(void) rt_kprintf(":%d done\n", result); } #else - const init_fn_t *fn_ptr; + volatile const init_fn_t *fn_ptr; for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++) { @@ -118,7 +118,7 @@ void rt_components_init(void) rt_kprintf(":%d done\n", result); } #else - const init_fn_t *fn_ptr; + volatile const init_fn_t *fn_ptr; for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++) { -- Gitee From 04c20bc8ed2a8e69aa53e8956739feda9800596f Mon Sep 17 00:00:00 2001 From: tonyzheng-rockchip Date: Fri, 3 Jan 2020 09:18:51 +0800 Subject: [PATCH 026/110] Revert "Add priority & stack_size parameters for dlmodule custom" This reverts commit f38b5a9f9f96ace22c68c747a9895c4e83416788. --- components/libc/libdl/dlmodule.c | 6 +----- components/libc/libdl/dlmodule.h | 4 ---- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/components/libc/libdl/dlmodule.c b/components/libc/libdl/dlmodule.c index ee50427605..2829b7df7d 100644 --- a/components/libc/libdl/dlmodule.c +++ b/components/libc/libdl/dlmodule.c @@ -709,7 +709,6 @@ __exit: struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops) { struct rt_dlmodule *module = RT_NULL; - rt_uint32_t tick = 10; module = dlmodule_load_custom(pgname, ops); if (module) @@ -722,14 +721,11 @@ struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, in module->cmd_line = rt_strdup(cmd); /* check stack size and priority */ - if (ops->priority) module->priority = ops->priority; - if (ops->stack_size) module->stack_size = ops->stack_size; - if (ops->tick) tick = ops->tick; if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1; if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048; tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module, - module->stack_size, module->priority, tick); + module->stack_size, module->priority, 10); if (tid) { tid->module_id = module; diff --git a/components/libc/libdl/dlmodule.h b/components/libc/libdl/dlmodule.h index 28677b06a7..b366c7603e 100644 --- a/components/libc/libdl/dlmodule.h +++ b/components/libc/libdl/dlmodule.h @@ -63,10 +63,6 @@ struct rt_dlmodule_ops { rt_uint8_t *(*load)(const char* filename); /* load dlmodule file data */ rt_err_t (*unload)(rt_uint8_t *param); /* unload dlmodule file data */ - - rt_uint16_t priority; - rt_uint32_t stack_size; - rt_uint32_t tick; }; struct rt_dlmodule *dlmodule_create(void); -- Gitee From 5eb53417f410328452460b3c78f21714ab3cca6e Mon Sep 17 00:00:00 2001 From: tonyzheng-rockchip Date: Fri, 3 Jan 2020 09:23:44 +0800 Subject: [PATCH 027/110] Add priority & stack_size param parsing for dlmodule --- components/libc/libdl/dlelf.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/components/libc/libdl/dlelf.c b/components/libc/libdl/dlelf.c index 1265ffcb07..b79e5c23ea 100644 --- a/components/libc/libdl/dlelf.c +++ b/components/libc/libdl/dlelf.c @@ -226,6 +226,24 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt length); count ++; } + + /* get priority param */ + for (i = 0; i < shdr[index].sh_size / sizeof(Elf32_Sym); i++) + { + if (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_priority") == 0) + { + module->priority = *(rt_uint16_t*)(module->mem_space + symtab[i].st_value - module->vstart_addr); + } + } + + /* get stack size param */ + for (i = 0; i < shdr[index].sh_size / sizeof(Elf32_Sym); i++) + { + if (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_stacksize") == 0) + { + module->stack_size = *(rt_uint32_t*)(module->mem_space + symtab[i].st_value - module->vstart_addr); + } + } } return RT_EOK; -- Gitee From 4e23cb027f86f5f9f02865fdfc6d9ff60885162b Mon Sep 17 00:00:00 2001 From: liuxinaliang Date: Fri, 3 Jan 2020 11:17:50 +0800 Subject: [PATCH 028/110] [bsp][stm32] fixed a bug that caused system crash by changing the run_mode in low power mode Signed-off-by: liuxinaliang --- bsp/stm32/libraries/HAL_Drivers/drv_pm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_pm.c b/bsp/stm32/libraries/HAL_Drivers/drv_pm.c index 84ddf6cd41..8f3890474e 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_pm.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_pm.c @@ -95,11 +95,13 @@ static void run(struct rt_pm *pm, uint8_t mode) { case PM_RUN_MODE_HIGH_SPEED: case PM_RUN_MODE_NORMAL_SPEED: + HAL_PWREx_DisableLowPowerRunMode(); SystemClock_80M(); /* Configure the main internal regulator output voltage (Range1 by default)*/ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); break; case PM_RUN_MODE_MEDIUM_SPEED: + HAL_PWREx_DisableLowPowerRunMode(); SystemClock_24M(); /* Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2); -- Gitee From 6ad56dfbec42e5fd2d798be7225bd8618875e4f0 Mon Sep 17 00:00:00 2001 From: liuxinaliang Date: Fri, 3 Jan 2020 12:45:46 +0800 Subject: [PATCH 029/110] [bsp][stm32] fix a problem that using gcc compile the chips of stm G4 series but chip doesn't work Signed-off-by: liuxinaliang --- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s | 6 +++--- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s | 6 +++--- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s | 6 +++--- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s | 6 +++--- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s | 6 +++--- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s | 6 +++--- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s | 6 +++--- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s index be5cc3fc22..816b49db7c 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s @@ -79,7 +79,7 @@ LoopCopyDataInit: adds r4, r0, r3 cmp r4, r1 bcc CopyDataInit - + /* Zero fill the bss segment. */ ldr r2, =_sbss ldr r4, =_ebss @@ -97,9 +97,9 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ - bl __libc_init_array +/* bl __libc_init_array */ /* Call the application's entry point.*/ - bl main + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s index dc621f9ad9..32e51a7493 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s @@ -79,7 +79,7 @@ LoopCopyDataInit: adds r4, r0, r3 cmp r4, r1 bcc CopyDataInit - + /* Zero fill the bss segment. */ ldr r2, =_sbss ldr r4, =_ebss @@ -97,9 +97,9 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ - bl __libc_init_array +/* bl __libc_init_array */ /* Call the application's entry point.*/ - bl main + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s index 918ebee877..95a9bfecbc 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s @@ -79,7 +79,7 @@ LoopCopyDataInit: adds r4, r0, r3 cmp r4, r1 bcc CopyDataInit - + /* Zero fill the bss segment. */ ldr r2, =_sbss ldr r4, =_ebss @@ -97,9 +97,9 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ - bl __libc_init_array +/* bl __libc_init_array */ /* Call the application's entry point.*/ - bl main + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s index 3b10aeb6ed..a6a3cfa206 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s @@ -79,7 +79,7 @@ LoopCopyDataInit: adds r4, r0, r3 cmp r4, r1 bcc CopyDataInit - + /* Zero fill the bss segment. */ ldr r2, =_sbss ldr r4, =_ebss @@ -97,9 +97,9 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ - bl __libc_init_array +/* bl __libc_init_array */ /* Call the application's entry point.*/ - bl main + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s index 2b39625b65..3ad8ccee4d 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s @@ -79,7 +79,7 @@ LoopCopyDataInit: adds r4, r0, r3 cmp r4, r1 bcc CopyDataInit - + /* Zero fill the bss segment. */ ldr r2, =_sbss ldr r4, =_ebss @@ -97,9 +97,9 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ - bl __libc_init_array +/* bl __libc_init_array */ /* Call the application's entry point.*/ - bl main + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s index 15e3ca1321..0eeb0b1850 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s @@ -79,7 +79,7 @@ LoopCopyDataInit: adds r4, r0, r3 cmp r4, r1 bcc CopyDataInit - + /* Zero fill the bss segment. */ ldr r2, =_sbss ldr r4, =_ebss @@ -97,9 +97,9 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ - bl __libc_init_array +/* bl __libc_init_array */ /* Call the application's entry point.*/ - bl main + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s index be0640457e..dd8d6207d0 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s @@ -78,7 +78,7 @@ LoopCopyDataInit: adds r4, r0, r3 cmp r4, r1 bcc CopyDataInit - + /* Zero fill the bss segment. */ ldr r2, =_sbss ldr r4, =_ebss @@ -96,9 +96,9 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ - bl __libc_init_array +/* bl __libc_init_array */ /* Call the application's entry point.*/ - bl main + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s index f302f42735..4e9a9963af 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s @@ -93,9 +93,9 @@ LoopFillZerobss: /* Call the clock system intitialization function.*/ bl SystemInit /* Call static constructors */ - bl __libc_init_array +/* bl __libc_init_array */ /* Call the application's entry point.*/ - bl main + bl entry LoopForever: b LoopForever -- Gitee From 1f5118f7ddfead2d4924e8a2018f32ab388c7392 Mon Sep 17 00:00:00 2001 From: tonyzheng-rockchip Date: Fri, 3 Jan 2020 09:23:44 +0800 Subject: [PATCH 030/110] Add priority & stack_size param parsing for dlmodule --- components/libc/libdl/dlelf.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/components/libc/libdl/dlelf.c b/components/libc/libdl/dlelf.c index 1265ffcb07..55ef0d8951 100644 --- a/components/libc/libdl/dlelf.c +++ b/components/libc/libdl/dlelf.c @@ -226,6 +226,40 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt length); count ++; } + + /* get priority & stack size params*/ + rt_uint32_t flag = 0; + rt_uint16_t priority; + rt_uint32_t stacksize; + for (i = 0; i < shdr[index].sh_size / sizeof(Elf32_Sym); i++) + { + if (((flag & 0x01) == 0) && + (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_priority") == 0)) + { + flag |= 0x01; + priority = *(rt_uint16_t*)(module->mem_space + symtab[i].st_value - module->vstart_addr); + if (priority < RT_THREAD_PRIORITY_MAX) + { + module->priority = priority; + } + } + + if (((flag & 0x02) == 0) && + (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_stacksize") == 0)) + { + flag |= 0x02; + stacksize = *(rt_uint32_t*)(module->mem_space + symtab[i].st_value - module->vstart_addr); + if ((stacksize < 2048) || (stacksize > 1024 * 32)) + { + module->stack_size = stacksize; + } + } + + if ((flag & 0x03) == 0x03) + { + break; + } + } } return RT_EOK; -- Gitee From 5f4b780558366ed7fd72e08bdfada6243252d2fc Mon Sep 17 00:00:00 2001 From: Kevin Peng Date: Mon, 28 Oct 2019 14:35:50 +0800 Subject: [PATCH 031/110] LPC55S69: Integration with TF-M This patch enables TF-M running on secure side and RT-Thread running on NS side by: 1. Updates the VTOR address 2. Remove a HW initialization which is already done in TF-M 3. Add a new project and linker script to build RTT in NS Note: There are no secure service calls to TF-M in this patch Change-Id: I4023a082cfb5c8df8a4f0ecc7ffee850daaadeb4 Signed-off-by: Kevin Peng Signed-off-by: Karl Zhang --- bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.c | 11 + .../LPC55S69_cm33_core0_flash_ns_mdk.scf | 110 + .../lpc55s69_nxp_evk/project_ns.uvoptx | 1811 +++++++++++++++++ .../lpc55s69_nxp_evk/project_ns.uvprojx | 1157 +++++++++++ 4 files changed, 3089 insertions(+) create mode 100644 bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_ns_mdk.scf create mode 100644 bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx create mode 100644 bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.c index 4a7fb3f885..22e663b1f4 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.c +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/board.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -10,6 +11,7 @@ * 2010-05-02 Aozima update CMSIS to 130 * 2017-08-02 XiaoYang porting to LPC54608 bsp * 2019-08-05 Magicoe porting to LPC55S69-EVK bsp + * 2020-01-01 Karl Add RT_USING_TFM support */ #include @@ -56,11 +58,20 @@ void rt_hw_board_init() /* Set the Vector Table base location at 0x10000000 */ SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK); #else /* VECT_TAB_FLASH */ + +#ifdef RT_USING_TFM + /* Set the Vector Table base location at 0x00020000 when RTT with TF-M*/ + SCB->VTOR = (0x00020000 & NVIC_VTOR_MASK); +#else /* Set the Vector Table base location at 0x00000000 */ SCB->VTOR = (0x00000000 & NVIC_VTOR_MASK); #endif +#endif +#ifndef RT_USING_TFM + /* This init has finished in secure side of TF-M */ BOARD_BootClockPLL150M(); +#endif //BOARD_BootClockFROHF96M(); /* init systick 1 systick = 1/(100M / 100) 100systick = 1s*/ diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_ns_mdk.scf b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_ns_mdk.scf new file mode 100644 index 0000000000..bb14890505 --- /dev/null +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_ns_mdk.scf @@ -0,0 +1,110 @@ +#!armclang --target=arm-arm-none-eabi -march=armv8-m.main -E -x c +/* +** ################################################################### +** Processors: LPC55S69JBD100_cm33_core0 +** LPC55S69JET98_cm33_core0 +** +** Compiler: Keil ARM C/C++ Compiler +** Reference manual: LPC55xx/LPC55Sxx User manual Rev.0.2 15 Aug 2018 +** Version: rev. 1.0, 2018-08-22 +** Build: b181008 +** +** Abstract: +** Linker file for the Keil ARM C/C++ Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2018 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* + * Original code taken from RTT project at: + * https://github.com/RT-Thread/rt-thread + * File: bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_mdk.scf + * Git SHA of the original version: 64945ba882d651a14933eb4e7b3d93d10d6daae1 + */ + +/* USB BDT size */ +#define usb_bdt_size 0x0 +/* Sizes */ +#if (defined(__stack_size__)) + #define Stack_Size __stack_size__ +#else + #define Stack_Size 0x1000 +#endif + +#if (defined(__heap_size__)) + #define Heap_Size __heap_size__ +#else + #define Heap_Size 0x1000 +#endif + +#define m_interrupts_start 0x00000000 +#define m_interrupts_size 0x00000200 + +#define m_text_start 0x00000200 +#define m_text_size 0x00071E00 + +#define m_core1_image_start 0x00072000 +#define m_core1_image_size 0x00026000 + +#if (defined(__use_shmem__)) + #define m_data_start 0x20000000 + #define m_data_size 0x00031800 + #define m_rpmsg_sh_mem_start 0x20031800 + #define m_rpmsg_sh_mem_size 0x00001800 +#else + #define m_data_start 0x20000000 + #define m_data_size 0x00033000 +#endif + +#define m_usb_sram_start 0x40100000 +#define m_usb_sram_size 0x00004000 + + +LR_m_text m_interrupts_start m_interrupts_size+m_text_size { ; load region size_region + + VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address + * (RESET,+FIRST) + } + + ER_m_text m_text_start FIXED m_text_size { ; load address = execution address + * (InRoot$$Sections) + * (+RO) + } + +#if (defined(__use_shmem__)) + RPMSG_SH_MEM m_rpmsg_sh_mem_start UNINIT m_rpmsg_sh_mem_size { ; Shared memory used by RPMSG + * (rpmsg_sh_mem_section) + } +#endif + + RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data + * (+RW +ZI) + } + ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up + } + ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down + } + + RW_m_usb_bdt m_usb_sram_start UNINIT usb_bdt_size { + * (m_usb_bdt) + } + + RW_m_usb_ram (m_usb_sram_start + usb_bdt_size) UNINIT (m_usb_sram_size - usb_bdt_size) { + * (m_usb_global) + } +} + +LR_CORE1_IMAGE m_core1_image_start { + CORE1_REGION m_core1_image_start m_core1_image_size { + *(M0CODE) + } +} diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx new file mode 100644 index 0000000000..7f28d506da --- /dev/null +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx @@ -0,0 +1,1811 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rtthread-lpc55s6x + 0x4 + ARM-ADS + + 12000000 + + 0 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 0 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 14 + + + + + + + + + + + BIN\UL2V8M.DLL + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN2 -FF0LPC55XX_640 -FS00 -FL098000 -FF1LPC55XX_S_640 -FS110000000 -FL198000 -FP0($$Device:LPC55S69JBD100$arm\LPC55XX_640.FLM) -FP1($$Device:LPC55S69JBD100$arm\LPC55XX_S_640.FLM)) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 5000000 + + + + + + Kernel + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\..\..\src\clock.c + clock.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + ..\..\..\src\components.c + components.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ..\..\..\src\device.c + device.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\..\src\idle.c + idle.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\..\src\ipc.c + ipc.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\..\src\irq.c + irq.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\..\src\kservice.c + kservice.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\..\..\src\mem.c + mem.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\..\src\mempool.c + mempool.c + 0 + 0 + + + 1 + 10 + 1 + 0 + 0 + 0 + ..\..\..\src\object.c + object.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + ..\..\..\src\scheduler.c + scheduler.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + ..\..\..\src\signal.c + signal.c + 0 + 0 + + + 1 + 13 + 1 + 0 + 0 + 0 + ..\..\..\src\thread.c + thread.c + 0 + 0 + + + 1 + 14 + 1 + 0 + 0 + 0 + ..\..\..\src\timer.c + timer.c + 0 + 0 + + + + + Applications + 0 + 0 + 0 + 0 + + 2 + 15 + 1 + 0 + 0 + 0 + applications\main.c + main.c + 0 + 0 + + + + + Drivers + 1 + 0 + 0 + 0 + + 3 + 16 + 1 + 0 + 0 + 0 + board\board.c + board.c + 0 + 0 + + + 3 + 17 + 1 + 0 + 0 + 0 + board\MCUX_Config\board\clock_config.c + clock_config.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + board\MCUX_Config\board\pin_mux.c + pin_mux.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_pin.c + drv_pin.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_led.c + drv_led.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_key.c + drv_key.c + 0 + 0 + + + 3 + 22 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_uart.c + drv_uart.c + 0 + 0 + + + 3 + 23 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_rtc.c + drv_rtc.c + 0 + 0 + + + 3 + 24 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_spi.c + drv_spi.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_sd.c + drv_sd.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_i2c.c + drv_i2c.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_mma8562.c + drv_mma8562.c + 0 + 0 + + + 3 + 28 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_adc.c + drv_adc.c + 0 + 0 + + + 3 + 29 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_hwtimer.c + drv_hwtimer.c + 0 + 0 + + + 3 + 30 + 1 + 0 + 0 + 0 + ..\Libraries\drivers\drv_pwm.c + drv_pwm.c + 0 + 0 + + + + + cpu + 1 + 0 + 0 + 0 + + 4 + 31 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\backtrace.c + backtrace.c + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\div0.c + div0.c + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\showmem.c + showmem.c + 0 + 0 + + + 4 + 34 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m4\cpuport.c + cpuport.c + 0 + 0 + + + 4 + 35 + 2 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m4\context_rvds.S + context_rvds.S + 0 + 0 + + + + + Filesystem + 1 + 0 + 0 + 0 + + 5 + 36 + 1 + 0 + 0 + 0 + ..\..\..\components\dfs\src\dfs.c + dfs.c + 0 + 0 + + + 5 + 37 + 1 + 0 + 0 + 0 + ..\..\..\components\dfs\src\dfs_file.c + dfs_file.c + 0 + 0 + + + 5 + 38 + 1 + 0 + 0 + 0 + ..\..\..\components\dfs\src\dfs_fs.c + dfs_fs.c + 0 + 0 + + + 5 + 39 + 1 + 0 + 0 + 0 + ..\..\..\components\dfs\src\dfs_posix.c + dfs_posix.c + 0 + 0 + + + 5 + 40 + 1 + 0 + 0 + 0 + ..\..\..\components\dfs\src\poll.c + poll.c + 0 + 0 + + + 5 + 41 + 1 + 0 + 0 + 0 + ..\..\..\components\dfs\src\select.c + select.c + 0 + 0 + + + 5 + 42 + 1 + 0 + 0 + 0 + ..\..\..\components\dfs\filesystems\devfs\devfs.c + devfs.c + 0 + 0 + + + + + DeviceDrivers + 0 + 0 + 0 + 0 + + 6 + 43 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\hwtimer\hwtimer.c + hwtimer.c + 0 + 0 + + + 6 + 44 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\i2c\i2c_core.c + i2c_core.c + 0 + 0 + + + 6 + 45 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\i2c\i2c_dev.c + i2c_dev.c + 0 + 0 + + + 6 + 46 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\i2c\i2c-bit-ops.c + i2c-bit-ops.c + 0 + 0 + + + 6 + 47 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\pin.c + pin.c + 0 + 0 + + + 6 + 48 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\adc.c + adc.c + 0 + 0 + + + 6 + 49 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\rt_drv_pwm.c + rt_drv_pwm.c + 0 + 0 + + + 6 + 50 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\rtc\rtc.c + rtc.c + 0 + 0 + + + 6 + 51 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\sdio\block_dev.c + block_dev.c + 0 + 0 + + + 6 + 52 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\sdio\mmcsd_core.c + mmcsd_core.c + 0 + 0 + + + 6 + 53 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\sdio\sd.c + sd.c + 0 + 0 + + + 6 + 54 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\sdio\sdio.c + sdio.c + 0 + 0 + + + 6 + 55 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\sdio\mmc.c + mmc.c + 0 + 0 + + + 6 + 56 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\serial\serial.c + serial.c + 0 + 0 + + + 6 + 57 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\spi\spi_core.c + spi_core.c + 0 + 0 + + + 6 + 58 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\spi\spi_dev.c + spi_dev.c + 0 + 0 + + + 6 + 59 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\completion.c + completion.c + 0 + 0 + + + 6 + 60 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\dataqueue.c + dataqueue.c + 0 + 0 + + + 6 + 61 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\pipe.c + pipe.c + 0 + 0 + + + 6 + 62 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\ringblk_buf.c + ringblk_buf.c + 0 + 0 + + + 6 + 63 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\ringbuffer.c + ringbuffer.c + 0 + 0 + + + 6 + 64 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\waitqueue.c + waitqueue.c + 0 + 0 + + + 6 + 65 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\workqueue.c + workqueue.c + 0 + 0 + + + + + finsh + 0 + 0 + 0 + 0 + + 7 + 66 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\shell.c + shell.c + 0 + 0 + + + 7 + 67 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\cmd.c + cmd.c + 0 + 0 + + + 7 + 68 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\msh.c + msh.c + 0 + 0 + + + 7 + 69 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\msh_file.c + msh_file.c + 0 + 0 + + + 7 + 70 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_compiler.c + finsh_compiler.c + 0 + 0 + + + 7 + 71 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_error.c + finsh_error.c + 0 + 0 + + + 7 + 72 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_heap.c + finsh_heap.c + 0 + 0 + + + 7 + 73 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_init.c + finsh_init.c + 0 + 0 + + + 7 + 74 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_node.c + finsh_node.c + 0 + 0 + + + 7 + 75 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_ops.c + finsh_ops.c + 0 + 0 + + + 7 + 76 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_parser.c + finsh_parser.c + 0 + 0 + + + 7 + 77 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_var.c + finsh_var.c + 0 + 0 + + + 7 + 78 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_vm.c + finsh_vm.c + 0 + 0 + + + 7 + 79 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_token.c + finsh_token.c + 0 + 0 + + + + + libc + 0 + 0 + 0 + 0 + + 8 + 80 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\armlibc\libc.c + libc.c + 0 + 0 + + + 8 + 81 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\armlibc\mem_std.c + mem_std.c + 0 + 0 + + + 8 + 82 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\armlibc\stdio.c + stdio.c + 0 + 0 + + + 8 + 83 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\armlibc\stubs.c + stubs.c + 0 + 0 + + + 8 + 84 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\time.c + time.c + 0 + 0 + + + + + Libraries + 0 + 0 + 0 + 0 + + 9 + 85 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\system_LPC55S69_cm33_core0.c + system_LPC55S69_cm33_core0.c + 0 + 0 + + + 9 + 86 + 2 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\arm\startup_LPC55S69_cm33_core0.s + startup_LPC55S69_cm33_core0.s + 0 + 0 + + + 9 + 87 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_anactrl.c + fsl_anactrl.c + 0 + 0 + + + 9 + 88 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_casper.c + fsl_casper.c + 0 + 0 + + + 9 + 89 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_clock.c + fsl_clock.c + 0 + 0 + + + 9 + 90 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_cmp.c + fsl_cmp.c + 0 + 0 + + + 9 + 91 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_common.c + fsl_common.c + 0 + 0 + + + 9 + 92 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_crc.c + fsl_crc.c + 0 + 0 + + + 9 + 93 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_ctimer.c + fsl_ctimer.c + 0 + 0 + + + 9 + 94 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_flexcomm.c + fsl_flexcomm.c + 0 + 0 + + + 9 + 95 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_dma.c + fsl_dma.c + 0 + 0 + + + 9 + 96 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_gint.c + fsl_gint.c + 0 + 0 + + + 9 + 97 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_gpio.c + fsl_gpio.c + 0 + 0 + + + 9 + 98 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_hashcrypt.c + fsl_hashcrypt.c + 0 + 0 + + + 9 + 99 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_i2c.c + fsl_i2c.c + 0 + 0 + + + 9 + 100 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_i2c_dma.c + fsl_i2c_dma.c + 0 + 0 + + + 9 + 101 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_i2s.c + fsl_i2s.c + 0 + 0 + + + 9 + 102 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_i2s_dma.c + fsl_i2s_dma.c + 0 + 0 + + + 9 + 103 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_iap.c + fsl_iap.c + 0 + 0 + + + 9 + 104 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_inputmux.c + fsl_inputmux.c + 0 + 0 + + + 9 + 105 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_lpadc.c + fsl_lpadc.c + 0 + 0 + + + 9 + 106 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_mrt.c + fsl_mrt.c + 0 + 0 + + + 9 + 107 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_ostimer.c + fsl_ostimer.c + 0 + 0 + + + 9 + 108 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_pint.c + fsl_pint.c + 0 + 0 + + + 9 + 109 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_plu.c + fsl_plu.c + 0 + 0 + + + 9 + 110 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_power.c + fsl_power.c + 0 + 0 + + + 9 + 111 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_powerquad_basic.c + fsl_powerquad_basic.c + 0 + 0 + + + 9 + 112 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_prince.c + fsl_prince.c + 0 + 0 + + + 9 + 113 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_puf.c + fsl_puf.c + 0 + 0 + + + 9 + 114 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_reset.c + fsl_reset.c + 0 + 0 + + + 9 + 115 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_rng.c + fsl_rng.c + 0 + 0 + + + 9 + 116 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_rtc.c + fsl_rtc.c + 0 + 0 + + + 9 + 117 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_sctimer.c + fsl_sctimer.c + 0 + 0 + + + 9 + 118 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_sdif.c + fsl_sdif.c + 0 + 0 + + + 9 + 119 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_spi.c + fsl_spi.c + 0 + 0 + + + 9 + 120 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_spi_dma.c + fsl_spi_dma.c + 0 + 0 + + + 9 + 121 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_sysctl.c + fsl_sysctl.c + 0 + 0 + + + 9 + 122 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_usart.c + fsl_usart.c + 0 + 0 + + + 9 + 123 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_usart_dma.c + fsl_usart_dma.c + 0 + 0 + + + 9 + 124 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_utick.c + fsl_utick.c + 0 + 0 + + + 9 + 125 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_wwdt.c + fsl_wwdt.c + 0 + 0 + + + 9 + 126 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\middleware\sdmmc\src\fsl_sd.c + fsl_sd.c + 0 + 0 + + + 9 + 127 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\middleware\sdmmc\src\fsl_sdmmc_common.c + fsl_sdmmc_common.c + 0 + 0 + + + 9 + 128 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\middleware\sdmmc\port\sdif\rt_thread\fsl_sdmmc_event.c + fsl_sdmmc_event.c + 0 + 0 + + + 9 + 129 + 1 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\middleware\sdmmc\port\sdif\rt_thread\fsl_sdmmc_host.c + fsl_sdmmc_host.c + 0 + 0 + + + 9 + 130 + 4 + 0 + 0 + 0 + ..\Libraries\LPC55S6X\LPC55S6X\arm\keil_lib_power_cm33_core0.lib + arm_keil_lib_power_cm33_core0.lib + 0 + 0 + + + +
diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx new file mode 100644 index 0000000000..4cfb8a82cd --- /dev/null +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx @@ -0,0 +1,1157 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread-lpc55s6x + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 6120000::V6.12::.\ARMCLANG + 1 + + + LPC55S69JBD100:cm33_core0 + NXP + NXP.LPC55S69_DFP.12.0.0 + http://mcuxpresso.nxp.com/cmsis_pack/repo/ + IRAM(0x20000000,0x044000) IRAM2(0x04000000,0x8000) IROM(0x00000000,0x098000) XRAM(0x40100000,0x4000) CPUTYPE("Cortex-M33") FPU3(SFPU) DSP TZ CLOCK(12000000) ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN2 -FF0LPC55XX_640 -FS00 -FL098000 -FF1LPC55XX_S_640 -FS110000000 -FL198000 -FP0($$Device:LPC55S69JBD100$arm\LPC55XX_640.FLM) -FP1($$Device:LPC55S69JBD100$arm\LPC55XX_S_640.FLM)) + 0 + $$Device:LPC55S69JBD100$fsl_device_registers.h + + + + + + + + + + $$Device:LPC55S69JBD100$LPC55S69_cm33_core0.xml + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-lpc55s6x + 1 + 0 + 0 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM33 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4101 + + 1 + BIN\UL2V8M.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M33" + + 0 + 0 + 0 + 1 + 1 + 1 + 0 + 2 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x44000 + + + 1 + 0x0 + 0x98000 + + + 1 + 0x40100000 + 0x4000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x98000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x40100000 + 0x4000 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x44000 + + + 0 + 0x4000000 + 0x8000 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + + --target=arm-arm-none-eabi + CPU_LPC55S69JBD100_cm33_core0, RT_USING_ARM_LIBC, RT_USING_TFM + + .;..\..\..\include;applications;board;board\MCUX_Config\board;..\Libraries\drivers;..\Libraries\drivers\config;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\dfs\include;..\..\..\components\dfs\filesystems\devfs;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\spi;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\finsh;..\..\..\components\libc\compilers\armlibc;..\..\..\components\libc\compilers\common;..\Libraries\LPC55S6X\CMSIS\Include;..\Libraries\LPC55S6X\components\codec;..\Libraries\LPC55S6X\LPC55S6X;..\Libraries\LPC55S6X\LPC55S6X\drivers;..\Libraries\LPC55S6X\middleware\sdmmc\inc;..\Libraries\LPC55S6X\middleware\sdmmc\port + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x02000000 + + .\board\linker_scripts\LPC55S69_cm33_core0_flash_ns_mdk.scf + + + + + + + + + + + Kernel + + + clock.c + 1 + ..\..\..\src\clock.c + + + components.c + 1 + ..\..\..\src\components.c + + + device.c + 1 + ..\..\..\src\device.c + + + idle.c + 1 + ..\..\..\src\idle.c + + + ipc.c + 1 + ..\..\..\src\ipc.c + + + irq.c + 1 + ..\..\..\src\irq.c + + + kservice.c + 1 + ..\..\..\src\kservice.c + + + mem.c + 1 + ..\..\..\src\mem.c + + + mempool.c + 1 + ..\..\..\src\mempool.c + + + object.c + 1 + ..\..\..\src\object.c + + + scheduler.c + 1 + ..\..\..\src\scheduler.c + + + signal.c + 1 + ..\..\..\src\signal.c + + + thread.c + 1 + ..\..\..\src\thread.c + + + timer.c + 1 + ..\..\..\src\timer.c + + + + + Applications + + + main.c + 1 + applications\main.c + + + + + Drivers + + + board.c + 1 + board\board.c + + + clock_config.c + 1 + board\MCUX_Config\board\clock_config.c + + + pin_mux.c + 1 + board\MCUX_Config\board\pin_mux.c + + + drv_pin.c + 1 + ..\Libraries\drivers\drv_pin.c + + + drv_led.c + 1 + ..\Libraries\drivers\drv_led.c + + + drv_key.c + 1 + ..\Libraries\drivers\drv_key.c + + + drv_uart.c + 1 + ..\Libraries\drivers\drv_uart.c + + + drv_rtc.c + 1 + ..\Libraries\drivers\drv_rtc.c + + + drv_spi.c + 1 + ..\Libraries\drivers\drv_spi.c + + + drv_sd.c + 1 + ..\Libraries\drivers\drv_sd.c + + + drv_i2c.c + 1 + ..\Libraries\drivers\drv_i2c.c + + + drv_mma8562.c + 1 + ..\Libraries\drivers\drv_mma8562.c + + + drv_adc.c + 1 + ..\Libraries\drivers\drv_adc.c + + + drv_hwtimer.c + 1 + ..\Libraries\drivers\drv_hwtimer.c + + + drv_pwm.c + 1 + ..\Libraries\drivers\drv_pwm.c + + + + + cpu + + + backtrace.c + 1 + ..\..\..\libcpu\arm\common\backtrace.c + + + div0.c + 1 + ..\..\..\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\..\libcpu\arm\common\showmem.c + + + cpuport.c + 1 + ..\..\..\libcpu\arm\cortex-m4\cpuport.c + + + context_rvds.S + 2 + ..\..\..\libcpu\arm\cortex-m4\context_rvds.S + + + + + Filesystem + + + dfs.c + 1 + ..\..\..\components\dfs\src\dfs.c + + + dfs_file.c + 1 + ..\..\..\components\dfs\src\dfs_file.c + + + dfs_fs.c + 1 + ..\..\..\components\dfs\src\dfs_fs.c + + + dfs_posix.c + 1 + ..\..\..\components\dfs\src\dfs_posix.c + + + poll.c + 1 + ..\..\..\components\dfs\src\poll.c + + + select.c + 1 + ..\..\..\components\dfs\src\select.c + + + devfs.c + 1 + ..\..\..\components\dfs\filesystems\devfs\devfs.c + + + + + DeviceDrivers + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + hwtimer.c + 1 + ..\..\..\components\drivers\hwtimer\hwtimer.c + + + i2c_core.c + 1 + ..\..\..\components\drivers\i2c\i2c_core.c + + + i2c_dev.c + 1 + ..\..\..\components\drivers\i2c\i2c_dev.c + + + i2c-bit-ops.c + 1 + ..\..\..\components\drivers\i2c\i2c-bit-ops.c + + + pin.c + 1 + ..\..\..\components\drivers\misc\pin.c + + + adc.c + 1 + ..\..\..\components\drivers\misc\adc.c + + + rt_drv_pwm.c + 1 + ..\..\..\components\drivers\misc\rt_drv_pwm.c + + + rtc.c + 1 + ..\..\..\components\drivers\rtc\rtc.c + + + block_dev.c + 1 + ..\..\..\components\drivers\sdio\block_dev.c + + + mmcsd_core.c + 1 + ..\..\..\components\drivers\sdio\mmcsd_core.c + + + sd.c + 1 + ..\..\..\components\drivers\sdio\sd.c + + + sdio.c + 1 + ..\..\..\components\drivers\sdio\sdio.c + + + mmc.c + 1 + ..\..\..\components\drivers\sdio\mmc.c + + + serial.c + 1 + ..\..\..\components\drivers\serial\serial.c + + + spi_core.c + 1 + ..\..\..\components\drivers\spi\spi_core.c + + + spi_dev.c + 1 + ..\..\..\components\drivers\spi\spi_dev.c + + + completion.c + 1 + ..\..\..\components\drivers\src\completion.c + + + dataqueue.c + 1 + ..\..\..\components\drivers\src\dataqueue.c + + + pipe.c + 1 + ..\..\..\components\drivers\src\pipe.c + + + ringblk_buf.c + 1 + ..\..\..\components\drivers\src\ringblk_buf.c + + + ringbuffer.c + 1 + ..\..\..\components\drivers\src\ringbuffer.c + + + waitqueue.c + 1 + ..\..\..\components\drivers\src\waitqueue.c + + + workqueue.c + 1 + ..\..\..\components\drivers\src\workqueue.c + + + + + finsh + + + shell.c + 1 + ..\..\..\components\finsh\shell.c + + + cmd.c + 1 + ..\..\..\components\finsh\cmd.c + + + msh.c + 1 + ..\..\..\components\finsh\msh.c + + + msh_file.c + 1 + ..\..\..\components\finsh\msh_file.c + + + finsh_compiler.c + 1 + ..\..\..\components\finsh\finsh_compiler.c + + + finsh_error.c + 1 + ..\..\..\components\finsh\finsh_error.c + + + finsh_heap.c + 1 + ..\..\..\components\finsh\finsh_heap.c + + + finsh_init.c + 1 + ..\..\..\components\finsh\finsh_init.c + + + finsh_node.c + 1 + ..\..\..\components\finsh\finsh_node.c + + + finsh_ops.c + 1 + ..\..\..\components\finsh\finsh_ops.c + + + finsh_parser.c + 1 + ..\..\..\components\finsh\finsh_parser.c + + + finsh_var.c + 1 + ..\..\..\components\finsh\finsh_var.c + + + finsh_vm.c + 1 + ..\..\..\components\finsh\finsh_vm.c + + + finsh_token.c + 1 + ..\..\..\components\finsh\finsh_token.c + + + + + libc + + + libc.c + 1 + ..\..\..\components\libc\compilers\armlibc\libc.c + + + mem_std.c + 1 + ..\..\..\components\libc\compilers\armlibc\mem_std.c + + + stdio.c + 1 + ..\..\..\components\libc\compilers\armlibc\stdio.c + + + stubs.c + 1 + ..\..\..\components\libc\compilers\armlibc\stubs.c + + + time.c + 1 + ..\..\..\components\libc\compilers\common\time.c + + + + + Libraries + + + system_LPC55S69_cm33_core0.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\system_LPC55S69_cm33_core0.c + + + startup_LPC55S69_cm33_core0.s + 2 + ..\Libraries\LPC55S6X\LPC55S6X\arm\startup_LPC55S69_cm33_core0.s + + + fsl_anactrl.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_anactrl.c + + + fsl_casper.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_casper.c + + + fsl_clock.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_clock.c + + + fsl_cmp.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_cmp.c + + + fsl_common.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_common.c + + + fsl_crc.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_crc.c + + + fsl_ctimer.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_ctimer.c + + + fsl_flexcomm.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_flexcomm.c + + + fsl_dma.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_dma.c + + + fsl_gint.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_gint.c + + + fsl_gpio.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_gpio.c + + + fsl_hashcrypt.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_hashcrypt.c + + + fsl_i2c.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_i2c.c + + + fsl_i2c_dma.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_i2c_dma.c + + + fsl_i2s.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_i2s.c + + + fsl_i2s_dma.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_i2s_dma.c + + + fsl_iap.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_iap.c + + + fsl_inputmux.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_inputmux.c + + + fsl_lpadc.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_lpadc.c + + + fsl_mrt.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_mrt.c + + + fsl_ostimer.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_ostimer.c + + + fsl_pint.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_pint.c + + + fsl_plu.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_plu.c + + + fsl_power.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_power.c + + + fsl_powerquad_basic.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_powerquad_basic.c + + + fsl_prince.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_prince.c + + + fsl_puf.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_puf.c + + + fsl_reset.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_reset.c + + + fsl_rng.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_rng.c + + + fsl_rtc.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_rtc.c + + + fsl_sctimer.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_sctimer.c + + + fsl_sdif.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_sdif.c + + + fsl_spi.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_spi.c + + + fsl_spi_dma.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_spi_dma.c + + + fsl_sysctl.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_sysctl.c + + + fsl_usart.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_usart.c + + + fsl_usart_dma.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_usart_dma.c + + + fsl_utick.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_utick.c + + + fsl_wwdt.c + 1 + ..\Libraries\LPC55S6X\LPC55S6X\drivers\fsl_wwdt.c + + + fsl_sd.c + 1 + ..\Libraries\LPC55S6X\middleware\sdmmc\src\fsl_sd.c + + + fsl_sdmmc_common.c + 1 + ..\Libraries\LPC55S6X\middleware\sdmmc\src\fsl_sdmmc_common.c + + + fsl_sdmmc_event.c + 1 + ..\Libraries\LPC55S6X\middleware\sdmmc\port\sdif\rt_thread\fsl_sdmmc_event.c + + + fsl_sdmmc_host.c + 1 + ..\Libraries\LPC55S6X\middleware\sdmmc\port\sdif\rt_thread\fsl_sdmmc_host.c + + + arm_keil_lib_power_cm33_core0.lib + 4 + ..\Libraries\LPC55S6X\LPC55S6X\arm\keil_lib_power_cm33_core0.lib + + + + + + + + + + + + + +
-- Gitee From be4e2395ff7ac58ed188fc31a93353d74ed6deb6 Mon Sep 17 00:00:00 2001 From: Karl Zhang Date: Thu, 2 Jan 2020 14:42:30 +0800 Subject: [PATCH 032/110] LPC55S69: Update the flash layout to fit RTT in NS RTT fits in NS flash when enabled TF-M for secure. Change-Id: Icfd796b7fbe8fba76f713f9d5a14bbdcb5dcd9d5 Signed-off-by: Karl Zhang --- .../LPC55S69_cm33_core0_flash_ns_mdk.scf | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_ns_mdk.scf b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_ns_mdk.scf index bb14890505..e0ee619399 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_ns_mdk.scf +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/board/linker_scripts/LPC55S69_cm33_core0_flash_ns_mdk.scf @@ -14,6 +14,7 @@ ** ** Copyright 2016 Freescale Semiconductor, Inc. ** Copyright 2016-2018 NXP +** Copyright 2019-2020 Arm Limited. All rights reserved. ** All rights reserved. ** ** SPDX-License-Identifier: BSD-3-Clause @@ -46,23 +47,23 @@ #define Heap_Size 0x1000 #endif -#define m_interrupts_start 0x00000000 +#define m_interrupts_start 0x00020000 #define m_interrupts_size 0x00000200 -#define m_text_start 0x00000200 -#define m_text_size 0x00071E00 +#define m_text_start 0x00020200 +#define m_text_size 0x00031000 #define m_core1_image_start 0x00072000 #define m_core1_image_size 0x00026000 #if (defined(__use_shmem__)) - #define m_data_start 0x20000000 - #define m_data_size 0x00031800 - #define m_rpmsg_sh_mem_start 0x20031800 - #define m_rpmsg_sh_mem_size 0x00001800 + #define m_data_start 0x20033000 + #define m_data_size 0x00010800 + #define m_rpmsg_sh_mem_start 0x20043800 + #define m_rpmsg_sh_mem_size 0x00000800 #else - #define m_data_start 0x20000000 - #define m_data_size 0x00033000 + #define m_data_start 0x20033000 + #define m_data_size 0x0000cc00 #endif #define m_usb_sram_start 0x40100000 -- Gitee From 1b0b463bb2368897ec09ef3de31b39dd8921b8cc Mon Sep 17 00:00:00 2001 From: amy qian Date: Fri, 3 Jan 2020 16:52:07 +0800 Subject: [PATCH 033/110] =?UTF-8?q?=E5=A2=9E=E5=8A=A0Cypress=20PSoC6?= =?UTF-8?q?=E7=B3=BB=E5=88=97=E4=BA=A7=E5=93=81=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/cypress/psoc6-pioneerkit_modus/.cproject | 157 +++ ...oc6-pioneerkit_modus Attach (JLink).launch | 78 ++ ...-pioneerkit_modus Attach (KitProg3).launch | 59 + ...soc6-pioneerkit_modus Debug (JLink).launch | 80 ++ ...6-pioneerkit_modus Debug (KitProg3).launch | 63 + ...soc6-pioneerkit_modus Erase (JLink).launch | 78 ++ ...6-pioneerkit_modus Erase (KitProg3).launch | 59 + ...c6-pioneerkit_modus Program (JLink).launch | 80 ++ ...pioneerkit_modus Program (KitProg3).launch | 61 + bsp/cypress/psoc6-pioneerkit_modus/.project | 28 + .../.settings/language.settings.xml | 27 + bsp/cypress/psoc6-pioneerkit_modus/LICENSE | 210 +++ bsp/cypress/psoc6-pioneerkit_modus/Makefile | 183 +++ bsp/cypress/psoc6-pioneerkit_modus/README.md | 106 ++ .../applications/demo.c | 60 + .../applications/main.c | 58 + .../psoc6-pioneerkit_modus/drivers/board.c | 51 + .../psoc6-pioneerkit_modus/drivers/board.h | 21 + .../psoc6-pioneerkit_modus/drivers/uart.c | 350 +++++ .../psoc6-pioneerkit_modus/drivers/uart.h | 50 + .../cyreservedresources.list | 4 + .../design.cycapsense | 409 ++++++ .../COMPONENT_BSP_DESIGN_MODUS/design.cyqspi | 63 + .../COMPONENT_BSP_DESIGN_MODUS/design.modus | 288 +++++ .../TARGET_CY8CKIT-062-BLE/CY8CKIT-062-BLE.mk | 37 + .../libs/TARGET_CY8CKIT-062-BLE/EULA | 55 + .../libs/TARGET_CY8CKIT-062-BLE/LICENSE | 165 +++ .../libs/TARGET_CY8CKIT-062-BLE/README.md | 57 + .../libs/TARGET_CY8CKIT-062-BLE/RELEASE.md | 35 + .../libs/TARGET_CY8CKIT-062-BLE/cybsp.c | 124 ++ .../libs/TARGET_CY8CKIT-062-BLE/cybsp.h | 74 ++ .../libs/TARGET_CY8CKIT-062-BLE/cybsp_types.h | 279 ++++ .../TOOLCHAIN_ARM/cy8c6xx7_cm4_dual.sct | 274 ++++ .../TOOLCHAIN_A_Clang/cy8c6xx7_cm4_dual.mk | 85 ++ .../TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual.ld | 459 +++++++ .../TOOLCHAIN_IAR/cy8c6xx7_cm4_dual.icf | 240 ++++ .../TOOLCHAIN_ARM/startup_psoc6_01_cm4.s | 645 +++++++++ .../TOOLCHAIN_A_Clang/startup_psoc6_01_cm4.S | 554 ++++++++ .../TOOLCHAIN_GCC_ARM/startup_psoc6_01_cm4.S | 656 ++++++++++ .../TOOLCHAIN_IAR/startup_psoc6_01_cm4.s | 1150 +++++++++++++++++ .../startup/system_psoc6.h | 684 ++++++++++ .../startup/system_psoc6_cm4.c | 552 ++++++++ .../libs/psoc6make/EULA | 55 + .../libs/psoc6make/LICENSE | 165 +++ .../libs/psoc6make/README.md | 22 + .../libs/psoc6make/RELEASE.md | 39 + .../libs/psoc6make/make/core/build.mk | 694 ++++++++++ .../libs/psoc6make/make/core/config.mk | 235 ++++ .../libs/psoc6make/make/core/help.mk | 374 ++++++ .../libs/psoc6make/make/core/main.mk | 317 +++++ .../libs/psoc6make/make/core/open.mk | 126 ++ .../libs/psoc6make/make/core/search.mk | 158 +++ .../libs/psoc6make/make/core/target.mk | 79 ++ .../libs/psoc6make/make/core/utils.mk | 358 +++++ .../libs/psoc6make/make/recipe/defines.mk | 295 +++++ .../libs/psoc6make/make/recipe/program.mk | 104 ++ .../libs/psoc6make/make/recipe/recipe.mk | 202 +++ .../make/scripts/bin_to_resource_c.pl | 107 ++ .../make/scripts/eclipse/Attach (JLink).xml | 78 ++ .../scripts/eclipse/Attach (KitProg3).xml | 59 + .../make/scripts/eclipse/Debug (JLink).xml | 80 ++ .../make/scripts/eclipse/Debug (KitProg3).xml | 61 + .../make/scripts/eclipse/Erase (JLink).xml | 78 ++ .../make/scripts/eclipse/Erase (KitProg3).xml | 59 + .../make/scripts/eclipse/Program (JLink).xml | 80 ++ .../scripts/eclipse/Program (KitProg3).xml | 61 + .../libs/psoc6make/make/scripts/gdbinit | 32 + .../psoc6make/make/scripts/gdbinit_secure | 34 + .../psoc6make/make/scripts/genresources.bash | 177 +++ .../libs/psoc6make/make/scripts/memcalc.bash | 78 ++ .../make/scripts/resources_header.pl | 83 ++ .../make/scripts/text_to_resource_c.pl | 132 ++ .../vscode/c_cpp_properties_GCC_ARM.json | 71 + .../psoc6make/make/scripts/vscode/launch.json | 138 ++ .../psoc6make/make/scripts/vscode/openocd.tcl | 4 + .../make/scripts/vscode/settings.json | 5 + .../psoc6make/make/scripts/vscode/tasks.json | 325 +++++ .../libs/psoc6make/make/toolchains/ARM.mk | 168 +++ .../libs/psoc6make/make/toolchains/A_Clang.mk | 218 ++++ .../libs/psoc6make/make/toolchains/GCC_ARM.mk | 174 +++ .../libs/psoc6make/make/toolchains/IAR.mk | 187 +++ .../libs/psoc6make/make/udd/features.mk | 45 + .../libs/psoc6make/version.xml | 1 + .../psoc6-pioneerkit_modus/makefile.init | 2 + bsp/cypress/psoc6-pioneerkit_modus/rtconfig.h | 156 +++ 85 files changed, 14664 insertions(+) create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.cproject create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Attach (JLink).launch create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Attach (KitProg3).launch create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Debug (JLink).launch create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Debug (KitProg3).launch create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Erase (JLink).launch create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Erase (KitProg3).launch create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Program (JLink).launch create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Program (KitProg3).launch create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.project create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/.settings/language.settings.xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/LICENSE create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/Makefile create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/README.md create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/applications/demo.c create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/applications/main.c create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/drivers/board.c create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/drivers/board.h create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/drivers/uart.c create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/drivers/uart.h create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/cyreservedresources.list create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.cycapsense create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.cyqspi create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.modus create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/CY8CKIT-062-BLE.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/EULA create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/LICENSE create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/README.md create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/RELEASE.md create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp.c create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp.h create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp_types.h create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual.sct create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_A_Clang/cy8c6xx7_cm4_dual.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual.ld create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual.icf create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_ARM/startup_psoc6_01_cm4.s create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_A_Clang/startup_psoc6_01_cm4.S create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_GCC_ARM/startup_psoc6_01_cm4.S create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_IAR/startup_psoc6_01_cm4.s create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/system_psoc6.h create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/system_psoc6_cm4.c create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/EULA create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/LICENSE create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/README.md create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/RELEASE.md create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/build.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/config.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/help.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/main.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/open.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/search.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/target.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/utils.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/defines.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/program.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/recipe.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/bin_to_resource_c.pl create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Attach (JLink).xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Attach (KitProg3).xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Debug (JLink).xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Debug (KitProg3).xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Erase (JLink).xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Erase (KitProg3).xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Program (JLink).xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Program (KitProg3).xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/gdbinit create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/gdbinit_secure create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/genresources.bash create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/memcalc.bash create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/resources_header.pl create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/text_to_resource_c.pl create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/c_cpp_properties_GCC_ARM.json create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/launch.json create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/openocd.tcl create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/settings.json create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/tasks.json create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/ARM.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/A_Clang.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/GCC_ARM.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/IAR.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/udd/features.mk create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/version.xml create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/makefile.init create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/rtconfig.h diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.cproject b/bsp/cypress/psoc6-pioneerkit_modus/.cproject new file mode 100644 index 0000000000..fbb8aa3a9c --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.cproject @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Attach (JLink).launch b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Attach (JLink).launch new file mode 100644 index 0000000000..5a9b77907e --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Attach (JLink).launch @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Attach (KitProg3).launch b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Attach (KitProg3).launch new file mode 100644 index 0000000000..63fbcc50a1 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Attach (KitProg3).launch @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Debug (JLink).launch b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Debug (JLink).launch new file mode 100644 index 0000000000..5280966cf9 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Debug (JLink).launch @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Debug (KitProg3).launch b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Debug (KitProg3).launch new file mode 100644 index 0000000000..8ca00070b2 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Debug (KitProg3).launch @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Erase (JLink).launch b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Erase (JLink).launch new file mode 100644 index 0000000000..86a77fd136 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Erase (JLink).launch @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Erase (KitProg3).launch b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Erase (KitProg3).launch new file mode 100644 index 0000000000..712c974380 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Erase (KitProg3).launch @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Program (JLink).launch b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Program (JLink).launch new file mode 100644 index 0000000000..7469c742e9 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Program (JLink).launch @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Program (KitProg3).launch b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Program (KitProg3).launch new file mode 100644 index 0000000000..0e5bbc11ec --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.mtbLaunchConfigs/psoc6-pioneerkit_modus Program (KitProg3).launch @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.project b/bsp/cypress/psoc6-pioneerkit_modus/.project new file mode 100644 index 0000000000..e9e2cefe65 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.project @@ -0,0 +1,28 @@ + + + psoc6-pioneerkit_modus + + + + + + 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.core.ccnature + com.cypress.studio.app.cymodusnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/.settings/language.settings.xml b/bsp/cypress/psoc6-pioneerkit_modus/.settings/language.settings.xml new file mode 100644 index 0000000000..6fdfc52492 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/.settings/language.settings.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/LICENSE b/bsp/cypress/psoc6-pioneerkit_modus/LICENSE new file mode 100644 index 0000000000..91c81ad20b --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/LICENSE @@ -0,0 +1,210 @@ +CYPRESS END USER LICENSE AGREEMENT + +PLEASE READ THIS END USER LICENSE AGREEMENT ("Agreement") CAREFULLY BEFORE +DOWNLOADING, INSTALLING, COPYING, OR USING THIS SOFTWARE AND ACCOMPANYING +DOCUMENTATION. BY DOWNLOADING, INSTALLING, COPYING OR USING THE SOFTWARE, +YOU ARE AGREEING TO BE BOUND BY THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL +OF THE TERMS OF THIS AGREEMENT, PROMPTLY RETURN AND DO NOT USE THE SOFTWARE. +IF YOU HAVE PURCHASED THIS LICENSE TO THE SOFTWARE, YOUR RIGHT TO RETURN THE +SOFTWARE EXPIRES 30 DAYS AFTER YOUR PURCHASE AND APPLIES ONLY TO THE ORIGINAL +PURCHASER. + +1. Definitions. + + "Software" means this software and any accompanying documentation, + including any upgrades, updates, bug fixes or modified versions provided + to you by Cypress. + + "Source Code" means software in human-readable form. + + "Binary Code" means the software in binary code form such as object code or + an executable. + + "Development Tools" means software that is intended to be installed on a + personal computer and used to create programming code for Firmware, + Drivers, or Host Applications. Examples of Development Tools are + Cypress's PSoC Creator software, Cypress's WICED SDKs, and Cypress's + ModusToolbox software. + + "Firmware" means software that executes on a Cypress hardware product. + + "Driver" means software that enables the use of a Cypress hardware product + on a particular host operating system such as GNU/Linux, Windows, MacOS, + Android, and iOS. + + "Host Application" means software that executes on a device other than a + Cypress hardware product in order to program, control, or communicate + with a Cypress hardware product. + + "inf File" means a hardware setup information file (.inf file) created by + the Software to allow a Microsoft Windows operating system to install + the driver for a Cypress hardware product. + +2. License. Subject to the terms and conditions of this Agreement, Cypress +Semiconductor Corporation ("Cypress") and its suppliers grant to you a +non-exclusive, non-transferable license under their copyright rights: + + a. to use the Development Tools in object code form solely for the purpose + of creating Firmware, Drivers, Host Applications, and inf Files for + Cypress hardware products; and + + b. (i) if provided in Source Code form, to copy, modify, and compile the + Firmware Source Code to create Firmware for execution on a Cypress + hardware product, and + (ii) to distribute Firmware in binary code form only, only when + installed onto a Cypress hardware product; and + + c. (i) if provided in Source Code form, to copy, modify, and compile the + Driver Source Code to create one or more Drivers to enable the use + of a Cypress hardware product on a particular host operating + system, and + (ii) to distribute the Driver, in binary code form only, only when + installed on a device that includes the Cypress hardware product + that the Driver is intended to enable; and + + d. (i) if provided in Source Code form, to copy, modify, and compile the + Host Application Source Code to create one or more Host + Applications to program, control, or communicate with a Cypress + hardware product, and + (ii) to distribute Host Applications, in binary code form only, only + when installed on a device that includes a Cypress hardware product + that the Host Application is intended to program, control, or + communicate with; and + + e. to freely distribute any inf File. + +Any distribution of Software permitted under this Agreement must be made +pursuant to your standard end user license agreement used for your proprietary +(closed source) software products, such end user license agreement to include, +at a minimum, provisions limiting your licensors' liability and prohibiting +reverse engineering of the Software, consistent with such provisions in this +Agreement. + +3. Free and Open Source Software. Portions of the Software may be licensed +under free and/or open source licenses such as the GNU General Public License +or other licenses from third parties ("Third Party Software"). Third Party +Software is subject to the applicable license agreement and not this +Agreement. If you are entitled to receive the source code from Cypress for +any Third Party Software included with the Software, either the source code +will be included with the Software or you may obtain the source code at no +charge from . The applicable license +terms will accompany each source code package. To review the license terms +applicable to any Third Party Software for which Cypress is not required to +provide you with source code, please see the Software's installation directory +on your computer. + +4. Proprietary Rights; Ownership. The Software, including all intellectual +property rights therein, is and will remain the sole and exclusive property of +Cypress or its suppliers. Cypress retains ownership of the Source Code and +any compiled version thereof. Subject to Cypress' ownership of the underlying +Software (including Source Code), you retain ownership of any modifications +you make to the Source Code. You agree not to remove any Cypress copyright or +other notices from the Source Code and any modifications thereof. You agree +to keep the Source Code confidential. Any reproduction, modification, +translation, compilation, or representation of the Source Code except as +permitted in Section 2 ("License") is prohibited without the express written +permission of Cypress. Except as otherwise expressly provided in this +Agreement, you may not: + (i) modify, adapt, or create derivative works based upon the Software; + (ii) copy the Software; + (iii) except and only to the extent explicitly permitted by applicable + law despite this limitation, decompile, translate, reverse engineer, + disassemble or otherwise reduce the Software to human-readable form; + or + (iv) use the Software or any sample code other than for the Purpose. +You hereby covenant that you will not assert any claim that the Software, or +derivative works thereof created by or for Cypress, infringe any intellectual +property right owned or controlled by you + +5. No Support. Cypress may, but is not required to, provide technical support +for the Software. + +6. Term and Termination. This Agreement is effective until terminated, and +either party may terminate this Agreement at any time with or without cause. +This Agreement and your license rights under this Agreement will terminate +immediately without notice from Cypress if you fail to comply with any +provision of this Agreement. Upon termination, you must destroy all copies of +Software in your possession or control. The following paragraphs shall +survive any termination of this Agreement: "Free and Open Source Software," +"Proprietary Rights; Ownership," "Compliance With Law," "Disclaimer," +"Limitation of Liability," and "General." + +7. Compliance With Law. Each party agrees to comply with all applicable laws, +rules and regulations in connection with its activities under this Agreement. +Without limiting the foregoing, the Software may be subject to export control +laws and regulations of the United States and other countries. You agree to +comply strictly with all such laws and regulations and acknowledge that you +have the responsibility to obtain licenses to export, re-export, or import the +Software. + +8. Disclaimer. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, CYPRESS +MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THE +SOFTWARE, INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress +reserves the right to make changes to the Software without notice. Cypress +does not assume any liability arising out of the application or use of +Software or any product or circuit described in the Software. It is the +responsibility of the user of the Software to properly design, program, and +test the functionality and safety of any application made of the Software and +any resulting product. Cypress does not authorize its Software or products +for use in any products where a malfunction or failure of the Software or +Cypress product may reasonably be expected to result in significant property +damage, injury or death ("High Risk Product"). If you include any Software or +Cypress product in a High Risk Product, you assume all risk of such use and +agree to indemnify Cypress and its suppliers against all liability. No +computing device can be absolutely secure. Therefore, despite security +measures implemented in Cypress hardware or software products, Cypress does +not assume any liability arising out of any security breach, such as +unauthorized access to or use of a Cypress product. + +9. Limitation of Liability. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE +LAW, IN NO EVENT WILL CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS BE +LIABLE FOR ANY LOST REVENUE, PROFIT, OR DATA, OR FOR SPECIAL, INDIRECT, +CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS +OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR +INABILITY TO USE THE SOFTWARE EVEN IF CYPRESS OR ITS SUPPLIERS, RESELLERS, OR +DISTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO +EVENT SHALL CYPRESS' OR ITS SUPPLIERS', RESELLERS', OR DISTRIBUTORS' TOTAL +LIABILITY TO YOU, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), OR +OTHERWISE, EXCEED THE GREATER OF US$500 OR THE PRICE PAID BY YOU FOR THE +SOFTWARE. THE FOREGOING LIMITATIONS SHALL APPLY EVEN IF THE ABOVE-STATED +WARRANTY FAILS OF ITS ESSENTIAL PURPOSE. BECAUSE SOME STATES OR JURISDICTIONS +DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, +ALL OR PORTIONS OF THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + +10. Restricted Rights. The Software is commercial computer software as that +term is described in 48 C.F.R. 252.227-7014(a)(1). If the Software is being +acquired by or on behalf of the U.S. Government or by a U.S. Government prime +contractor or subcontractor (at any tier), then the Government's rights in +Software shall be only those set forth in this Agreement. + +11. Personal Information. You agree that information you provide through your +registration on Cypress IoT Community Forum or other Cypress websites, +including contact information or other personal information, may be collected +and used by Cypress consistent with its Data Privacy Policy +(www.cypress.com/privacy-policy), as updated or revised from time to time, and +may be provided to its third party sales representatives, distributors and +other entities conducting sales activities for Cypress for sales-related and +other business purposes. + +12. General. This Agreement will bind and inure to the benefit of each +party's successors and assigns, provided that you may not assign or transfer +this Agreement, in whole or in part, without Cypress' written consent. This +Agreement shall be governed by and construed in accordance with the laws of +the State of California, United States of America, as if performed wholly +within the state and without giving effect to the principles of conflict of +law. The parties consent to personal and exclusive jurisdiction of and venue +in, the state and federal courts within Santa Clara County, California; +provided however, that nothing in this Agreement will limit Cypress' right to +bring legal action in any venue in order to protect or enforce its +intellectual property rights. No failure of either party to exercise or +enforce any of its rights under this Agreement will act as a waiver of such +rights. If any portion of this Agreement is found to be void or +unenforceable, the remaining provisions of this Agreement shall remain in full +force and effect. This Agreement is the complete and exclusive agreement +between the parties with respect to the subject matter hereof, superseding and +replacing any and all prior agreements, communications, and understandings +(both written and oral) regarding such subject matter. Any notice to Cypress +will be deemed effective when actually received and must be sent to Cypress +Semiconductor Corporation, ATTN: Chief Legal Officer, 198 Champion Court, San +Jose, CA 95134 USA. diff --git a/bsp/cypress/psoc6-pioneerkit_modus/Makefile b/bsp/cypress/psoc6-pioneerkit_modus/Makefile new file mode 100644 index 0000000000..61a750c0c1 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/Makefile @@ -0,0 +1,183 @@ +################################################################################ +# \file Makefile +# \version 1.0 +# +# \brief +# Top-level application make file. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + + +################################################################################ +# Basic Configuration +################################################################################ + +# Target board/hardware +TARGET=CY8CKIT-062-BLE +# Name of application (used to derive name of final linked file). +APPNAME=mtb-example-psoc6-empty-app + +# Name of toolchain to use. Options include: +# +# GCC_ARM -- GCC 7.2.1, provided with ModusToolbox IDE +# ARM -- ARM Compiler (must be installed separately) +# IAR -- IAR Compiler (must be installed separately) +# +# See also: CY_COMPILER_PATH below +TOOLCHAIN=GCC_ARM + +# Default build configuration. Options include: +# +# Debug -- build with minimal optimizations, focus on debugging. +# Release -- build with full optimizations +CONFIG=Debug + +# If set to "true" or "1", display full command-lines when building. +VERBOSE= + +# RT-Thread root directory +RTT_ROOT_DIR=../../../ + +################################################################################ +# Advanced Configuration +################################################################################ + +# Enable optional code that is ordinarily disabled by default. +# +# Available components depend on the specific targeted hardware and firmware +# in use. In general, if you have +# +# COMPONENTS=foo bar +# +# ... then code in directories named COMPONENT_foo and COMPONENT_bar will be +# added to the build +# +COMPONENTS= + +# Like COMPONENTS, but disable optional code that was enabled by default. +DISABLE_COMPONENTS= + +# By default the build system automatically looks in the Makefile's directory +# tree for source code and builds it. The SOURCES variable can be used to +# manually add source code to the build process from a location not searched +# by default, or otherwise not found by the build system. +SOURCES=$(wildcard $(RTT_ROOT_DIR)/libcpu/arm/cortex-m4/*.c) \ + $(wildcard $(RTT_ROOT_DIR)/libcpu/arm/common/*.c) \ + $(wildcard $(RTT_ROOT_DIR)/src/*.c) \ + $(wildcard $(RTT_ROOT_DIR)/components/drivers/src/*.c) \ + $(wildcard $(RTT_ROOT_DIR)/components/drivers/serial/*.c) \ + $(wildcard $(RTT_ROOT_DIR)/components/finsh/*.c) +ifeq ($(TOOLCHAIN),GCC_ARM) + SOURCES+=$(RTT_ROOT_DIR)/libcpu/arm/cortex-m4/context_gcc.S +else ifeq ($(TOOLCHAIN),ARM) + SOURCES+=$(RTT_ROOT_DIR)/libcpu/arm/cortex-m4/context_rvds.S +else + SOURCES+=$(RTT_ROOT_DIR)/libcpu/arm/cortex-m4/context_iar.S +endif + +# Like SOURCES, but for include directories. Value should be paths to +# directories (without a leading -I). +INCLUDES=$(RTT_ROOT_DIR)/include/ \ + $(RTT_ROOT_DIR)/components/finsh/ \ + $(RTT_ROOT_DIR)/components/drivers/include/ + +# Add additional defines to the build process (without a leading -D). +DEFINES=HAVE_SIGVAL HAVE_SIGEVENT HAVE_SIGINFO RT_USING_NEWLIB + +# Select softfp or hardfp floating point. Default is softfp. +VFP_SELECT=hardfp + +# Additional / custom C compiler flags. +# +# NOTE: Includes and defines should use the INCLUDES and DEFINES variable +# above. +CFLAGS= + +# Additional / custom C++ compiler flags. +# +# NOTE: Includes and defines should use the INCLUDES and DEFINES variable +# above. +CXXFLAGS= + +# Additional / custom assembler flags. +# +# NOTE: Includes and defines should use the INCLUDES and DEFINES variable +# above. +ASFLAGS=-mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wa,-mimplicit-it=always + +# Additional / custom linker flags. +LDFLAGS= + +# Additional / custom libraries to link in to the application. +LDLIBS= + +# Path to the linker script to use (if empty, use the default linker script). +LINKER_SCRIPT= + +# Custom pre-build commands to run. +PREBUILD= + +# Custom post-build commands to run. +POSTBUILD= + + +################################################################################ +# Paths +################################################################################ + +# Relative path to the project directory (default is the Makefile's directory). +# +# This controls where automatic source code discovery looks for code. +CY_APP_PATH= + +# Relative path to the "base" library. It provides the core makefile build +# infrastructure. +CY_BASELIB_PATH=libs/psoc6make + +# Absolute path to the compiler's "bin" directory. +# +# The default depends on the selected TOOLCHAIN (GCC_ARM uses the ModusToolbox +# IDE provided compiler by default). +CY_COMPILER_PATH= + + +# Locate ModusToolbox IDE helper tools folders in default installation +# locations for Windows, Linux, and macOS. +CY_WIN_HOME=$(subst \,/,$(USERPROFILE)) +CY_TOOLS_PATHS ?= $(wildcard \ + $(CY_WIN_HOME)/ModusToolbox/tools_* \ + $(HOME)/ModusToolbox/tools_* \ + /Applications/ModusToolbox/tools_*) + +# If you install ModusToolbox IDE in a custom location, add the path to its +# "tools_X.Y" folder (where X and Y are the version number of the tools +# folder). +CY_TOOLS_PATHS+= + +# Default to the newest installed tools folder, or the users override (if it's +# found). +CY_TOOLS_DIR=$(lastword $(sort $(wildcard $(CY_TOOLS_PATHS)))) + +ifeq ($(CY_TOOLS_DIR),) +$(error Unable to find any of the available CY_TOOLS_PATHS -- $(CY_TOOLS_PATHS)) +endif + +$(info Tools Directory: $(CY_TOOLS_DIR)) + +include $(CY_TOOLS_DIR)/make/start.mk diff --git a/bsp/cypress/psoc6-pioneerkit_modus/README.md b/bsp/cypress/psoc6-pioneerkit_modus/README.md new file mode 100644 index 0000000000..bc3ba2803e --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/README.md @@ -0,0 +1,106 @@ +# Cypress CY8CKIT-062-BLE PSoC 6 BLE Pioneer Kit 说明 + +## 简介 + +本文档为Cypress为PSoC6 BLE Pioneer Kit开发板提供的 BSP (板级支持包) 说明。 + +主要内容如下: + +- 开发板资源介绍 +- BSP 快速上手 +- 进阶使用方法 + +通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。在进阶使用指南章节,将会介绍更多高级功能,帮助开发者利用 RT-Thread 驱动更多板载资源。 + +## 开发板介绍 + +CY8CKIT-062-BLE PSoC6 BLE Pioneer Kit 是赛普拉斯推出的一款32位双核CPU子系统( ARM Cortex-M4 和 ARM Cortex-M0)的开发板,具有单周期乘法的150-MHz Arm Cortex-M4F CPU (浮点和 +存储器保护单元),100-MHz Cortex M0+ CPU,带单周期乘法和MPU,可以充分发挥 PSoC6 双核芯片性能。 + +开发板外观详细信息:https://www.cypress.com/file/390496/download + + +该开发板常用 **板载资源** 如下: + +- MCU:CY8C6347BZI-BLD53,Cortex-M4主频 150MHz,Cortex-M0主频 100MHz,1 MB 应用闪存,32 KB EEPROM 区域和32 KB 安全闪存 ,288 KB 集成SRAM + MCU手册更多详细信息请参考文档 https://www.cypress.com/file/457541/download + +- 开发环境:ModusToolbox 2.0 + PSoC® Creator™ 下载链接 https://www.cypress.com/products/modustoolbox-software-environment + +- 开发板:CY8CKIT-062-BLE PSoC 6 BLE Pioneer Kit + 开发板更多详细信息请参考文档 https://www.cypress.com/file/390496/download + + +## 外设支持 + +本 BSP 目前对外设的支持情况如下: + +开发板更多详细信息请参考文档 https://www.cypress.com/file/390496/download + +## 使用说明 + +使用说明分为如下两个章节: + +- 快速上手 + + 本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。 + +- 进阶使用 + + 本章节是为需要在 RT-Thread 操作系统上使用赛普拉斯开发板资源的开发者准备的。 + + +### 快速上手 + +本 BSP 以 ModusToolbox 2.0开发环境(GCC),介绍如何将系统运行起来。 + +#### 硬件连接 + +使用Type-C数据线连接开发板到 PC. + +#### 编译下载 +1, 安装ModusToolbox 2.0时请使用默认路径 + +2, 打开ModusToolbox 2.0时workspace选择工程所在目录下(例如workspace: C:\Git\rt-thread\bsp\cypress) + +3, 在Project Explorer的空白处右键,点击import,General->Existing Projects into Workspace ->next,点击Browse选择 + 此BSP所在目录加载工程->Finish + +4, 下载lib:在左下角Quick Panel的Tools栏,点击library Manager-> BSPs下面勾选CY8CKIT-062-BLE (若已勾选可以不用再选) + -> Libraries里PSoC6 Base Libraries下面全部勾选core-lib,psoc6cm0p,psoc6hal,psoc6make,psoc6pdl -> 点击apply 进行下载 + +5, 编译此工程 + +6, 下载此工程 + + +工程默认配置使用 SWD方式下载程序,Type-C数据线连接开发板,编译之后直接点击下载按钮即可。 + +#### 运行结果 + +下载程序成功之后,系统会自动运行。打开终端工具串口小助手,复位设备后,可以看到 RT-Thread 的输出信息: + +注:推荐使用串口调试助手如:sscom + + msh > + \ | / + - RT - Thread Operating System + / | \ 4.0.3 build Jan 3 2020 + 2006 - 2019 Copyright by rt-thread team + thread1 created ok + thread1 count: 0 + thread2 created ok + thread2 count: 0 + thread2 count: 1 + thread2 count: 2 + thread2 count: 3 + thread1 count: 1 + thread2 count: 4 + + +## 联系人信息 + +维护人: + +- [amyqian379](https://github.com/amyqian379) \ No newline at end of file diff --git a/bsp/cypress/psoc6-pioneerkit_modus/applications/demo.c b/bsp/cypress/psoc6-pioneerkit_modus/applications/demo.c new file mode 100644 index 0000000000..84e37aedd7 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/applications/demo.c @@ -0,0 +1,60 @@ + +#include +#include "board.h" +#include "cybsp.h" +#include "cy_device_headers.h" +#ifdef RT_USING_FINSH +#include +#include +#endif + + +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; + + +static void thread1_entry(void* parameter) +{ + rt_uint32_t count = 0; + parameter = parameter; + + rt_kprintf("thread1 created ok\n"); + while (1) + { + rt_kprintf("thread1 count: %d\n",count++); + rt_thread_delay(RT_TICK_PER_SECOND); + + } +} + +static void thread2_entry(void* parameter) +{ + rt_uint32_t count = 0; + parameter = parameter; + + rt_kprintf("thread2 created ok\n"); + while(1) + { + rt_kprintf("thread2 count: %d\n",count++); + rt_thread_delay(RT_TICK_PER_SECOND/4); + + } + + rt_thread_delay(RT_TICK_PER_SECOND * 4); + rt_thread_delete(tid1); + rt_kprintf("thread1 deleted ok\n"); +} + +int demo_init(void) +{ + tid1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 512, 6, 10); + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + + tid2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 512, 6, 10); + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + + return 0; +} + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/applications/main.c b/bsp/cypress/psoc6-pioneerkit_modus/applications/main.c new file mode 100644 index 0000000000..99008c8326 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/applications/main.c @@ -0,0 +1,58 @@ +/****************************************************************************** +* File Name: main.c +* +* Description: This is the source code for the Empty PSoC6 Application +* for ModusToolbox. +* +* Related Document: See Readme.md +* +* +******************************************************************************* +* (c) 2019, Cypress Semiconductor Corporation. All rights reserved. +******************************************************************************* +* This software, including source code, documentation and related materials +* ("Software"), is owned by Cypress Semiconductor Corporation or one of its +* subsidiaries ("Cypress") and is protected by and subject to worldwide patent +* protection (United States and foreign), United States copyright laws and +* international treaty provisions. Therefore, you may use this Software only +* as provided in the license agreement accompanying the software package from +* which you obtained this Software ("EULA"). +* +* If no EULA applies, Cypress hereby grants you a personal, non-exclusive, +* non-transferable license to copy, modify, and compile the Software source +* code solely for use in connection with Cypress's integrated circuit products. +* Any reproduction, modification, translation, compilation, or representation +* of this Software except as specified above is prohibited without the express +* written permission of Cypress. +* +* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress +* reserves the right to make changes to the Software without notice. Cypress +* does not assume any liability arising out of the application or use of the +* Software or any product or circuit described in the Software. Cypress does +* not authorize its products for use in any products where a malfunction or +* failure of the Cypress product may reasonably be expected to result in +* significant property damage, injury or death ("High Risk Product"). By +* including Cypress's product in a High Risk Product, the manufacturer of such +* system or application assumes all risk of such use and in doing so agrees to +* indemnify Cypress against all liability. +*******************************************************************************/ + +#include "cy_pdl.h" +#include "cycfg.h" +#include "cy_device_headers.h" +#include "cycfg_peripherals.h" + +extern int demo_init(void); +int main(void) +{ + demo_init(); + + for(;;) + { + + } +} + +/* [] END OF FILE */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/drivers/board.c b/bsp/cypress/psoc6-pioneerkit_modus/drivers/board.c new file mode 100644 index 0000000000..00b6607a7f --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/drivers/board.c @@ -0,0 +1,51 @@ + +#include +#include +#include +#include "cy_device_headers.h" +#include "board.h" +#include "uart.h" +#include "cy_systick.h" +#include "cycfg.h" + +#define configTOTAL_HEAP_SIZE (24*1024) +/* Allocate the memory for the heap. */ +ALIGN(RT_ALIGN_SIZE) +static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +/** + * This is the timer interrupt service routine. + * + */ +void SysTick_Handler_CB(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + + +void rt_hw_board_init() +{ + /* init systick */ + init_cycfg_all(); + + SystemCoreClockUpdate(); + + Cy_SysTick_Init(CY_SYSTICK_CLOCK_SOURCE_CLK_CPU, SystemCoreClock/RT_TICK_PER_SECOND); + Cy_SysTick_SetCallback(0, SysTick_Handler_CB); + Cy_SysTick_EnableInterrupt(); + + rt_system_heap_init((void*)ucHeap, (void*)(ucHeap+configTOTAL_HEAP_SIZE)); + /* initialize UART device */ + rt_hw_uart_init(); + +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif +} + +/*@}*/ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/drivers/board.h b/bsp/cypress/psoc6-pioneerkit_modus/drivers/board.h new file mode 100644 index 0000000000..54fb261397 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/drivers/board.h @@ -0,0 +1,21 @@ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="HEAP" +#define HEAP_BEGIN (__segment_end("HEAP")) +#else +extern unsigned int __end__; +extern unsigned int __HeapLimit; +#define HEAP_BEGIN (void*)&__end__ +#define HEAP_END (void*)&__HeapLimit +#endif + +void rt_hw_board_init(void); + +#endif + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/drivers/uart.c b/bsp/cypress/psoc6-pioneerkit_modus/drivers/uart.c new file mode 100644 index 0000000000..54ba921ed9 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/drivers/uart.c @@ -0,0 +1,350 @@ +#include +#include "uart.h" +#include "cycfg_peripherals.h" +/** + * @addtogroup + */ +/*@{*/ + +/* RT-Thread Device Interface */ +/** + * This function initializes uart + */ +static rt_err_t rt_uart_init (rt_device_t dev) +{ + struct uart_device* uart = (struct uart_device*) dev->user_data; + + if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) + { + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + rt_memset(uart->int_rx->rx_buffer, 0, + sizeof(uart->int_rx->rx_buffer)); + uart->int_rx->read_index = uart->int_rx->save_index = 0; + } + + if (dev->flag & RT_DEVICE_FLAG_INT_TX) + { + rt_memset(uart->int_tx->tx_buffer, 0, + sizeof(uart->int_tx->tx_buffer)); + uart->int_tx->write_index = uart->int_tx->save_index = 0; + } + + dev->flag |= RT_DEVICE_FLAG_ACTIVATED; + } + + return RT_EOK; +} + +/* save a char to uart buffer */ +static void rt_uart_savechar(struct uart_device* uart, char ch) +{ + rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch; + uart->int_rx->save_index ++; + if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE) + uart->int_rx->save_index = 0; + + /* if the next position is read index, discard this 'read char' */ + if (uart->int_rx->save_index == uart->int_rx->read_index) + { + uart->int_rx->read_index ++; + if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) + uart->int_rx->read_index = 0; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); +} + +static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag) +{ + struct uart_device* uart; + oflag = oflag; + + RT_ASSERT(dev != RT_NULL); + uart = (struct uart_device*) dev->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* enable interrupt */ + UART_ENABLE_IRQ(uart->rx_irq); + } + + return RT_EOK; +} + +static rt_err_t rt_uart_close(rt_device_t dev) +{ + struct uart_device* uart; + + RT_ASSERT(dev != RT_NULL); + uart = (struct uart_device*) dev->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* disable interrupt */ + UART_DISABLE_IRQ(uart->rx_irq); + } + + return RT_EOK; +} + +static rt_size_t rt_uart_read (rt_device_t dev, rt_off_t pos, void* buffer, + rt_size_t size) +{ + rt_uint8_t* ptr; + rt_err_t err_code; + struct uart_device* uart; + pos = pos; + + ptr = buffer; + err_code = RT_EOK; + uart = (struct uart_device*)dev->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + rt_base_t level; + + /* interrupt mode Rx */ + while (size) + { + if (uart->int_rx->read_index != uart->int_rx->save_index) + { + *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index]; + size --; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + uart->int_rx->read_index ++; + if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) + uart->int_rx->read_index = 0; + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + } + else + { + /* set error code */ + err_code = -RT_EEMPTY; + break; + } + } + } + else + { + /* polling mode */ + while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) + { + while (0UL != Cy_SCB_UART_GetNumInRxFifo(uart->scb_device)) + { + *ptr = Cy_SCB_UART_Get(uart->scb_device); + ptr ++; + } + } + } + + /* set error code */ + rt_set_errno(err_code); + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; +} + +static rt_size_t rt_uart_write (rt_device_t dev, rt_off_t pos, + const void* buffer, rt_size_t size) +{ + rt_uint8_t* ptr; + rt_err_t err_code; + struct uart_device* uart; + pos = pos; + + err_code = RT_EOK; + ptr = (rt_uint8_t*)buffer; + uart = (struct uart_device*)dev->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_TX) + { + /* interrupt mode Tx */ + while (uart->int_tx->save_index != uart->int_tx->write_index) + { + /* save on tx buffer */ + uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++; + + -- size; + + /* move to next position */ + uart->int_tx->save_index ++; + + /* wrap save index */ + if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE) + uart->int_tx->save_index = 0; + } + + /* set error code */ + if (size > 0) + err_code = -RT_EFULL; + } + else + { + /* polling mode */ + while (size) + { + /* + * to be polite with serial console add a line feed + * to the carriage return character + */ + if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM)) + { + while(0 == Cy_SCB_UART_Put(uart->scb_device, '\r')); + } + while(0 == Cy_SCB_UART_Put(uart->scb_device, (*ptr & 0x1FF))); + + ++ptr; + --size; + } + } + + /* set error code */ + rt_set_errno(err_code); + + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; +} + +static rt_err_t rt_uart_control (rt_device_t dev, int cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + args = args; + + switch (cmd) + { + case RT_DEVICE_CTRL_SUSPEND: + /* suspend device */ + dev->flag |= RT_DEVICE_FLAG_SUSPENDED; + break; + + case RT_DEVICE_CTRL_RESUME: + /* resume device */ + dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; + break; + } + + return RT_EOK; +} + +/* + * serial register + */ +rt_err_t rt_hw_uart_register(rt_device_t device, const char* name, + rt_uint32_t flag, struct uart_device *serial) +{ + RT_ASSERT(device != RT_NULL); + + device->type = RT_Device_Class_Char; + device->rx_indicate = RT_NULL; + device->tx_complete = RT_NULL; + device->init = rt_uart_init; + device->open = rt_uart_open; + device->close = rt_uart_close; + device->read = rt_uart_read; + device->write = rt_uart_write; + device->control = rt_uart_control; + device->user_data = serial; + + /* register a character device */ + return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); +} + +/* ISR for uart interrupt */ +void rt_hw_uart_isr(rt_device_t device) +{ + struct uart_device* uart = (struct uart_device*) device->user_data; + + /* interrupt mode receive */ + RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX); + + /* Check for "RX fifo not empty interrupt" */ + if((uart->scb_device->INTR_RX_MASKED & SCB_INTR_RX_MASKED_NOT_EMPTY_Msk ) != 0) + { + /* Clear UART "RX fifo not empty interrupt" */ + uart->scb_device->INTR_RX = uart->scb_device->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk; + /* Get the character from terminal */ + rt_uart_savechar(uart, Cy_SCB_UART_Get(uart->scb_device)); + } + + /* invoke callback */ + if (device->rx_indicate != RT_NULL) + { + rt_size_t rx_length; + + /* get rx length */ + rx_length = uart->int_rx->read_index > uart->int_rx->save_index ? + UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index : + uart->int_rx->save_index - uart->int_rx->read_index; + + device->rx_indicate(device, rx_length); + } +} + +#ifdef RT_USING_UART0 +/* UART0 device driver structure */ +#define UART0_SCB_IRQ__INTC_NUMBER 46u +cy_stc_scb_uart_context_t UART0_context; +const cy_stc_sysint_t UART0_SCB_IRQ_cfg = +{ + .intrSrc = scb_5_interrupt_IRQn, + .intrPriority = 3u, +}; + +/* UART0 device driver structure */ +struct uart_int_rx uart0_int_rx; +struct uart_device uart0 = +{ + UART0_HW, + &UART0_config, + &UART0_context, + &UART0_SCB_IRQ_cfg, + (IRQn_Type)UART0_SCB_IRQ__INTC_NUMBER, + (IRQn_Type)UART0_SCB_IRQ__INTC_NUMBER, + &uart0_int_rx, + RT_NULL +}; +struct rt_device uart0_device; +/* UART0 Interrupt Hanlder */ +void uart0_isr_callback(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + rt_hw_uart_isr(&uart0_device); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif + + +void rt_hw_uart_init(void) +{ + /* Start UART operation. */ + if(Cy_SCB_UART_Init(uart0.scb_device, uart0.uart_config, uart0.uart_context) != CY_SCB_UART_SUCCESS) + { + rt_assert_handler("UART0 init", __FUNCTION__, __LINE__); + } + Cy_SCB_UART_Enable(uart0.scb_device); + /* Unmasking only the RX fifo not empty interrupt bit */ + uart0.scb_device->INTR_RX_MASK = SCB_INTR_RX_MASK_NOT_EMPTY_Msk; + /* Interrupt Settings for UART */ + Cy_SysInt_Init(uart0.uart_int, uart0_isr_callback); + /* Enable the interrupt */ + NVIC_EnableIRQ(uart0.uart_int->intrSrc); + /* register UART0 device */ + rt_hw_uart_register(&uart0_device, + "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + &uart0); + +} + +/*@}*/ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/drivers/uart.h b/bsp/cypress/psoc6-pioneerkit_modus/drivers/uart.h new file mode 100644 index 0000000000..9a2c6dd3bf --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/drivers/uart.h @@ -0,0 +1,50 @@ + +#ifndef __UART_H__ +#define __UART_H__ + +#include +#include +#include "cy_device_headers.h" +#include "board.h" +#include "cy_pdl.h" + +#define UART_RX_BUFFER_SIZE 128u +#define UART_TX_BUFFER_SIZE 128u + +#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) +#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) + +struct uart_int_rx +{ + rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE]; + rt_uint32_t read_index, save_index; +}; + +struct uart_int_tx +{ + rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE]; + rt_uint32_t write_index, save_index; +}; + +struct uart_device +{ + CySCB_Type* scb_device; + /* uart config */ + cy_stc_scb_uart_config_t const *uart_config; + /* uart context */ + cy_stc_scb_uart_context_t *uart_context; + /* uart interrupt */ + const cy_stc_sysint_t *uart_int; + /* irq number */ + IRQn_Type rx_irq; + IRQn_Type tx_irq; + + /* rx structure */ + struct uart_int_rx* int_rx; + /* tx structure */ + struct uart_int_tx* int_tx; +}; + +void rt_hw_uart_init(void); + +#endif diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/cyreservedresources.list b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/cyreservedresources.list new file mode 100644 index 0000000000..28210ff466 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/cyreservedresources.list @@ -0,0 +1,4 @@ +[Device=CY8C6347BZI-BLD53] + +[Blocks] +# Nothing needs to be reserved for this device diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.cycapsense b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.cycapsense new file mode 100644 index 0000000000..43d6108110 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.cycapsense @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.cyqspi b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.cyqspi new file mode 100644 index 0000000000..3c5fbe94fb --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.cyqspi @@ -0,0 +1,63 @@ + + + + PSoC 6.xml + + + 0 + S25FL512S-4byteaddr + true + None + 0x18000000 + 0x4000000 + 0x1BFFFFFF + true + false + QUAD_SPI_DATA_0_3 + S25FL512S-4byteaddr + true + + + 1 + Not used + false + None + 0x18010000 + 0x10000 + 0x1801FFFF + false + false + SPI_MOSI_MISO_DATA_0_1 + default_memory.xml + true + + + 2 + Not used + false + None + 0x18020000 + 0x10000 + 0x1802FFFF + false + false + SPI_MOSI_MISO_DATA_0_1 + default_memory.xml + true + + + 3 + Not used + false + None + 0x18030000 + 0x10000 + 0x1803FFFF + false + false + SPI_MOSI_MISO_DATA_0_1 + default_memory.xml + true + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.modus b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.modus new file mode 100644 index 0000000000..839d49276b --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/COMPONENT_BSP_DESIGN_MODUS/design.modus @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/CY8CKIT-062-BLE.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/CY8CKIT-062-BLE.mk new file mode 100644 index 0000000000..520a7087fa --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/CY8CKIT-062-BLE.mk @@ -0,0 +1,37 @@ +################################################################################ +# \file CY8CKIT-062-BLE.mk +# \version 1.0 +# +# \brief +# Define the CY8CKIT-062-BLE target. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + +# MCU device selection +DEVICE:=CY8C6347BZI-BLD53 + +# Additional components supported by the target +COMPONENTS+=CM0P_SLEEP BSP_DESIGN_MODUS + +# Use CyHAL +DEFINES+=CY_USING_HAL diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/EULA b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/EULA new file mode 100644 index 0000000000..f10c742b10 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/EULA @@ -0,0 +1,55 @@ +CYPRESS END USER LICENSE AGREEMENT + +PLEASE READ THIS END USER LICENSE AGREEMENT ("Agreement") CAREFULLY BEFORE DOWNLOADING, INSTALLING, COPYING, OR USING THIS SOFTWARE AND ACCOMPANYING DOCUMENTATION. BY DOWNLOADING, INSTALLING, COPYING OR USING THE SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL OF THE TERMS OF THIS AGREEMENT, PROMPTLY RETURN AND DO NOT USE THE SOFTWARE. IF YOU HAVE PURCHASED THIS LICENSE TO THE SOFTWARE, YOUR RIGHT TO RETURN THE SOFTWARE EXPIRES 30 DAYS AFTER YOUR PURCHASE AND APPLIES ONLY TO THE ORIGINAL PURCHASER. + +1. Definitions. + + "Software" means this software and any accompanying documentation, including any upgrades, updates, bug fixes or modified versions provided to you by Cypress. + + "Source Code" means software in human-readable form. + + "Binary Code" means the software in binary code form such as object code or an executable. + + "Development Tools" means software that is intended to be installed on a personal computer and used to create programming code for Firmware, Drivers, or Host Applications. Examples of Development Tools are Cypress's PSoC Creator software, Cypress's WICED SDKs, and Cypress's ModusToolbox software. + + "Firmware" means software that executes on a Cypress hardware product. + + "Driver" means software that enables the use of a Cypress hardware product on a particular host operating system such as GNU/Linux, Windows, MacOS, Android, and iOS. + + "Host Application" means software that executes on a device other than a Cypress hardware product in order to program, control, or communicate with a Cypress hardware product. + + "inf File" means a hardware setup information file (.inf file) created by the Software to allow a Microsoft Windows operating system to install the driver for a Cypress hardware product. + +2. License. Subject to the terms and conditions of this Agreement, Cypress Semiconductor Corporation ("Cypress") and its suppliers grant to you a non-exclusive, non-transferable license under their copyright rights: + + a. to use the Development Tools in object code form solely for the purpose of creating Firmware, Drivers, Host Applications, and inf Files for Cypress hardware products; and + + b. (i) if provided in Source Code form, to copy, modify, and compile the Firmware Source Code to create Firmware for execution on a Cypress hardware product, and (ii) to distribute Firmware in binary code form only, only when installed onto a Cypress hardware product; and + + c. (i) if provided in Source Code form, to copy, modify, and compile the Driver Source Code to create one or more Drivers to enable the use of a Cypress hardware product on a particular host operating system, and (ii) to distribute the Driver, in binary code form only, only when installed on a device that includes the Cypress hardware product that the Driver is intended to enable; and + + d. (i) if provided in Source Code form, to copy, modify, and compile the Host Application Source Code to create one or more Host Applications to program, control, or communicate with a Cypress hardware product, and (ii) to distribute Host Applications, in binary code form only, only when installed on a device that includes a Cypress hardware product that the Host Application is intended to program, control, or communicate with; and + + e. to freely distribute any inf File. + +Any distribution of Software permitted under this Agreement must be made pursuant to your standard end user license agreement used for your proprietary (closed source) software products, such end user license agreement to include, at a minimum, provisions limiting your licensors' liability and prohibiting reverse engineering of the Software, consistent with such provisions in this Agreement. + +3. Free and Open Source Software. Portions of the Software may be licensed under free and/or open source licenses such as the GNU General Public License or other licenses from third parties ("Third Party Software"). Third Party Software is subject to the applicable license agreement and not this Agreement. If you are entitled to receive the source code from Cypress for any Third Party Software included with the Software, either the source code will be included with the Software or you may obtain the source code at no charge from . The applicable license terms will accompany each source code package. To review the license terms applicable to any Third Party Software for which Cypress is not required to provide you with source code, please see the Software's installation directory on your computer. + +4. Proprietary Rights; Ownership. The Software, including all intellectual property rights therein, is and will remain the sole and exclusive property of Cypress or its suppliers. Cypress retains ownership of the Source Code and any compiled version thereof. Subject to Cypress' ownership of the underlying Software (including Source Code), you retain ownership of any modifications you make to the Source Code. You agree not to remove any Cypress copyright or other notices from the Source Code and any modifications thereof. You agree to keep the Source Code confidential. Any reproduction, modification, translation, compilation, or representation of the Source Code except as permitted in Section 2 ("License") is prohibited without the express written permission of Cypress. Except as otherwise expressly provided in this Agreement, you may not: (i) modify, adapt, or create derivative works based upon the Software; (ii) copy the Software; (iii) except and only to the extent explicitly permitted by applicable law despite this limitation, decompile, translate, reverse engineer, disassemble or otherwise reduce the Software to human-readable form; or (iv) use the Software or any sample code other than for the Purpose. You hereby covenant that you will not assert any claim that the Software, or derivative works thereof created by or for Cypress, infringe any intellectual property right owned or controlled by you + +5. No Support. Cypress may, but is not required to, provide technical support for the Software. + +6. Term and Termination. This Agreement is effective until terminated, and either party may terminate this Agreement at any time with or without cause. This Agreement and your license rights under this Agreement will terminate immediately without notice from Cypress if you fail to comply with any provision of this Agreement. Upon termination, you must destroy all copies of Software in your possession or control. The following paragraphs shall survive any termination of this Agreement: "Free and Open Source Software," "Proprietary Rights; Ownership," "Compliance With Law," "Disclaimer," "Limitation of Liability," and "General." + +7. Compliance With Law. Each party agrees to comply with all applicable laws, rules and regulations in connection with its activities under this Agreement. Without limiting the foregoing, the Software may be subject to export control laws and regulations of the United States and other countries. You agree to comply strictly with all such laws and regulations and acknowledge that you have the responsibility to obtain licenses to export, re-export, or import the Software. + +8. Disclaimer. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THE SOFTWARE, INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress reserves the right to make changes to the Software without notice. Cypress does not assume any liability arising out of the application or use of Software or any product or circuit described in the Software. It is the responsibility of the user of the Software to properly design, program, and test the functionality and safety of any application made of the Software and any resulting product. Cypress does not authorize its Software or products for use in any products where a malfunction or failure of the Software or Cypress product may reasonably be expected to result in significant property damage, injury or death ("High Risk Product"). If you include any Software or Cypress product in a High Risk Product, you assume all risk of such use and agree to indemnify Cypress and its suppliers against all liability. No computing device can be absolutely secure. Therefore, despite security measures implemented in Cypress hardware or software products, Cypress does not assume any liability arising out of any security breach, such as unauthorized access to or use of a Cypress product. + +9. Limitation of Liability. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS BE LIABLE FOR ANY LOST REVENUE, PROFIT, OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO EVENT SHALL CYPRESS' OR ITS SUPPLIERS', RESELLERS', OR DISTRIBUTORS' TOTAL LIABILITY TO YOU, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, EXCEED THE GREATER OF US$500 OR THE PRICE PAID BY YOU FOR THE SOFTWARE. THE FOREGOING LIMITATIONS SHALL APPLY EVEN IF THE ABOVE-STATED WARRANTY FAILS OF ITS ESSENTIAL PURPOSE. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, ALL OR PORTIONS OF THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + +10. Restricted Rights. The Software is commercial computer software as that term is described in 48 C.F.R. 252.227-7014(a)(1). If the Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in Software shall be only those set forth in this Agreement. + +11. Personal Information. You agree that information you provide through your registration on Cypress IoT Community Forum or other Cypress websites, including contact information or other personal information, may be collected and used by Cypress consistent with its Data Privacy Policy (www.cypress.com/privacy-policy), as updated or revised from time to time, and may be provided to its third party sales representatives, distributors and other entities conducting sales activities for Cypress for sales-related and other business purposes. + +12. General. This Agreement will bind and inure to the benefit of each party's successors and assigns, provided that you may not assign or transfer this Agreement, in whole or in part, without Cypress' written consent. This Agreement shall be governed by and construed in accordance with the laws of the State of California, United States of America, as if performed wholly within the state and without giving effect to the principles of conflict of law. The parties consent to personal and exclusive jurisdiction of and venue in, the state and federal courts within Santa Clara County, California; provided however, that nothing in this Agreement will limit Cypress' right to bring legal action in any venue in order to protect or enforce its intellectual property rights. No failure of either party to exercise or enforce any of its rights under this Agreement will act as a waiver of such rights. If any portion of this Agreement is found to be void or unenforceable, the remaining provisions of this Agreement shall remain in full force and effect. This Agreement is the complete and exclusive agreement between the parties with respect to the subject matter hereof, superseding and replacing any and all prior agreements, communications, and understandings (both written and oral) regarding such subject matter. Any notice to Cypress will be deemed effective when actually received and must be sent to Cypress Semiconductor Corporation, ATTN: Chief Legal Officer, 198 Champion Court, San Jose, CA 95134 USA. diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/LICENSE b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/LICENSE new file mode 100644 index 0000000000..59cd3f8a32 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/LICENSE @@ -0,0 +1,165 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/README.md b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/README.md new file mode 100644 index 0000000000..36884311c7 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/README.md @@ -0,0 +1,57 @@ +# CY8CKIT-062-BLE BSP + +## Overview + +The PSoC 6 BLE Pioneer Kit is a low-cost hardware platform that enables design and debug of the PSoC 63 Line (CY8C6347BZI-BLD53). +![](docs/html/board.png) + +To use code from the BSP, simply include a reference to `cybsp.h`. + +## Features + +### Kit Features: + +* BLE v5.0 +* Serial memory interface +* PDM-PCM digital microphone interface +* Industry-leading CapSense + +### Kit Contents: + +* CY8CKIT-062-BLE evaluation board +* E-Ink display shield with an ultra-low-power 2.7" E-ink display, thermistor, 6-axis motion sensor, and digital microphone +* USB cable + +## BSP Configuration + +### Clock Configuration + +| Clock | Source | Output Frequency | +|----------|-----------|------------------| +| CLK_HF0 | CLK_PATH0 | 100 MHz | +| CLK_HF1 | CLK_PATH1 | 48 MHz | +| CLK_HF2 | CLK_PATH0 | 50 MHz | +| CLK_HF3 | CLK_PATH1 | 48 MHz | + +### Power Configuration + +* System Active Power Mode: LP +* System Idle Power Mode: Deep Sleep +* VDDA Voltage: 3300 mV +* VDDD Voltage: 3300 mV + +## API Reference Manual + +The CY8CKIT-062-BLE Board Support Package provides a set of APIs to configure, initialize and use the board resources. + +See the [BSP API Reference Manual][api] for the complete list of the provided interfaces. + +## More information +* [CY8CKIT-062-BLE BSP API Reference Manual][api] +* [CY8CKIT-062-BLE Documentation](http://www.cypress.com/documentation/development-kitsboards/psoc-6-ble-pioneer-kit) +* [Cypress Semiconductor](http://www.cypress.com) + +[api]: https://cypresssemiconductorco.github.io/TARGET_CY8CKIT-062-BLE/html/modules.html + +--- +© Cypress Semiconductor Corporation, 2019. \ No newline at end of file diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/RELEASE.md b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/RELEASE.md new file mode 100644 index 0000000000..2f6d7a9551 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/RELEASE.md @@ -0,0 +1,35 @@ +### CY8CKIT-062-BLE BSP +The PSoC 6 BLE Pioneer Kit is a low-cost hardware platform that enables design and debug of the PSoC 63 Line (CY8C6347BZI-BLD53). + +### What's New In This Release? +* Added pin references for the board's J2 Header + +### What's Included? +The CY8CKIT-062-BLE library includes the following: +* BSP specific makefile to configure the build process for the board +* cybsp.c/h files to initialize the board and any system peripherals +* cybsp_types.h file describing basic board setup +* Linker script & startup code for GCC, IAR, ARM toolchains +* Configurator design files (and generated code) to setup board specific peripherals +* .lib file references for all dependent libraries +* API documentation + +### Supported Software and Tools +This version of the CY8CKIT-062-BLE BSP was validated for compatibility with the following Software and Tools: + +| Software and Tools | Version | +| :--- | :----: | +| ModusToolbox Software Environment | 2.0 | +| GCC Compiler | 7.4 | +| IAR Compiler | 8.32 | +| ARM Compiler | 6.11 | + +### More information +* [CY8CKIT-062-BLE BSP API Reference Manual][api] +* [CY8CKIT-062-BLE Documentation](http://www.cypress.com/documentation/development-kitsboards/psoc-6-ble-pioneer-kit) +* [Cypress Semiconductor](http://www.cypress.com) + +[api]: modules.html + +--- +© Cypress Semiconductor Corporation, 2019. \ No newline at end of file diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp.c b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp.c new file mode 100644 index 0000000000..30540962ab --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp.c @@ -0,0 +1,124 @@ +/***************************************************************************//** +* \file cybsp.c +* +* Description: +* Provides initialization code for starting up the hardware contained on the +* Cypress board. +* +******************************************************************************** +* \copyright +* Copyright 2018-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include +#include "cybsp.h" +#if defined(CY_USING_HAL) +#include "cyhal_hwmgr.h" +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/* The sysclk deep sleep callback is recommended to be the last callback that +* is executed before entry into deep sleep mode and the first one upon +* exit the deep sleep mode. +* Doing so minimizes the time spent on low power mode entry and exit. +*/ +#ifndef CYBSP_SYSCLK_PM_CALLBACK_ORDER + #define CYBSP_SYSCLK_PM_CALLBACK_ORDER (255u) +#endif + +#if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL) +static cyhal_sdio_t sdio_obj; + +cyhal_sdio_t* cybsp_get_wifi_sdio_obj(void) +{ + return &sdio_obj; +} +#endif + +/** + * Registers a power management callback that prepares the clock system + * for entering deep sleep mode and restore the clocks upon wakeup from deep sleep. + * NOTE: This is called automatically as part of \ref cybsp_init + */ +static cy_rslt_t cybsp_register_sysclk_pm_callback(void) +{ + cy_rslt_t result = CY_RSLT_SUCCESS; + static cy_stc_syspm_callback_params_t cybsp_sysclk_pm_callback_param = {NULL, NULL}; + static cy_stc_syspm_callback_t cybsp_sysclk_pm_callback = { + .callback = &Cy_SysClk_DeepSleepCallback, + .type = CY_SYSPM_DEEPSLEEP, + .callbackParams = &cybsp_sysclk_pm_callback_param, + .order = CYBSP_SYSCLK_PM_CALLBACK_ORDER + }; + + if (!Cy_SysPm_RegisterCallback(&cybsp_sysclk_pm_callback)) + { + result = CYBSP_RSLT_ERR_SYSCLK_PM_CALLBACK; + } + return result; +} + +cy_rslt_t cybsp_init(void) +{ + /* Setup hardware manager to track resource usage then initialize all system (clock/power) board configuration */ +#if defined(CY_USING_HAL) + cy_rslt_t result = cyhal_hwmgr_init(); +#else + cy_rslt_t result = CY_RSLT_SUCCESS; +#endif + + init_cycfg_all(); + + if (CY_RSLT_SUCCESS == result) + { + result = cybsp_register_sysclk_pm_callback(); + } + +#if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL) + /* Initialize SDIO interface. This must be done before other HAL API calls as some SDIO implementations require + * specific peripheral instances. + * NOTE: The full WiFi interface still needs to be initialized via cybsp_wifi_init_primary(). This is typically + * done when starting up WiFi. + */ + if (CY_RSLT_SUCCESS == result) + { + /* Reserves: CYBSP_WIFI_SDIO, CYBSP_WIFI_SDIO_D0, CYBSP_WIFI_SDIO_D1, CYBSP_WIFI_SDIO_D2, CYBSP_WIFI_SDIO_D3 + * CYBSP_WIFI_SDIO_CMD and CYBSP_WIFI_SDIO_CLK. + */ + result = cyhal_sdio_init( + &sdio_obj, + CYBSP_WIFI_SDIO_CMD, + CYBSP_WIFI_SDIO_CLK, + CYBSP_WIFI_SDIO_D0, + CYBSP_WIFI_SDIO_D1, + CYBSP_WIFI_SDIO_D2, + CYBSP_WIFI_SDIO_D3); + } +#endif /* defined(CYBSP_WIFI_CAPABLE) */ + + /* CYHAL_HWMGR_RSLT_ERR_INUSE error code could be returned if any needed for BSP resource was reserved by + * user previously. Please review the Device Configurator (design.modus) and the BSP reservation list + * (cyreservedresources.list) to make sure no resources are reserved by both. + */ + return result; +} + +#if defined(__cplusplus) +} +#endif diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp.h b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp.h new file mode 100644 index 0000000000..80ab3c2a1d --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp.h @@ -0,0 +1,74 @@ +/***************************************************************************//** +* \file cybsp.h +* +* \brief +* Basic API for setting up boards containing a Cypress MCU. +* +******************************************************************************** +* \copyright +* Copyright 2018-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include "cy_result.h" +#include "cybsp_types.h" +#include "cycfg.h" +#if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL) +#include "cyhal_sdio.h" +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/** +* \addtogroup group_bsp_macros Macros +* \{ +*/ + +/** Failed to configure sysclk power management callback */ +#define CYBSP_RSLT_ERR_SYSCLK_PM_CALLBACK (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_BSP, 0)) + +/** \} group_bsp_macros */ + +/** +* \addtogroup group_bsp_functions Functions +* \{ +*/ + +/** + * \brief Initialize all hardware on the board + * \returns CY_RSLT_SUCCESS if the board is sucessfully initialized, if there is + * a problem initializing any hardware it returns an error code specific + * to the hardware module that had a problem. + */ +cy_rslt_t cybsp_init(void); + +#if defined(CYBSP_WIFI_CAPABLE) && defined(CY_USING_HAL) +/** + * \brief Get the initialized sdio object used for communicating with the WiFi Chip. + * \note This function should only be called after cybsp_init(); + * \returns The initialized sdio object. + */ +cyhal_sdio_t* cybsp_get_wifi_sdio_obj(void); +#endif /* defined(CYBSP_WIFI_CAPABLE) */ + +/** \} group_bsp_functions */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp_types.h b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp_types.h new file mode 100644 index 0000000000..89f543b181 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/cybsp_types.h @@ -0,0 +1,279 @@ +/***************************************************************************//** +* \file CY8CKIT-062-BLE/cybsp_types.h +* +* Description: +* Provides APIs for interacting with the hardware contained on the Cypress +* CY8CKIT-062-BLE pioneer kit. +* +******************************************************************************** +* \copyright +* Copyright 2018-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#if defined(CY_USING_HAL) +#include "cyhal_pin_package.h" +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/** +* \addtogroup group_bsp_settings BSP Settings +* \{ +* +*
Peripheral Default HAL Settings:
+* | Resource | Parameter | Value | Remarks | +* | :------: | :-------: | :---: | :------ | +* | ADC | VREF | 1.2 V | | +* | ^ | Measurement type | Single Ended | | +* | ^ | Input voltage range | 0 to 2.4 V (0 to 2*VREF) | | +* | ^ | Output range | 0x000 to 0x7FF | | +* | DAC | Reference source | VDDA | | +* | ^ | Input range | 0x000 to 0xFFF | | +* | ^ | Output range | 0 to VDDA | | +* | ^ | Output type | Unbuffered output | | +* | I2C | Role | Master | Configurable to slave mode through HAL function | +* | ^ | Data rate | 100 kbps | Configurable through HAL function | +* | ^ | Drive mode of SCL & SDA pins | Open Drain (drives low) | External pull-up resistors are required | +* | LpTimer | Uses WCO (32.768 kHz) as clock source & MCWDT as counter. 1 count = 1/32768 second or 32768 counts = 1 second. ||| +* | SPI | Data rate | 100 kpbs | Configurable through HAL function | +* | ^ | Slave select polarity | Active low | | +* | UART | Flow control | No flow control | Configurable through HAL function | +* | ^ | Data format | 8N1 | Configurable through HAL function | +* | ^ | Baud rate | 115200 | Configurable through HAL function | +*/ +/** \} group_bsp_settings */ + +/** +* \addtogroup group_bsp_pin_state Pin States +* \{ +*/ + +/** Pin state for the LED on. */ +#define CYBSP_LED_STATE_ON (0U) +/** Pin state for the LED off. */ +#define CYBSP_LED_STATE_OFF (1U) + +/** Pin state for when a button is pressed. */ +#define CYBSP_BTN_PRESSED (0U) +/** Pin state for when a button is released. */ +#define CYBSP_BTN_OFF (1U) + +/** \} group_bsp_pin_state */ + +#if defined(CY_USING_HAL) + +/** +* \addtogroup group_bsp_pins Pin Mappings +* \{ +*/ + +/** +* \addtogroup group_bsp_pins_led LED Pins +* \{ +*/ + +/** LED 8; User LED1 */ +#define CYBSP_LED8 (P1_5) +/** LED 9; User LED2 */ +#define CYBSP_LED9 (P13_7) +/** LED 5: RGB LED - Red; User LED3 */ +#define CYBSP_LED_RGB_RED (P0_3) +/** LED 5: RGB LED - Green; User LED4 */ +#define CYBSP_LED_RGB_GREEN (P1_1) +/** LED 5: RGB LED - Blue; User LED5 */ +#define CYBSP_LED_RGB_BLUE (P11_1) + +/** LED 8; User LED1 */ +#define CYBSP_USER_LED1 (CYBSP_LED8) +/** LED 9; User LED2 */ +#define CYBSP_USER_LED2 (CYBSP_LED9) +/** LED 5: RGB LED - Red; User LED3 */ +#define CYBSP_USER_LED3 (CYBSP_LED_RGB_RED) +/** LED 5: RGB LED - Green; User LED4 */ +#define CYBSP_USER_LED4 (CYBSP_LED_RGB_GREEN) +/** LED 5: RGB LED - Blue; User LED5 */ +#define CYBSP_USER_LED5 (CYBSP_LED_RGB_BLUE) +/** LED 8; User LED1 */ +#define CYBSP_USER_LED (CYBSP_USER_LED1) + +/** \} group_bsp_pins_led */ + +/** +* \addtogroup group_bsp_pins_btn Button Pins +* \{ +*/ + +/** Switch 2; User Button 1 */ +#define CYBSP_SW2 (P0_4) + +/** Switch 2; User Button 1 */ +#define CYBSP_USER_BTN1 (CYBSP_SW2) +/** Switch 2; User Button 1 */ +#define CYBSP_USER_BTN (CYBSP_USER_BTN1) + +/** \} group_bsp_pins_btn */ + + +/** +* \addtogroup group_bsp_pins_comm Communication Pins +* \{ +*/ + +/** Pin: UART RX */ +#define CYBSP_DEBUG_UART_RX (P5_0) +/** Pin: UART TX */ +#define CYBSP_DEBUG_UART_TX (P5_1) + +/** Pin: I2C SCL */ +#define CYBSP_I2C_SCL (P6_0) +/** Pin: I2C SDA */ +#define CYBSP_I2C_SDA (P6_1) + +/** Pin: SWO */ +#define CYBSP_SWO (P6_4) +/** Pin: SWDIO */ +#define CYBSP_SWDIO (P6_6) +/** Pin: SWDCK */ +#define CYBSP_SWDCK (P6_7) + +/** Pin: QUAD SPI SS */ +#define CYBSP_QSPI_SS (P11_2) +/** Pin: QUAD SPI D3 */ +#define CYBSP_QSPI_D3 (P11_3) +/** Pin: QUAD SPI D2 */ +#define CYBSP_QSPI_D2 (P11_4) +/** Pin: QUAD SPI D1 */ +#define CYBSP_QSPI_D1 (P11_5) +/** Pin: QUAD SPI D0 */ +#define CYBSP_QSPI_D0 (P11_6) +/** Pin: QUAD SPI SCK */ +#define CYBSP_QSPI_SCK (P11_7) + +/** \} group_bsp_pins_comm */ + + +/** +* \addtogroup group_bsp_pins_arduino Arduino Header Pins +* \{ +*/ + +/** Arduino A0 */ +#define CYBSP_A0 (P10_0) +/** Arduino A1 */ +#define CYBSP_A1 (P10_1) +/** Arduino A2 */ +#define CYBSP_A2 (P10_2) +/** Arduino A3 */ +#define CYBSP_A3 (P10_3) +/** Arduino A4 */ +#define CYBSP_A4 (P10_4) +/** Arduino A5 */ +#define CYBSP_A5 (P10_5) +/** Arduino D0 */ +#define CYBSP_D0 (P5_0) +/** Arduino D1 */ +#define CYBSP_D1 (P5_1) +/** Arduino D2 */ +#define CYBSP_D2 (P5_2) +/** Arduino D3 */ +#define CYBSP_D3 (P5_3) +/** Arduino D4 */ +#define CYBSP_D4 (P5_4) +/** Arduino D5 */ +#define CYBSP_D5 (P5_5) +/** Arduino D6 */ +#define CYBSP_D6 (P5_6) +/** Arduino D7 */ +#define CYBSP_D7 (P0_2) +/** Arduino D8 */ +#define CYBSP_D8 (P13_0) +/** Arduino D9 */ +#define CYBSP_D9 (P13_1) +/** Arduino D10 */ +#define CYBSP_D10 (P12_3) +/** Arduino D11 */ +#define CYBSP_D11 (P12_0) +/** Arduino D12 */ +#define CYBSP_D12 (P12_1) +/** Arduino D13 */ +#define CYBSP_D13 (P12_2) +/** Arduino D14 */ +#define CYBSP_D14 (P6_1) +/** Arduino D15 */ +#define CYBSP_D15 (P6_0) + +/** \} group_bsp_pins_arduino */ + + +/** +* \addtogroup group_bsp_pins_j2 J2 Header Pins +* \{ +*/ + +/** Cypress J2 Header pin 1 */ +#define CYBSP_J2_1 (CYBSP_A0) +/** Cypress J2 Header pin 2 */ +#define CYBSP_J2_2 (P9_0) +/** Cypress J2 Header pin 3 */ +#define CYBSP_J2_3 (CYBSP_A1) +/** Cypress J2 Header pin 4 */ +#define CYBSP_J2_4 (P9_1) +/** Cypress J2 Header pin 5 */ +#define CYBSP_J2_5 (CYBSP_A2) +/** Cypress J2 Header pin 6 */ +#define CYBSP_J2_6 (P9_2) +/** Cypress J2 Header pin 7 */ +#define CYBSP_J2_7 (CYBSP_A3) +/** Cypress J2 Header pin 8 */ +#define CYBSP_J2_8 (P9_3) +/** Cypress J2 Header pin 9 */ +#define CYBSP_J2_9 (CYBSP_A4) +/** Cypress J2 Header pin 10 */ +#define CYBSP_J2_10 (P9_4) +/** Cypress J2 Header pin 11 */ +#define CYBSP_J2_11 (CYBSP_A5) +/** Cypress J2 Header pin 12 */ +#define CYBSP_J2_12 (P9_5) +/** Cypress J2 Header pin 13 */ +#define CYBSP_J2_13 (P10_6) +/** Cypress J2 Header pin 14 */ +#define CYBSP_J2_14 (NC) +/** Cypress J2 Header pin 15 */ +#define CYBSP_J2_15 (P6_2) +/** Cypress J2 Header pin 16 */ +#define CYBSP_J2_16 (P9_6) +/** Cypress J2 Header pin 17 */ +#define CYBSP_J2_17 (P6_3) +/** Cypress J2 Header pin 18 */ +#define CYBSP_J2_18 (P9_7) +/** Cypress J2 Header pin 19 */ +#define CYBSP_J2_19 (P13_6) +/** Cypress J2 Header pin 20 */ +#define CYBSP_J2_20 (P13_7) + +/** \} group_bsp_pins_j2 */ + +/** \} group_bsp_pins */ + +#endif /* defined(CY_USING_HAL) */ + +#if defined(__cplusplus) +} +#endif diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual.sct b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual.sct new file mode 100644 index 0000000000..5af1eb2067 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_ARM/cy8c6xx7_cm4_dual.sct @@ -0,0 +1,274 @@ +#! armclang -E --target=arm-arm-none-eabi -x c -mcpu=cortex-m4 +; The first line specifies a preprocessor command that the linker invokes +; to pass a scatter file through a C preprocessor. + +;******************************************************************************* +;* \file cy8c6xx7_cm4_dual.sct +;* \version 2.60 +;* +;* Linker file for the ARMCC. +;* +;* The main purpose of the linker script is to describe how the sections in the +;* input files should be mapped into the output file, and to control the memory +;* layout of the output file. +;* +;* \note The entry point location is fixed and starts at 0x10000000. The valid +;* application image should be placed there. +;* +;* \note The linker files included with the PDL template projects must be +;* generic and handle all common use cases. Your project may not use every +;* section defined in the linker files. In that case you may see the warnings +;* during the build process: L6314W (no section matches pattern) and/or L6329W +;* (pattern only matches removed unused sections). In your project, you can +;* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +;* the linker, simply comment out or remove the relevant code in the linker +;* file. +;* +;******************************************************************************* +;* \copyright +;* Copyright 2016-2019 Cypress Semiconductor Corporation +;* SPDX-License-Identifier: Apache-2.0 +;* +;* Licensed under the Apache License, Version 2.0 (the "License"); +;* you may not use this file except in compliance with the License. +;* You may obtain a copy of the License at +;* +;* http://www.apache.org/licenses/LICENSE-2.0 +;* +;* Unless required by applicable law or agreed to in writing, software +;* distributed under the License is distributed on an "AS IS" BASIS, +;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;* See the License for the specific language governing permissions and +;* limitations under the License. +;******************************************************************************/ + +; The defines below describe the location and size of blocks of memory in the target. +; Use these defines to specify the memory regions available for allocation. + +; The following defines control RAM and flash memory allocation for the CM4 core. +; You can change the memory allocation by editing RAM and Flash defines. +; Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. +; Using this memory region for other purposes will lead to unexpected behavior. +; Your changes must be aligned with the corresponding defines for CM0+ core in 'xx_cm0plus.scat', +; where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.scat'. +; RAM +#define RAM_START 0x08002000 +#define RAM_SIZE 0x00045800 +; Flash +#define FLASH_START 0x10000000 +#define FLASH_SIZE 0x00100000 + +; Size of the stack section at the end of CM4 SRAM +#define STACK_SIZE 0x00001000 + +; Size of the Cortex-M0+ application flash image +#define FLASH_CM0P_SIZE 0x2000 + +; The following defines describe a 32K flash region used for EEPROM emulation. +; This region can also be used as the general purpose flash. +; You can assign sections to this memory region for only one of the cores. +; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. +; Therefore, repurposing this memory region will prevent such middleware from operation. +#define EM_EEPROM_START 0x14000000 +#define EM_EEPROM_SIZE 0x8000 + +; The following defines describe device specific memory regions and must not be changed. +; Supervisory flash: User data +#define SFLASH_USER_DATA_START 0x16000800 +#define SFLASH_USER_DATA_SIZE 0x00000800 + +; Supervisory flash: Normal Access Restrictions (NAR) +#define SFLASH_NAR_START 0x16001A00 +#define SFLASH_NAR_SIZE 0x00000200 + +; Supervisory flash: Public Key +#define SFLASH_PUBLIC_KEY_START 0x16005A00 +#define SFLASH_PUBLIC_KEY_SIZE 0x00000C00 + +; Supervisory flash: Table of Content # 2 +#define SFLASH_TOC_2_START 0x16007C00 +#define SFLASH_TOC_2_SIZE 0x00000200 + +; Supervisory flash: Table of Content # 2 Copy +#define SFLASH_RTOC_2_START 0x16007E00 +#define SFLASH_RTOC_2_SIZE 0x00000200 + +; External memory +#define XIP_START 0x18000000 +#define XIP_SIZE 0x08000000 + +; eFuse +#define EFUSE_START 0x90700000 +#define EFUSE_SIZE 0x100000 + + +; Cortex-M0+ application flash image area +LR_IROM FLASH_START FLASH_CM0P_SIZE +{ + .cy_m0p_image +0 FLASH_CM0P_SIZE + { + * (.cy_m0p_image) + } +} + +; Cortex-M4 application flash area +LR_IROM1 (FLASH_START + FLASH_CM0P_SIZE) (FLASH_SIZE - FLASH_CM0P_SIZE) +{ + ER_FLASH_VECTORS +0 + { + * (RESET, +FIRST) + } + + ER_FLASH_CODE +0 FIXED + { + * (InRoot$$Sections) + * (+RO) + } + + ER_RAM_VECTORS RAM_START UNINIT + { + * (RESET_RAM, +FIRST) + } + + RW_RAM_DATA +0 + { + * (.cy_ramfunc) + * (+RW, +ZI) + } + + ; Place variables in the section that should not be initialized during the + ; device startup. + RW_IRAM1 +0 UNINIT + { + * (.noinit) + } + + ; Application heap area (HEAP) + ARM_LIB_HEAP +0 EMPTY ((RAM_START+RAM_SIZE)-AlignExpr(ImageLimit(RW_IRAM1), 8)-STACK_SIZE) + { + } + + ; Stack region growing down + ARM_LIB_STACK (RAM_START+RAM_SIZE) EMPTY -STACK_SIZE + { + } + + ; Used for the digital signature of the secure application and the + ; Bootloader SDK application. The size of the section depends on the required + ; data size. + .cy_app_signature (FLASH_START + FLASH_SIZE - 256) 256 + { + * (.cy_app_signature) + } +} + + +; Emulated EEPROM Flash area +LR_EM_EEPROM EM_EEPROM_START EM_EEPROM_SIZE +{ + .cy_em_eeprom +0 + { + * (.cy_em_eeprom) + } +} + +; Supervisory flash: User data +LR_SFLASH_USER_DATA SFLASH_USER_DATA_START SFLASH_USER_DATA_SIZE +{ + .cy_sflash_user_data +0 + { + * (.cy_sflash_user_data) + } +} + +; Supervisory flash: Normal Access Restrictions (NAR) +LR_SFLASH_NAR SFLASH_NAR_START SFLASH_NAR_SIZE +{ + .cy_sflash_nar +0 + { + * (.cy_sflash_nar) + } +} + +; Supervisory flash: Public Key +LR_SFLASH_PUBLIC_KEY SFLASH_PUBLIC_KEY_START SFLASH_PUBLIC_KEY_SIZE +{ + .cy_sflash_public_key +0 + { + * (.cy_sflash_public_key) + } +} + +; Supervisory flash: Table of Content # 2 +LR_SFLASH_TOC_2 SFLASH_TOC_2_START SFLASH_TOC_2_SIZE +{ + .cy_toc_part2 +0 + { + * (.cy_toc_part2) + } +} + +; Supervisory flash: Table of Content # 2 Copy +LR_SFLASH_RTOC_2 SFLASH_RTOC_2_START SFLASH_RTOC_2_SIZE +{ + .cy_rtoc_part2 +0 + { + * (.cy_rtoc_part2) + } +} + + +; Places the code in the Execute in Place (XIP) section. See the smif driver documentation for details. +LR_EROM XIP_START XIP_SIZE +{ + .cy_xip +0 + { + * (.cy_xip) + } +} + + +; eFuse +LR_EFUSE EFUSE_START EFUSE_SIZE +{ + .cy_efuse +0 + { + * (.cy_efuse) + } +} + + +; The section is used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. +CYMETA 0x90500000 +{ + .cymeta +0 { * (.cymeta) } +} + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +#define __cy_memory_0_start 0x10000000 +#define __cy_memory_0_length 0x00100000 +#define __cy_memory_0_row_size 0x200 + +/* Emulated EEPROM Flash area */ +#define __cy_memory_1_start 0x14000000 +#define __cy_memory_1_length 0x8000 +#define __cy_memory_1_row_size 0x200 + +/* Supervisory Flash */ +#define __cy_memory_2_start 0x16000000 +#define __cy_memory_2_length 0x8000 +#define __cy_memory_2_row_size 0x200 + +/* XIP */ +#define __cy_memory_3_start 0x18000000 +#define __cy_memory_3_length 0x08000000 +#define __cy_memory_3_row_size 0x200 + +/* eFuse */ +#define __cy_memory_4_start 0x90700000 +#define __cy_memory_4_length 0x100000 +#define __cy_memory_4_row_size 1 + + +/* [] END OF FILE */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_A_Clang/cy8c6xx7_cm4_dual.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_A_Clang/cy8c6xx7_cm4_dual.mk new file mode 100644 index 0000000000..212b141d2c --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_A_Clang/cy8c6xx7_cm4_dual.mk @@ -0,0 +1,85 @@ +################################################################################ +# \file cy8c6xx7_cm4_dual.mk +# \version 2.60 +# +# \brief +# Specifies the starting address and the size of the segments in the output +# file. +# +# \note The section definitions in this file are generic and handle all common +# use cases. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +### CM0P ### +export HEAP_SIZE_CM0P := 0x400 +export VECT_BASE_CM0P := 0x10000000 +export RAM_VECT_BASE_CM0P := 0x08000000 +export VECT_SIZE_CM0P := 0x000000C0 +export TEXT_BASE_CM0P := 0x100000C0 +export TEXT_SIZE_CM0P := 0x00002000 +export RAM_BASE_CM0P := 0x080000C0 +export RAM_SIZE_CM0P := 0x00002000 +export CYMETA_BASE_CM0P := 0x90500000 +export STACK_SIZE_CM0P := 0x2000 + +STACK_ADDRESS_TOP_CM0P := $(shell printf "0x%x" $$(($(RAM_VECT_BASE_CM0P) + $(RAM_SIZE_CM0P)))) +STACK_ADDRESS_BOTTOM_CM0P := $(shell printf "0x%x" $$(($(STACK_ADDRESS_TOP_CM0P) - $(STACK_SIZE_CM0P)))) +TOOLCHAIN_VECT_BASE_CM0 := $(VECT_BASE_CM0P) + +SECTIONS_CM0P := \ + -segaddr __VECT $(VECT_BASE_CM0P) \ + -segaddr __TEXT $(TEXT_BASE_CM0P) \ + -segaddr __DATA $(RAM_BASE_CM0P) \ + -segaddr __RAMVECTORS $(RAM_VECT_BASE_CM0P) \ + -segaddr __CYMETA $(CYMETA_BASE_CM0P) \ + -segaddr __STACK $(STACK_ADDRESS_TOP_CM0P) + +### CM4 ### +export HEAP_SIZE_CM4 := 0x400 +export VECT_BASE_CM4 := 0x10002000 +export RAM_VECT_BASE_CM4 := 0x08002000 +export VECT_SIZE_CM4 := 0x0000028C +export TEXT_BASE_CM4 := 0x1000228C +export TEXT_SIZE_CM4 := 0x000FE000 +export RAM_BASE_CM4 := 0x0800228C +export RAM_SIZE_CM4 := 0x00045800 +export CYMETA_BASE_CM4 := 0x90500000 +export STACK_SIZE_CM4 := 0x2000 +STACK_ADDRESS_TOP_CM4 := $(shell printf "0x%x" $$(($(RAM_VECT_BASE_CM4) + $(RAM_SIZE_CM4)))) +STACK_ADDRESS_BOTTOM_CM4 := $(shell printf "0x%x" $$(($(STACK_ADDRESS_TOP_CM4) - $(STACK_SIZE_CM4)))) +TOOLCHAIN_VECT_BASE_CM4 := $(VECT_BASE_CM4) + +SECTIONS_CM4 := \ + -segaddr __CY_M0P_IMAGE $(VECT_BASE_CM0P) \ + -segaddr __VECT $(VECT_BASE_CM4) \ + -segaddr __TEXT $(TEXT_BASE_CM4) \ + -segaddr __DATA $(RAM_BASE_CM4) \ + -segaddr __RAMVECTORS $(RAM_VECT_BASE_CM4) \ + -segaddr __CYMETA $(CYMETA_BASE_CM4) \ + -segaddr __STACK $(STACK_ADDRESS_TOP_CM4) + +# Pass section addresses to the linker +ifeq ($(CORE),CM4) +LDFLAGS += $(SECTIONS_CM4) +else ifeq ($(CORE),CM0P) +LDFLAGS += $(SECTIONS_CM0P) +endif + +# EOF diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual.ld b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual.ld new file mode 100644 index 0000000000..012a379e70 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_GCC_ARM/cy8c6xx7_cm4_dual.ld @@ -0,0 +1,459 @@ +/***************************************************************************//** +* \file cy8c6xx7_cm4_dual.ld +* \version 2.60 +* +* Linker file for the GNU C compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point location is fixed and starts at 0x10000000. The valid +* application image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) +ENTRY(Reset_Handler) + +/* Size of the stack section at the end of CM4 SRAM */ +STACK_SIZE = 0x1000; + +/* Size of the Cortex-M0+ application image at the start of FLASH */ +FLASH_CM0P_SIZE = 0x2000; + +/* Force symbol to be entered in the output file as an undefined symbol. Doing +* this may, for example, trigger linking of additional modules from standard +* libraries. You may list several symbols for each EXTERN, and you may use +* EXTERN multiple times. This command has the same effect as the -u command-line +* option. +*/ +EXTERN(Reset_Handler) + +/* The MEMORY section below describes the location and size of blocks of memory in the target. +* Use this section to specify the memory regions available for allocation. +*/ +MEMORY +{ + /* The ram and flash regions control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing the 'ram' and 'flash' regions. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'. + */ + ram (rwx) : ORIGIN = 0x08002000, LENGTH = 0x45800 + flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x100000 + + /* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ + em_eeprom (rx) : ORIGIN = 0x14000000, LENGTH = 0x8000 /* 32 KB */ + + /* The following regions define device specific memory regions and must not be changed. */ + sflash_user_data (rx) : ORIGIN = 0x16000800, LENGTH = 0x800 /* Supervisory flash: User data */ + sflash_nar (rx) : ORIGIN = 0x16001A00, LENGTH = 0x200 /* Supervisory flash: Normal Access Restrictions (NAR) */ + sflash_public_key (rx) : ORIGIN = 0x16005A00, LENGTH = 0xC00 /* Supervisory flash: Public Key */ + sflash_toc_2 (rx) : ORIGIN = 0x16007C00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 */ + sflash_rtoc_2 (rx) : ORIGIN = 0x16007E00, LENGTH = 0x200 /* Supervisory flash: Table of Content # 2 Copy */ + xip (rx) : ORIGIN = 0x18000000, LENGTH = 0x8000000 /* 128 MB */ + efuse (r) : ORIGIN = 0x90700000, LENGTH = 0x100000 /* 1 MB */ +} + +/* Library configurations */ +GROUP(libgcc.a libc.a libm.a libnosys.a) + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ + + +SECTIONS +{ + /* Cortex-M0+ application flash image area */ + .cy_m0p_image ORIGIN(flash) : + { + . = ALIGN(4); + __cy_m0p_code_start = . ; + KEEP(*(.cy_m0p_image)) + __cy_m0p_code_end = . ; + } > flash + + /* Check if .cy_m0p_image size exceeds FLASH_CM0P_SIZE */ + ASSERT(__cy_m0p_code_end <= ORIGIN(flash) + FLASH_CM0P_SIZE, "CM0+ flash image overflows with CM4, increase FLASH_CM0P_SIZE") + + /* Cortex-M4 application flash area */ + .text ORIGIN(flash) + FLASH_CM0P_SIZE : + { + . = ALIGN(4); + __Vectors = . ; + KEEP(*(.vectors)) + . = ALIGN(4); + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + . = ALIGN(4); + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* Read-only code (constants). */ + *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) + + KEEP(*(.eh_frame*)) + } > flash + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash + + __exidx_start = .; + + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_psoc6_01_cm4.S */ + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + /* Copy interrupt vectors from flash to RAM */ + LONG (__Vectors) /* From */ + LONG (__ram_vectors_start__) /* To */ + LONG (__Vectors_End - __Vectors) /* Size */ + + /* Copy data section to RAM */ + LONG (__etext) /* From */ + LONG (__data_start__) /* To */ + LONG (__data_end__ - __data_start__) /* Size */ + + __copy_table_end__ = .; + } > flash + + /* setction information for finsh shell begin */ + FSymTab : + { + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + } > flash + VSymTab : + { + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + } > flash + rti_fn : + { + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + } > flash + /* setction information for finsh shell end */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_psoc6_01_cm4.S */ + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + __zero_table_end__ = .; + } > flash + + __etext = . ; + + + .ramVectors (NOLOAD) : ALIGN(8) + { + __ram_vectors_start__ = .; + KEEP(*(.ram_vectors)) + __ram_vectors_end__ = .; + } > ram + + + .data __ram_vectors_end__ : AT (__etext) + { + __data_start__ = .; + + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + + KEEP(*(.cy_ramfunc*)) + . = ALIGN(4); + + __data_end__ = .; + + } > ram + + + /* Place variables in the section that should not be initialized during the + * device startup. + */ + .noinit (NOLOAD) : ALIGN(8) + { + KEEP(*(.noinit)) + } > ram + + + /* The uninitialized global or static variables are placed in this section. + * + * The NOLOAD attribute tells linker that .bss section does not consume + * any space in the image. The NOLOAD attribute changes the .bss type to + * NOBITS, and that makes linker to A) not allocate section in memory, and + * A) put information to clear the section with all zeros during application + * loading. + * + * Without the NOLOAD attribute, the .bss section might get PROGBITS type. + * This makes linker to A) allocate zeroed section in memory, and B) copy + * this section to RAM during application loading. + */ + .bss (NOLOAD): + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > ram + + + .heap (NOLOAD): + { + __HeapBase = .; + __end__ = .; + end = __end__; + KEEP(*(.heap*)) + . = ORIGIN(ram) + LENGTH(ram) - STACK_SIZE; + __HeapLimit = .; + } > ram + + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + KEEP(*(.stack*)) + } > ram + + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(ram) + LENGTH(ram); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + + /* Used for the digital signature of the secure application and the Bootloader SDK application. + * The size of the section depends on the required data size. */ + .cy_app_signature ORIGIN(flash) + LENGTH(flash) - 256 : + { + KEEP(*(.cy_app_signature)) + } > flash + + + /* Emulated EEPROM Flash area */ + .cy_em_eeprom : + { + KEEP(*(.cy_em_eeprom)) + } > em_eeprom + + + /* Supervisory Flash: User data */ + .cy_sflash_user_data : + { + KEEP(*(.cy_sflash_user_data)) + } > sflash_user_data + + + /* Supervisory Flash: Normal Access Restrictions (NAR) */ + .cy_sflash_nar : + { + KEEP(*(.cy_sflash_nar)) + } > sflash_nar + + + /* Supervisory Flash: Public Key */ + .cy_sflash_public_key : + { + KEEP(*(.cy_sflash_public_key)) + } > sflash_public_key + + + /* Supervisory Flash: Table of Content # 2 */ + .cy_toc_part2 : + { + KEEP(*(.cy_toc_part2)) + } > sflash_toc_2 + + + /* Supervisory Flash: Table of Content # 2 Copy */ + .cy_rtoc_part2 : + { + KEEP(*(.cy_rtoc_part2)) + } > sflash_rtoc_2 + + + /* Places the code in the Execute in Place (XIP) section. See the smif driver + * documentation for details. + */ + .cy_xip : + { + KEEP(*(.cy_xip)) + } > xip + + + /* eFuse */ + .cy_efuse : + { + KEEP(*(.cy_efuse)) + } > efuse + + + /* These sections are used for additional metadata (silicon revision, + * Silicon/JTAG ID, etc.) storage. + */ + .cymeta 0x90500000 : { KEEP(*(.cymeta)) } :NONE +} + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +__cy_memory_0_start = 0x10000000; +__cy_memory_0_length = 0x00100000; +__cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +__cy_memory_1_start = 0x14000000; +__cy_memory_1_length = 0x8000; +__cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +__cy_memory_2_start = 0x16000000; +__cy_memory_2_length = 0x8000; +__cy_memory_2_row_size = 0x200; + +/* XIP */ +__cy_memory_3_start = 0x18000000; +__cy_memory_3_length = 0x08000000; +__cy_memory_3_row_size = 0x200; + +/* eFuse */ +__cy_memory_4_start = 0x90700000; +__cy_memory_4_length = 0x100000; +__cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual.icf b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual.icf new file mode 100644 index 0000000000..e30133713a --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/linker/TOOLCHAIN_IAR/cy8c6xx7_cm4_dual.icf @@ -0,0 +1,240 @@ +/***************************************************************************//** +* \file cy8c6xx7_cm4_dual.icf +* \version 2.60 +* +* Linker file for the IAR compiler. +* +* The main purpose of the linker script is to describe how the sections in the +* input files should be mapped into the output file, and to control the memory +* layout of the output file. +* +* \note The entry point is fixed and starts at 0x10000000. The valid application +* image should be placed there. +* +* \note The linker files included with the PDL template projects must be generic +* and handle all common use cases. Your project may not use every section +* defined in the linker files. In that case you may see warnings during the +* build process. In your project, you can simply comment out or remove the +* relevant code in the linker file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; + +/* The symbols below define the location and size of blocks of memory in the target. + * Use these symbols to specify the memory regions available for allocation. + */ + +/* The following symbols control RAM and flash memory allocation for the CM4 core. + * You can change the memory allocation by editing RAM and Flash symbols. + * Note that 2 KB of RAM (at the end of the SRAM) are reserved for system use. + * Using this memory region for other purposes will lead to unexpected behavior. + * Your changes must be aligned with the corresponding symbols for CM0+ core in 'xx_cm0plus.icf', + * where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.icf'. + */ +/* RAM */ +define symbol __ICFEDIT_region_IRAM1_start__ = 0x08002000; +define symbol __ICFEDIT_region_IRAM1_end__ = 0x08047800; +/* Flash */ +define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000; +define symbol __ICFEDIT_region_IROM1_end__ = 0x10100000; + +/* The following symbols define a 32K flash region used for EEPROM emulation. + * This region can also be used as the general purpose flash. + * You can assign sections to this memory region for only one of the cores. + * Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region. + * Therefore, repurposing this memory region will prevent such middleware from operation. + */ +define symbol __ICFEDIT_region_IROM2_start__ = 0x14000000; +define symbol __ICFEDIT_region_IROM2_end__ = 0x14007FFF; + +/* The following symbols define device specific memory regions and must not be changed. */ +/* Supervisory FLASH - User Data */ +define symbol __ICFEDIT_region_IROM3_start__ = 0x16000800; +define symbol __ICFEDIT_region_IROM3_end__ = 0x160007FF; + +/* Supervisory FLASH - Normal Access Restrictions (NAR) */ +define symbol __ICFEDIT_region_IROM4_start__ = 0x16001A00; +define symbol __ICFEDIT_region_IROM4_end__ = 0x16001BFF; + +/* Supervisory FLASH - Public Key */ +define symbol __ICFEDIT_region_IROM5_start__ = 0x16005A00; +define symbol __ICFEDIT_region_IROM5_end__ = 0x160065FF; + +/* Supervisory FLASH - Table of Content # 2 */ +define symbol __ICFEDIT_region_IROM6_start__ = 0x16007C00; +define symbol __ICFEDIT_region_IROM6_end__ = 0x16007DFF; + +/* Supervisory FLASH - Table of Content # 2 Copy */ +define symbol __ICFEDIT_region_IROM7_start__ = 0x16007E00; +define symbol __ICFEDIT_region_IROM7_end__ = 0x16007FFF; + +/* eFuse */ +define symbol __ICFEDIT_region_IROM8_start__ = 0x90700000; +define symbol __ICFEDIT_region_IROM8_end__ = 0x907FFFFF; + +/* XIP */ +define symbol __ICFEDIT_region_EROM1_start__ = 0x18000000; +define symbol __ICFEDIT_region_EROM1_end__ = 0x1FFFFFFF; + +define symbol __ICFEDIT_region_EROM2_start__ = 0x0; +define symbol __ICFEDIT_region_EROM2_end__ = 0x0; +define symbol __ICFEDIT_region_EROM3_start__ = 0x0; +define symbol __ICFEDIT_region_EROM3_end__ = 0x0; + + +define symbol __ICFEDIT_region_IRAM2_start__ = 0x0; +define symbol __ICFEDIT_region_IRAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM1_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM2_end__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_start__ = 0x0; +define symbol __ICFEDIT_region_ERAM3_end__ = 0x0; +/*-Sizes-*/ +if (!isdefinedsymbol(__STACK_SIZE)) { + define symbol __ICFEDIT_size_cstack__ = 0x1000; +} else { + define symbol __ICFEDIT_size_cstack__ = __STACK_SIZE; +} +define symbol __ICFEDIT_size_proc_stack__ = 0x0; + +/* Defines the minimum heap size. The actual heap size will be expanded to the end of the stack region */ +if (!isdefinedsymbol(__HEAP_SIZE)) { + define symbol __ICFEDIT_size_heap__ = 0x0400; +} else { + define symbol __ICFEDIT_size_heap__ = __HEAP_SIZE; +} +/**** End of ICF editor section. ###ICF###*/ + +/* Size of the Cortex-M0+ application image */ +define symbol FLASH_CM0P_SIZE = 0x2000; + +define memory mem with size = 4G; +define region IROM1_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]; +define region IROM2_region = mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__]; +define region IROM3_region = mem:[from __ICFEDIT_region_IROM3_start__ to __ICFEDIT_region_IROM3_end__]; +define region IROM4_region = mem:[from __ICFEDIT_region_IROM4_start__ to __ICFEDIT_region_IROM4_end__]; +define region IROM5_region = mem:[from __ICFEDIT_region_IROM5_start__ to __ICFEDIT_region_IROM5_end__]; +define region IROM6_region = mem:[from __ICFEDIT_region_IROM6_start__ to __ICFEDIT_region_IROM6_end__]; +define region IROM7_region = mem:[from __ICFEDIT_region_IROM7_start__ to __ICFEDIT_region_IROM7_end__]; +define region IROM8_region = mem:[from __ICFEDIT_region_IROM8_start__ to __ICFEDIT_region_IROM8_end__]; +define region EROM1_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]; +define region IRAM1_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { }; +define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { }; +define block HSTACK {block HEAP, block PROC_STACK, last block CSTACK}; +define block CM0P_RO with size = FLASH_CM0P_SIZE { readonly section .cy_m0p_image }; +define block RO {first section .intvec, readonly}; + +/*-Initializations-*/ +initialize by copy { readwrite }; +do not initialize { section .noinit, section .intvec_ram }; + +/*-Placement-*/ + +/* Flash - Cortex-M0+ application image */ +place at start of IROM1_region { block CM0P_RO }; + +/* Flash - Cortex-M4 application */ +place in IROM1_region { block RO }; + +/* Used for the digital signature of the secure application and the Bootloader SDK application. */ +".cy_app_signature" : place at address (__ICFEDIT_region_IROM1_end__ - 0x200) { section .cy_app_signature }; + +/* Emulated EEPROM Flash area */ +".cy_em_eeprom" : place at start of IROM2_region { section .cy_em_eeprom }; + +/* Supervisory Flash - User Data */ +".cy_sflash_user_data" : place at start of IROM3_region { section .cy_sflash_user_data }; + +/* Supervisory Flash - NAR */ +".cy_sflash_nar" : place at start of IROM4_region { section .cy_sflash_nar }; + +/* Supervisory Flash - Public Key */ +".cy_sflash_public_key" : place at start of IROM5_region { section .cy_sflash_public_key }; + +/* Supervisory Flash - TOC2 */ +".cy_toc_part2" : place at start of IROM6_region { section .cy_toc_part2 }; + +/* Supervisory Flash - RTOC2 */ +".cy_rtoc_part2" : place at start of IROM7_region { section .cy_rtoc_part2 }; + +/* eFuse */ +".cy_efuse" : place at start of IROM8_region { section .cy_efuse }; + +/* Execute in Place (XIP). See the smif driver documentation for details. */ +".cy_xip" : place at start of EROM1_region { section .cy_xip }; + +/* RAM */ +place at start of IRAM1_region { readwrite section .intvec_ram}; +place in IRAM1_region { readwrite }; +place at end of IRAM1_region { block HSTACK }; + +/* These sections are used for additional metadata (silicon revision, Silicon/JTAG ID, etc.) storage. */ +".cymeta" : place at address mem : 0x90500000 { readonly section .cymeta }; + + +keep { section .cy_m0p_image, + section .cy_app_signature, + section .cy_em_eeprom, + section .cy_sflash_user_data, + section .cy_sflash_nar, + section .cy_sflash_public_key, + section .cy_toc_part2, + section .cy_rtoc_part2, + section .cy_efuse, + section .cy_xip, + section .cymeta, + }; + + +/* The following symbols used by the cymcuelftool. */ +/* Flash */ +define exported symbol __cy_memory_0_start = 0x10000000; +define exported symbol __cy_memory_0_length = 0x00100000; +define exported symbol __cy_memory_0_row_size = 0x200; + +/* Emulated EEPROM Flash area */ +define exported symbol __cy_memory_1_start = 0x14000000; +define exported symbol __cy_memory_1_length = 0x8000; +define exported symbol __cy_memory_1_row_size = 0x200; + +/* Supervisory Flash */ +define exported symbol __cy_memory_2_start = 0x16000000; +define exported symbol __cy_memory_2_length = 0x8000; +define exported symbol __cy_memory_2_row_size = 0x200; + +/* XIP */ +define exported symbol __cy_memory_3_start = 0x18000000; +define exported symbol __cy_memory_3_length = 0x08000000; +define exported symbol __cy_memory_3_row_size = 0x200; + +/* eFuse */ +define exported symbol __cy_memory_4_start = 0x90700000; +define exported symbol __cy_memory_4_length = 0x100000; +define exported symbol __cy_memory_4_row_size = 1; + +/* EOF */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_ARM/startup_psoc6_01_cm4.s b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_ARM/startup_psoc6_01_cm4.s new file mode 100644 index 0000000000..dd04a07d30 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_ARM/startup_psoc6_01_cm4.s @@ -0,0 +1,645 @@ +;/**************************************************************************//** +; * @file startup_psoc6_01_cm4.s +; * @brief CMSIS Core Device Startup File for +; * ARMCM4 Device Series +; * @version V5.00 +; * @date 02. March 2016 +; ******************************************************************************/ +;/* +; * Copyright (c) 2009-2016 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * 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. +; */ + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + + IMPORT |Image$$ARM_LIB_STACK$$ZI$$Base| + IMPORT |Image$$ARM_LIB_STACK$$ZI$$Length| + +__Vectors DCD |Image$$ARM_LIB_STACK$$ZI$$Base| + |Image$$ARM_LIB_STACK$$ZI$$Length| ; Top of Stack + + DCD Reset_Handler ; Reset Handler + + DCD 0x0000000D ; NMI Handler located at ROM code + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External interrupts Description + DCD ioss_interrupts_gpio_0_IRQHandler ; GPIO Port Interrupt #0 + DCD ioss_interrupts_gpio_1_IRQHandler ; GPIO Port Interrupt #1 + DCD ioss_interrupts_gpio_2_IRQHandler ; GPIO Port Interrupt #2 + DCD ioss_interrupts_gpio_3_IRQHandler ; GPIO Port Interrupt #3 + DCD ioss_interrupts_gpio_4_IRQHandler ; GPIO Port Interrupt #4 + DCD ioss_interrupts_gpio_5_IRQHandler ; GPIO Port Interrupt #5 + DCD ioss_interrupts_gpio_6_IRQHandler ; GPIO Port Interrupt #6 + DCD ioss_interrupts_gpio_7_IRQHandler ; GPIO Port Interrupt #7 + DCD ioss_interrupts_gpio_8_IRQHandler ; GPIO Port Interrupt #8 + DCD ioss_interrupts_gpio_9_IRQHandler ; GPIO Port Interrupt #9 + DCD ioss_interrupts_gpio_10_IRQHandler ; GPIO Port Interrupt #10 + DCD ioss_interrupts_gpio_11_IRQHandler ; GPIO Port Interrupt #11 + DCD ioss_interrupts_gpio_12_IRQHandler ; GPIO Port Interrupt #12 + DCD ioss_interrupts_gpio_13_IRQHandler ; GPIO Port Interrupt #13 + DCD ioss_interrupts_gpio_14_IRQHandler ; GPIO Port Interrupt #14 + DCD ioss_interrupt_gpio_IRQHandler ; GPIO All Ports + DCD ioss_interrupt_vdd_IRQHandler ; GPIO Supply Detect Interrupt + DCD lpcomp_interrupt_IRQHandler ; Low Power Comparator Interrupt + DCD scb_8_interrupt_IRQHandler ; Serial Communication Block #8 (DeepSleep capable) + DCD srss_interrupt_mcwdt_0_IRQHandler ; Multi Counter Watchdog Timer interrupt + DCD srss_interrupt_mcwdt_1_IRQHandler ; Multi Counter Watchdog Timer interrupt + DCD srss_interrupt_backup_IRQHandler ; Backup domain interrupt + DCD srss_interrupt_IRQHandler ; Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) + DCD pass_interrupt_ctbs_IRQHandler ; CTBm Interrupt (all CTBms) + DCD bless_interrupt_IRQHandler ; Bluetooth Radio interrupt + DCD cpuss_interrupts_ipc_0_IRQHandler ; CPUSS Inter Process Communication Interrupt #0 + DCD cpuss_interrupts_ipc_1_IRQHandler ; CPUSS Inter Process Communication Interrupt #1 + DCD cpuss_interrupts_ipc_2_IRQHandler ; CPUSS Inter Process Communication Interrupt #2 + DCD cpuss_interrupts_ipc_3_IRQHandler ; CPUSS Inter Process Communication Interrupt #3 + DCD cpuss_interrupts_ipc_4_IRQHandler ; CPUSS Inter Process Communication Interrupt #4 + DCD cpuss_interrupts_ipc_5_IRQHandler ; CPUSS Inter Process Communication Interrupt #5 + DCD cpuss_interrupts_ipc_6_IRQHandler ; CPUSS Inter Process Communication Interrupt #6 + DCD cpuss_interrupts_ipc_7_IRQHandler ; CPUSS Inter Process Communication Interrupt #7 + DCD cpuss_interrupts_ipc_8_IRQHandler ; CPUSS Inter Process Communication Interrupt #8 + DCD cpuss_interrupts_ipc_9_IRQHandler ; CPUSS Inter Process Communication Interrupt #9 + DCD cpuss_interrupts_ipc_10_IRQHandler ; CPUSS Inter Process Communication Interrupt #10 + DCD cpuss_interrupts_ipc_11_IRQHandler ; CPUSS Inter Process Communication Interrupt #11 + DCD cpuss_interrupts_ipc_12_IRQHandler ; CPUSS Inter Process Communication Interrupt #12 + DCD cpuss_interrupts_ipc_13_IRQHandler ; CPUSS Inter Process Communication Interrupt #13 + DCD cpuss_interrupts_ipc_14_IRQHandler ; CPUSS Inter Process Communication Interrupt #14 + DCD cpuss_interrupts_ipc_15_IRQHandler ; CPUSS Inter Process Communication Interrupt #15 + DCD scb_0_interrupt_IRQHandler ; Serial Communication Block #0 + DCD scb_1_interrupt_IRQHandler ; Serial Communication Block #1 + DCD scb_2_interrupt_IRQHandler ; Serial Communication Block #2 + DCD scb_3_interrupt_IRQHandler ; Serial Communication Block #3 + DCD scb_4_interrupt_IRQHandler ; Serial Communication Block #4 + DCD scb_5_interrupt_IRQHandler ; Serial Communication Block #5 + DCD scb_6_interrupt_IRQHandler ; Serial Communication Block #6 + DCD scb_7_interrupt_IRQHandler ; Serial Communication Block #7 + DCD csd_interrupt_IRQHandler ; CSD (Capsense) interrupt + DCD cpuss_interrupts_dw0_0_IRQHandler ; CPUSS DataWire #0, Channel #0 + DCD cpuss_interrupts_dw0_1_IRQHandler ; CPUSS DataWire #0, Channel #1 + DCD cpuss_interrupts_dw0_2_IRQHandler ; CPUSS DataWire #0, Channel #2 + DCD cpuss_interrupts_dw0_3_IRQHandler ; CPUSS DataWire #0, Channel #3 + DCD cpuss_interrupts_dw0_4_IRQHandler ; CPUSS DataWire #0, Channel #4 + DCD cpuss_interrupts_dw0_5_IRQHandler ; CPUSS DataWire #0, Channel #5 + DCD cpuss_interrupts_dw0_6_IRQHandler ; CPUSS DataWire #0, Channel #6 + DCD cpuss_interrupts_dw0_7_IRQHandler ; CPUSS DataWire #0, Channel #7 + DCD cpuss_interrupts_dw0_8_IRQHandler ; CPUSS DataWire #0, Channel #8 + DCD cpuss_interrupts_dw0_9_IRQHandler ; CPUSS DataWire #0, Channel #9 + DCD cpuss_interrupts_dw0_10_IRQHandler ; CPUSS DataWire #0, Channel #10 + DCD cpuss_interrupts_dw0_11_IRQHandler ; CPUSS DataWire #0, Channel #11 + DCD cpuss_interrupts_dw0_12_IRQHandler ; CPUSS DataWire #0, Channel #12 + DCD cpuss_interrupts_dw0_13_IRQHandler ; CPUSS DataWire #0, Channel #13 + DCD cpuss_interrupts_dw0_14_IRQHandler ; CPUSS DataWire #0, Channel #14 + DCD cpuss_interrupts_dw0_15_IRQHandler ; CPUSS DataWire #0, Channel #15 + DCD cpuss_interrupts_dw1_0_IRQHandler ; CPUSS DataWire #1, Channel #0 + DCD cpuss_interrupts_dw1_1_IRQHandler ; CPUSS DataWire #1, Channel #1 + DCD cpuss_interrupts_dw1_2_IRQHandler ; CPUSS DataWire #1, Channel #2 + DCD cpuss_interrupts_dw1_3_IRQHandler ; CPUSS DataWire #1, Channel #3 + DCD cpuss_interrupts_dw1_4_IRQHandler ; CPUSS DataWire #1, Channel #4 + DCD cpuss_interrupts_dw1_5_IRQHandler ; CPUSS DataWire #1, Channel #5 + DCD cpuss_interrupts_dw1_6_IRQHandler ; CPUSS DataWire #1, Channel #6 + DCD cpuss_interrupts_dw1_7_IRQHandler ; CPUSS DataWire #1, Channel #7 + DCD cpuss_interrupts_dw1_8_IRQHandler ; CPUSS DataWire #1, Channel #8 + DCD cpuss_interrupts_dw1_9_IRQHandler ; CPUSS DataWire #1, Channel #9 + DCD cpuss_interrupts_dw1_10_IRQHandler ; CPUSS DataWire #1, Channel #10 + DCD cpuss_interrupts_dw1_11_IRQHandler ; CPUSS DataWire #1, Channel #11 + DCD cpuss_interrupts_dw1_12_IRQHandler ; CPUSS DataWire #1, Channel #12 + DCD cpuss_interrupts_dw1_13_IRQHandler ; CPUSS DataWire #1, Channel #13 + DCD cpuss_interrupts_dw1_14_IRQHandler ; CPUSS DataWire #1, Channel #14 + DCD cpuss_interrupts_dw1_15_IRQHandler ; CPUSS DataWire #1, Channel #15 + DCD cpuss_interrupts_fault_0_IRQHandler ; CPUSS Fault Structure Interrupt #0 + DCD cpuss_interrupts_fault_1_IRQHandler ; CPUSS Fault Structure Interrupt #1 + DCD cpuss_interrupt_crypto_IRQHandler ; CRYPTO Accelerator Interrupt + DCD cpuss_interrupt_fm_IRQHandler ; FLASH Macro Interrupt + DCD cpuss_interrupts_cm0_cti_0_IRQHandler ; CM0+ CTI #0 + DCD cpuss_interrupts_cm0_cti_1_IRQHandler ; CM0+ CTI #1 + DCD cpuss_interrupts_cm4_cti_0_IRQHandler ; CM4 CTI #0 + DCD cpuss_interrupts_cm4_cti_1_IRQHandler ; CM4 CTI #1 + DCD tcpwm_0_interrupts_0_IRQHandler ; TCPWM #0, Counter #0 + DCD tcpwm_0_interrupts_1_IRQHandler ; TCPWM #0, Counter #1 + DCD tcpwm_0_interrupts_2_IRQHandler ; TCPWM #0, Counter #2 + DCD tcpwm_0_interrupts_3_IRQHandler ; TCPWM #0, Counter #3 + DCD tcpwm_0_interrupts_4_IRQHandler ; TCPWM #0, Counter #4 + DCD tcpwm_0_interrupts_5_IRQHandler ; TCPWM #0, Counter #5 + DCD tcpwm_0_interrupts_6_IRQHandler ; TCPWM #0, Counter #6 + DCD tcpwm_0_interrupts_7_IRQHandler ; TCPWM #0, Counter #7 + DCD tcpwm_1_interrupts_0_IRQHandler ; TCPWM #1, Counter #0 + DCD tcpwm_1_interrupts_1_IRQHandler ; TCPWM #1, Counter #1 + DCD tcpwm_1_interrupts_2_IRQHandler ; TCPWM #1, Counter #2 + DCD tcpwm_1_interrupts_3_IRQHandler ; TCPWM #1, Counter #3 + DCD tcpwm_1_interrupts_4_IRQHandler ; TCPWM #1, Counter #4 + DCD tcpwm_1_interrupts_5_IRQHandler ; TCPWM #1, Counter #5 + DCD tcpwm_1_interrupts_6_IRQHandler ; TCPWM #1, Counter #6 + DCD tcpwm_1_interrupts_7_IRQHandler ; TCPWM #1, Counter #7 + DCD tcpwm_1_interrupts_8_IRQHandler ; TCPWM #1, Counter #8 + DCD tcpwm_1_interrupts_9_IRQHandler ; TCPWM #1, Counter #9 + DCD tcpwm_1_interrupts_10_IRQHandler ; TCPWM #1, Counter #10 + DCD tcpwm_1_interrupts_11_IRQHandler ; TCPWM #1, Counter #11 + DCD tcpwm_1_interrupts_12_IRQHandler ; TCPWM #1, Counter #12 + DCD tcpwm_1_interrupts_13_IRQHandler ; TCPWM #1, Counter #13 + DCD tcpwm_1_interrupts_14_IRQHandler ; TCPWM #1, Counter #14 + DCD tcpwm_1_interrupts_15_IRQHandler ; TCPWM #1, Counter #15 + DCD tcpwm_1_interrupts_16_IRQHandler ; TCPWM #1, Counter #16 + DCD tcpwm_1_interrupts_17_IRQHandler ; TCPWM #1, Counter #17 + DCD tcpwm_1_interrupts_18_IRQHandler ; TCPWM #1, Counter #18 + DCD tcpwm_1_interrupts_19_IRQHandler ; TCPWM #1, Counter #19 + DCD tcpwm_1_interrupts_20_IRQHandler ; TCPWM #1, Counter #20 + DCD tcpwm_1_interrupts_21_IRQHandler ; TCPWM #1, Counter #21 + DCD tcpwm_1_interrupts_22_IRQHandler ; TCPWM #1, Counter #22 + DCD tcpwm_1_interrupts_23_IRQHandler ; TCPWM #1, Counter #23 + DCD udb_interrupts_0_IRQHandler ; UDB Interrupt #0 + DCD udb_interrupts_1_IRQHandler ; UDB Interrupt #1 + DCD udb_interrupts_2_IRQHandler ; UDB Interrupt #2 + DCD udb_interrupts_3_IRQHandler ; UDB Interrupt #3 + DCD udb_interrupts_4_IRQHandler ; UDB Interrupt #4 + DCD udb_interrupts_5_IRQHandler ; UDB Interrupt #5 + DCD udb_interrupts_6_IRQHandler ; UDB Interrupt #6 + DCD udb_interrupts_7_IRQHandler ; UDB Interrupt #7 + DCD udb_interrupts_8_IRQHandler ; UDB Interrupt #8 + DCD udb_interrupts_9_IRQHandler ; UDB Interrupt #9 + DCD udb_interrupts_10_IRQHandler ; UDB Interrupt #10 + DCD udb_interrupts_11_IRQHandler ; UDB Interrupt #11 + DCD udb_interrupts_12_IRQHandler ; UDB Interrupt #12 + DCD udb_interrupts_13_IRQHandler ; UDB Interrupt #13 + DCD udb_interrupts_14_IRQHandler ; UDB Interrupt #14 + DCD udb_interrupts_15_IRQHandler ; UDB Interrupt #15 + DCD pass_interrupt_sar_IRQHandler ; SAR ADC interrupt + DCD audioss_interrupt_i2s_IRQHandler ; I2S Audio interrupt + DCD audioss_interrupt_pdm_IRQHandler ; PDM/PCM Audio interrupt + DCD profile_interrupt_IRQHandler ; Energy Profiler interrupt + DCD smif_interrupt_IRQHandler ; Serial Memory Interface interrupt + DCD usb_interrupt_hi_IRQHandler ; USB Interrupt + DCD usb_interrupt_med_IRQHandler ; USB Interrupt + DCD usb_interrupt_lo_IRQHandler ; USB Interrupt + DCD pass_interrupt_dacs_IRQHandler ; Consolidated interrrupt for all DACs + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + EXPORT __ramVectors + AREA RESET_RAM, READWRITE, NOINIT +__ramVectors SPACE __Vectors_Size + + + AREA |.text|, CODE, READONLY + + +; Weak function for startup customization +; +; Note. The global resources are not yet initialized (for example global variables, peripherals, clocks) +; because this function is executed as the first instruction in the ResetHandler. +; The PDL is also not initialized to use the proper register offsets. +; The user of this function is responsible for initializing the PDL and resources before using them. +; +Cy_OnResetUser PROC + EXPORT Cy_OnResetUser [WEAK] + BX LR + ENDP + +; Reset Handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT Cy_SystemInitFpuEnable + IMPORT __main + + ; Define strong function for startup customization + BL Cy_OnResetUser + + ; Disable global interrupts + CPSID I + + ; Copy vectors from ROM to RAM + LDR r1, =__Vectors + LDR r0, =__ramVectors + LDR r2, =__Vectors_Size +Vectors_Copy + LDR r3, [r1] + STR r3, [r0] + ADDS r0, r0, #4 + ADDS r1, r1, #4 + SUBS r2, r2, #1 + CMP r2, #0 + BNE Vectors_Copy + + ; Update Vector Table Offset Register. */ + LDR r0, =__ramVectors + LDR r1, =0xE000ED08 + STR r0, [r1] + dsb 0xF + + ; Enable the FPU if used + LDR R0, =Cy_SystemInitFpuEnable + BLX R0 + + LDR R0, =__main + BLX R0 + + ; Should never get here + B . + + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP + +Cy_SysLib_FaultHandler PROC + EXPORT Cy_SysLib_FaultHandler [WEAK] + B . + ENDP +HardFault_Wrapper\ + PROC + EXPORT HardFault_Wrapper [WEAK] + movs r0, #4 + mov r1, LR + tst r0, r1 + beq L_MSP + mrs r0, PSP + bl L_API_call +L_MSP + mrs r0, MSP +L_API_call + bl Cy_SysLib_FaultHandler + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B HardFault_Wrapper + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B HardFault_Wrapper + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B HardFault_Wrapper + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B HardFault_Wrapper + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + EXPORT Default_Handler [WEAK] + EXPORT ioss_interrupts_gpio_0_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_1_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_2_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_3_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_4_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_5_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_6_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_7_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_8_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_9_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_10_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_11_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_12_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_13_IRQHandler [WEAK] + EXPORT ioss_interrupts_gpio_14_IRQHandler [WEAK] + EXPORT ioss_interrupt_gpio_IRQHandler [WEAK] + EXPORT ioss_interrupt_vdd_IRQHandler [WEAK] + EXPORT lpcomp_interrupt_IRQHandler [WEAK] + EXPORT scb_8_interrupt_IRQHandler [WEAK] + EXPORT srss_interrupt_mcwdt_0_IRQHandler [WEAK] + EXPORT srss_interrupt_mcwdt_1_IRQHandler [WEAK] + EXPORT srss_interrupt_backup_IRQHandler [WEAK] + EXPORT srss_interrupt_IRQHandler [WEAK] + EXPORT pass_interrupt_ctbs_IRQHandler [WEAK] + EXPORT bless_interrupt_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_0_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_1_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_2_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_3_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_4_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_5_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_6_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_7_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_8_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_9_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_10_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_11_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_12_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_13_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_14_IRQHandler [WEAK] + EXPORT cpuss_interrupts_ipc_15_IRQHandler [WEAK] + EXPORT scb_0_interrupt_IRQHandler [WEAK] + EXPORT scb_1_interrupt_IRQHandler [WEAK] + EXPORT scb_2_interrupt_IRQHandler [WEAK] + EXPORT scb_3_interrupt_IRQHandler [WEAK] + EXPORT scb_4_interrupt_IRQHandler [WEAK] + EXPORT scb_5_interrupt_IRQHandler [WEAK] + EXPORT scb_6_interrupt_IRQHandler [WEAK] + EXPORT scb_7_interrupt_IRQHandler [WEAK] + EXPORT csd_interrupt_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_0_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_1_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_2_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_3_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_4_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_5_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_6_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_7_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_8_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_9_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_10_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_11_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_12_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_13_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_14_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw0_15_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_0_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_1_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_2_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_3_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_4_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_5_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_6_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_7_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_8_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_9_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_10_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_11_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_12_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_13_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_14_IRQHandler [WEAK] + EXPORT cpuss_interrupts_dw1_15_IRQHandler [WEAK] + EXPORT cpuss_interrupts_fault_0_IRQHandler [WEAK] + EXPORT cpuss_interrupts_fault_1_IRQHandler [WEAK] + EXPORT cpuss_interrupt_crypto_IRQHandler [WEAK] + EXPORT cpuss_interrupt_fm_IRQHandler [WEAK] + EXPORT cpuss_interrupts_cm0_cti_0_IRQHandler [WEAK] + EXPORT cpuss_interrupts_cm0_cti_1_IRQHandler [WEAK] + EXPORT cpuss_interrupts_cm4_cti_0_IRQHandler [WEAK] + EXPORT cpuss_interrupts_cm4_cti_1_IRQHandler [WEAK] + EXPORT tcpwm_0_interrupts_0_IRQHandler [WEAK] + EXPORT tcpwm_0_interrupts_1_IRQHandler [WEAK] + EXPORT tcpwm_0_interrupts_2_IRQHandler [WEAK] + EXPORT tcpwm_0_interrupts_3_IRQHandler [WEAK] + EXPORT tcpwm_0_interrupts_4_IRQHandler [WEAK] + EXPORT tcpwm_0_interrupts_5_IRQHandler [WEAK] + EXPORT tcpwm_0_interrupts_6_IRQHandler [WEAK] + EXPORT tcpwm_0_interrupts_7_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_0_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_1_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_2_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_3_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_4_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_5_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_6_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_7_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_8_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_9_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_10_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_11_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_12_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_13_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_14_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_15_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_16_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_17_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_18_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_19_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_20_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_21_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_22_IRQHandler [WEAK] + EXPORT tcpwm_1_interrupts_23_IRQHandler [WEAK] + EXPORT udb_interrupts_0_IRQHandler [WEAK] + EXPORT udb_interrupts_1_IRQHandler [WEAK] + EXPORT udb_interrupts_2_IRQHandler [WEAK] + EXPORT udb_interrupts_3_IRQHandler [WEAK] + EXPORT udb_interrupts_4_IRQHandler [WEAK] + EXPORT udb_interrupts_5_IRQHandler [WEAK] + EXPORT udb_interrupts_6_IRQHandler [WEAK] + EXPORT udb_interrupts_7_IRQHandler [WEAK] + EXPORT udb_interrupts_8_IRQHandler [WEAK] + EXPORT udb_interrupts_9_IRQHandler [WEAK] + EXPORT udb_interrupts_10_IRQHandler [WEAK] + EXPORT udb_interrupts_11_IRQHandler [WEAK] + EXPORT udb_interrupts_12_IRQHandler [WEAK] + EXPORT udb_interrupts_13_IRQHandler [WEAK] + EXPORT udb_interrupts_14_IRQHandler [WEAK] + EXPORT udb_interrupts_15_IRQHandler [WEAK] + EXPORT pass_interrupt_sar_IRQHandler [WEAK] + EXPORT audioss_interrupt_i2s_IRQHandler [WEAK] + EXPORT audioss_interrupt_pdm_IRQHandler [WEAK] + EXPORT profile_interrupt_IRQHandler [WEAK] + EXPORT smif_interrupt_IRQHandler [WEAK] + EXPORT usb_interrupt_hi_IRQHandler [WEAK] + EXPORT usb_interrupt_med_IRQHandler [WEAK] + EXPORT usb_interrupt_lo_IRQHandler [WEAK] + EXPORT pass_interrupt_dacs_IRQHandler [WEAK] + +ioss_interrupts_gpio_0_IRQHandler +ioss_interrupts_gpio_1_IRQHandler +ioss_interrupts_gpio_2_IRQHandler +ioss_interrupts_gpio_3_IRQHandler +ioss_interrupts_gpio_4_IRQHandler +ioss_interrupts_gpio_5_IRQHandler +ioss_interrupts_gpio_6_IRQHandler +ioss_interrupts_gpio_7_IRQHandler +ioss_interrupts_gpio_8_IRQHandler +ioss_interrupts_gpio_9_IRQHandler +ioss_interrupts_gpio_10_IRQHandler +ioss_interrupts_gpio_11_IRQHandler +ioss_interrupts_gpio_12_IRQHandler +ioss_interrupts_gpio_13_IRQHandler +ioss_interrupts_gpio_14_IRQHandler +ioss_interrupt_gpio_IRQHandler +ioss_interrupt_vdd_IRQHandler +lpcomp_interrupt_IRQHandler +scb_8_interrupt_IRQHandler +srss_interrupt_mcwdt_0_IRQHandler +srss_interrupt_mcwdt_1_IRQHandler +srss_interrupt_backup_IRQHandler +srss_interrupt_IRQHandler +pass_interrupt_ctbs_IRQHandler +bless_interrupt_IRQHandler +cpuss_interrupts_ipc_0_IRQHandler +cpuss_interrupts_ipc_1_IRQHandler +cpuss_interrupts_ipc_2_IRQHandler +cpuss_interrupts_ipc_3_IRQHandler +cpuss_interrupts_ipc_4_IRQHandler +cpuss_interrupts_ipc_5_IRQHandler +cpuss_interrupts_ipc_6_IRQHandler +cpuss_interrupts_ipc_7_IRQHandler +cpuss_interrupts_ipc_8_IRQHandler +cpuss_interrupts_ipc_9_IRQHandler +cpuss_interrupts_ipc_10_IRQHandler +cpuss_interrupts_ipc_11_IRQHandler +cpuss_interrupts_ipc_12_IRQHandler +cpuss_interrupts_ipc_13_IRQHandler +cpuss_interrupts_ipc_14_IRQHandler +cpuss_interrupts_ipc_15_IRQHandler +scb_0_interrupt_IRQHandler +scb_1_interrupt_IRQHandler +scb_2_interrupt_IRQHandler +scb_3_interrupt_IRQHandler +scb_4_interrupt_IRQHandler +scb_5_interrupt_IRQHandler +scb_6_interrupt_IRQHandler +scb_7_interrupt_IRQHandler +csd_interrupt_IRQHandler +cpuss_interrupts_dw0_0_IRQHandler +cpuss_interrupts_dw0_1_IRQHandler +cpuss_interrupts_dw0_2_IRQHandler +cpuss_interrupts_dw0_3_IRQHandler +cpuss_interrupts_dw0_4_IRQHandler +cpuss_interrupts_dw0_5_IRQHandler +cpuss_interrupts_dw0_6_IRQHandler +cpuss_interrupts_dw0_7_IRQHandler +cpuss_interrupts_dw0_8_IRQHandler +cpuss_interrupts_dw0_9_IRQHandler +cpuss_interrupts_dw0_10_IRQHandler +cpuss_interrupts_dw0_11_IRQHandler +cpuss_interrupts_dw0_12_IRQHandler +cpuss_interrupts_dw0_13_IRQHandler +cpuss_interrupts_dw0_14_IRQHandler +cpuss_interrupts_dw0_15_IRQHandler +cpuss_interrupts_dw1_0_IRQHandler +cpuss_interrupts_dw1_1_IRQHandler +cpuss_interrupts_dw1_2_IRQHandler +cpuss_interrupts_dw1_3_IRQHandler +cpuss_interrupts_dw1_4_IRQHandler +cpuss_interrupts_dw1_5_IRQHandler +cpuss_interrupts_dw1_6_IRQHandler +cpuss_interrupts_dw1_7_IRQHandler +cpuss_interrupts_dw1_8_IRQHandler +cpuss_interrupts_dw1_9_IRQHandler +cpuss_interrupts_dw1_10_IRQHandler +cpuss_interrupts_dw1_11_IRQHandler +cpuss_interrupts_dw1_12_IRQHandler +cpuss_interrupts_dw1_13_IRQHandler +cpuss_interrupts_dw1_14_IRQHandler +cpuss_interrupts_dw1_15_IRQHandler +cpuss_interrupts_fault_0_IRQHandler +cpuss_interrupts_fault_1_IRQHandler +cpuss_interrupt_crypto_IRQHandler +cpuss_interrupt_fm_IRQHandler +cpuss_interrupts_cm0_cti_0_IRQHandler +cpuss_interrupts_cm0_cti_1_IRQHandler +cpuss_interrupts_cm4_cti_0_IRQHandler +cpuss_interrupts_cm4_cti_1_IRQHandler +tcpwm_0_interrupts_0_IRQHandler +tcpwm_0_interrupts_1_IRQHandler +tcpwm_0_interrupts_2_IRQHandler +tcpwm_0_interrupts_3_IRQHandler +tcpwm_0_interrupts_4_IRQHandler +tcpwm_0_interrupts_5_IRQHandler +tcpwm_0_interrupts_6_IRQHandler +tcpwm_0_interrupts_7_IRQHandler +tcpwm_1_interrupts_0_IRQHandler +tcpwm_1_interrupts_1_IRQHandler +tcpwm_1_interrupts_2_IRQHandler +tcpwm_1_interrupts_3_IRQHandler +tcpwm_1_interrupts_4_IRQHandler +tcpwm_1_interrupts_5_IRQHandler +tcpwm_1_interrupts_6_IRQHandler +tcpwm_1_interrupts_7_IRQHandler +tcpwm_1_interrupts_8_IRQHandler +tcpwm_1_interrupts_9_IRQHandler +tcpwm_1_interrupts_10_IRQHandler +tcpwm_1_interrupts_11_IRQHandler +tcpwm_1_interrupts_12_IRQHandler +tcpwm_1_interrupts_13_IRQHandler +tcpwm_1_interrupts_14_IRQHandler +tcpwm_1_interrupts_15_IRQHandler +tcpwm_1_interrupts_16_IRQHandler +tcpwm_1_interrupts_17_IRQHandler +tcpwm_1_interrupts_18_IRQHandler +tcpwm_1_interrupts_19_IRQHandler +tcpwm_1_interrupts_20_IRQHandler +tcpwm_1_interrupts_21_IRQHandler +tcpwm_1_interrupts_22_IRQHandler +tcpwm_1_interrupts_23_IRQHandler +udb_interrupts_0_IRQHandler +udb_interrupts_1_IRQHandler +udb_interrupts_2_IRQHandler +udb_interrupts_3_IRQHandler +udb_interrupts_4_IRQHandler +udb_interrupts_5_IRQHandler +udb_interrupts_6_IRQHandler +udb_interrupts_7_IRQHandler +udb_interrupts_8_IRQHandler +udb_interrupts_9_IRQHandler +udb_interrupts_10_IRQHandler +udb_interrupts_11_IRQHandler +udb_interrupts_12_IRQHandler +udb_interrupts_13_IRQHandler +udb_interrupts_14_IRQHandler +udb_interrupts_15_IRQHandler +pass_interrupt_sar_IRQHandler +audioss_interrupt_i2s_IRQHandler +audioss_interrupt_pdm_IRQHandler +profile_interrupt_IRQHandler +smif_interrupt_IRQHandler +usb_interrupt_hi_IRQHandler +usb_interrupt_med_IRQHandler +usb_interrupt_lo_IRQHandler +pass_interrupt_dacs_IRQHandler + + B . + ENDP + + ALIGN + + +; User Initial Stack & Heap + IMPORT __use_two_region_memory + + END + + +; [] END OF FILE diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_A_Clang/startup_psoc6_01_cm4.S b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_A_Clang/startup_psoc6_01_cm4.S new file mode 100644 index 0000000000..e641b3cc42 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_A_Clang/startup_psoc6_01_cm4.S @@ -0,0 +1,554 @@ +/**************************************************************************//** + * @file startup_psoc6_01_cm4.S + * @brief CMSIS Core Device Startup File for + * ARMCM4 Device Series + * @version V5.00 + * @date 02. March 2016 + ******************************************************************************/ +/* + * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * 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. + */ + + /* Address of the NMI handler */ + #define CY_NMI_HANLDER_ADDR 0x0000000D + + /* The CPU VTOR register */ + #define CY_CPU_VTOR_ADDR 0xE000ED08 + + .syntax unified + .section __STACK , __stack + .align 3 + +#ifdef __STACK_SIZE + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 0x00001000 +#endif + .globl __StackTop + .globl __StackLimit + __StackLimit: + .space Stack_Size + .equ __StackTop, . - Stack_Size + + .section __HEAP, __heap + .align 3 +#ifdef __HEAP_SIZE + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 0x00000400 +#endif + .globl __HeapBase +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + + .section __VECT, ___Vectors + .align 2 + .globl ___Vectors +___Vectors: + .long __StackTop /* Top of Stack */ + .long Reset_Handler+1 /* Reset Handler. Added +1, clang doesn't make lsb to 1 for thumb */ + .long CY_NMI_HANLDER_ADDR /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* External interrupts Description */ + .long ioss_interrupts_gpio_0_IRQHandler /* GPIO Port Interrupt #0 */ + .long ioss_interrupts_gpio_1_IRQHandler /* GPIO Port Interrupt #1 */ + .long ioss_interrupts_gpio_2_IRQHandler /* GPIO Port Interrupt #2 */ + .long ioss_interrupts_gpio_3_IRQHandler /* GPIO Port Interrupt #3 */ + .long ioss_interrupts_gpio_4_IRQHandler /* GPIO Port Interrupt #4 */ + .long ioss_interrupts_gpio_5_IRQHandler /* GPIO Port Interrupt #5 */ + .long ioss_interrupts_gpio_6_IRQHandler /* GPIO Port Interrupt #6 */ + .long ioss_interrupts_gpio_7_IRQHandler /* GPIO Port Interrupt #7 */ + .long ioss_interrupts_gpio_8_IRQHandler /* GPIO Port Interrupt #8 */ + .long ioss_interrupts_gpio_9_IRQHandler /* GPIO Port Interrupt #9 */ + .long ioss_interrupts_gpio_10_IRQHandler /* GPIO Port Interrupt #10 */ + .long ioss_interrupts_gpio_11_IRQHandler /* GPIO Port Interrupt #11 */ + .long ioss_interrupts_gpio_12_IRQHandler /* GPIO Port Interrupt #12 */ + .long ioss_interrupts_gpio_13_IRQHandler /* GPIO Port Interrupt #13 */ + .long ioss_interrupts_gpio_14_IRQHandler /* GPIO Port Interrupt #14 */ + .long ioss_interrupt_gpio_IRQHandler /* GPIO All Ports */ + .long ioss_interrupt_vdd_IRQHandler /* GPIO Supply Detect Interrupt */ + .long lpcomp_interrupt_IRQHandler /* Low Power Comparator Interrupt */ + .long scb_8_interrupt_IRQHandler /* Serial Communication Block #8 (DeepSleep capable) */ + .long srss_interrupt_mcwdt_0_IRQHandler /* Multi Counter Watchdog Timer interrupt */ + .long srss_interrupt_mcwdt_1_IRQHandler /* Multi Counter Watchdog Timer interrupt */ + .long srss_interrupt_backup_IRQHandler /* Backup domain interrupt */ + .long srss_interrupt_IRQHandler /* Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) */ + .long pass_interrupt_ctbs_IRQHandler /* CTBm Interrupt (all CTBms) */ + .long bless_interrupt_IRQHandler /* Bluetooth Radio interrupt */ + .long cpuss_interrupts_ipc_0_IRQHandler /* CPUSS Inter Process Communication Interrupt #0 */ + .long cpuss_interrupts_ipc_1_IRQHandler /* CPUSS Inter Process Communication Interrupt #1 */ + .long cpuss_interrupts_ipc_2_IRQHandler /* CPUSS Inter Process Communication Interrupt #2 */ + .long cpuss_interrupts_ipc_3_IRQHandler /* CPUSS Inter Process Communication Interrupt #3 */ + .long cpuss_interrupts_ipc_4_IRQHandler /* CPUSS Inter Process Communication Interrupt #4 */ + .long cpuss_interrupts_ipc_5_IRQHandler /* CPUSS Inter Process Communication Interrupt #5 */ + .long cpuss_interrupts_ipc_6_IRQHandler /* CPUSS Inter Process Communication Interrupt #6 */ + .long cpuss_interrupts_ipc_7_IRQHandler /* CPUSS Inter Process Communication Interrupt #7 */ + .long cpuss_interrupts_ipc_8_IRQHandler /* CPUSS Inter Process Communication Interrupt #8 */ + .long cpuss_interrupts_ipc_9_IRQHandler /* CPUSS Inter Process Communication Interrupt #9 */ + .long cpuss_interrupts_ipc_10_IRQHandler /* CPUSS Inter Process Communication Interrupt #10 */ + .long cpuss_interrupts_ipc_11_IRQHandler /* CPUSS Inter Process Communication Interrupt #11 */ + .long cpuss_interrupts_ipc_12_IRQHandler /* CPUSS Inter Process Communication Interrupt #12 */ + .long cpuss_interrupts_ipc_13_IRQHandler /* CPUSS Inter Process Communication Interrupt #13 */ + .long cpuss_interrupts_ipc_14_IRQHandler /* CPUSS Inter Process Communication Interrupt #14 */ + .long cpuss_interrupts_ipc_15_IRQHandler /* CPUSS Inter Process Communication Interrupt #15 */ + .long scb_0_interrupt_IRQHandler /* Serial Communication Block #0 */ + .long scb_1_interrupt_IRQHandler /* Serial Communication Block #1 */ + .long scb_2_interrupt_IRQHandler /* Serial Communication Block #2 */ + .long scb_3_interrupt_IRQHandler /* Serial Communication Block #3 */ + .long scb_4_interrupt_IRQHandler /* Serial Communication Block #4 */ + .long scb_5_interrupt_IRQHandler /* Serial Communication Block #5 */ + .long scb_6_interrupt_IRQHandler /* Serial Communication Block #6 */ + .long scb_7_interrupt_IRQHandler /* Serial Communication Block #7 */ + .long csd_interrupt_IRQHandler /* CSD (Capsense) interrupt */ + .long cpuss_interrupts_dw0_0_IRQHandler /* CPUSS DataWire #0, Channel #0 */ + .long cpuss_interrupts_dw0_1_IRQHandler /* CPUSS DataWire #0, Channel #1 */ + .long cpuss_interrupts_dw0_2_IRQHandler /* CPUSS DataWire #0, Channel #2 */ + .long cpuss_interrupts_dw0_3_IRQHandler /* CPUSS DataWire #0, Channel #3 */ + .long cpuss_interrupts_dw0_4_IRQHandler /* CPUSS DataWire #0, Channel #4 */ + .long cpuss_interrupts_dw0_5_IRQHandler /* CPUSS DataWire #0, Channel #5 */ + .long cpuss_interrupts_dw0_6_IRQHandler /* CPUSS DataWire #0, Channel #6 */ + .long cpuss_interrupts_dw0_7_IRQHandler /* CPUSS DataWire #0, Channel #7 */ + .long cpuss_interrupts_dw0_8_IRQHandler /* CPUSS DataWire #0, Channel #8 */ + .long cpuss_interrupts_dw0_9_IRQHandler /* CPUSS DataWire #0, Channel #9 */ + .long cpuss_interrupts_dw0_10_IRQHandler /* CPUSS DataWire #0, Channel #10 */ + .long cpuss_interrupts_dw0_11_IRQHandler /* CPUSS DataWire #0, Channel #11 */ + .long cpuss_interrupts_dw0_12_IRQHandler /* CPUSS DataWire #0, Channel #12 */ + .long cpuss_interrupts_dw0_13_IRQHandler /* CPUSS DataWire #0, Channel #13 */ + .long cpuss_interrupts_dw0_14_IRQHandler /* CPUSS DataWire #0, Channel #14 */ + .long cpuss_interrupts_dw0_15_IRQHandler /* CPUSS DataWire #0, Channel #15 */ + .long cpuss_interrupts_dw1_0_IRQHandler /* CPUSS DataWire #1, Channel #0 */ + .long cpuss_interrupts_dw1_1_IRQHandler /* CPUSS DataWire #1, Channel #1 */ + .long cpuss_interrupts_dw1_2_IRQHandler /* CPUSS DataWire #1, Channel #2 */ + .long cpuss_interrupts_dw1_3_IRQHandler /* CPUSS DataWire #1, Channel #3 */ + .long cpuss_interrupts_dw1_4_IRQHandler /* CPUSS DataWire #1, Channel #4 */ + .long cpuss_interrupts_dw1_5_IRQHandler /* CPUSS DataWire #1, Channel #5 */ + .long cpuss_interrupts_dw1_6_IRQHandler /* CPUSS DataWire #1, Channel #6 */ + .long cpuss_interrupts_dw1_7_IRQHandler /* CPUSS DataWire #1, Channel #7 */ + .long cpuss_interrupts_dw1_8_IRQHandler /* CPUSS DataWire #1, Channel #8 */ + .long cpuss_interrupts_dw1_9_IRQHandler /* CPUSS DataWire #1, Channel #9 */ + .long cpuss_interrupts_dw1_10_IRQHandler /* CPUSS DataWire #1, Channel #10 */ + .long cpuss_interrupts_dw1_11_IRQHandler /* CPUSS DataWire #1, Channel #11 */ + .long cpuss_interrupts_dw1_12_IRQHandler /* CPUSS DataWire #1, Channel #12 */ + .long cpuss_interrupts_dw1_13_IRQHandler /* CPUSS DataWire #1, Channel #13 */ + .long cpuss_interrupts_dw1_14_IRQHandler /* CPUSS DataWire #1, Channel #14 */ + .long cpuss_interrupts_dw1_15_IRQHandler /* CPUSS DataWire #1, Channel #15 */ + .long cpuss_interrupts_fault_0_IRQHandler /* CPUSS Fault Structure Interrupt #0 */ + .long cpuss_interrupts_fault_1_IRQHandler /* CPUSS Fault Structure Interrupt #1 */ + .long cpuss_interrupt_crypto_IRQHandler /* CRYPTO Accelerator Interrupt */ + .long cpuss_interrupt_fm_IRQHandler /* FLASH Macro Interrupt */ + .long cpuss_interrupts_cm0_cti_0_IRQHandler /* CM0+ CTI #0 */ + .long cpuss_interrupts_cm0_cti_1_IRQHandler /* CM0+ CTI #1 */ + .long cpuss_interrupts_cm4_cti_0_IRQHandler /* CM4 CTI #0 */ + .long cpuss_interrupts_cm4_cti_1_IRQHandler /* CM4 CTI #1 */ + .long tcpwm_0_interrupts_0_IRQHandler /* TCPWM #0, Counter #0 */ + .long tcpwm_0_interrupts_1_IRQHandler /* TCPWM #0, Counter #1 */ + .long tcpwm_0_interrupts_2_IRQHandler /* TCPWM #0, Counter #2 */ + .long tcpwm_0_interrupts_3_IRQHandler /* TCPWM #0, Counter #3 */ + .long tcpwm_0_interrupts_4_IRQHandler /* TCPWM #0, Counter #4 */ + .long tcpwm_0_interrupts_5_IRQHandler /* TCPWM #0, Counter #5 */ + .long tcpwm_0_interrupts_6_IRQHandler /* TCPWM #0, Counter #6 */ + .long tcpwm_0_interrupts_7_IRQHandler /* TCPWM #0, Counter #7 */ + .long tcpwm_1_interrupts_0_IRQHandler /* TCPWM #1, Counter #0 */ + .long tcpwm_1_interrupts_1_IRQHandler /* TCPWM #1, Counter #1 */ + .long tcpwm_1_interrupts_2_IRQHandler /* TCPWM #1, Counter #2 */ + .long tcpwm_1_interrupts_3_IRQHandler /* TCPWM #1, Counter #3 */ + .long tcpwm_1_interrupts_4_IRQHandler /* TCPWM #1, Counter #4 */ + .long tcpwm_1_interrupts_5_IRQHandler /* TCPWM #1, Counter #5 */ + .long tcpwm_1_interrupts_6_IRQHandler /* TCPWM #1, Counter #6 */ + .long tcpwm_1_interrupts_7_IRQHandler /* TCPWM #1, Counter #7 */ + .long tcpwm_1_interrupts_8_IRQHandler /* TCPWM #1, Counter #8 */ + .long tcpwm_1_interrupts_9_IRQHandler /* TCPWM #1, Counter #9 */ + .long tcpwm_1_interrupts_10_IRQHandler /* TCPWM #1, Counter #10 */ + .long tcpwm_1_interrupts_11_IRQHandler /* TCPWM #1, Counter #11 */ + .long tcpwm_1_interrupts_12_IRQHandler /* TCPWM #1, Counter #12 */ + .long tcpwm_1_interrupts_13_IRQHandler /* TCPWM #1, Counter #13 */ + .long tcpwm_1_interrupts_14_IRQHandler /* TCPWM #1, Counter #14 */ + .long tcpwm_1_interrupts_15_IRQHandler /* TCPWM #1, Counter #15 */ + .long tcpwm_1_interrupts_16_IRQHandler /* TCPWM #1, Counter #16 */ + .long tcpwm_1_interrupts_17_IRQHandler /* TCPWM #1, Counter #17 */ + .long tcpwm_1_interrupts_18_IRQHandler /* TCPWM #1, Counter #18 */ + .long tcpwm_1_interrupts_19_IRQHandler /* TCPWM #1, Counter #19 */ + .long tcpwm_1_interrupts_20_IRQHandler /* TCPWM #1, Counter #20 */ + .long tcpwm_1_interrupts_21_IRQHandler /* TCPWM #1, Counter #21 */ + .long tcpwm_1_interrupts_22_IRQHandler /* TCPWM #1, Counter #22 */ + .long tcpwm_1_interrupts_23_IRQHandler /* TCPWM #1, Counter #23 */ + .long udb_interrupts_0_IRQHandler /* UDB Interrupt #0 */ + .long udb_interrupts_1_IRQHandler /* UDB Interrupt #1 */ + .long udb_interrupts_2_IRQHandler /* UDB Interrupt #2 */ + .long udb_interrupts_3_IRQHandler /* UDB Interrupt #3 */ + .long udb_interrupts_4_IRQHandler /* UDB Interrupt #4 */ + .long udb_interrupts_5_IRQHandler /* UDB Interrupt #5 */ + .long udb_interrupts_6_IRQHandler /* UDB Interrupt #6 */ + .long udb_interrupts_7_IRQHandler /* UDB Interrupt #7 */ + .long udb_interrupts_8_IRQHandler /* UDB Interrupt #8 */ + .long udb_interrupts_9_IRQHandler /* UDB Interrupt #9 */ + .long udb_interrupts_10_IRQHandler /* UDB Interrupt #10 */ + .long udb_interrupts_11_IRQHandler /* UDB Interrupt #11 */ + .long udb_interrupts_12_IRQHandler /* UDB Interrupt #12 */ + .long udb_interrupts_13_IRQHandler /* UDB Interrupt #13 */ + .long udb_interrupts_14_IRQHandler /* UDB Interrupt #14 */ + .long udb_interrupts_15_IRQHandler /* UDB Interrupt #15 */ + .long pass_interrupt_sar_IRQHandler /* SAR ADC interrupt */ + .long audioss_interrupt_i2s_IRQHandler /* I2S Audio interrupt */ + .long audioss_interrupt_pdm_IRQHandler /* PDM/PCM Audio interrupt */ + .long profile_interrupt_IRQHandler /* Energy Profiler interrupt */ + .long smif_interrupt_IRQHandler /* Serial Memory Interface interrupt */ + .long usb_interrupt_hi_IRQHandler /* USB Interrupt */ + .long usb_interrupt_med_IRQHandler /* USB Interrupt */ + .long usb_interrupt_lo_IRQHandler /* USB Interrupt */ + .long pass_interrupt_dacs_IRQHandler /* Consolidated interrrupt for all DACs */ + + .equ __VectorsSize, . - ___Vectors + + .section __RAMVECTORS, ___ramVectors + .align 2 + .globl ___ramVectors +___ramVectors: + .space __VectorsSize + + + /* Only .text, otherwise the linker is smart enough to treat .thumb_func as 2 byte aligned and the + * Reset handler vector + 1 in the vector table ends up at +2 and boot fails. Clang/LLVM issue. + */ + .text + /* Reset handler */ + .globl Reset_Handler + +Reset_Handler: + bl Cy_OnResetUser + cpsid i + +/* Single section scheme. + * + * The ranges of copy from/to are specified by following symbols + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to + * __data_end__: VMA of end of the section to copy to + * + * All addresses must be aligned to 4 bytes boundary. + */ + .equ __copy_table_start__, ___Vectors + .equ __data_start__, ___ramVectors + .equ __data_end__, __data_start__ + __VectorsSize + ldr r1, =__copy_table_start__ + ldr r2, =__data_start__ + ldr r3, =__data_end__ +.L_loop_copy_table: + subs r4, r3, r2 + ble .L_loop_copy_table_done + ldr r0, [r1,r4] + str r0, [r2,r4] + subs r3, #4 + bgt .L_loop_copy_table +.L_loop_copy_table_done: + ldr r1, =segment$end$__TEXT + ldr r2, =section$start$__DATA$__data + ldr r3, =section$end$__DATA$__data + mov r4, #3 + adds r1, #3 + mvn r4, r4 + and r1, r4 +.L_loop_copy_data: + subs r4, r3, r2 + ble .L_loop_copy_data_done + ldr r0, [r1,r4] + str r0, [r2,r4] + subs r3, #4 + bgt .L_loop_copy_data +.L_loop_copy_data_done: + ldr r2, =section$start$__DATA$__bss + ldr r3, =section$end$__DATA$__bss +.L_loop_bss: + subs r1, r3, r2 + ble .L_loop_bss_done + movs r0, #0 + str r0, [r2,r1] + subs r3, #4 + bgt .L_loop_bss +.L_loop_bss_done: + ldr r2, =section$start$__DATA$__zerofill + ldr r3, =section$end$__DATA$__zerofill +.L_loop_zerofill: + subs r1, r3, r2 + ble .L_loop_zerofill_done + movs r0, #0 + str r0, [r2,r1] + subs r3, #4 + bgt .L_loop_zerofill +.L_loop_zerofill_done: + + /* Update Vector Table Offset Register. */ + ldr r0, =___ramVectors + ldr r1, =CY_CPU_VTOR_ADDR + str r0, [r1] + dsb 0xF + + /* Enable the FPU if used */ + bl _Cy_SystemInitFpuEnable + + bl _HeapInit +#ifndef __NO_SYSTEM_INIT + bl _SystemInit +#endif + + bl _main + + /* Should never get here */ + b . + + .pool + + .text + .thumb + .thumb_func + .align 2 + + /* Device startup customization */ + .weak_definition Cy_OnResetUser + .global Cy_OnResetUser, Cy_OnResetUser +Cy_OnResetUser: + bx lr + + .text + .align 1 + .thumb_func + .weak_reference Default_Handler + +Default_Handler: + b . + + .text + .thumb_func + .align 2 + .weak_definition Cy_SysLib_FaultHandler + +Cy_SysLib_FaultHandler: + b . + + .text + .thumb_func + .align 2 + +Fault_Handler: + /* Storing LR content for Creator call stack trace */ + push {LR} + movs r0, #4 + mov r1, LR + tst r0, r1 + beq .L_MSP + mrs r0, PSP + b .L_API_call +.L_MSP: + mrs r0, MSP +.L_API_call: + /* Compensation of stack pointer address due to pushing 4 bytes of LR */ + adds r0, r0, #4 + bl Cy_SysLib_FaultHandler + b . + +.macro def_fault_Handler fault_handler_name + .weak_definition \fault_handler_name + .set \fault_handler_name, Fault_Handler + .endm + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak_definition \handler_name + .set \handler_name, Default_Handler + .endm + + def_irq_handler NMI_Handler + + def_fault_Handler HardFault_Handler + def_fault_Handler MemManage_Handler + def_fault_Handler BusFault_Handler + def_fault_Handler UsageFault_Handler + + def_irq_handler SVC_Handler + def_irq_handler DebugMon_Handler + def_irq_handler PendSV_Handler + def_irq_handler SysTick_Handler + + def_irq_handler ioss_interrupts_gpio_0_IRQHandler /* GPIO Port Interrupt #0 */ + def_irq_handler ioss_interrupts_gpio_1_IRQHandler /* GPIO Port Interrupt #1 */ + def_irq_handler ioss_interrupts_gpio_2_IRQHandler /* GPIO Port Interrupt #2 */ + def_irq_handler ioss_interrupts_gpio_3_IRQHandler /* GPIO Port Interrupt #3 */ + def_irq_handler ioss_interrupts_gpio_4_IRQHandler /* GPIO Port Interrupt #4 */ + def_irq_handler ioss_interrupts_gpio_5_IRQHandler /* GPIO Port Interrupt #5 */ + def_irq_handler ioss_interrupts_gpio_6_IRQHandler /* GPIO Port Interrupt #6 */ + def_irq_handler ioss_interrupts_gpio_7_IRQHandler /* GPIO Port Interrupt #7 */ + def_irq_handler ioss_interrupts_gpio_8_IRQHandler /* GPIO Port Interrupt #8 */ + def_irq_handler ioss_interrupts_gpio_9_IRQHandler /* GPIO Port Interrupt #9 */ + def_irq_handler ioss_interrupts_gpio_10_IRQHandler /* GPIO Port Interrupt #10 */ + def_irq_handler ioss_interrupts_gpio_11_IRQHandler /* GPIO Port Interrupt #11 */ + def_irq_handler ioss_interrupts_gpio_12_IRQHandler /* GPIO Port Interrupt #12 */ + def_irq_handler ioss_interrupts_gpio_13_IRQHandler /* GPIO Port Interrupt #13 */ + def_irq_handler ioss_interrupts_gpio_14_IRQHandler /* GPIO Port Interrupt #14 */ + def_irq_handler ioss_interrupt_gpio_IRQHandler /* GPIO All Ports */ + def_irq_handler ioss_interrupt_vdd_IRQHandler /* GPIO Supply Detect Interrupt */ + def_irq_handler lpcomp_interrupt_IRQHandler /* Low Power Comparator Interrupt */ + def_irq_handler scb_8_interrupt_IRQHandler /* Serial Communication Block #8 (DeepSleep capable) */ + def_irq_handler srss_interrupt_mcwdt_0_IRQHandler /* Multi Counter Watchdog Timer interrupt */ + def_irq_handler srss_interrupt_mcwdt_1_IRQHandler /* Multi Counter Watchdog Timer interrupt */ + def_irq_handler srss_interrupt_backup_IRQHandler /* Backup domain interrupt */ + def_irq_handler srss_interrupt_IRQHandler /* Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) */ + def_irq_handler pass_interrupt_ctbs_IRQHandler /* CTBm Interrupt (all CTBms) */ + def_irq_handler bless_interrupt_IRQHandler /* Bluetooth Radio interrupt */ + def_irq_handler cpuss_interrupts_ipc_0_IRQHandler /* CPUSS Inter Process Communication Interrupt #0 */ + def_irq_handler cpuss_interrupts_ipc_1_IRQHandler /* CPUSS Inter Process Communication Interrupt #1 */ + def_irq_handler cpuss_interrupts_ipc_2_IRQHandler /* CPUSS Inter Process Communication Interrupt #2 */ + def_irq_handler cpuss_interrupts_ipc_3_IRQHandler /* CPUSS Inter Process Communication Interrupt #3 */ + def_irq_handler cpuss_interrupts_ipc_4_IRQHandler /* CPUSS Inter Process Communication Interrupt #4 */ + def_irq_handler cpuss_interrupts_ipc_5_IRQHandler /* CPUSS Inter Process Communication Interrupt #5 */ + def_irq_handler cpuss_interrupts_ipc_6_IRQHandler /* CPUSS Inter Process Communication Interrupt #6 */ + def_irq_handler cpuss_interrupts_ipc_7_IRQHandler /* CPUSS Inter Process Communication Interrupt #7 */ + def_irq_handler cpuss_interrupts_ipc_8_IRQHandler /* CPUSS Inter Process Communication Interrupt #8 */ + def_irq_handler cpuss_interrupts_ipc_9_IRQHandler /* CPUSS Inter Process Communication Interrupt #9 */ + def_irq_handler cpuss_interrupts_ipc_10_IRQHandler /* CPUSS Inter Process Communication Interrupt #10 */ + def_irq_handler cpuss_interrupts_ipc_11_IRQHandler /* CPUSS Inter Process Communication Interrupt #11 */ + def_irq_handler cpuss_interrupts_ipc_12_IRQHandler /* CPUSS Inter Process Communication Interrupt #12 */ + def_irq_handler cpuss_interrupts_ipc_13_IRQHandler /* CPUSS Inter Process Communication Interrupt #13 */ + def_irq_handler cpuss_interrupts_ipc_14_IRQHandler /* CPUSS Inter Process Communication Interrupt #14 */ + def_irq_handler cpuss_interrupts_ipc_15_IRQHandler /* CPUSS Inter Process Communication Interrupt #15 */ + def_irq_handler scb_0_interrupt_IRQHandler /* Serial Communication Block #0 */ + def_irq_handler scb_1_interrupt_IRQHandler /* Serial Communication Block #1 */ + def_irq_handler scb_2_interrupt_IRQHandler /* Serial Communication Block #2 */ + def_irq_handler scb_3_interrupt_IRQHandler /* Serial Communication Block #3 */ + def_irq_handler scb_4_interrupt_IRQHandler /* Serial Communication Block #4 */ + def_irq_handler scb_5_interrupt_IRQHandler /* Serial Communication Block #5 */ + def_irq_handler scb_6_interrupt_IRQHandler /* Serial Communication Block #6 */ + def_irq_handler scb_7_interrupt_IRQHandler /* Serial Communication Block #7 */ + def_irq_handler csd_interrupt_IRQHandler /* CSD (Capsense) interrupt */ + def_irq_handler cpuss_interrupts_dw0_0_IRQHandler /* CPUSS DataWire #0, Channel #0 */ + def_irq_handler cpuss_interrupts_dw0_1_IRQHandler /* CPUSS DataWire #0, Channel #1 */ + def_irq_handler cpuss_interrupts_dw0_2_IRQHandler /* CPUSS DataWire #0, Channel #2 */ + def_irq_handler cpuss_interrupts_dw0_3_IRQHandler /* CPUSS DataWire #0, Channel #3 */ + def_irq_handler cpuss_interrupts_dw0_4_IRQHandler /* CPUSS DataWire #0, Channel #4 */ + def_irq_handler cpuss_interrupts_dw0_5_IRQHandler /* CPUSS DataWire #0, Channel #5 */ + def_irq_handler cpuss_interrupts_dw0_6_IRQHandler /* CPUSS DataWire #0, Channel #6 */ + def_irq_handler cpuss_interrupts_dw0_7_IRQHandler /* CPUSS DataWire #0, Channel #7 */ + def_irq_handler cpuss_interrupts_dw0_8_IRQHandler /* CPUSS DataWire #0, Channel #8 */ + def_irq_handler cpuss_interrupts_dw0_9_IRQHandler /* CPUSS DataWire #0, Channel #9 */ + def_irq_handler cpuss_interrupts_dw0_10_IRQHandler /* CPUSS DataWire #0, Channel #10 */ + def_irq_handler cpuss_interrupts_dw0_11_IRQHandler /* CPUSS DataWire #0, Channel #11 */ + def_irq_handler cpuss_interrupts_dw0_12_IRQHandler /* CPUSS DataWire #0, Channel #12 */ + def_irq_handler cpuss_interrupts_dw0_13_IRQHandler /* CPUSS DataWire #0, Channel #13 */ + def_irq_handler cpuss_interrupts_dw0_14_IRQHandler /* CPUSS DataWire #0, Channel #14 */ + def_irq_handler cpuss_interrupts_dw0_15_IRQHandler /* CPUSS DataWire #0, Channel #15 */ + def_irq_handler cpuss_interrupts_dw1_0_IRQHandler /* CPUSS DataWire #1, Channel #0 */ + def_irq_handler cpuss_interrupts_dw1_1_IRQHandler /* CPUSS DataWire #1, Channel #1 */ + def_irq_handler cpuss_interrupts_dw1_2_IRQHandler /* CPUSS DataWire #1, Channel #2 */ + def_irq_handler cpuss_interrupts_dw1_3_IRQHandler /* CPUSS DataWire #1, Channel #3 */ + def_irq_handler cpuss_interrupts_dw1_4_IRQHandler /* CPUSS DataWire #1, Channel #4 */ + def_irq_handler cpuss_interrupts_dw1_5_IRQHandler /* CPUSS DataWire #1, Channel #5 */ + def_irq_handler cpuss_interrupts_dw1_6_IRQHandler /* CPUSS DataWire #1, Channel #6 */ + def_irq_handler cpuss_interrupts_dw1_7_IRQHandler /* CPUSS DataWire #1, Channel #7 */ + def_irq_handler cpuss_interrupts_dw1_8_IRQHandler /* CPUSS DataWire #1, Channel #8 */ + def_irq_handler cpuss_interrupts_dw1_9_IRQHandler /* CPUSS DataWire #1, Channel #9 */ + def_irq_handler cpuss_interrupts_dw1_10_IRQHandler /* CPUSS DataWire #1, Channel #10 */ + def_irq_handler cpuss_interrupts_dw1_11_IRQHandler /* CPUSS DataWire #1, Channel #11 */ + def_irq_handler cpuss_interrupts_dw1_12_IRQHandler /* CPUSS DataWire #1, Channel #12 */ + def_irq_handler cpuss_interrupts_dw1_13_IRQHandler /* CPUSS DataWire #1, Channel #13 */ + def_irq_handler cpuss_interrupts_dw1_14_IRQHandler /* CPUSS DataWire #1, Channel #14 */ + def_irq_handler cpuss_interrupts_dw1_15_IRQHandler /* CPUSS DataWire #1, Channel #15 */ + def_irq_handler cpuss_interrupts_fault_0_IRQHandler /* CPUSS Fault Structure Interrupt #0 */ + def_irq_handler cpuss_interrupts_fault_1_IRQHandler /* CPUSS Fault Structure Interrupt #1 */ + def_irq_handler cpuss_interrupt_crypto_IRQHandler /* CRYPTO Accelerator Interrupt */ + def_irq_handler cpuss_interrupt_fm_IRQHandler /* FLASH Macro Interrupt */ + def_irq_handler cpuss_interrupts_cm0_cti_0_IRQHandler /* CM0+ CTI #0 */ + def_irq_handler cpuss_interrupts_cm0_cti_1_IRQHandler /* CM0+ CTI #1 */ + def_irq_handler cpuss_interrupts_cm4_cti_0_IRQHandler /* CM4 CTI #0 */ + def_irq_handler cpuss_interrupts_cm4_cti_1_IRQHandler /* CM4 CTI #1 */ + def_irq_handler tcpwm_0_interrupts_0_IRQHandler /* TCPWM #0, Counter #0 */ + def_irq_handler tcpwm_0_interrupts_1_IRQHandler /* TCPWM #0, Counter #1 */ + def_irq_handler tcpwm_0_interrupts_2_IRQHandler /* TCPWM #0, Counter #2 */ + def_irq_handler tcpwm_0_interrupts_3_IRQHandler /* TCPWM #0, Counter #3 */ + def_irq_handler tcpwm_0_interrupts_4_IRQHandler /* TCPWM #0, Counter #4 */ + def_irq_handler tcpwm_0_interrupts_5_IRQHandler /* TCPWM #0, Counter #5 */ + def_irq_handler tcpwm_0_interrupts_6_IRQHandler /* TCPWM #0, Counter #6 */ + def_irq_handler tcpwm_0_interrupts_7_IRQHandler /* TCPWM #0, Counter #7 */ + def_irq_handler tcpwm_1_interrupts_0_IRQHandler /* TCPWM #1, Counter #0 */ + def_irq_handler tcpwm_1_interrupts_1_IRQHandler /* TCPWM #1, Counter #1 */ + def_irq_handler tcpwm_1_interrupts_2_IRQHandler /* TCPWM #1, Counter #2 */ + def_irq_handler tcpwm_1_interrupts_3_IRQHandler /* TCPWM #1, Counter #3 */ + def_irq_handler tcpwm_1_interrupts_4_IRQHandler /* TCPWM #1, Counter #4 */ + def_irq_handler tcpwm_1_interrupts_5_IRQHandler /* TCPWM #1, Counter #5 */ + def_irq_handler tcpwm_1_interrupts_6_IRQHandler /* TCPWM #1, Counter #6 */ + def_irq_handler tcpwm_1_interrupts_7_IRQHandler /* TCPWM #1, Counter #7 */ + def_irq_handler tcpwm_1_interrupts_8_IRQHandler /* TCPWM #1, Counter #8 */ + def_irq_handler tcpwm_1_interrupts_9_IRQHandler /* TCPWM #1, Counter #9 */ + def_irq_handler tcpwm_1_interrupts_10_IRQHandler /* TCPWM #1, Counter #10 */ + def_irq_handler tcpwm_1_interrupts_11_IRQHandler /* TCPWM #1, Counter #11 */ + def_irq_handler tcpwm_1_interrupts_12_IRQHandler /* TCPWM #1, Counter #12 */ + def_irq_handler tcpwm_1_interrupts_13_IRQHandler /* TCPWM #1, Counter #13 */ + def_irq_handler tcpwm_1_interrupts_14_IRQHandler /* TCPWM #1, Counter #14 */ + def_irq_handler tcpwm_1_interrupts_15_IRQHandler /* TCPWM #1, Counter #15 */ + def_irq_handler tcpwm_1_interrupts_16_IRQHandler /* TCPWM #1, Counter #16 */ + def_irq_handler tcpwm_1_interrupts_17_IRQHandler /* TCPWM #1, Counter #17 */ + def_irq_handler tcpwm_1_interrupts_18_IRQHandler /* TCPWM #1, Counter #18 */ + def_irq_handler tcpwm_1_interrupts_19_IRQHandler /* TCPWM #1, Counter #19 */ + def_irq_handler tcpwm_1_interrupts_20_IRQHandler /* TCPWM #1, Counter #20 */ + def_irq_handler tcpwm_1_interrupts_21_IRQHandler /* TCPWM #1, Counter #21 */ + def_irq_handler tcpwm_1_interrupts_22_IRQHandler /* TCPWM #1, Counter #22 */ + def_irq_handler tcpwm_1_interrupts_23_IRQHandler /* TCPWM #1, Counter #23 */ + def_irq_handler udb_interrupts_0_IRQHandler /* UDB Interrupt #0 */ + def_irq_handler udb_interrupts_1_IRQHandler /* UDB Interrupt #1 */ + def_irq_handler udb_interrupts_2_IRQHandler /* UDB Interrupt #2 */ + def_irq_handler udb_interrupts_3_IRQHandler /* UDB Interrupt #3 */ + def_irq_handler udb_interrupts_4_IRQHandler /* UDB Interrupt #4 */ + def_irq_handler udb_interrupts_5_IRQHandler /* UDB Interrupt #5 */ + def_irq_handler udb_interrupts_6_IRQHandler /* UDB Interrupt #6 */ + def_irq_handler udb_interrupts_7_IRQHandler /* UDB Interrupt #7 */ + def_irq_handler udb_interrupts_8_IRQHandler /* UDB Interrupt #8 */ + def_irq_handler udb_interrupts_9_IRQHandler /* UDB Interrupt #9 */ + def_irq_handler udb_interrupts_10_IRQHandler /* UDB Interrupt #10 */ + def_irq_handler udb_interrupts_11_IRQHandler /* UDB Interrupt #11 */ + def_irq_handler udb_interrupts_12_IRQHandler /* UDB Interrupt #12 */ + def_irq_handler udb_interrupts_13_IRQHandler /* UDB Interrupt #13 */ + def_irq_handler udb_interrupts_14_IRQHandler /* UDB Interrupt #14 */ + def_irq_handler udb_interrupts_15_IRQHandler /* UDB Interrupt #15 */ + def_irq_handler pass_interrupt_sar_IRQHandler /* SAR ADC interrupt */ + def_irq_handler audioss_interrupt_i2s_IRQHandler /* I2S Audio interrupt */ + def_irq_handler audioss_interrupt_pdm_IRQHandler /* PDM/PCM Audio interrupt */ + def_irq_handler profile_interrupt_IRQHandler /* Energy Profiler interrupt */ + def_irq_handler smif_interrupt_IRQHandler /* Serial Memory Interface interrupt */ + def_irq_handler usb_interrupt_hi_IRQHandler /* USB Interrupt */ + def_irq_handler usb_interrupt_med_IRQHandler /* USB Interrupt */ + def_irq_handler usb_interrupt_lo_IRQHandler /* USB Interrupt */ + def_irq_handler pass_interrupt_dacs_IRQHandler /* Consolidated interrrupt for all DACs */ + + .end + + +/* [] END OF FILE */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_GCC_ARM/startup_psoc6_01_cm4.S b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_GCC_ARM/startup_psoc6_01_cm4.S new file mode 100644 index 0000000000..2220eb3a06 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_GCC_ARM/startup_psoc6_01_cm4.S @@ -0,0 +1,656 @@ +/**************************************************************************//** + * @file startup_psoc6_01_cm4.S + * @brief CMSIS Core Device Startup File for + * ARMCM4 Device Series + * @version V5.00 + * @date 02. March 2016 + ******************************************************************************/ +/* + * Copyright (c) 2009-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * 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. + */ + + /* Address of the NMI handler */ + #define CY_NMI_HANLDER_ADDR 0x0000000D + + /* The CPU VTOR register */ + #define CY_CPU_VTOR_ADDR 0xE000ED08 + + /* Copy flash vectors and data section to RAM */ + #define __STARTUP_COPY_MULTIPLE + + /* Clear single BSS section */ + #define __STARTUP_CLEAR_BSS + + .syntax unified + .arch armv7-m + + .section .stack + .align 3 +#ifdef __STACK_SIZE + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 0x00001000 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#ifdef __HEAP_SIZE + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 0x00000400 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .vectors + .align 2 + .globl __Vectors +__Vectors: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long CY_NMI_HANLDER_ADDR /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* External interrupts Description */ + .long ioss_interrupts_gpio_0_IRQHandler /* GPIO Port Interrupt #0 */ + .long ioss_interrupts_gpio_1_IRQHandler /* GPIO Port Interrupt #1 */ + .long ioss_interrupts_gpio_2_IRQHandler /* GPIO Port Interrupt #2 */ + .long ioss_interrupts_gpio_3_IRQHandler /* GPIO Port Interrupt #3 */ + .long ioss_interrupts_gpio_4_IRQHandler /* GPIO Port Interrupt #4 */ + .long ioss_interrupts_gpio_5_IRQHandler /* GPIO Port Interrupt #5 */ + .long ioss_interrupts_gpio_6_IRQHandler /* GPIO Port Interrupt #6 */ + .long ioss_interrupts_gpio_7_IRQHandler /* GPIO Port Interrupt #7 */ + .long ioss_interrupts_gpio_8_IRQHandler /* GPIO Port Interrupt #8 */ + .long ioss_interrupts_gpio_9_IRQHandler /* GPIO Port Interrupt #9 */ + .long ioss_interrupts_gpio_10_IRQHandler /* GPIO Port Interrupt #10 */ + .long ioss_interrupts_gpio_11_IRQHandler /* GPIO Port Interrupt #11 */ + .long ioss_interrupts_gpio_12_IRQHandler /* GPIO Port Interrupt #12 */ + .long ioss_interrupts_gpio_13_IRQHandler /* GPIO Port Interrupt #13 */ + .long ioss_interrupts_gpio_14_IRQHandler /* GPIO Port Interrupt #14 */ + .long ioss_interrupt_gpio_IRQHandler /* GPIO All Ports */ + .long ioss_interrupt_vdd_IRQHandler /* GPIO Supply Detect Interrupt */ + .long lpcomp_interrupt_IRQHandler /* Low Power Comparator Interrupt */ + .long scb_8_interrupt_IRQHandler /* Serial Communication Block #8 (DeepSleep capable) */ + .long srss_interrupt_mcwdt_0_IRQHandler /* Multi Counter Watchdog Timer interrupt */ + .long srss_interrupt_mcwdt_1_IRQHandler /* Multi Counter Watchdog Timer interrupt */ + .long srss_interrupt_backup_IRQHandler /* Backup domain interrupt */ + .long srss_interrupt_IRQHandler /* Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) */ + .long pass_interrupt_ctbs_IRQHandler /* CTBm Interrupt (all CTBms) */ + .long bless_interrupt_IRQHandler /* Bluetooth Radio interrupt */ + .long cpuss_interrupts_ipc_0_IRQHandler /* CPUSS Inter Process Communication Interrupt #0 */ + .long cpuss_interrupts_ipc_1_IRQHandler /* CPUSS Inter Process Communication Interrupt #1 */ + .long cpuss_interrupts_ipc_2_IRQHandler /* CPUSS Inter Process Communication Interrupt #2 */ + .long cpuss_interrupts_ipc_3_IRQHandler /* CPUSS Inter Process Communication Interrupt #3 */ + .long cpuss_interrupts_ipc_4_IRQHandler /* CPUSS Inter Process Communication Interrupt #4 */ + .long cpuss_interrupts_ipc_5_IRQHandler /* CPUSS Inter Process Communication Interrupt #5 */ + .long cpuss_interrupts_ipc_6_IRQHandler /* CPUSS Inter Process Communication Interrupt #6 */ + .long cpuss_interrupts_ipc_7_IRQHandler /* CPUSS Inter Process Communication Interrupt #7 */ + .long cpuss_interrupts_ipc_8_IRQHandler /* CPUSS Inter Process Communication Interrupt #8 */ + .long cpuss_interrupts_ipc_9_IRQHandler /* CPUSS Inter Process Communication Interrupt #9 */ + .long cpuss_interrupts_ipc_10_IRQHandler /* CPUSS Inter Process Communication Interrupt #10 */ + .long cpuss_interrupts_ipc_11_IRQHandler /* CPUSS Inter Process Communication Interrupt #11 */ + .long cpuss_interrupts_ipc_12_IRQHandler /* CPUSS Inter Process Communication Interrupt #12 */ + .long cpuss_interrupts_ipc_13_IRQHandler /* CPUSS Inter Process Communication Interrupt #13 */ + .long cpuss_interrupts_ipc_14_IRQHandler /* CPUSS Inter Process Communication Interrupt #14 */ + .long cpuss_interrupts_ipc_15_IRQHandler /* CPUSS Inter Process Communication Interrupt #15 */ + .long scb_0_interrupt_IRQHandler /* Serial Communication Block #0 */ + .long scb_1_interrupt_IRQHandler /* Serial Communication Block #1 */ + .long scb_2_interrupt_IRQHandler /* Serial Communication Block #2 */ + .long scb_3_interrupt_IRQHandler /* Serial Communication Block #3 */ + .long scb_4_interrupt_IRQHandler /* Serial Communication Block #4 */ + .long scb_5_interrupt_IRQHandler /* Serial Communication Block #5 */ + .long scb_6_interrupt_IRQHandler /* Serial Communication Block #6 */ + .long scb_7_interrupt_IRQHandler /* Serial Communication Block #7 */ + .long csd_interrupt_IRQHandler /* CSD (Capsense) interrupt */ + .long cpuss_interrupts_dw0_0_IRQHandler /* CPUSS DataWire #0, Channel #0 */ + .long cpuss_interrupts_dw0_1_IRQHandler /* CPUSS DataWire #0, Channel #1 */ + .long cpuss_interrupts_dw0_2_IRQHandler /* CPUSS DataWire #0, Channel #2 */ + .long cpuss_interrupts_dw0_3_IRQHandler /* CPUSS DataWire #0, Channel #3 */ + .long cpuss_interrupts_dw0_4_IRQHandler /* CPUSS DataWire #0, Channel #4 */ + .long cpuss_interrupts_dw0_5_IRQHandler /* CPUSS DataWire #0, Channel #5 */ + .long cpuss_interrupts_dw0_6_IRQHandler /* CPUSS DataWire #0, Channel #6 */ + .long cpuss_interrupts_dw0_7_IRQHandler /* CPUSS DataWire #0, Channel #7 */ + .long cpuss_interrupts_dw0_8_IRQHandler /* CPUSS DataWire #0, Channel #8 */ + .long cpuss_interrupts_dw0_9_IRQHandler /* CPUSS DataWire #0, Channel #9 */ + .long cpuss_interrupts_dw0_10_IRQHandler /* CPUSS DataWire #0, Channel #10 */ + .long cpuss_interrupts_dw0_11_IRQHandler /* CPUSS DataWire #0, Channel #11 */ + .long cpuss_interrupts_dw0_12_IRQHandler /* CPUSS DataWire #0, Channel #12 */ + .long cpuss_interrupts_dw0_13_IRQHandler /* CPUSS DataWire #0, Channel #13 */ + .long cpuss_interrupts_dw0_14_IRQHandler /* CPUSS DataWire #0, Channel #14 */ + .long cpuss_interrupts_dw0_15_IRQHandler /* CPUSS DataWire #0, Channel #15 */ + .long cpuss_interrupts_dw1_0_IRQHandler /* CPUSS DataWire #1, Channel #0 */ + .long cpuss_interrupts_dw1_1_IRQHandler /* CPUSS DataWire #1, Channel #1 */ + .long cpuss_interrupts_dw1_2_IRQHandler /* CPUSS DataWire #1, Channel #2 */ + .long cpuss_interrupts_dw1_3_IRQHandler /* CPUSS DataWire #1, Channel #3 */ + .long cpuss_interrupts_dw1_4_IRQHandler /* CPUSS DataWire #1, Channel #4 */ + .long cpuss_interrupts_dw1_5_IRQHandler /* CPUSS DataWire #1, Channel #5 */ + .long cpuss_interrupts_dw1_6_IRQHandler /* CPUSS DataWire #1, Channel #6 */ + .long cpuss_interrupts_dw1_7_IRQHandler /* CPUSS DataWire #1, Channel #7 */ + .long cpuss_interrupts_dw1_8_IRQHandler /* CPUSS DataWire #1, Channel #8 */ + .long cpuss_interrupts_dw1_9_IRQHandler /* CPUSS DataWire #1, Channel #9 */ + .long cpuss_interrupts_dw1_10_IRQHandler /* CPUSS DataWire #1, Channel #10 */ + .long cpuss_interrupts_dw1_11_IRQHandler /* CPUSS DataWire #1, Channel #11 */ + .long cpuss_interrupts_dw1_12_IRQHandler /* CPUSS DataWire #1, Channel #12 */ + .long cpuss_interrupts_dw1_13_IRQHandler /* CPUSS DataWire #1, Channel #13 */ + .long cpuss_interrupts_dw1_14_IRQHandler /* CPUSS DataWire #1, Channel #14 */ + .long cpuss_interrupts_dw1_15_IRQHandler /* CPUSS DataWire #1, Channel #15 */ + .long cpuss_interrupts_fault_0_IRQHandler /* CPUSS Fault Structure Interrupt #0 */ + .long cpuss_interrupts_fault_1_IRQHandler /* CPUSS Fault Structure Interrupt #1 */ + .long cpuss_interrupt_crypto_IRQHandler /* CRYPTO Accelerator Interrupt */ + .long cpuss_interrupt_fm_IRQHandler /* FLASH Macro Interrupt */ + .long cpuss_interrupts_cm0_cti_0_IRQHandler /* CM0+ CTI #0 */ + .long cpuss_interrupts_cm0_cti_1_IRQHandler /* CM0+ CTI #1 */ + .long cpuss_interrupts_cm4_cti_0_IRQHandler /* CM4 CTI #0 */ + .long cpuss_interrupts_cm4_cti_1_IRQHandler /* CM4 CTI #1 */ + .long tcpwm_0_interrupts_0_IRQHandler /* TCPWM #0, Counter #0 */ + .long tcpwm_0_interrupts_1_IRQHandler /* TCPWM #0, Counter #1 */ + .long tcpwm_0_interrupts_2_IRQHandler /* TCPWM #0, Counter #2 */ + .long tcpwm_0_interrupts_3_IRQHandler /* TCPWM #0, Counter #3 */ + .long tcpwm_0_interrupts_4_IRQHandler /* TCPWM #0, Counter #4 */ + .long tcpwm_0_interrupts_5_IRQHandler /* TCPWM #0, Counter #5 */ + .long tcpwm_0_interrupts_6_IRQHandler /* TCPWM #0, Counter #6 */ + .long tcpwm_0_interrupts_7_IRQHandler /* TCPWM #0, Counter #7 */ + .long tcpwm_1_interrupts_0_IRQHandler /* TCPWM #1, Counter #0 */ + .long tcpwm_1_interrupts_1_IRQHandler /* TCPWM #1, Counter #1 */ + .long tcpwm_1_interrupts_2_IRQHandler /* TCPWM #1, Counter #2 */ + .long tcpwm_1_interrupts_3_IRQHandler /* TCPWM #1, Counter #3 */ + .long tcpwm_1_interrupts_4_IRQHandler /* TCPWM #1, Counter #4 */ + .long tcpwm_1_interrupts_5_IRQHandler /* TCPWM #1, Counter #5 */ + .long tcpwm_1_interrupts_6_IRQHandler /* TCPWM #1, Counter #6 */ + .long tcpwm_1_interrupts_7_IRQHandler /* TCPWM #1, Counter #7 */ + .long tcpwm_1_interrupts_8_IRQHandler /* TCPWM #1, Counter #8 */ + .long tcpwm_1_interrupts_9_IRQHandler /* TCPWM #1, Counter #9 */ + .long tcpwm_1_interrupts_10_IRQHandler /* TCPWM #1, Counter #10 */ + .long tcpwm_1_interrupts_11_IRQHandler /* TCPWM #1, Counter #11 */ + .long tcpwm_1_interrupts_12_IRQHandler /* TCPWM #1, Counter #12 */ + .long tcpwm_1_interrupts_13_IRQHandler /* TCPWM #1, Counter #13 */ + .long tcpwm_1_interrupts_14_IRQHandler /* TCPWM #1, Counter #14 */ + .long tcpwm_1_interrupts_15_IRQHandler /* TCPWM #1, Counter #15 */ + .long tcpwm_1_interrupts_16_IRQHandler /* TCPWM #1, Counter #16 */ + .long tcpwm_1_interrupts_17_IRQHandler /* TCPWM #1, Counter #17 */ + .long tcpwm_1_interrupts_18_IRQHandler /* TCPWM #1, Counter #18 */ + .long tcpwm_1_interrupts_19_IRQHandler /* TCPWM #1, Counter #19 */ + .long tcpwm_1_interrupts_20_IRQHandler /* TCPWM #1, Counter #20 */ + .long tcpwm_1_interrupts_21_IRQHandler /* TCPWM #1, Counter #21 */ + .long tcpwm_1_interrupts_22_IRQHandler /* TCPWM #1, Counter #22 */ + .long tcpwm_1_interrupts_23_IRQHandler /* TCPWM #1, Counter #23 */ + .long udb_interrupts_0_IRQHandler /* UDB Interrupt #0 */ + .long udb_interrupts_1_IRQHandler /* UDB Interrupt #1 */ + .long udb_interrupts_2_IRQHandler /* UDB Interrupt #2 */ + .long udb_interrupts_3_IRQHandler /* UDB Interrupt #3 */ + .long udb_interrupts_4_IRQHandler /* UDB Interrupt #4 */ + .long udb_interrupts_5_IRQHandler /* UDB Interrupt #5 */ + .long udb_interrupts_6_IRQHandler /* UDB Interrupt #6 */ + .long udb_interrupts_7_IRQHandler /* UDB Interrupt #7 */ + .long udb_interrupts_8_IRQHandler /* UDB Interrupt #8 */ + .long udb_interrupts_9_IRQHandler /* UDB Interrupt #9 */ + .long udb_interrupts_10_IRQHandler /* UDB Interrupt #10 */ + .long udb_interrupts_11_IRQHandler /* UDB Interrupt #11 */ + .long udb_interrupts_12_IRQHandler /* UDB Interrupt #12 */ + .long udb_interrupts_13_IRQHandler /* UDB Interrupt #13 */ + .long udb_interrupts_14_IRQHandler /* UDB Interrupt #14 */ + .long udb_interrupts_15_IRQHandler /* UDB Interrupt #15 */ + .long pass_interrupt_sar_IRQHandler /* SAR ADC interrupt */ + .long audioss_interrupt_i2s_IRQHandler /* I2S Audio interrupt */ + .long audioss_interrupt_pdm_IRQHandler /* PDM/PCM Audio interrupt */ + .long profile_interrupt_IRQHandler /* Energy Profiler interrupt */ + .long smif_interrupt_IRQHandler /* Serial Memory Interface interrupt */ + .long usb_interrupt_hi_IRQHandler /* USB Interrupt */ + .long usb_interrupt_med_IRQHandler /* USB Interrupt */ + .long usb_interrupt_lo_IRQHandler /* USB Interrupt */ + .long pass_interrupt_dacs_IRQHandler /* Consolidated interrrupt for all DACs */ + + + .size __Vectors, . - __Vectors + .equ __VectorsSize, . - __Vectors + + .section .ram_vectors + .align 2 + .globl __ramVectors +__ramVectors: + .space __VectorsSize + .size __ramVectors, . - __ramVectors + + + .text + .thumb + .thumb_func + .align 2 + + /* + * Device startup customization + * + * Note. The global resources are not yet initialized (for example global variables, peripherals, clocks) + * because this function is executed as the first instruction in the ResetHandler. + * The PDL is also not initialized to use the proper register offsets. + * The user of this function is responsible for initializing the PDL and resources before using them. + */ + .weak Cy_OnResetUser + .func Cy_OnResetUser, Cy_OnResetUser + .type Cy_OnResetUser, %function + +Cy_OnResetUser: + bx lr + .size Cy_OnResetUser, . - Cy_OnResetUser + .endfunc + + /* OS-specific low-level initialization */ + .weak cy_toolchain_init + .func cy_toolchain_init, cy_toolchain_init + .type cy_toolchain_init, %function + +cy_toolchain_init: + bx lr + .size cy_toolchain_init, . - cy_toolchain_init + .endfunc + + /* Reset handler */ + .weak Reset_Handler + .type Reset_Handler, %function + +Reset_Handler: + bl Cy_OnResetUser + cpsid i + +/* Firstly it copies data from read only memory to RAM. There are two schemes + * to copy. One can copy more than one sections. Another can only copy + * one section. The former scheme needs more instructions and read-only + * data to implement than the latter. + * Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */ + +#ifdef __STARTUP_COPY_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of triplets, each of which specify: + * offset 0: LMA of start of a section to copy from + * offset 4: VMA of start of a section to copy to + * offset 8: size of the section to copy. Must be multiply of 4 + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r4, =__copy_table_start__ + ldr r5, =__copy_table_end__ + +.L_loop0: + cmp r4, r5 + bge .L_loop0_done + ldr r1, [r4] + ldr r2, [r4, #4] + ldr r3, [r4, #8] + +.L_loop0_0: + subs r3, #4 + ittt ge + ldrge r0, [r1, r3] + strge r0, [r2, r3] + bge .L_loop0_0 + + adds r4, #12 + b .L_loop0 + +.L_loop0_done: +#else +/* Single section scheme. + * + * The ranges of copy from/to are specified by following symbols + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to + * __data_end__: VMA of end of the section to copy to + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + +.L_loop1: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .L_loop1 +#endif /*__STARTUP_COPY_MULTIPLE */ + +/* This part of work usually is done in C library startup code. Otherwise, + * define this macro to enable it in this startup. + * + * There are two schemes too. One can clear multiple BSS sections. Another + * can only clear one section. The former is more size expensive than the + * latter. + * + * Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former. + * Otherwise define macro __STARTUP_CLEAR_BSS to choose the later. + */ +#ifdef __STARTUP_CLEAR_BSS_MULTIPLE +/* Multiple sections scheme. + * + * Between symbol address __copy_table_start__ and __copy_table_end__, + * there are array of tuples specifying: + * offset 0: Start of a BSS section + * offset 4: Size of this BSS section. Must be multiply of 4 + */ + ldr r3, =__zero_table_start__ + ldr r4, =__zero_table_end__ + +.L_loop2: + cmp r3, r4 + bge .L_loop2_done + ldr r1, [r3] + ldr r2, [r3, #4] + movs r0, 0 + +.L_loop2_0: + subs r2, #4 + itt ge + strge r0, [r1, r2] + bge .L_loop2_0 + + adds r3, #8 + b .L_loop2 +.L_loop2_done: +#elif defined (__STARTUP_CLEAR_BSS) +/* Single BSS section scheme. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * Both addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 +.L_loop3: + cmp r1, r2 + itt lt + strlt r0, [r1], #4 + blt .L_loop3 +#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */ + + /* Update Vector Table Offset Register. */ + ldr r0, =__ramVectors + ldr r1, =CY_CPU_VTOR_ADDR + str r0, [r1] + dsb 0xF + + /* Enable the FPU if used */ + bl Cy_SystemInitFpuEnable + +#ifndef __NO_SYSTEM_INIT + bl SystemInit +#endif + + /* OS-specific low-level initialization */ + bl cy_toolchain_init + + /* Call C/C++ static constructors */ + bl __libc_init_array + + /* Execute main application */ + /*bl main */ + bl entry + + /* Call C/C++ static destructors */ + bl __libc_fini_array + + /* Should never get here */ + b . + + .pool + .size Reset_Handler, . - Reset_Handler + + .align 1 + .thumb_func + .weak Default_Handler + .type Default_Handler, %function + +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + + .weak Cy_SysLib_FaultHandler + .type Cy_SysLib_FaultHandler, %function + +Cy_SysLib_FaultHandler: + b . + .size Cy_SysLib_FaultHandler, . - Cy_SysLib_FaultHandler + .type Fault_Handler, %function + +Fault_Handler: + /* Storing LR content for Creator call stack trace */ + push {LR} + movs r0, #4 + mov r1, LR + tst r0, r1 + beq .L_MSP + mrs r0, PSP + b .L_API_call +.L_MSP: + mrs r0, MSP +.L_API_call: + /* Compensation of stack pointer address due to pushing 4 bytes of LR */ + adds r0, r0, #4 + bl Cy_SysLib_FaultHandler + b . + .size Fault_Handler, . - Fault_Handler + +.macro def_fault_Handler fault_handler_name + .weak \fault_handler_name + .set \fault_handler_name, Fault_Handler + .endm + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .set \handler_name, Default_Handler + .endm + + def_irq_handler NMI_Handler + + def_fault_Handler HardFault_Handler + def_fault_Handler MemManage_Handler + def_fault_Handler BusFault_Handler + def_fault_Handler UsageFault_Handler + + def_irq_handler SVC_Handler + def_irq_handler DebugMon_Handler + def_irq_handler PendSV_Handler + def_irq_handler SysTick_Handler + + def_irq_handler ioss_interrupts_gpio_0_IRQHandler /* GPIO Port Interrupt #0 */ + def_irq_handler ioss_interrupts_gpio_1_IRQHandler /* GPIO Port Interrupt #1 */ + def_irq_handler ioss_interrupts_gpio_2_IRQHandler /* GPIO Port Interrupt #2 */ + def_irq_handler ioss_interrupts_gpio_3_IRQHandler /* GPIO Port Interrupt #3 */ + def_irq_handler ioss_interrupts_gpio_4_IRQHandler /* GPIO Port Interrupt #4 */ + def_irq_handler ioss_interrupts_gpio_5_IRQHandler /* GPIO Port Interrupt #5 */ + def_irq_handler ioss_interrupts_gpio_6_IRQHandler /* GPIO Port Interrupt #6 */ + def_irq_handler ioss_interrupts_gpio_7_IRQHandler /* GPIO Port Interrupt #7 */ + def_irq_handler ioss_interrupts_gpio_8_IRQHandler /* GPIO Port Interrupt #8 */ + def_irq_handler ioss_interrupts_gpio_9_IRQHandler /* GPIO Port Interrupt #9 */ + def_irq_handler ioss_interrupts_gpio_10_IRQHandler /* GPIO Port Interrupt #10 */ + def_irq_handler ioss_interrupts_gpio_11_IRQHandler /* GPIO Port Interrupt #11 */ + def_irq_handler ioss_interrupts_gpio_12_IRQHandler /* GPIO Port Interrupt #12 */ + def_irq_handler ioss_interrupts_gpio_13_IRQHandler /* GPIO Port Interrupt #13 */ + def_irq_handler ioss_interrupts_gpio_14_IRQHandler /* GPIO Port Interrupt #14 */ + def_irq_handler ioss_interrupt_gpio_IRQHandler /* GPIO All Ports */ + def_irq_handler ioss_interrupt_vdd_IRQHandler /* GPIO Supply Detect Interrupt */ + def_irq_handler lpcomp_interrupt_IRQHandler /* Low Power Comparator Interrupt */ + def_irq_handler scb_8_interrupt_IRQHandler /* Serial Communication Block #8 (DeepSleep capable) */ + def_irq_handler srss_interrupt_mcwdt_0_IRQHandler /* Multi Counter Watchdog Timer interrupt */ + def_irq_handler srss_interrupt_mcwdt_1_IRQHandler /* Multi Counter Watchdog Timer interrupt */ + def_irq_handler srss_interrupt_backup_IRQHandler /* Backup domain interrupt */ + def_irq_handler srss_interrupt_IRQHandler /* Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) */ + def_irq_handler pass_interrupt_ctbs_IRQHandler /* CTBm Interrupt (all CTBms) */ + def_irq_handler bless_interrupt_IRQHandler /* Bluetooth Radio interrupt */ + def_irq_handler cpuss_interrupts_ipc_0_IRQHandler /* CPUSS Inter Process Communication Interrupt #0 */ + def_irq_handler cpuss_interrupts_ipc_1_IRQHandler /* CPUSS Inter Process Communication Interrupt #1 */ + def_irq_handler cpuss_interrupts_ipc_2_IRQHandler /* CPUSS Inter Process Communication Interrupt #2 */ + def_irq_handler cpuss_interrupts_ipc_3_IRQHandler /* CPUSS Inter Process Communication Interrupt #3 */ + def_irq_handler cpuss_interrupts_ipc_4_IRQHandler /* CPUSS Inter Process Communication Interrupt #4 */ + def_irq_handler cpuss_interrupts_ipc_5_IRQHandler /* CPUSS Inter Process Communication Interrupt #5 */ + def_irq_handler cpuss_interrupts_ipc_6_IRQHandler /* CPUSS Inter Process Communication Interrupt #6 */ + def_irq_handler cpuss_interrupts_ipc_7_IRQHandler /* CPUSS Inter Process Communication Interrupt #7 */ + def_irq_handler cpuss_interrupts_ipc_8_IRQHandler /* CPUSS Inter Process Communication Interrupt #8 */ + def_irq_handler cpuss_interrupts_ipc_9_IRQHandler /* CPUSS Inter Process Communication Interrupt #9 */ + def_irq_handler cpuss_interrupts_ipc_10_IRQHandler /* CPUSS Inter Process Communication Interrupt #10 */ + def_irq_handler cpuss_interrupts_ipc_11_IRQHandler /* CPUSS Inter Process Communication Interrupt #11 */ + def_irq_handler cpuss_interrupts_ipc_12_IRQHandler /* CPUSS Inter Process Communication Interrupt #12 */ + def_irq_handler cpuss_interrupts_ipc_13_IRQHandler /* CPUSS Inter Process Communication Interrupt #13 */ + def_irq_handler cpuss_interrupts_ipc_14_IRQHandler /* CPUSS Inter Process Communication Interrupt #14 */ + def_irq_handler cpuss_interrupts_ipc_15_IRQHandler /* CPUSS Inter Process Communication Interrupt #15 */ + def_irq_handler scb_0_interrupt_IRQHandler /* Serial Communication Block #0 */ + def_irq_handler scb_1_interrupt_IRQHandler /* Serial Communication Block #1 */ + def_irq_handler scb_2_interrupt_IRQHandler /* Serial Communication Block #2 */ + def_irq_handler scb_3_interrupt_IRQHandler /* Serial Communication Block #3 */ + def_irq_handler scb_4_interrupt_IRQHandler /* Serial Communication Block #4 */ + def_irq_handler scb_5_interrupt_IRQHandler /* Serial Communication Block #5 */ + def_irq_handler scb_6_interrupt_IRQHandler /* Serial Communication Block #6 */ + def_irq_handler scb_7_interrupt_IRQHandler /* Serial Communication Block #7 */ + def_irq_handler csd_interrupt_IRQHandler /* CSD (Capsense) interrupt */ + def_irq_handler cpuss_interrupts_dw0_0_IRQHandler /* CPUSS DataWire #0, Channel #0 */ + def_irq_handler cpuss_interrupts_dw0_1_IRQHandler /* CPUSS DataWire #0, Channel #1 */ + def_irq_handler cpuss_interrupts_dw0_2_IRQHandler /* CPUSS DataWire #0, Channel #2 */ + def_irq_handler cpuss_interrupts_dw0_3_IRQHandler /* CPUSS DataWire #0, Channel #3 */ + def_irq_handler cpuss_interrupts_dw0_4_IRQHandler /* CPUSS DataWire #0, Channel #4 */ + def_irq_handler cpuss_interrupts_dw0_5_IRQHandler /* CPUSS DataWire #0, Channel #5 */ + def_irq_handler cpuss_interrupts_dw0_6_IRQHandler /* CPUSS DataWire #0, Channel #6 */ + def_irq_handler cpuss_interrupts_dw0_7_IRQHandler /* CPUSS DataWire #0, Channel #7 */ + def_irq_handler cpuss_interrupts_dw0_8_IRQHandler /* CPUSS DataWire #0, Channel #8 */ + def_irq_handler cpuss_interrupts_dw0_9_IRQHandler /* CPUSS DataWire #0, Channel #9 */ + def_irq_handler cpuss_interrupts_dw0_10_IRQHandler /* CPUSS DataWire #0, Channel #10 */ + def_irq_handler cpuss_interrupts_dw0_11_IRQHandler /* CPUSS DataWire #0, Channel #11 */ + def_irq_handler cpuss_interrupts_dw0_12_IRQHandler /* CPUSS DataWire #0, Channel #12 */ + def_irq_handler cpuss_interrupts_dw0_13_IRQHandler /* CPUSS DataWire #0, Channel #13 */ + def_irq_handler cpuss_interrupts_dw0_14_IRQHandler /* CPUSS DataWire #0, Channel #14 */ + def_irq_handler cpuss_interrupts_dw0_15_IRQHandler /* CPUSS DataWire #0, Channel #15 */ + def_irq_handler cpuss_interrupts_dw1_0_IRQHandler /* CPUSS DataWire #1, Channel #0 */ + def_irq_handler cpuss_interrupts_dw1_1_IRQHandler /* CPUSS DataWire #1, Channel #1 */ + def_irq_handler cpuss_interrupts_dw1_2_IRQHandler /* CPUSS DataWire #1, Channel #2 */ + def_irq_handler cpuss_interrupts_dw1_3_IRQHandler /* CPUSS DataWire #1, Channel #3 */ + def_irq_handler cpuss_interrupts_dw1_4_IRQHandler /* CPUSS DataWire #1, Channel #4 */ + def_irq_handler cpuss_interrupts_dw1_5_IRQHandler /* CPUSS DataWire #1, Channel #5 */ + def_irq_handler cpuss_interrupts_dw1_6_IRQHandler /* CPUSS DataWire #1, Channel #6 */ + def_irq_handler cpuss_interrupts_dw1_7_IRQHandler /* CPUSS DataWire #1, Channel #7 */ + def_irq_handler cpuss_interrupts_dw1_8_IRQHandler /* CPUSS DataWire #1, Channel #8 */ + def_irq_handler cpuss_interrupts_dw1_9_IRQHandler /* CPUSS DataWire #1, Channel #9 */ + def_irq_handler cpuss_interrupts_dw1_10_IRQHandler /* CPUSS DataWire #1, Channel #10 */ + def_irq_handler cpuss_interrupts_dw1_11_IRQHandler /* CPUSS DataWire #1, Channel #11 */ + def_irq_handler cpuss_interrupts_dw1_12_IRQHandler /* CPUSS DataWire #1, Channel #12 */ + def_irq_handler cpuss_interrupts_dw1_13_IRQHandler /* CPUSS DataWire #1, Channel #13 */ + def_irq_handler cpuss_interrupts_dw1_14_IRQHandler /* CPUSS DataWire #1, Channel #14 */ + def_irq_handler cpuss_interrupts_dw1_15_IRQHandler /* CPUSS DataWire #1, Channel #15 */ + def_irq_handler cpuss_interrupts_fault_0_IRQHandler /* CPUSS Fault Structure Interrupt #0 */ + def_irq_handler cpuss_interrupts_fault_1_IRQHandler /* CPUSS Fault Structure Interrupt #1 */ + def_irq_handler cpuss_interrupt_crypto_IRQHandler /* CRYPTO Accelerator Interrupt */ + def_irq_handler cpuss_interrupt_fm_IRQHandler /* FLASH Macro Interrupt */ + def_irq_handler cpuss_interrupts_cm0_cti_0_IRQHandler /* CM0+ CTI #0 */ + def_irq_handler cpuss_interrupts_cm0_cti_1_IRQHandler /* CM0+ CTI #1 */ + def_irq_handler cpuss_interrupts_cm4_cti_0_IRQHandler /* CM4 CTI #0 */ + def_irq_handler cpuss_interrupts_cm4_cti_1_IRQHandler /* CM4 CTI #1 */ + def_irq_handler tcpwm_0_interrupts_0_IRQHandler /* TCPWM #0, Counter #0 */ + def_irq_handler tcpwm_0_interrupts_1_IRQHandler /* TCPWM #0, Counter #1 */ + def_irq_handler tcpwm_0_interrupts_2_IRQHandler /* TCPWM #0, Counter #2 */ + def_irq_handler tcpwm_0_interrupts_3_IRQHandler /* TCPWM #0, Counter #3 */ + def_irq_handler tcpwm_0_interrupts_4_IRQHandler /* TCPWM #0, Counter #4 */ + def_irq_handler tcpwm_0_interrupts_5_IRQHandler /* TCPWM #0, Counter #5 */ + def_irq_handler tcpwm_0_interrupts_6_IRQHandler /* TCPWM #0, Counter #6 */ + def_irq_handler tcpwm_0_interrupts_7_IRQHandler /* TCPWM #0, Counter #7 */ + def_irq_handler tcpwm_1_interrupts_0_IRQHandler /* TCPWM #1, Counter #0 */ + def_irq_handler tcpwm_1_interrupts_1_IRQHandler /* TCPWM #1, Counter #1 */ + def_irq_handler tcpwm_1_interrupts_2_IRQHandler /* TCPWM #1, Counter #2 */ + def_irq_handler tcpwm_1_interrupts_3_IRQHandler /* TCPWM #1, Counter #3 */ + def_irq_handler tcpwm_1_interrupts_4_IRQHandler /* TCPWM #1, Counter #4 */ + def_irq_handler tcpwm_1_interrupts_5_IRQHandler /* TCPWM #1, Counter #5 */ + def_irq_handler tcpwm_1_interrupts_6_IRQHandler /* TCPWM #1, Counter #6 */ + def_irq_handler tcpwm_1_interrupts_7_IRQHandler /* TCPWM #1, Counter #7 */ + def_irq_handler tcpwm_1_interrupts_8_IRQHandler /* TCPWM #1, Counter #8 */ + def_irq_handler tcpwm_1_interrupts_9_IRQHandler /* TCPWM #1, Counter #9 */ + def_irq_handler tcpwm_1_interrupts_10_IRQHandler /* TCPWM #1, Counter #10 */ + def_irq_handler tcpwm_1_interrupts_11_IRQHandler /* TCPWM #1, Counter #11 */ + def_irq_handler tcpwm_1_interrupts_12_IRQHandler /* TCPWM #1, Counter #12 */ + def_irq_handler tcpwm_1_interrupts_13_IRQHandler /* TCPWM #1, Counter #13 */ + def_irq_handler tcpwm_1_interrupts_14_IRQHandler /* TCPWM #1, Counter #14 */ + def_irq_handler tcpwm_1_interrupts_15_IRQHandler /* TCPWM #1, Counter #15 */ + def_irq_handler tcpwm_1_interrupts_16_IRQHandler /* TCPWM #1, Counter #16 */ + def_irq_handler tcpwm_1_interrupts_17_IRQHandler /* TCPWM #1, Counter #17 */ + def_irq_handler tcpwm_1_interrupts_18_IRQHandler /* TCPWM #1, Counter #18 */ + def_irq_handler tcpwm_1_interrupts_19_IRQHandler /* TCPWM #1, Counter #19 */ + def_irq_handler tcpwm_1_interrupts_20_IRQHandler /* TCPWM #1, Counter #20 */ + def_irq_handler tcpwm_1_interrupts_21_IRQHandler /* TCPWM #1, Counter #21 */ + def_irq_handler tcpwm_1_interrupts_22_IRQHandler /* TCPWM #1, Counter #22 */ + def_irq_handler tcpwm_1_interrupts_23_IRQHandler /* TCPWM #1, Counter #23 */ + def_irq_handler udb_interrupts_0_IRQHandler /* UDB Interrupt #0 */ + def_irq_handler udb_interrupts_1_IRQHandler /* UDB Interrupt #1 */ + def_irq_handler udb_interrupts_2_IRQHandler /* UDB Interrupt #2 */ + def_irq_handler udb_interrupts_3_IRQHandler /* UDB Interrupt #3 */ + def_irq_handler udb_interrupts_4_IRQHandler /* UDB Interrupt #4 */ + def_irq_handler udb_interrupts_5_IRQHandler /* UDB Interrupt #5 */ + def_irq_handler udb_interrupts_6_IRQHandler /* UDB Interrupt #6 */ + def_irq_handler udb_interrupts_7_IRQHandler /* UDB Interrupt #7 */ + def_irq_handler udb_interrupts_8_IRQHandler /* UDB Interrupt #8 */ + def_irq_handler udb_interrupts_9_IRQHandler /* UDB Interrupt #9 */ + def_irq_handler udb_interrupts_10_IRQHandler /* UDB Interrupt #10 */ + def_irq_handler udb_interrupts_11_IRQHandler /* UDB Interrupt #11 */ + def_irq_handler udb_interrupts_12_IRQHandler /* UDB Interrupt #12 */ + def_irq_handler udb_interrupts_13_IRQHandler /* UDB Interrupt #13 */ + def_irq_handler udb_interrupts_14_IRQHandler /* UDB Interrupt #14 */ + def_irq_handler udb_interrupts_15_IRQHandler /* UDB Interrupt #15 */ + def_irq_handler pass_interrupt_sar_IRQHandler /* SAR ADC interrupt */ + def_irq_handler audioss_interrupt_i2s_IRQHandler /* I2S Audio interrupt */ + def_irq_handler audioss_interrupt_pdm_IRQHandler /* PDM/PCM Audio interrupt */ + def_irq_handler profile_interrupt_IRQHandler /* Energy Profiler interrupt */ + def_irq_handler smif_interrupt_IRQHandler /* Serial Memory Interface interrupt */ + def_irq_handler usb_interrupt_hi_IRQHandler /* USB Interrupt */ + def_irq_handler usb_interrupt_med_IRQHandler /* USB Interrupt */ + def_irq_handler usb_interrupt_lo_IRQHandler /* USB Interrupt */ + def_irq_handler pass_interrupt_dacs_IRQHandler /* Consolidated interrrupt for all DACs */ + + .end + + +/* [] END OF FILE */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_IAR/startup_psoc6_01_cm4.s b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_IAR/startup_psoc6_01_cm4.s new file mode 100644 index 0000000000..2ce41f1064 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/TOOLCHAIN_IAR/startup_psoc6_01_cm4.s @@ -0,0 +1,1150 @@ +;/**************************************************************************//** +; * @file startup_psoc6_01_cm4.s +; * @brief CMSIS Core Device Startup File for +; * ARMCM4 Device Series +; * @version V5.00 +; * @date 08. March 2016 +; ******************************************************************************/ +;/* +; * Copyright (c) 2009-2016 ARM Limited. All rights reserved. +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Licensed under the Apache License, Version 2.0 (the License); you may +; * 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. +; */ + +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + SECTION .intvec_ram:DATA:NOROOT(2) + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + EXTERN Cy_SystemInitFpuEnable + EXTERN __iar_data_init3 + PUBLIC __vector_table + PUBLIC __vector_table_0x1c + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + PUBLIC __ramVectors + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + + DCD 0x0000000D ; NMI_Handler is defined in ROM code + DCD HardFault_Handler + DCD MemManage_Handler + DCD BusFault_Handler + DCD UsageFault_Handler +__vector_table_0x1c + DCD 0 + DCD 0 + DCD 0 + DCD 0 + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 + DCD PendSV_Handler + DCD SysTick_Handler + + ; External interrupts Description + DCD ioss_interrupts_gpio_0_IRQHandler ; GPIO Port Interrupt #0 + DCD ioss_interrupts_gpio_1_IRQHandler ; GPIO Port Interrupt #1 + DCD ioss_interrupts_gpio_2_IRQHandler ; GPIO Port Interrupt #2 + DCD ioss_interrupts_gpio_3_IRQHandler ; GPIO Port Interrupt #3 + DCD ioss_interrupts_gpio_4_IRQHandler ; GPIO Port Interrupt #4 + DCD ioss_interrupts_gpio_5_IRQHandler ; GPIO Port Interrupt #5 + DCD ioss_interrupts_gpio_6_IRQHandler ; GPIO Port Interrupt #6 + DCD ioss_interrupts_gpio_7_IRQHandler ; GPIO Port Interrupt #7 + DCD ioss_interrupts_gpio_8_IRQHandler ; GPIO Port Interrupt #8 + DCD ioss_interrupts_gpio_9_IRQHandler ; GPIO Port Interrupt #9 + DCD ioss_interrupts_gpio_10_IRQHandler ; GPIO Port Interrupt #10 + DCD ioss_interrupts_gpio_11_IRQHandler ; GPIO Port Interrupt #11 + DCD ioss_interrupts_gpio_12_IRQHandler ; GPIO Port Interrupt #12 + DCD ioss_interrupts_gpio_13_IRQHandler ; GPIO Port Interrupt #13 + DCD ioss_interrupts_gpio_14_IRQHandler ; GPIO Port Interrupt #14 + DCD ioss_interrupt_gpio_IRQHandler ; GPIO All Ports + DCD ioss_interrupt_vdd_IRQHandler ; GPIO Supply Detect Interrupt + DCD lpcomp_interrupt_IRQHandler ; Low Power Comparator Interrupt + DCD scb_8_interrupt_IRQHandler ; Serial Communication Block #8 (DeepSleep capable) + DCD srss_interrupt_mcwdt_0_IRQHandler ; Multi Counter Watchdog Timer interrupt + DCD srss_interrupt_mcwdt_1_IRQHandler ; Multi Counter Watchdog Timer interrupt + DCD srss_interrupt_backup_IRQHandler ; Backup domain interrupt + DCD srss_interrupt_IRQHandler ; Other combined Interrupts for SRSS (LVD, WDT, CLKCAL) + DCD pass_interrupt_ctbs_IRQHandler ; CTBm Interrupt (all CTBms) + DCD bless_interrupt_IRQHandler ; Bluetooth Radio interrupt + DCD cpuss_interrupts_ipc_0_IRQHandler ; CPUSS Inter Process Communication Interrupt #0 + DCD cpuss_interrupts_ipc_1_IRQHandler ; CPUSS Inter Process Communication Interrupt #1 + DCD cpuss_interrupts_ipc_2_IRQHandler ; CPUSS Inter Process Communication Interrupt #2 + DCD cpuss_interrupts_ipc_3_IRQHandler ; CPUSS Inter Process Communication Interrupt #3 + DCD cpuss_interrupts_ipc_4_IRQHandler ; CPUSS Inter Process Communication Interrupt #4 + DCD cpuss_interrupts_ipc_5_IRQHandler ; CPUSS Inter Process Communication Interrupt #5 + DCD cpuss_interrupts_ipc_6_IRQHandler ; CPUSS Inter Process Communication Interrupt #6 + DCD cpuss_interrupts_ipc_7_IRQHandler ; CPUSS Inter Process Communication Interrupt #7 + DCD cpuss_interrupts_ipc_8_IRQHandler ; CPUSS Inter Process Communication Interrupt #8 + DCD cpuss_interrupts_ipc_9_IRQHandler ; CPUSS Inter Process Communication Interrupt #9 + DCD cpuss_interrupts_ipc_10_IRQHandler ; CPUSS Inter Process Communication Interrupt #10 + DCD cpuss_interrupts_ipc_11_IRQHandler ; CPUSS Inter Process Communication Interrupt #11 + DCD cpuss_interrupts_ipc_12_IRQHandler ; CPUSS Inter Process Communication Interrupt #12 + DCD cpuss_interrupts_ipc_13_IRQHandler ; CPUSS Inter Process Communication Interrupt #13 + DCD cpuss_interrupts_ipc_14_IRQHandler ; CPUSS Inter Process Communication Interrupt #14 + DCD cpuss_interrupts_ipc_15_IRQHandler ; CPUSS Inter Process Communication Interrupt #15 + DCD scb_0_interrupt_IRQHandler ; Serial Communication Block #0 + DCD scb_1_interrupt_IRQHandler ; Serial Communication Block #1 + DCD scb_2_interrupt_IRQHandler ; Serial Communication Block #2 + DCD scb_3_interrupt_IRQHandler ; Serial Communication Block #3 + DCD scb_4_interrupt_IRQHandler ; Serial Communication Block #4 + DCD scb_5_interrupt_IRQHandler ; Serial Communication Block #5 + DCD scb_6_interrupt_IRQHandler ; Serial Communication Block #6 + DCD scb_7_interrupt_IRQHandler ; Serial Communication Block #7 + DCD csd_interrupt_IRQHandler ; CSD (Capsense) interrupt + DCD cpuss_interrupts_dw0_0_IRQHandler ; CPUSS DataWire #0, Channel #0 + DCD cpuss_interrupts_dw0_1_IRQHandler ; CPUSS DataWire #0, Channel #1 + DCD cpuss_interrupts_dw0_2_IRQHandler ; CPUSS DataWire #0, Channel #2 + DCD cpuss_interrupts_dw0_3_IRQHandler ; CPUSS DataWire #0, Channel #3 + DCD cpuss_interrupts_dw0_4_IRQHandler ; CPUSS DataWire #0, Channel #4 + DCD cpuss_interrupts_dw0_5_IRQHandler ; CPUSS DataWire #0, Channel #5 + DCD cpuss_interrupts_dw0_6_IRQHandler ; CPUSS DataWire #0, Channel #6 + DCD cpuss_interrupts_dw0_7_IRQHandler ; CPUSS DataWire #0, Channel #7 + DCD cpuss_interrupts_dw0_8_IRQHandler ; CPUSS DataWire #0, Channel #8 + DCD cpuss_interrupts_dw0_9_IRQHandler ; CPUSS DataWire #0, Channel #9 + DCD cpuss_interrupts_dw0_10_IRQHandler ; CPUSS DataWire #0, Channel #10 + DCD cpuss_interrupts_dw0_11_IRQHandler ; CPUSS DataWire #0, Channel #11 + DCD cpuss_interrupts_dw0_12_IRQHandler ; CPUSS DataWire #0, Channel #12 + DCD cpuss_interrupts_dw0_13_IRQHandler ; CPUSS DataWire #0, Channel #13 + DCD cpuss_interrupts_dw0_14_IRQHandler ; CPUSS DataWire #0, Channel #14 + DCD cpuss_interrupts_dw0_15_IRQHandler ; CPUSS DataWire #0, Channel #15 + DCD cpuss_interrupts_dw1_0_IRQHandler ; CPUSS DataWire #1, Channel #0 + DCD cpuss_interrupts_dw1_1_IRQHandler ; CPUSS DataWire #1, Channel #1 + DCD cpuss_interrupts_dw1_2_IRQHandler ; CPUSS DataWire #1, Channel #2 + DCD cpuss_interrupts_dw1_3_IRQHandler ; CPUSS DataWire #1, Channel #3 + DCD cpuss_interrupts_dw1_4_IRQHandler ; CPUSS DataWire #1, Channel #4 + DCD cpuss_interrupts_dw1_5_IRQHandler ; CPUSS DataWire #1, Channel #5 + DCD cpuss_interrupts_dw1_6_IRQHandler ; CPUSS DataWire #1, Channel #6 + DCD cpuss_interrupts_dw1_7_IRQHandler ; CPUSS DataWire #1, Channel #7 + DCD cpuss_interrupts_dw1_8_IRQHandler ; CPUSS DataWire #1, Channel #8 + DCD cpuss_interrupts_dw1_9_IRQHandler ; CPUSS DataWire #1, Channel #9 + DCD cpuss_interrupts_dw1_10_IRQHandler ; CPUSS DataWire #1, Channel #10 + DCD cpuss_interrupts_dw1_11_IRQHandler ; CPUSS DataWire #1, Channel #11 + DCD cpuss_interrupts_dw1_12_IRQHandler ; CPUSS DataWire #1, Channel #12 + DCD cpuss_interrupts_dw1_13_IRQHandler ; CPUSS DataWire #1, Channel #13 + DCD cpuss_interrupts_dw1_14_IRQHandler ; CPUSS DataWire #1, Channel #14 + DCD cpuss_interrupts_dw1_15_IRQHandler ; CPUSS DataWire #1, Channel #15 + DCD cpuss_interrupts_fault_0_IRQHandler ; CPUSS Fault Structure Interrupt #0 + DCD cpuss_interrupts_fault_1_IRQHandler ; CPUSS Fault Structure Interrupt #1 + DCD cpuss_interrupt_crypto_IRQHandler ; CRYPTO Accelerator Interrupt + DCD cpuss_interrupt_fm_IRQHandler ; FLASH Macro Interrupt + DCD cpuss_interrupts_cm0_cti_0_IRQHandler ; CM0+ CTI #0 + DCD cpuss_interrupts_cm0_cti_1_IRQHandler ; CM0+ CTI #1 + DCD cpuss_interrupts_cm4_cti_0_IRQHandler ; CM4 CTI #0 + DCD cpuss_interrupts_cm4_cti_1_IRQHandler ; CM4 CTI #1 + DCD tcpwm_0_interrupts_0_IRQHandler ; TCPWM #0, Counter #0 + DCD tcpwm_0_interrupts_1_IRQHandler ; TCPWM #0, Counter #1 + DCD tcpwm_0_interrupts_2_IRQHandler ; TCPWM #0, Counter #2 + DCD tcpwm_0_interrupts_3_IRQHandler ; TCPWM #0, Counter #3 + DCD tcpwm_0_interrupts_4_IRQHandler ; TCPWM #0, Counter #4 + DCD tcpwm_0_interrupts_5_IRQHandler ; TCPWM #0, Counter #5 + DCD tcpwm_0_interrupts_6_IRQHandler ; TCPWM #0, Counter #6 + DCD tcpwm_0_interrupts_7_IRQHandler ; TCPWM #0, Counter #7 + DCD tcpwm_1_interrupts_0_IRQHandler ; TCPWM #1, Counter #0 + DCD tcpwm_1_interrupts_1_IRQHandler ; TCPWM #1, Counter #1 + DCD tcpwm_1_interrupts_2_IRQHandler ; TCPWM #1, Counter #2 + DCD tcpwm_1_interrupts_3_IRQHandler ; TCPWM #1, Counter #3 + DCD tcpwm_1_interrupts_4_IRQHandler ; TCPWM #1, Counter #4 + DCD tcpwm_1_interrupts_5_IRQHandler ; TCPWM #1, Counter #5 + DCD tcpwm_1_interrupts_6_IRQHandler ; TCPWM #1, Counter #6 + DCD tcpwm_1_interrupts_7_IRQHandler ; TCPWM #1, Counter #7 + DCD tcpwm_1_interrupts_8_IRQHandler ; TCPWM #1, Counter #8 + DCD tcpwm_1_interrupts_9_IRQHandler ; TCPWM #1, Counter #9 + DCD tcpwm_1_interrupts_10_IRQHandler ; TCPWM #1, Counter #10 + DCD tcpwm_1_interrupts_11_IRQHandler ; TCPWM #1, Counter #11 + DCD tcpwm_1_interrupts_12_IRQHandler ; TCPWM #1, Counter #12 + DCD tcpwm_1_interrupts_13_IRQHandler ; TCPWM #1, Counter #13 + DCD tcpwm_1_interrupts_14_IRQHandler ; TCPWM #1, Counter #14 + DCD tcpwm_1_interrupts_15_IRQHandler ; TCPWM #1, Counter #15 + DCD tcpwm_1_interrupts_16_IRQHandler ; TCPWM #1, Counter #16 + DCD tcpwm_1_interrupts_17_IRQHandler ; TCPWM #1, Counter #17 + DCD tcpwm_1_interrupts_18_IRQHandler ; TCPWM #1, Counter #18 + DCD tcpwm_1_interrupts_19_IRQHandler ; TCPWM #1, Counter #19 + DCD tcpwm_1_interrupts_20_IRQHandler ; TCPWM #1, Counter #20 + DCD tcpwm_1_interrupts_21_IRQHandler ; TCPWM #1, Counter #21 + DCD tcpwm_1_interrupts_22_IRQHandler ; TCPWM #1, Counter #22 + DCD tcpwm_1_interrupts_23_IRQHandler ; TCPWM #1, Counter #23 + DCD udb_interrupts_0_IRQHandler ; UDB Interrupt #0 + DCD udb_interrupts_1_IRQHandler ; UDB Interrupt #1 + DCD udb_interrupts_2_IRQHandler ; UDB Interrupt #2 + DCD udb_interrupts_3_IRQHandler ; UDB Interrupt #3 + DCD udb_interrupts_4_IRQHandler ; UDB Interrupt #4 + DCD udb_interrupts_5_IRQHandler ; UDB Interrupt #5 + DCD udb_interrupts_6_IRQHandler ; UDB Interrupt #6 + DCD udb_interrupts_7_IRQHandler ; UDB Interrupt #7 + DCD udb_interrupts_8_IRQHandler ; UDB Interrupt #8 + DCD udb_interrupts_9_IRQHandler ; UDB Interrupt #9 + DCD udb_interrupts_10_IRQHandler ; UDB Interrupt #10 + DCD udb_interrupts_11_IRQHandler ; UDB Interrupt #11 + DCD udb_interrupts_12_IRQHandler ; UDB Interrupt #12 + DCD udb_interrupts_13_IRQHandler ; UDB Interrupt #13 + DCD udb_interrupts_14_IRQHandler ; UDB Interrupt #14 + DCD udb_interrupts_15_IRQHandler ; UDB Interrupt #15 + DCD pass_interrupt_sar_IRQHandler ; SAR ADC interrupt + DCD audioss_interrupt_i2s_IRQHandler ; I2S Audio interrupt + DCD audioss_interrupt_pdm_IRQHandler ; PDM/PCM Audio interrupt + DCD profile_interrupt_IRQHandler ; Energy Profiler interrupt + DCD smif_interrupt_IRQHandler ; Serial Memory Interface interrupt + DCD usb_interrupt_hi_IRQHandler ; USB Interrupt + DCD usb_interrupt_med_IRQHandler ; USB Interrupt + DCD usb_interrupt_lo_IRQHandler ; USB Interrupt + DCD pass_interrupt_dacs_IRQHandler ; Consolidated interrrupt for all DACs + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + SECTION .intvec_ram:DATA:REORDER:NOROOT(2) +__ramVectors + DS32 __Vectors_Size + + + THUMB + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default handlers +;; + PUBWEAK Default_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Default_Handler + B Default_Handler + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Weak function for startup customization +;; +;; Note. The global resources are not yet initialized (for example global variables, peripherals, clocks) +;; because this function is executed as the first instruction in the ResetHandler. +;; The PDL is also not initialized to use the proper register offsets. +;; The user of this function is responsible for initializing the PDL and resources before using them. +;; + PUBWEAK Cy_OnResetUser + SECTION .text:CODE:REORDER:NOROOT(2) +Cy_OnResetUser + BX LR + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Weak function for OS-specific customization +;; + PUBWEAK cy_toolchain_init + SECTION .text:CODE:REORDER:NOROOT(2) +cy_toolchain_init + BX LR + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Define strong version to return zero for +;; __iar_program_start to skip data sections +;; initialization. +;; + PUBLIC __low_level_init + SECTION .text:CODE:REORDER:NOROOT(2) +__low_level_init + MOVS R0, #0 + BX LR + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + + ; Define strong function for startup customization + LDR R0, =Cy_OnResetUser + BLX R0 + + ; Disable global interrupts + CPSID I + + ; Copy vectors from ROM to RAM + LDR r1, =__vector_table + LDR r0, =__ramVectors + LDR r2, =__Vectors_Size +intvec_copy + LDR r3, [r1] + STR r3, [r0] + ADDS r0, r0, #4 + ADDS r1, r1, #4 + SUBS r2, r2, #1 + CMP r2, #0 + BNE intvec_copy + + ; Update Vector Table Offset Register + LDR r0, =__ramVectors + LDR r1, =0xE000ED08 + STR r0, [r1] + dsb + + ; OS-specific low-level initialization + LDR R0, =cy_toolchain_init + BLX R0 + + ; Initialize data sections + LDR R0, =__iar_data_init3 + BLX R0 + + LDR R0, =SystemInit + BLX R0 + + LDR R0, =__iar_program_start + BLX R0 + +; Should never get here +Cy_Main_Exited + B Cy_Main_Exited + + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B NMI_Handler + + + PUBWEAK Cy_SysLib_FaultHandler + SECTION .text:CODE:REORDER:NOROOT(1) +Cy_SysLib_FaultHandler + B Cy_SysLib_FaultHandler + + PUBWEAK HardFault_Wrapper + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Wrapper + IMPORT Cy_SysLib_FaultHandler + movs r0, #4 + mov r1, LR + tst r0, r1 + beq L_MSP + mrs r0, PSP + b L_API_call +L_MSP + mrs r0, MSP +L_API_call + ; Storing LR content for Creator call stack trace + push {LR} + bl Cy_SysLib_FaultHandler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B HardFault_Wrapper + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemManage_Handler + B HardFault_Wrapper + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B HardFault_Wrapper + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B HardFault_Wrapper + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B SysTick_Handler + + + ; External interrupts + PUBWEAK ioss_interrupts_gpio_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_0_IRQHandler + B ioss_interrupts_gpio_0_IRQHandler + + PUBWEAK ioss_interrupts_gpio_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_1_IRQHandler + B ioss_interrupts_gpio_1_IRQHandler + + PUBWEAK ioss_interrupts_gpio_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_2_IRQHandler + B ioss_interrupts_gpio_2_IRQHandler + + PUBWEAK ioss_interrupts_gpio_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_3_IRQHandler + B ioss_interrupts_gpio_3_IRQHandler + + PUBWEAK ioss_interrupts_gpio_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_4_IRQHandler + B ioss_interrupts_gpio_4_IRQHandler + + PUBWEAK ioss_interrupts_gpio_5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_5_IRQHandler + B ioss_interrupts_gpio_5_IRQHandler + + PUBWEAK ioss_interrupts_gpio_6_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_6_IRQHandler + B ioss_interrupts_gpio_6_IRQHandler + + PUBWEAK ioss_interrupts_gpio_7_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_7_IRQHandler + B ioss_interrupts_gpio_7_IRQHandler + + PUBWEAK ioss_interrupts_gpio_8_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_8_IRQHandler + B ioss_interrupts_gpio_8_IRQHandler + + PUBWEAK ioss_interrupts_gpio_9_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_9_IRQHandler + B ioss_interrupts_gpio_9_IRQHandler + + PUBWEAK ioss_interrupts_gpio_10_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_10_IRQHandler + B ioss_interrupts_gpio_10_IRQHandler + + PUBWEAK ioss_interrupts_gpio_11_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_11_IRQHandler + B ioss_interrupts_gpio_11_IRQHandler + + PUBWEAK ioss_interrupts_gpio_12_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_12_IRQHandler + B ioss_interrupts_gpio_12_IRQHandler + + PUBWEAK ioss_interrupts_gpio_13_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_13_IRQHandler + B ioss_interrupts_gpio_13_IRQHandler + + PUBWEAK ioss_interrupts_gpio_14_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupts_gpio_14_IRQHandler + B ioss_interrupts_gpio_14_IRQHandler + + PUBWEAK ioss_interrupt_gpio_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupt_gpio_IRQHandler + B ioss_interrupt_gpio_IRQHandler + + PUBWEAK ioss_interrupt_vdd_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ioss_interrupt_vdd_IRQHandler + B ioss_interrupt_vdd_IRQHandler + + PUBWEAK lpcomp_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +lpcomp_interrupt_IRQHandler + B lpcomp_interrupt_IRQHandler + + PUBWEAK scb_8_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_8_interrupt_IRQHandler + B scb_8_interrupt_IRQHandler + + PUBWEAK srss_interrupt_mcwdt_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +srss_interrupt_mcwdt_0_IRQHandler + B srss_interrupt_mcwdt_0_IRQHandler + + PUBWEAK srss_interrupt_mcwdt_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +srss_interrupt_mcwdt_1_IRQHandler + B srss_interrupt_mcwdt_1_IRQHandler + + PUBWEAK srss_interrupt_backup_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +srss_interrupt_backup_IRQHandler + B srss_interrupt_backup_IRQHandler + + PUBWEAK srss_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +srss_interrupt_IRQHandler + B srss_interrupt_IRQHandler + + PUBWEAK pass_interrupt_ctbs_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +pass_interrupt_ctbs_IRQHandler + B pass_interrupt_ctbs_IRQHandler + + PUBWEAK bless_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +bless_interrupt_IRQHandler + B bless_interrupt_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_0_IRQHandler + B cpuss_interrupts_ipc_0_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_1_IRQHandler + B cpuss_interrupts_ipc_1_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_2_IRQHandler + B cpuss_interrupts_ipc_2_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_3_IRQHandler + B cpuss_interrupts_ipc_3_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_4_IRQHandler + B cpuss_interrupts_ipc_4_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_5_IRQHandler + B cpuss_interrupts_ipc_5_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_6_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_6_IRQHandler + B cpuss_interrupts_ipc_6_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_7_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_7_IRQHandler + B cpuss_interrupts_ipc_7_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_8_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_8_IRQHandler + B cpuss_interrupts_ipc_8_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_9_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_9_IRQHandler + B cpuss_interrupts_ipc_9_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_10_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_10_IRQHandler + B cpuss_interrupts_ipc_10_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_11_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_11_IRQHandler + B cpuss_interrupts_ipc_11_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_12_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_12_IRQHandler + B cpuss_interrupts_ipc_12_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_13_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_13_IRQHandler + B cpuss_interrupts_ipc_13_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_14_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_14_IRQHandler + B cpuss_interrupts_ipc_14_IRQHandler + + PUBWEAK cpuss_interrupts_ipc_15_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_ipc_15_IRQHandler + B cpuss_interrupts_ipc_15_IRQHandler + + PUBWEAK scb_0_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_0_interrupt_IRQHandler + B scb_0_interrupt_IRQHandler + + PUBWEAK scb_1_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_1_interrupt_IRQHandler + B scb_1_interrupt_IRQHandler + + PUBWEAK scb_2_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_2_interrupt_IRQHandler + B scb_2_interrupt_IRQHandler + + PUBWEAK scb_3_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_3_interrupt_IRQHandler + B scb_3_interrupt_IRQHandler + + PUBWEAK scb_4_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_4_interrupt_IRQHandler + B scb_4_interrupt_IRQHandler + + PUBWEAK scb_5_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_5_interrupt_IRQHandler + B scb_5_interrupt_IRQHandler + + PUBWEAK scb_6_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_6_interrupt_IRQHandler + B scb_6_interrupt_IRQHandler + + PUBWEAK scb_7_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +scb_7_interrupt_IRQHandler + B scb_7_interrupt_IRQHandler + + PUBWEAK csd_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +csd_interrupt_IRQHandler + B csd_interrupt_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_0_IRQHandler + B cpuss_interrupts_dw0_0_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_1_IRQHandler + B cpuss_interrupts_dw0_1_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_2_IRQHandler + B cpuss_interrupts_dw0_2_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_3_IRQHandler + B cpuss_interrupts_dw0_3_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_4_IRQHandler + B cpuss_interrupts_dw0_4_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_5_IRQHandler + B cpuss_interrupts_dw0_5_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_6_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_6_IRQHandler + B cpuss_interrupts_dw0_6_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_7_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_7_IRQHandler + B cpuss_interrupts_dw0_7_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_8_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_8_IRQHandler + B cpuss_interrupts_dw0_8_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_9_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_9_IRQHandler + B cpuss_interrupts_dw0_9_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_10_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_10_IRQHandler + B cpuss_interrupts_dw0_10_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_11_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_11_IRQHandler + B cpuss_interrupts_dw0_11_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_12_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_12_IRQHandler + B cpuss_interrupts_dw0_12_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_13_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_13_IRQHandler + B cpuss_interrupts_dw0_13_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_14_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_14_IRQHandler + B cpuss_interrupts_dw0_14_IRQHandler + + PUBWEAK cpuss_interrupts_dw0_15_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw0_15_IRQHandler + B cpuss_interrupts_dw0_15_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_0_IRQHandler + B cpuss_interrupts_dw1_0_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_1_IRQHandler + B cpuss_interrupts_dw1_1_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_2_IRQHandler + B cpuss_interrupts_dw1_2_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_3_IRQHandler + B cpuss_interrupts_dw1_3_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_4_IRQHandler + B cpuss_interrupts_dw1_4_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_5_IRQHandler + B cpuss_interrupts_dw1_5_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_6_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_6_IRQHandler + B cpuss_interrupts_dw1_6_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_7_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_7_IRQHandler + B cpuss_interrupts_dw1_7_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_8_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_8_IRQHandler + B cpuss_interrupts_dw1_8_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_9_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_9_IRQHandler + B cpuss_interrupts_dw1_9_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_10_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_10_IRQHandler + B cpuss_interrupts_dw1_10_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_11_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_11_IRQHandler + B cpuss_interrupts_dw1_11_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_12_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_12_IRQHandler + B cpuss_interrupts_dw1_12_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_13_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_13_IRQHandler + B cpuss_interrupts_dw1_13_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_14_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_14_IRQHandler + B cpuss_interrupts_dw1_14_IRQHandler + + PUBWEAK cpuss_interrupts_dw1_15_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_dw1_15_IRQHandler + B cpuss_interrupts_dw1_15_IRQHandler + + PUBWEAK cpuss_interrupts_fault_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_fault_0_IRQHandler + B cpuss_interrupts_fault_0_IRQHandler + + PUBWEAK cpuss_interrupts_fault_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_fault_1_IRQHandler + B cpuss_interrupts_fault_1_IRQHandler + + PUBWEAK cpuss_interrupt_crypto_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupt_crypto_IRQHandler + B cpuss_interrupt_crypto_IRQHandler + + PUBWEAK cpuss_interrupt_fm_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupt_fm_IRQHandler + B cpuss_interrupt_fm_IRQHandler + + PUBWEAK cpuss_interrupts_cm0_cti_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_cm0_cti_0_IRQHandler + B cpuss_interrupts_cm0_cti_0_IRQHandler + + PUBWEAK cpuss_interrupts_cm0_cti_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_cm0_cti_1_IRQHandler + B cpuss_interrupts_cm0_cti_1_IRQHandler + + PUBWEAK cpuss_interrupts_cm4_cti_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_cm4_cti_0_IRQHandler + B cpuss_interrupts_cm4_cti_0_IRQHandler + + PUBWEAK cpuss_interrupts_cm4_cti_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +cpuss_interrupts_cm4_cti_1_IRQHandler + B cpuss_interrupts_cm4_cti_1_IRQHandler + + PUBWEAK tcpwm_0_interrupts_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_0_interrupts_0_IRQHandler + B tcpwm_0_interrupts_0_IRQHandler + + PUBWEAK tcpwm_0_interrupts_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_0_interrupts_1_IRQHandler + B tcpwm_0_interrupts_1_IRQHandler + + PUBWEAK tcpwm_0_interrupts_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_0_interrupts_2_IRQHandler + B tcpwm_0_interrupts_2_IRQHandler + + PUBWEAK tcpwm_0_interrupts_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_0_interrupts_3_IRQHandler + B tcpwm_0_interrupts_3_IRQHandler + + PUBWEAK tcpwm_0_interrupts_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_0_interrupts_4_IRQHandler + B tcpwm_0_interrupts_4_IRQHandler + + PUBWEAK tcpwm_0_interrupts_5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_0_interrupts_5_IRQHandler + B tcpwm_0_interrupts_5_IRQHandler + + PUBWEAK tcpwm_0_interrupts_6_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_0_interrupts_6_IRQHandler + B tcpwm_0_interrupts_6_IRQHandler + + PUBWEAK tcpwm_0_interrupts_7_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_0_interrupts_7_IRQHandler + B tcpwm_0_interrupts_7_IRQHandler + + PUBWEAK tcpwm_1_interrupts_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_0_IRQHandler + B tcpwm_1_interrupts_0_IRQHandler + + PUBWEAK tcpwm_1_interrupts_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_1_IRQHandler + B tcpwm_1_interrupts_1_IRQHandler + + PUBWEAK tcpwm_1_interrupts_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_2_IRQHandler + B tcpwm_1_interrupts_2_IRQHandler + + PUBWEAK tcpwm_1_interrupts_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_3_IRQHandler + B tcpwm_1_interrupts_3_IRQHandler + + PUBWEAK tcpwm_1_interrupts_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_4_IRQHandler + B tcpwm_1_interrupts_4_IRQHandler + + PUBWEAK tcpwm_1_interrupts_5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_5_IRQHandler + B tcpwm_1_interrupts_5_IRQHandler + + PUBWEAK tcpwm_1_interrupts_6_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_6_IRQHandler + B tcpwm_1_interrupts_6_IRQHandler + + PUBWEAK tcpwm_1_interrupts_7_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_7_IRQHandler + B tcpwm_1_interrupts_7_IRQHandler + + PUBWEAK tcpwm_1_interrupts_8_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_8_IRQHandler + B tcpwm_1_interrupts_8_IRQHandler + + PUBWEAK tcpwm_1_interrupts_9_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_9_IRQHandler + B tcpwm_1_interrupts_9_IRQHandler + + PUBWEAK tcpwm_1_interrupts_10_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_10_IRQHandler + B tcpwm_1_interrupts_10_IRQHandler + + PUBWEAK tcpwm_1_interrupts_11_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_11_IRQHandler + B tcpwm_1_interrupts_11_IRQHandler + + PUBWEAK tcpwm_1_interrupts_12_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_12_IRQHandler + B tcpwm_1_interrupts_12_IRQHandler + + PUBWEAK tcpwm_1_interrupts_13_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_13_IRQHandler + B tcpwm_1_interrupts_13_IRQHandler + + PUBWEAK tcpwm_1_interrupts_14_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_14_IRQHandler + B tcpwm_1_interrupts_14_IRQHandler + + PUBWEAK tcpwm_1_interrupts_15_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_15_IRQHandler + B tcpwm_1_interrupts_15_IRQHandler + + PUBWEAK tcpwm_1_interrupts_16_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_16_IRQHandler + B tcpwm_1_interrupts_16_IRQHandler + + PUBWEAK tcpwm_1_interrupts_17_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_17_IRQHandler + B tcpwm_1_interrupts_17_IRQHandler + + PUBWEAK tcpwm_1_interrupts_18_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_18_IRQHandler + B tcpwm_1_interrupts_18_IRQHandler + + PUBWEAK tcpwm_1_interrupts_19_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_19_IRQHandler + B tcpwm_1_interrupts_19_IRQHandler + + PUBWEAK tcpwm_1_interrupts_20_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_20_IRQHandler + B tcpwm_1_interrupts_20_IRQHandler + + PUBWEAK tcpwm_1_interrupts_21_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_21_IRQHandler + B tcpwm_1_interrupts_21_IRQHandler + + PUBWEAK tcpwm_1_interrupts_22_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_22_IRQHandler + B tcpwm_1_interrupts_22_IRQHandler + + PUBWEAK tcpwm_1_interrupts_23_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +tcpwm_1_interrupts_23_IRQHandler + B tcpwm_1_interrupts_23_IRQHandler + + PUBWEAK udb_interrupts_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_0_IRQHandler + B udb_interrupts_0_IRQHandler + + PUBWEAK udb_interrupts_1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_1_IRQHandler + B udb_interrupts_1_IRQHandler + + PUBWEAK udb_interrupts_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_2_IRQHandler + B udb_interrupts_2_IRQHandler + + PUBWEAK udb_interrupts_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_3_IRQHandler + B udb_interrupts_3_IRQHandler + + PUBWEAK udb_interrupts_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_4_IRQHandler + B udb_interrupts_4_IRQHandler + + PUBWEAK udb_interrupts_5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_5_IRQHandler + B udb_interrupts_5_IRQHandler + + PUBWEAK udb_interrupts_6_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_6_IRQHandler + B udb_interrupts_6_IRQHandler + + PUBWEAK udb_interrupts_7_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_7_IRQHandler + B udb_interrupts_7_IRQHandler + + PUBWEAK udb_interrupts_8_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_8_IRQHandler + B udb_interrupts_8_IRQHandler + + PUBWEAK udb_interrupts_9_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_9_IRQHandler + B udb_interrupts_9_IRQHandler + + PUBWEAK udb_interrupts_10_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_10_IRQHandler + B udb_interrupts_10_IRQHandler + + PUBWEAK udb_interrupts_11_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_11_IRQHandler + B udb_interrupts_11_IRQHandler + + PUBWEAK udb_interrupts_12_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_12_IRQHandler + B udb_interrupts_12_IRQHandler + + PUBWEAK udb_interrupts_13_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_13_IRQHandler + B udb_interrupts_13_IRQHandler + + PUBWEAK udb_interrupts_14_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_14_IRQHandler + B udb_interrupts_14_IRQHandler + + PUBWEAK udb_interrupts_15_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +udb_interrupts_15_IRQHandler + B udb_interrupts_15_IRQHandler + + PUBWEAK pass_interrupt_sar_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +pass_interrupt_sar_IRQHandler + B pass_interrupt_sar_IRQHandler + + PUBWEAK audioss_interrupt_i2s_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +audioss_interrupt_i2s_IRQHandler + B audioss_interrupt_i2s_IRQHandler + + PUBWEAK audioss_interrupt_pdm_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +audioss_interrupt_pdm_IRQHandler + B audioss_interrupt_pdm_IRQHandler + + PUBWEAK profile_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +profile_interrupt_IRQHandler + B profile_interrupt_IRQHandler + + PUBWEAK smif_interrupt_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +smif_interrupt_IRQHandler + B smif_interrupt_IRQHandler + + PUBWEAK usb_interrupt_hi_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +usb_interrupt_hi_IRQHandler + B usb_interrupt_hi_IRQHandler + + PUBWEAK usb_interrupt_med_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +usb_interrupt_med_IRQHandler + B usb_interrupt_med_IRQHandler + + PUBWEAK usb_interrupt_lo_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +usb_interrupt_lo_IRQHandler + B usb_interrupt_lo_IRQHandler + + PUBWEAK pass_interrupt_dacs_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +pass_interrupt_dacs_IRQHandler + B pass_interrupt_dacs_IRQHandler + + + END + + +; [] END OF FILE diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/system_psoc6.h b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/system_psoc6.h new file mode 100644 index 0000000000..f0276e3794 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/system_psoc6.h @@ -0,0 +1,684 @@ +/***************************************************************************//** +* \file system_psoc6.h +* \version 2.60 +* +* \brief Device system header file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + + +#ifndef _SYSTEM_PSOC6_H_ +#define _SYSTEM_PSOC6_H_ + +/** +* \addtogroup group_system_config +* \{ +* Provides device startup, system configuration, and linker script files. +* The system startup provides the followings features: +* - See \ref group_system_config_device_initialization for the: +* * \ref group_system_config_dual_core_device_initialization +* * \ref group_system_config_single_core_device_initialization +* - \ref group_system_config_device_memory_definition +* - \ref group_system_config_heap_stack_config +* - \ref group_system_config_merge_apps +* - \ref group_system_config_default_handlers +* - \ref group_system_config_device_vector_table +* - \ref group_system_config_cm4_functions +* +* \section group_system_config_configuration Configuration Considerations +* +* \subsection group_system_config_device_memory_definition Device Memory Definition +* The flash and RAM allocation for each CPU is defined by the linker scripts. +* For dual-core devices, the physical flash and RAM memory is shared between the CPU cores. +* 2 KB of RAM (allocated at the end of RAM) are reserved for system use. +* For Single-Core devices the system reserves additional 80 bytes of RAM. +* Using the reserved memory area for other purposes will lead to unexpected behavior. +* +* \note The linker files provided with the PDL are generic and handle all common +* use cases. Your project may not use every section defined in the linker files. +* In that case you may see warnings during the build process. To eliminate build +* warnings in your project, you can simply comment out or remove the relevant +* code in the linker file. +* +* ARM GCC\n +* The flash and RAM sections for the CPU are defined in the linker files: +* 'xx_yy.ld', where 'xx' is the device group, and 'yy' is the target CPU; for example, +* 'cy8c6xx7_cm0plus.ld' and 'cy8c6xx7_cm4_dual.ld'. +* \note If the start of the Cortex-M4 application image is changed, the value +* of the of the \ref CY_CORTEX_M4_APPL_ADDR should also be changed. The +* \ref CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the +* Cy_SysEnableCM4() function call. +* +* Change the flash and RAM sizes by editing the macros value in the +* linker files for both CPUs: +* - 'xx_cm0plus.ld', where 'xx' is the device group: +* \code +* flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x00080000 +* ram (rwx) : ORIGIN = 0x08000000, LENGTH = 0x00024000 +* \endcode +* - 'xx_cm4_dual.ld', where 'xx' is the device group: +* \code +* flash (rx) : ORIGIN = 0x10080000, LENGTH = 0x00080000 +* ram (rwx) : ORIGIN = 0x08024000, LENGTH = 0x00023800 +* \endcode +* +* Change the value of the \ref CY_CORTEX_M4_APPL_ADDR macro to the rom ORIGIN's +* value in the 'xx_cm4_dual.ld' file, where 'xx' is the device group. Do this +* by either: +* - Passing the following commands to the compiler:\n +* \code -D CY_CORTEX_M4_APPL_ADDR=0x10080000 \endcode +* - Editing the \ref CY_CORTEX_M4_APPL_ADDR value in the 'system_xx.h', where 'xx' is device family:\n +* \code #define CY_CORTEX_M4_APPL_ADDR (0x10080000u) \endcode +* +* ARM MDK\n +* The flash and RAM sections for the CPU are defined in the linker files: +* 'xx_yy.scat', where 'xx' is the device group, and 'yy' is the target CPU; for example, +* 'cy8c6xx7_cm0plus.scat' and 'cy8c6xx7_cm4_dual.scat'. +* \note If the start of the Cortex-M4 application image is changed, the value +* of the of the \ref CY_CORTEX_M4_APPL_ADDR should also be changed. The +* \ref CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the \ref +* Cy_SysEnableCM4() function call. +* +* \note The linker files provided with the PDL are generic and handle all common +* use cases. Your project may not use every section defined in the linker files. +* In that case you may see the warnings during the build process: +* L6314W (no section matches pattern) and/or L6329W +* (pattern only matches removed unused sections). In your project, you can +* suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to +* the linker. You can also comment out or remove the relevant code in the linker +* file. +* +* Change the flash and RAM sizes by editing the macros value in the +* linker files for both CPUs: +* - 'xx_cm0plus.scat', where 'xx' is the device group: +* \code +* #define FLASH_START 0x10000000 +* #define FLASH_SIZE 0x00080000 +* #define RAM_START 0x08000000 +* #define RAM_SIZE 0x00024000 +* \endcode +* - 'xx_cm4_dual.scat', where 'xx' is the device group: +* \code +* #define FLASH_START 0x10080000 +* #define FLASH_SIZE 0x00080000 +* #define RAM_START 0x08024000 +* #define RAM_SIZE 0x00023800 +* \endcode +* +* Change the value of the \ref CY_CORTEX_M4_APPL_ADDR macro to the FLASH_START +* value in the 'xx_cm4_dual.scat' file, +* where 'xx' is the device group. Do this by either: +* - Passing the following commands to the compiler:\n +* \code -D CY_CORTEX_M4_APPL_ADDR=0x10080000 \endcode +* - Editing the \ref CY_CORTEX_M4_APPL_ADDR value in the 'system_xx.h', where +* 'xx' is device family:\n +* \code #define CY_CORTEX_M4_APPL_ADDR (0x10080000u) \endcode +* +* IAR\n +* The flash and RAM sections for the CPU are defined in the linker files: +* 'xx_yy.icf', where 'xx' is the device group, and 'yy' is the target CPU; for example, +* 'cy8c6xx7_cm0plus.icf' and 'cy8c6xx7_cm4_dual.icf'. +* \note If the start of the Cortex-M4 application image is changed, the value +* of the of the \ref CY_CORTEX_M4_APPL_ADDR should also be changed. The +* \ref CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the \ref +* Cy_SysEnableCM4() function call. +* +* Change the flash and RAM sizes by editing the macros value in the +* linker files for both CPUs: +* - 'xx_cm0plus.icf', where 'xx' is the device group: +* \code +* define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000; +* define symbol __ICFEDIT_region_IROM1_end__ = 0x10080000; +* define symbol __ICFEDIT_region_IRAM1_start__ = 0x08000000; +* define symbol __ICFEDIT_region_IRAM1_end__ = 0x08024000; +* \endcode +* - 'xx_cm4_dual.icf', where 'xx' is the device group: +* \code +* define symbol __ICFEDIT_region_IROM1_start__ = 0x10080000; +* define symbol __ICFEDIT_region_IROM1_end__ = 0x10100000; +* define symbol __ICFEDIT_region_IRAM1_start__ = 0x08024000; +* define symbol __ICFEDIT_region_IRAM1_end__ = 0x08047800; +* \endcode +* +* Change the value of the \ref CY_CORTEX_M4_APPL_ADDR macro to the +* __ICFEDIT_region_IROM1_start__ value in the 'xx_cm4_dual.icf' file, where 'xx' +* is the device group. Do this by either: +* - Passing the following commands to the compiler:\n +* \code -D CY_CORTEX_M4_APPL_ADDR=0x10080000 \endcode +* - Editing the \ref CY_CORTEX_M4_APPL_ADDR value in the 'system_xx.h', where +* 'xx' is device family:\n +* \code #define CY_CORTEX_M4_APPL_ADDR (0x10080000u) \endcode +* +* \subsection group_system_config_device_initialization Device Initialization +* After a power-on-reset (POR), the boot process is handled by the boot code +* from the on-chip ROM that is always executed by the Cortex-M0+ core. The boot +* code passes the control to the Cortex-M0+ startup code located in flash. +* +* \subsubsection group_system_config_dual_core_device_initialization Dual-Core Devices +* The Cortex-M0+ startup code performs the device initialization by a call to +* SystemInit() and then calls the main() function. The Cortex-M4 core is disabled +* by default. Enable the core using the \ref Cy_SysEnableCM4() function. +* See \ref group_system_config_cm4_functions for more details. +* \note Startup code executes SystemInit() function for the both Cortex-M0+ and Cortex-M4 cores. +* The function has a separate implementation on each core. +* Both function implementations unlock and disable the WDT. +* Therefore enable the WDT after both cores have been initialized. +* +* \subsubsection group_system_config_single_core_device_initialization Single-Core Devices +* The Cortex-M0+ core is not user-accessible on these devices. In this case the +* Flash Boot handles setup of the CM0+ core and starts the Cortex-M4 core. +* +* \subsection group_system_config_heap_stack_config Heap and Stack Configuration +* There are two ways to adjust heap and stack configurations: +* -# Editing source code files +* -# Specifying via command line +* +* By default, the stack size is set to 0x00001000 and the heap size is set to 0x00000400. +* +* \subsubsection group_system_config_heap_stack_config_gcc ARM GCC +* - Editing source code files\n +* The heap and stack sizes are defined in the assembler startup files +* (e.g. startup_psoc6_01_cm0plus.S and startup_psoc6_01_cm4.S). +* Change the heap and stack sizes by modifying the following lines:\n +* \code .equ Stack_Size, 0x00001000 \endcode +* \code .equ Heap_Size, 0x00000400 \endcode +* +* - Specifying via command line\n +* Change the heap and stack sizes passing the following commands to the compiler:\n +* \code -D __STACK_SIZE=0x000000400 \endcode +* \code -D __HEAP_SIZE=0x000000100 \endcode +* +* \subsubsection group_system_config_heap_stack_config_mdk ARM MDK +* - Editing source code files\n +* The heap and stack sizes are defined in the assembler startup files +* (e.g. startup_psoc6_01_cm0plus.s and startup_psoc6_01_cm4.s). +* Change the heap and stack sizes by modifying the following lines:\n +* \code Stack_Size EQU 0x00001000 \endcode +* \code Heap_Size EQU 0x00000400 \endcode +* +* - Specifying via command line\n +* Change the heap and stack sizes passing the following commands to the assembler:\n +* \code "--predefine=___STACK_SIZE SETA 0x000000400" \endcode +* \code "--predefine=__HEAP_SIZE SETA 0x000000100" \endcode +* +* \subsubsection group_system_config_heap_stack_config_iar IAR +* - Editing source code files\n +* The heap and stack sizes are defined in the linker scatter files: 'xx_yy.icf', +* where 'xx' is the device family, and 'yy' is the target CPU; for example, +* cy8c6xx7_cm0plus.icf and cy8c6xx7_cm4_dual.icf. +* Change the heap and stack sizes by modifying the following lines:\n +* \code Stack_Size EQU 0x00001000 \endcode +* \code Heap_Size EQU 0x00000400 \endcode +* +* - Specifying via command line\n +* Change the heap and stack sizes passing the following commands to the +* linker (including quotation marks):\n +* \code --define_symbol __STACK_SIZE=0x000000400 \endcode +* \code --define_symbol __HEAP_SIZE=0x000000100 \endcode +* +* \subsection group_system_config_merge_apps Merging CM0+ and CM4 Executables +* The CM0+ project and linker script build the CM0+ application image. Similarly, +* the CM4 linker script builds the CM4 application image. Each specifies +* locations, sizes, and contents of sections in memory. See +* \ref group_system_config_device_memory_definition for the symbols and default +* values. +* +* The cymcuelftool is invoked by a post-build command. The precise project +* setting is IDE-specific. +* +* The cymcuelftool combines the two executables. The tool examines the +* executables to ensure that memory regions either do not overlap, or contain +* identical bytes (shared). If there are no problems, it creates a new ELF file +* with the merged image, without changing any of the addresses or data. +* +* \subsection group_system_config_default_handlers Default Interrupt Handlers Definition +* The default interrupt handler functions are defined as weak functions to a dummy +* handler in the startup file. The naming convention for the interrupt handler names +* is \_IRQHandler. A default interrupt handler can be overwritten in +* user code by defining the handler function using the same name. For example: +* \code +* void scb_0_interrupt_IRQHandler(void) +*{ +* ... +*} +* \endcode +* +* \subsection group_system_config_device_vector_table Vectors Table Copy from Flash to RAM +* This process uses memory sections defined in the linker script. The startup +* code actually defines the contents of the vector table and performs the copy. +* \subsubsection group_system_config_device_vector_table_gcc ARM GCC +* The linker script file is 'xx_yy.ld', where 'xx' is the device family, and +* 'yy' is the target CPU; for example, cy8c6xx7_cm0plus.ld and cy8c6xx7_cm4_dual.ld. +* It defines sections and locations in memory.\n +* Copy interrupt vectors from flash to RAM: \n +* From: \code LONG (__Vectors) \endcode +* To: \code LONG (__ram_vectors_start__) \endcode +* Size: \code LONG (__Vectors_End - __Vectors) \endcode +* The vector table address (and the vector table itself) are defined in the +* assembler startup files (e.g. startup_psoc6_01_cm0plus.S and startup_psoc6_01_cm4.S). +* The code in these files copies the vector table from Flash to RAM. +* \subsubsection group_system_config_device_vector_table_mdk ARM MDK +* The linker script file is 'xx_yy.scat', where 'xx' is the device family, +* and 'yy' is the target CPU; for example, cy8c6xx7_cm0plus.scat and +* cy8c6xx7_cm4_dual.scat. The linker script specifies that the vector table +* (RESET_RAM) shall be first in the RAM section.\n +* RESET_RAM represents the vector table. It is defined in the assembler startup +* files (e.g. startup_psoc6_01_cm0plus.s and startup_psoc6_01_cm4.s). +* The code in these files copies the vector table from Flash to RAM. +* +* \subsubsection group_system_config_device_vector_table_iar IAR +* The linker script file is 'xx_yy.icf', where 'xx' is the device family, and +* 'yy' is the target CPU; for example, cy8c6xx7_cm0plus.icf and cy8c6xx7_cm4_dual.icf. +* This file defines the .intvec_ram section and its location. +* \code place at start of IRAM1_region { readwrite section .intvec_ram}; \endcode +* The vector table address (and the vector table itself) are defined in the +* assembler startup files (e.g. startup_psoc6_01_cm0plus.s and startup_psoc6_01_cm4.s). +* The code in these files copies the vector table from Flash to RAM. +* +* \section group_system_config_more_information More Information +* Refer to the PDL User Guide for the +* more details. +* +* \section group_system_config_MISRA MISRA Compliance +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
MISRA RuleRule Class (Required/Advisory)Rule DescriptionDescription of Deviation(s)
2.3RThe character sequence // shall not be used within a comment.The comments provide a useful WEB link to the documentation.
+* +* \section group_system_config_changelog Changelog +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
VersionChangesReason for Change
2.60Updated linker scripts.Provided support for new devices, updated usage of CM0p prebuilt image.
2.50Updated assembler files, C files, linker scripts.Dynamic allocated HEAP size for Arm Compiler 6, IAR 8.
2.40Updated assembler files, C files, linker scripts.Added Arm Compiler 6 support.
2.30Added assembler files, linker scripts for Mbed OS.Added Arm Mbed OS embedded operating system support.
Updated linker scripts to extend the Flash and Ram memories size available for the CM4 core.Enhanced PDL usability.
2.20Moved the Cy_IPC_SystemSemaInit(), Cy_IPC_SystemPipeInit() functions implementation from IPC to Startup.Changed the IPC driver configuration method from compile time to run time.
2.10Added constructor attribute to SystemInit() function declaration for ARM MDK compiler. \n +* Removed $Sub$$main symbol for ARM MDK compiler. +* uVision Debugger support.
Updated description of the Startup behavior for Single-Core Devices. \n +* Added note about WDT disabling by SystemInit() function. +* Documentation improvement.
2.0Added restoring of FLL registers to the default state in SystemInit() API for single core devices. +* Single core device support. +*
Added Normal Access Restrictions, Public Key, TOC part2 and TOC part2 copy to Supervisory flash linker memory regions. \n +* Renamed 'wflash' memory region to 'em_eeprom'. +* Linker scripts usability improvement.
Added Cy_IPC_SystemSemaInit(), Cy_IPC_SystemPipeInit(), Cy_Flash_Init() functions call to SystemInit() API.Reserved system resources for internal operations.
Added clearing and releasing of IPC structure #7 (reserved for the Deep-Sleep operations) to SystemInit() API.To avoid deadlocks in case of SW or WDT reset during Deep-Sleep entering.
1.0Initial version
+* +* +* \defgroup group_system_config_macro Macro +* \{ +* \defgroup group_system_config_system_macro System +* \defgroup group_system_config_cm4_status_macro Cortex-M4 Status +* \defgroup group_system_config_user_settings_macro User Settings +* \} +* \defgroup group_system_config_functions Functions +* \{ +* \defgroup group_system_config_system_functions System +* \defgroup group_system_config_cm4_functions Cortex-M4 Control +* \} +* \defgroup group_system_config_globals Global Variables +* +* \} +*/ + +/** +* \addtogroup group_system_config_system_functions +* \{ +* \details +* The following system functions implement CMSIS Core functions. +* Refer to the [CMSIS documentation] +* (http://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html "System and Clock Configuration") +* for more details. +* \} +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* +* Include files +*******************************************************************************/ +#include + + +/******************************************************************************* +* Global preprocessor symbols/macros ('define') +*******************************************************************************/ +#if ((defined(__GNUC__) && (__ARM_ARCH == 6) && (__ARM_ARCH_6M__ == 1)) || \ + (defined (__ICCARM__) && (__CORE__ == __ARM6M__)) || \ + (defined(__ARMCC_VERSION) && (__TARGET_ARCH_THUMB == 3))) + #define CY_SYSTEM_CPU_CM0P 1UL +#else + #define CY_SYSTEM_CPU_CM0P 0UL +#endif + +#if defined (CY_PSOC_CREATOR_USED) && (CY_PSOC_CREATOR_USED == 1U) + #include "cyfitter.h" +#endif /* (CY_PSOC_CREATOR_USED) && (CY_PSOC_CREATOR_USED == 1U) */ + + + + +/******************************************************************************* +* +* START OF USER SETTINGS HERE +* =========================== +* +* All lines with '<<<' can be set by user. +* +*******************************************************************************/ + +/** +* \addtogroup group_system_config_user_settings_macro +* \{ +*/ + +#if defined (CYDEV_CLK_EXTCLK__HZ) + #define CY_CLK_EXT_FREQ_HZ (CYDEV_CLK_EXTCLK__HZ) +#else + /***************************************************************************//** + * External Clock Frequency (in Hz, [value]UL). If compiled within + * PSoC Creator and the clock is enabled in the DWR, the value from DWR used. + * Otherwise, edit the value below. + * (USER SETTING) + *******************************************************************************/ + #define CY_CLK_EXT_FREQ_HZ (24000000UL) /* <<< 24 MHz */ +#endif /* (CYDEV_CLK_EXTCLK__HZ) */ + + +#if defined (CYDEV_CLK_ECO__HZ) + #define CY_CLK_ECO_FREQ_HZ (CYDEV_CLK_ECO__HZ) +#else + /***************************************************************************//** + * \brief External crystal oscillator frequency (in Hz, [value]UL). If compiled + * within PSoC Creator and the clock is enabled in the DWR, the value from DWR + * used. + * (USER SETTING) + *******************************************************************************/ + #define CY_CLK_ECO_FREQ_HZ (24000000UL) /* <<< 24 MHz */ +#endif /* (CYDEV_CLK_ECO__HZ) */ + + +#if defined (CYDEV_CLK_ALTHF__HZ) + #define CY_CLK_ALTHF_FREQ_HZ (CYDEV_CLK_ALTHF__HZ) +#else + /***************************************************************************//** + * \brief Alternate high frequency (in Hz, [value]UL). If compiled within + * PSoC Creator and the clock is enabled in the DWR, the value from DWR used. + * Otherwise, edit the value below. + * (USER SETTING) + *******************************************************************************/ + #define CY_CLK_ALTHF_FREQ_HZ (32000000UL) /* <<< 32 MHz */ +#endif /* (CYDEV_CLK_ALTHF__HZ) */ + + +/***************************************************************************//** +* \brief Start address of the Cortex-M4 application ([address]UL) +* (USER SETTING) +*******************************************************************************/ +#if !defined (CY_CORTEX_M4_APPL_ADDR) + #define CY_CORTEX_M4_APPL_ADDR (CY_FLASH_BASE + 0x2000U) /* <<< 8 kB of flash is reserved for the Cortex-M0+ application */ +#endif /* (CY_CORTEX_M4_APPL_ADDR) */ + + +/***************************************************************************//** +* \brief IPC Semaphores allocation ([value]UL). +* (USER SETTING) +*******************************************************************************/ +#define CY_IPC_SEMA_COUNT (128UL) /* <<< This will allow 128 (4*32) semaphores */ + + +/***************************************************************************//** +* \brief IPC Pipe definitions ([value]UL). +* (USER SETTING) +*******************************************************************************/ +#define CY_IPC_MAX_ENDPOINTS (8UL) /* <<< 8 endpoints */ + + +/******************************************************************************* +* +* END OF USER SETTINGS HERE +* ========================= +* +*******************************************************************************/ + +/** \} group_system_config_user_settings_macro */ + + +/** +* \addtogroup group_system_config_system_macro +* \{ +*/ + +#if (CY_SYSTEM_CPU_CM0P == 1UL) || defined(CY_DOXYGEN) + /** The Cortex-M0+ startup driver identifier */ + #define CY_STARTUP_M0P_ID ((uint32_t)((uint32_t)((0x0EU) & 0x3FFFU) << 18U)) +#endif /* (CY_SYSTEM_CPU_CM0P == 1UL) */ + +#if (CY_SYSTEM_CPU_CM0P != 1UL) || defined(CY_DOXYGEN) + /** The Cortex-M4 startup driver identifier */ + #define CY_STARTUP_M4_ID ((uint32_t)((uint32_t)((0x0FU) & 0x3FFFU) << 18U)) +#endif /* (CY_SYSTEM_CPU_CM0P != 1UL) */ + +/** \} group_system_config_system_macro */ + + +/** +* \addtogroup group_system_config_system_functions +* \{ +*/ +#if defined(__ARMCC_VERSION) + extern void SystemInit(void) __attribute__((constructor)); +#else + extern void SystemInit(void); +#endif /* (__ARMCC_VERSION) */ + +extern void SystemCoreClockUpdate(void); +/** \} group_system_config_system_functions */ + + +/** +* \addtogroup group_system_config_cm4_functions +* \{ +*/ +extern uint32_t Cy_SysGetCM4Status(void); +extern void Cy_SysEnableCM4(uint32_t vectorTableOffset); +extern void Cy_SysDisableCM4(void); +extern void Cy_SysRetainCM4(void); +extern void Cy_SysResetCM4(void); +/** \} group_system_config_cm4_functions */ + + +/** \cond */ +extern void Default_Handler (void); + +void Cy_SysIpcPipeIsrCm0(void); +void Cy_SysIpcPipeIsrCm4(void); + +extern void Cy_SystemInit(void); +extern void Cy_SystemInitFpuEnable(void); + +extern uint32_t cy_delayFreqHz; +extern uint32_t cy_delayFreqKhz; +extern uint8_t cy_delayFreqMhz; +extern uint32_t cy_delay32kMs; +/** \endcond */ + + +#if (CY_SYSTEM_CPU_CM0P == 1UL) || defined(CY_DOXYGEN) +/** +* \addtogroup group_system_config_cm4_status_macro +* \{ +*/ +#define CY_SYS_CM4_STATUS_ENABLED (3U) /**< The Cortex-M4 core is enabled: power on, clock on, no isolate, no reset and no retain. */ +#define CY_SYS_CM4_STATUS_DISABLED (0U) /**< The Cortex-M4 core is disabled: power off, clock off, isolate, reset and no retain. */ +#define CY_SYS_CM4_STATUS_RETAINED (2U) /**< The Cortex-M4 core is retained. power off, clock off, isolate, no reset and retain. */ +#define CY_SYS_CM4_STATUS_RESET (1U) /**< The Cortex-M4 core is in the Reset mode: clock off, no isolated, no retain and reset. */ +/** \} group_system_config_cm4_status_macro */ + +#endif /* (CY_SYSTEM_CPU_CM0P == 1UL) */ + + +/******************************************************************************* +* IPC Configuration +* ========================= +*******************************************************************************/ +/* IPC CY_PIPE default configuration */ +#define CY_SYS_CYPIPE_CLIENT_CNT (8UL) + +#define CY_SYS_INTR_CYPIPE_MUX_EP0 (1UL) /* IPC CYPRESS PIPE */ +#define CY_SYS_INTR_CYPIPE_PRIOR_EP0 (1UL) /* Notifier Priority */ +#define CY_SYS_INTR_CYPIPE_PRIOR_EP1 (1UL) /* Notifier Priority */ + +#define CY_SYS_CYPIPE_CHAN_MASK_EP0 (0x0001UL << CY_IPC_CHAN_CYPIPE_EP0) +#define CY_SYS_CYPIPE_CHAN_MASK_EP1 (0x0001UL << CY_IPC_CHAN_CYPIPE_EP1) + + +/******************************************************************************/ +/* + * The System pipe configuration defines the IPC channel number, interrupt + * number, and the pipe interrupt mask for the endpoint. + * + * The format of the endPoint configuration + * Bits[31:16] Interrupt Mask + * Bits[15:8 ] IPC interrupt + * Bits[ 7:0 ] IPC channel + */ + +/* System Pipe addresses */ +/* CyPipe defines */ + +#define CY_SYS_CYPIPE_INTR_MASK ( CY_SYS_CYPIPE_CHAN_MASK_EP0 | CY_SYS_CYPIPE_CHAN_MASK_EP1 ) + +#define CY_SYS_CYPIPE_CONFIG_EP0 ( (CY_SYS_CYPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos) \ + | (CY_IPC_INTR_CYPIPE_EP0 << CY_IPC_PIPE_CFG_INTR_Pos) \ + | CY_IPC_CHAN_CYPIPE_EP0) +#define CY_SYS_CYPIPE_CONFIG_EP1 ( (CY_SYS_CYPIPE_INTR_MASK << CY_IPC_PIPE_CFG_IMASK_Pos) \ + | (CY_IPC_INTR_CYPIPE_EP1 << CY_IPC_PIPE_CFG_INTR_Pos) \ + | CY_IPC_CHAN_CYPIPE_EP1) + +/******************************************************************************/ + + +/** \addtogroup group_system_config_globals +* \{ +*/ + +extern uint32_t SystemCoreClock; +extern uint32_t cy_BleEcoClockFreqHz; +extern uint32_t cy_Hfclk0FreqHz; +extern uint32_t cy_PeriClkFreqHz; + +/** \} group_system_config_globals */ + + + +/** \cond INTERNAL */ +/******************************************************************************* +* Backward compatibility macro. The following code is DEPRECATED and must +* not be used in new projects +*******************************************************************************/ + +/* BWC defines for functions related to enter/exit critical section */ +#define Cy_SaveIRQ Cy_SysLib_EnterCriticalSection +#define Cy_RestoreIRQ Cy_SysLib_ExitCriticalSection +#define CY_SYS_INTR_CYPIPE_EP0 (CY_IPC_INTR_CYPIPE_EP0) +#define CY_SYS_INTR_CYPIPE_EP1 (CY_IPC_INTR_CYPIPE_EP1) + +/** \endcond */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_PSOC6_H_ */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/system_psoc6_cm4.c b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/system_psoc6_cm4.c new file mode 100644 index 0000000000..0a18f50a4d --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE/startup/system_psoc6_cm4.c @@ -0,0 +1,552 @@ +/***************************************************************************//** +* \file system_psoc6_cm4.c +* \version 2.60 +* +* The device system-source file. +* +******************************************************************************** +* \copyright +* Copyright 2016-2019 Cypress Semiconductor Corporation +* SPDX-License-Identifier: Apache-2.0 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include +#include "system_psoc6.h" +#include "cy_device.h" +#include "cy_device_headers.h" +#include "cy_syslib.h" +#include "cy_wdt.h" + +#if !defined(CY_IPC_DEFAULT_CFG_DISABLE) + #include "cy_ipc_sema.h" + #include "cy_ipc_pipe.h" + #include "cy_ipc_drv.h" + + #if defined(CY_DEVICE_PSOC6ABLE2) + #include "cy_flash.h" + #endif /* defined(CY_DEVICE_PSOC6ABLE2) */ +#endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */ + + +/******************************************************************************* +* SystemCoreClockUpdate() +*******************************************************************************/ + +/** Default HFClk frequency in Hz */ +#define CY_CLK_HFCLK0_FREQ_HZ_DEFAULT (8000000UL) + +/** Default PeriClk frequency in Hz */ +#define CY_CLK_PERICLK_FREQ_HZ_DEFAULT (4000000UL) + +/** Default SlowClk system core frequency in Hz */ +#define CY_CLK_SYSTEM_FREQ_HZ_DEFAULT (8000000UL) + +/** IMO frequency in Hz */ +#define CY_CLK_IMO_FREQ_HZ (8000000UL) + +/** HVILO frequency in Hz */ +#define CY_CLK_HVILO_FREQ_HZ (32000UL) + +/** PILO frequency in Hz */ +#define CY_CLK_PILO_FREQ_HZ (32768UL) + +/** WCO frequency in Hz */ +#define CY_CLK_WCO_FREQ_HZ (32768UL) + +/** ALTLF frequency in Hz */ +#define CY_CLK_ALTLF_FREQ_HZ (32768UL) + + +/** +* Holds the SlowClk (Cortex-M0+) or FastClk (Cortex-M4) system core clock, +* which is the system clock frequency supplied to the SysTick timer and the +* processor core clock. +* This variable implements CMSIS Core global variable. +* Refer to the [CMSIS documentation] +* (http://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html "System and Clock Configuration") +* for more details. +* This variable can be used by debuggers to query the frequency +* of the debug timer or to configure the trace clock speed. +* +* \attention Compilers must be configured to avoid removing this variable in case +* the application program is not using it. Debugging systems require the variable +* to be physically present in memory so that it can be examined to configure the debugger. */ +uint32_t SystemCoreClock = CY_CLK_SYSTEM_FREQ_HZ_DEFAULT; + +/** Holds the HFClk0 clock frequency. Updated by \ref SystemCoreClockUpdate(). */ +uint32_t cy_Hfclk0FreqHz = CY_CLK_HFCLK0_FREQ_HZ_DEFAULT; + +/** Holds the PeriClk clock frequency. Updated by \ref SystemCoreClockUpdate(). */ +uint32_t cy_PeriClkFreqHz = CY_CLK_PERICLK_FREQ_HZ_DEFAULT; + +/** Holds the Alternate high frequency clock in Hz. Updated by \ref SystemCoreClockUpdate(). */ +#if (defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL)) || defined (CY_DOXYGEN) + uint32_t cy_BleEcoClockFreqHz = CY_CLK_ALTHF_FREQ_HZ; +#endif /* (defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL)) || defined (CY_DOXYGEN) */ + +/* SCB->CPACR */ +#define SCB_CPACR_CP10_CP11_ENABLE (0xFUL << 20u) + + +/******************************************************************************* +* SystemInit() +*******************************************************************************/ + +/* CLK_FLL_CONFIG default values */ +#define CY_FB_CLK_FLL_CONFIG_VALUE (0x01000000u) +#define CY_FB_CLK_FLL_CONFIG2_VALUE (0x00020001u) +#define CY_FB_CLK_FLL_CONFIG3_VALUE (0x00002800u) +#define CY_FB_CLK_FLL_CONFIG4_VALUE (0x000000FFu) + + +/******************************************************************************* +* SystemCoreClockUpdate (void) +*******************************************************************************/ + +/* Do not use these definitions directly in your application */ +#define CY_DELAY_MS_OVERFLOW_THRESHOLD (0x8000u) +#define CY_DELAY_1K_THRESHOLD (1000u) +#define CY_DELAY_1K_MINUS_1_THRESHOLD (CY_DELAY_1K_THRESHOLD - 1u) +#define CY_DELAY_1M_THRESHOLD (1000000u) +#define CY_DELAY_1M_MINUS_1_THRESHOLD (CY_DELAY_1M_THRESHOLD - 1u) +uint32_t cy_delayFreqHz = CY_CLK_SYSTEM_FREQ_HZ_DEFAULT; + +uint32_t cy_delayFreqKhz = (CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1K_MINUS_1_THRESHOLD) / + CY_DELAY_1K_THRESHOLD; + +uint8_t cy_delayFreqMhz = (uint8_t)((CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1M_MINUS_1_THRESHOLD) / + CY_DELAY_1M_THRESHOLD); + +uint32_t cy_delay32kMs = CY_DELAY_MS_OVERFLOW_THRESHOLD * + ((CY_CLK_SYSTEM_FREQ_HZ_DEFAULT + CY_DELAY_1K_MINUS_1_THRESHOLD) / CY_DELAY_1K_THRESHOLD); + +#define CY_ROOT_PATH_SRC_IMO (0UL) +#define CY_ROOT_PATH_SRC_EXT (1UL) +#if (SRSS_ECO_PRESENT == 1U) + #define CY_ROOT_PATH_SRC_ECO (2UL) +#endif /* (SRSS_ECO_PRESENT == 1U) */ +#if (SRSS_ALTHF_PRESENT == 1U) + #define CY_ROOT_PATH_SRC_ALTHF (3UL) +#endif /* (SRSS_ALTHF_PRESENT == 1U) */ +#define CY_ROOT_PATH_SRC_DSI_MUX (4UL) +#define CY_ROOT_PATH_SRC_DSI_MUX_HVILO (16UL) +#define CY_ROOT_PATH_SRC_DSI_MUX_WCO (17UL) +#if (SRSS_ALTLF_PRESENT == 1U) + #define CY_ROOT_PATH_SRC_DSI_MUX_ALTLF (18UL) +#endif /* (SRSS_ALTLF_PRESENT == 1U) */ +#if (SRSS_PILO_PRESENT == 1U) + #define CY_ROOT_PATH_SRC_DSI_MUX_PILO (19UL) +#endif /* (SRSS_PILO_PRESENT == 1U) */ + + +/******************************************************************************* +* Function Name: SystemInit +****************************************************************************//** +* \cond +* Initializes the system: +* - Restores FLL registers to the default state for single core devices. +* - Unlocks and disables WDT. +* - Calls Cy_PDL_Init() function to define the driver library. +* - Calls the Cy_SystemInit() function, if compiled from PSoC Creator. +* - Calls \ref SystemCoreClockUpdate(). +* \endcond +*******************************************************************************/ +void SystemInit(void) +{ + Cy_PDL_Init(CY_DEVICE_CFG); + +#ifdef __CM0P_PRESENT + #if (__CM0P_PRESENT == 0) + /* Restore FLL registers to the default state as they are not restored by the ROM code */ + uint32_t copy = SRSS->CLK_FLL_CONFIG; + copy &= ~SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk; + SRSS->CLK_FLL_CONFIG = copy; + + copy = SRSS->CLK_ROOT_SELECT[0u]; + copy &= ~SRSS_CLK_ROOT_SELECT_ROOT_DIV_Msk; /* Set ROOT_DIV = 0*/ + SRSS->CLK_ROOT_SELECT[0u] = copy; + + SRSS->CLK_FLL_CONFIG = CY_FB_CLK_FLL_CONFIG_VALUE; + SRSS->CLK_FLL_CONFIG2 = CY_FB_CLK_FLL_CONFIG2_VALUE; + SRSS->CLK_FLL_CONFIG3 = CY_FB_CLK_FLL_CONFIG3_VALUE; + SRSS->CLK_FLL_CONFIG4 = CY_FB_CLK_FLL_CONFIG4_VALUE; + + /* Unlock and disable WDT */ + Cy_WDT_Unlock(); + Cy_WDT_Disable(); + #endif /* (__CM0P_PRESENT == 0) */ +#endif /* __CM0P_PRESENT */ + + Cy_SystemInit(); + SystemCoreClockUpdate(); + +#if !defined(CY_IPC_DEFAULT_CFG_DISABLE) + +#ifdef __CM0P_PRESENT + #if (__CM0P_PRESENT == 0) + /* Allocate and initialize semaphores for the system operations. */ + static uint32_t ipcSemaArray[CY_IPC_SEMA_COUNT / CY_IPC_SEMA_PER_WORD]; + (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, CY_IPC_SEMA_COUNT, ipcSemaArray); + #else + (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL); + #endif /* (__CM0P_PRESENT) */ +#else + (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL); +#endif /* __CM0P_PRESENT */ + + + /******************************************************************************** + * + * Initializes the system pipes. The system pipes are used by BLE and Flash. + * + * If the default startup file is not used, or SystemInit() is not called in your + * project, call the following three functions prior to executing any flash or + * EmEEPROM write or erase operation: + * -# Cy_IPC_Sema_Init() + * -# Cy_IPC_Pipe_Config() + * -# Cy_IPC_Pipe_Init() + * -# Cy_Flash_Init() + * + *******************************************************************************/ + /* Create an array of endpoint structures */ + static cy_stc_ipc_pipe_ep_t systemIpcPipeEpArray[CY_IPC_MAX_ENDPOINTS]; + + Cy_IPC_Pipe_Config(systemIpcPipeEpArray); + + static cy_ipc_pipe_callback_ptr_t systemIpcPipeSysCbArray[CY_SYS_CYPIPE_CLIENT_CNT]; + + static const cy_stc_ipc_pipe_config_t systemIpcPipeConfigCm4 = + { + /* .ep0ConfigData */ + { + /* .ipcNotifierNumber */ CY_IPC_INTR_CYPIPE_EP0, + /* .ipcNotifierPriority */ CY_SYS_INTR_CYPIPE_PRIOR_EP0, + /* .ipcNotifierMuxNumber */ CY_SYS_INTR_CYPIPE_MUX_EP0, + /* .epAddress */ CY_IPC_EP_CYPIPE_CM0_ADDR, + /* .epConfig */ CY_SYS_CYPIPE_CONFIG_EP0 + }, + /* .ep1ConfigData */ + { + /* .ipcNotifierNumber */ CY_IPC_INTR_CYPIPE_EP1, + /* .ipcNotifierPriority */ CY_SYS_INTR_CYPIPE_PRIOR_EP1, + /* .ipcNotifierMuxNumber */ 0u, + /* .epAddress */ CY_IPC_EP_CYPIPE_CM4_ADDR, + /* .epConfig */ CY_SYS_CYPIPE_CONFIG_EP1 + }, + /* .endpointClientsCount */ CY_SYS_CYPIPE_CLIENT_CNT, + /* .endpointsCallbacksArray */ systemIpcPipeSysCbArray, + /* .userPipeIsrHandler */ &Cy_SysIpcPipeIsrCm4 + }; + + if (cy_device->flashPipeRequired != 0u) + { + Cy_IPC_Pipe_Init(&systemIpcPipeConfigCm4); + } + +#if defined(CY_DEVICE_PSOC6ABLE2) + Cy_Flash_Init(); +#endif /* defined(CY_DEVICE_PSOC6ABLE2) */ + +#endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */ +} + + +/******************************************************************************* +* Function Name: Cy_SystemInit +****************************************************************************//** +* +* The function is called during device startup. Once project compiled as part of +* the PSoC Creator project, the Cy_SystemInit() function is generated by the +* PSoC Creator. +* +* The function generated by PSoC Creator performs all of the necessary device +* configuration based on the design settings. This includes settings from the +* Design Wide Resources (DWR) such as Clocks and Pins as well as any component +* configuration that is necessary. +* +*******************************************************************************/ +__WEAK void Cy_SystemInit(void) +{ + /* Empty weak function. The actual implementation to be in the PSoC Creator + * generated strong function. + */ +} + + +/******************************************************************************* +* Function Name: SystemCoreClockUpdate +****************************************************************************//** +* +* Gets core clock frequency and updates \ref SystemCoreClock, \ref +* cy_Hfclk0FreqHz, and \ref cy_PeriClkFreqHz. +* +* Updates global variables used by the \ref Cy_SysLib_Delay(), \ref +* Cy_SysLib_DelayUs(), and \ref Cy_SysLib_DelayCycles(). +* +*******************************************************************************/ +void SystemCoreClockUpdate (void) +{ + uint32_t srcFreqHz; + uint32_t pathFreqHz; + uint32_t fastClkDiv; + uint32_t periClkDiv; + uint32_t rootPath; + uint32_t srcClk; + + /* Get root path clock for the high-frequency clock # 0 */ + rootPath = _FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_MUX, SRSS->CLK_ROOT_SELECT[0u]); + + /* Get source of the root path clock */ + srcClk = _FLD2VAL(SRSS_CLK_PATH_SELECT_PATH_MUX, SRSS->CLK_PATH_SELECT[rootPath]); + + /* Get frequency of the source */ + switch (srcClk) + { + case CY_ROOT_PATH_SRC_IMO: + srcFreqHz = CY_CLK_IMO_FREQ_HZ; + break; + + case CY_ROOT_PATH_SRC_EXT: + srcFreqHz = CY_CLK_EXT_FREQ_HZ; + break; + + #if (SRSS_ECO_PRESENT == 1U) + case CY_ROOT_PATH_SRC_ECO: + srcFreqHz = CY_CLK_ECO_FREQ_HZ; + break; + #endif /* (SRSS_ECO_PRESENT == 1U) */ + +#if defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) && (SRSS_ALTHF_PRESENT == 1U) + case CY_ROOT_PATH_SRC_ALTHF: + srcFreqHz = cy_BleEcoClockFreqHz; + break; +#endif /* defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) && (SRSS_ALTHF_PRESENT == 1U) */ + + case CY_ROOT_PATH_SRC_DSI_MUX: + { + uint32_t dsi_src; + dsi_src = _FLD2VAL(SRSS_CLK_DSI_SELECT_DSI_MUX, SRSS->CLK_DSI_SELECT[rootPath]); + switch (dsi_src) + { + case CY_ROOT_PATH_SRC_DSI_MUX_HVILO: + srcFreqHz = CY_CLK_HVILO_FREQ_HZ; + break; + + case CY_ROOT_PATH_SRC_DSI_MUX_WCO: + srcFreqHz = CY_CLK_WCO_FREQ_HZ; + break; + + #if (SRSS_ALTLF_PRESENT == 1U) + case CY_ROOT_PATH_SRC_DSI_MUX_ALTLF: + srcFreqHz = CY_CLK_ALTLF_FREQ_HZ; + break; + #endif /* (SRSS_ALTLF_PRESENT == 1U) */ + + #if (SRSS_PILO_PRESENT == 1U) + case CY_ROOT_PATH_SRC_DSI_MUX_PILO: + srcFreqHz = CY_CLK_PILO_FREQ_HZ; + break; + #endif /* (SRSS_PILO_PRESENT == 1U) */ + + default: + srcFreqHz = CY_CLK_HVILO_FREQ_HZ; + break; + } + } + break; + + default: + srcFreqHz = CY_CLK_EXT_FREQ_HZ; + break; + } + + if (rootPath == 0UL) + { + /* FLL */ + bool fllLocked = ( 0UL != _FLD2VAL(SRSS_CLK_FLL_STATUS_LOCKED, SRSS->CLK_FLL_STATUS)); + bool fllOutputOutput = ( 3UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3)); + bool fllOutputAuto = ((0UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3)) || + (1UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3))); + if ((fllOutputAuto && fllLocked) || fllOutputOutput) + { + uint32_t fllMult; + uint32_t refDiv; + uint32_t outputDiv; + + fllMult = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_MULT, SRSS->CLK_FLL_CONFIG); + refDiv = _FLD2VAL(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, SRSS->CLK_FLL_CONFIG2); + outputDiv = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, SRSS->CLK_FLL_CONFIG) + 1UL; + + pathFreqHz = ((srcFreqHz / refDiv) * fllMult) / outputDiv; + } + else + { + pathFreqHz = srcFreqHz; + } + } + else if ((rootPath == 1UL) || (rootPath == 2UL)) + { + /* PLL */ + bool pllLocked = ( 0UL != _FLD2VAL(SRSS_CLK_PLL_STATUS_LOCKED, SRSS->CLK_PLL_STATUS[rootPath - 1UL])); + bool pllOutputOutput = ( 3UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[rootPath - 1UL])); + bool pllOutputAuto = ((0UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[rootPath - 1UL])) || + (1UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[rootPath - 1UL]))); + if ((pllOutputAuto && pllLocked) || pllOutputOutput) + { + uint32_t feedbackDiv; + uint32_t referenceDiv; + uint32_t outputDiv; + + feedbackDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV, SRSS->CLK_PLL_CONFIG[rootPath - 1UL]); + referenceDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, SRSS->CLK_PLL_CONFIG[rootPath - 1UL]); + outputDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV, SRSS->CLK_PLL_CONFIG[rootPath - 1UL]); + + pathFreqHz = ((srcFreqHz * feedbackDiv) / referenceDiv) / outputDiv; + + } + else + { + pathFreqHz = srcFreqHz; + } + } + else + { + /* Direct */ + pathFreqHz = srcFreqHz; + } + + /* Get frequency after hf_clk pre-divider */ + pathFreqHz = pathFreqHz >> _FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_DIV, SRSS->CLK_ROOT_SELECT[0u]); + cy_Hfclk0FreqHz = pathFreqHz; + + /* Fast Clock Divider */ + fastClkDiv = 1u + _FLD2VAL(CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, CPUSS->CM4_CLOCK_CTL); + + /* Peripheral Clock Divider */ + periClkDiv = 1u + _FLD2VAL(CPUSS_CM0_CLOCK_CTL_PERI_INT_DIV, CPUSS->CM0_CLOCK_CTL); + cy_PeriClkFreqHz = pathFreqHz / periClkDiv; + + pathFreqHz = pathFreqHz / fastClkDiv; + SystemCoreClock = pathFreqHz; + + /* Sets clock frequency for Delay API */ + cy_delayFreqHz = SystemCoreClock; + cy_delayFreqMhz = (uint8_t)((cy_delayFreqHz + CY_DELAY_1M_MINUS_1_THRESHOLD) / CY_DELAY_1M_THRESHOLD); + cy_delayFreqKhz = (cy_delayFreqHz + CY_DELAY_1K_MINUS_1_THRESHOLD) / CY_DELAY_1K_THRESHOLD; + cy_delay32kMs = CY_DELAY_MS_OVERFLOW_THRESHOLD * cy_delayFreqKhz; +} + + +/******************************************************************************* +* Function Name: Cy_SystemInitFpuEnable +****************************************************************************//** +* +* Enables the FPU if it is used. The function is called from the startup file. +* +*******************************************************************************/ +void Cy_SystemInitFpuEnable(void) +{ + #if defined (__FPU_USED) && (__FPU_USED == 1U) + uint32_t interruptState; + interruptState = Cy_SysLib_EnterCriticalSection(); + SCB->CPACR |= SCB_CPACR_CP10_CP11_ENABLE; + __DSB(); + __ISB(); + Cy_SysLib_ExitCriticalSection(interruptState); + #endif /* (__FPU_USED) && (__FPU_USED == 1U) */ +} + + +#if !defined(CY_IPC_DEFAULT_CFG_DISABLE) +/******************************************************************************* +* Function Name: Cy_SysIpcPipeIsrCm4 +****************************************************************************//** +* +* This is the interrupt service routine for the system pipe. +* +*******************************************************************************/ +void Cy_SysIpcPipeIsrCm4(void) +{ + Cy_IPC_Pipe_ExecuteCallback(CY_IPC_EP_CYPIPE_CM4_ADDR); +} +#endif + + +/******************************************************************************* +* Function Name: Cy_MemorySymbols +****************************************************************************//** +* +* The intention of the function is to declare boundaries of the memories for the +* MDK compilers. For the rest of the supported compilers, this is done using +* linker configuration files. The following symbols used by the cymcuelftool. +* +*******************************************************************************/ +#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050) +__asm void Cy_MemorySymbols(void) +{ + /* Flash */ + EXPORT __cy_memory_0_start + EXPORT __cy_memory_0_length + EXPORT __cy_memory_0_row_size + + /* Working Flash */ + EXPORT __cy_memory_1_start + EXPORT __cy_memory_1_length + EXPORT __cy_memory_1_row_size + + /* Supervisory Flash */ + EXPORT __cy_memory_2_start + EXPORT __cy_memory_2_length + EXPORT __cy_memory_2_row_size + + /* XIP */ + EXPORT __cy_memory_3_start + EXPORT __cy_memory_3_length + EXPORT __cy_memory_3_row_size + + /* eFuse */ + EXPORT __cy_memory_4_start + EXPORT __cy_memory_4_length + EXPORT __cy_memory_4_row_size + + /* Flash */ +__cy_memory_0_start EQU __cpp(CY_FLASH_BASE) +__cy_memory_0_length EQU __cpp(CY_FLASH_SIZE) +__cy_memory_0_row_size EQU 0x200 + + /* Flash region for EEPROM emulation */ +__cy_memory_1_start EQU __cpp(CY_EM_EEPROM_BASE) +__cy_memory_1_length EQU __cpp(CY_EM_EEPROM_SIZE) +__cy_memory_1_row_size EQU 0x200 + + /* Supervisory Flash */ +__cy_memory_2_start EQU __cpp(CY_SFLASH_BASE) +__cy_memory_2_length EQU __cpp(CY_SFLASH_SIZE) +__cy_memory_2_row_size EQU 0x200 + + /* XIP */ +__cy_memory_3_start EQU __cpp(CY_XIP_BASE) +__cy_memory_3_length EQU __cpp(CY_XIP_SIZE) +__cy_memory_3_row_size EQU 0x200 + + /* eFuse */ +__cy_memory_4_start EQU __cpp(0x90700000) +__cy_memory_4_length EQU __cpp(0x100000) +__cy_memory_4_row_size EQU __cpp(1) +} +#endif /* defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/EULA b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/EULA new file mode 100644 index 0000000000..f10c742b10 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/EULA @@ -0,0 +1,55 @@ +CYPRESS END USER LICENSE AGREEMENT + +PLEASE READ THIS END USER LICENSE AGREEMENT ("Agreement") CAREFULLY BEFORE DOWNLOADING, INSTALLING, COPYING, OR USING THIS SOFTWARE AND ACCOMPANYING DOCUMENTATION. BY DOWNLOADING, INSTALLING, COPYING OR USING THE SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL OF THE TERMS OF THIS AGREEMENT, PROMPTLY RETURN AND DO NOT USE THE SOFTWARE. IF YOU HAVE PURCHASED THIS LICENSE TO THE SOFTWARE, YOUR RIGHT TO RETURN THE SOFTWARE EXPIRES 30 DAYS AFTER YOUR PURCHASE AND APPLIES ONLY TO THE ORIGINAL PURCHASER. + +1. Definitions. + + "Software" means this software and any accompanying documentation, including any upgrades, updates, bug fixes or modified versions provided to you by Cypress. + + "Source Code" means software in human-readable form. + + "Binary Code" means the software in binary code form such as object code or an executable. + + "Development Tools" means software that is intended to be installed on a personal computer and used to create programming code for Firmware, Drivers, or Host Applications. Examples of Development Tools are Cypress's PSoC Creator software, Cypress's WICED SDKs, and Cypress's ModusToolbox software. + + "Firmware" means software that executes on a Cypress hardware product. + + "Driver" means software that enables the use of a Cypress hardware product on a particular host operating system such as GNU/Linux, Windows, MacOS, Android, and iOS. + + "Host Application" means software that executes on a device other than a Cypress hardware product in order to program, control, or communicate with a Cypress hardware product. + + "inf File" means a hardware setup information file (.inf file) created by the Software to allow a Microsoft Windows operating system to install the driver for a Cypress hardware product. + +2. License. Subject to the terms and conditions of this Agreement, Cypress Semiconductor Corporation ("Cypress") and its suppliers grant to you a non-exclusive, non-transferable license under their copyright rights: + + a. to use the Development Tools in object code form solely for the purpose of creating Firmware, Drivers, Host Applications, and inf Files for Cypress hardware products; and + + b. (i) if provided in Source Code form, to copy, modify, and compile the Firmware Source Code to create Firmware for execution on a Cypress hardware product, and (ii) to distribute Firmware in binary code form only, only when installed onto a Cypress hardware product; and + + c. (i) if provided in Source Code form, to copy, modify, and compile the Driver Source Code to create one or more Drivers to enable the use of a Cypress hardware product on a particular host operating system, and (ii) to distribute the Driver, in binary code form only, only when installed on a device that includes the Cypress hardware product that the Driver is intended to enable; and + + d. (i) if provided in Source Code form, to copy, modify, and compile the Host Application Source Code to create one or more Host Applications to program, control, or communicate with a Cypress hardware product, and (ii) to distribute Host Applications, in binary code form only, only when installed on a device that includes a Cypress hardware product that the Host Application is intended to program, control, or communicate with; and + + e. to freely distribute any inf File. + +Any distribution of Software permitted under this Agreement must be made pursuant to your standard end user license agreement used for your proprietary (closed source) software products, such end user license agreement to include, at a minimum, provisions limiting your licensors' liability and prohibiting reverse engineering of the Software, consistent with such provisions in this Agreement. + +3. Free and Open Source Software. Portions of the Software may be licensed under free and/or open source licenses such as the GNU General Public License or other licenses from third parties ("Third Party Software"). Third Party Software is subject to the applicable license agreement and not this Agreement. If you are entitled to receive the source code from Cypress for any Third Party Software included with the Software, either the source code will be included with the Software or you may obtain the source code at no charge from . The applicable license terms will accompany each source code package. To review the license terms applicable to any Third Party Software for which Cypress is not required to provide you with source code, please see the Software's installation directory on your computer. + +4. Proprietary Rights; Ownership. The Software, including all intellectual property rights therein, is and will remain the sole and exclusive property of Cypress or its suppliers. Cypress retains ownership of the Source Code and any compiled version thereof. Subject to Cypress' ownership of the underlying Software (including Source Code), you retain ownership of any modifications you make to the Source Code. You agree not to remove any Cypress copyright or other notices from the Source Code and any modifications thereof. You agree to keep the Source Code confidential. Any reproduction, modification, translation, compilation, or representation of the Source Code except as permitted in Section 2 ("License") is prohibited without the express written permission of Cypress. Except as otherwise expressly provided in this Agreement, you may not: (i) modify, adapt, or create derivative works based upon the Software; (ii) copy the Software; (iii) except and only to the extent explicitly permitted by applicable law despite this limitation, decompile, translate, reverse engineer, disassemble or otherwise reduce the Software to human-readable form; or (iv) use the Software or any sample code other than for the Purpose. You hereby covenant that you will not assert any claim that the Software, or derivative works thereof created by or for Cypress, infringe any intellectual property right owned or controlled by you + +5. No Support. Cypress may, but is not required to, provide technical support for the Software. + +6. Term and Termination. This Agreement is effective until terminated, and either party may terminate this Agreement at any time with or without cause. This Agreement and your license rights under this Agreement will terminate immediately without notice from Cypress if you fail to comply with any provision of this Agreement. Upon termination, you must destroy all copies of Software in your possession or control. The following paragraphs shall survive any termination of this Agreement: "Free and Open Source Software," "Proprietary Rights; Ownership," "Compliance With Law," "Disclaimer," "Limitation of Liability," and "General." + +7. Compliance With Law. Each party agrees to comply with all applicable laws, rules and regulations in connection with its activities under this Agreement. Without limiting the foregoing, the Software may be subject to export control laws and regulations of the United States and other countries. You agree to comply strictly with all such laws and regulations and acknowledge that you have the responsibility to obtain licenses to export, re-export, or import the Software. + +8. Disclaimer. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THE SOFTWARE, INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress reserves the right to make changes to the Software without notice. Cypress does not assume any liability arising out of the application or use of Software or any product or circuit described in the Software. It is the responsibility of the user of the Software to properly design, program, and test the functionality and safety of any application made of the Software and any resulting product. Cypress does not authorize its Software or products for use in any products where a malfunction or failure of the Software or Cypress product may reasonably be expected to result in significant property damage, injury or death ("High Risk Product"). If you include any Software or Cypress product in a High Risk Product, you assume all risk of such use and agree to indemnify Cypress and its suppliers against all liability. No computing device can be absolutely secure. Therefore, despite security measures implemented in Cypress hardware or software products, Cypress does not assume any liability arising out of any security breach, such as unauthorized access to or use of a Cypress product. + +9. Limitation of Liability. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS BE LIABLE FOR ANY LOST REVENUE, PROFIT, OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO EVENT SHALL CYPRESS' OR ITS SUPPLIERS', RESELLERS', OR DISTRIBUTORS' TOTAL LIABILITY TO YOU, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, EXCEED THE GREATER OF US$500 OR THE PRICE PAID BY YOU FOR THE SOFTWARE. THE FOREGOING LIMITATIONS SHALL APPLY EVEN IF THE ABOVE-STATED WARRANTY FAILS OF ITS ESSENTIAL PURPOSE. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, ALL OR PORTIONS OF THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + +10. Restricted Rights. The Software is commercial computer software as that term is described in 48 C.F.R. 252.227-7014(a)(1). If the Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in Software shall be only those set forth in this Agreement. + +11. Personal Information. You agree that information you provide through your registration on Cypress IoT Community Forum or other Cypress websites, including contact information or other personal information, may be collected and used by Cypress consistent with its Data Privacy Policy (www.cypress.com/privacy-policy), as updated or revised from time to time, and may be provided to its third party sales representatives, distributors and other entities conducting sales activities for Cypress for sales-related and other business purposes. + +12. General. This Agreement will bind and inure to the benefit of each party's successors and assigns, provided that you may not assign or transfer this Agreement, in whole or in part, without Cypress' written consent. This Agreement shall be governed by and construed in accordance with the laws of the State of California, United States of America, as if performed wholly within the state and without giving effect to the principles of conflict of law. The parties consent to personal and exclusive jurisdiction of and venue in, the state and federal courts within Santa Clara County, California; provided however, that nothing in this Agreement will limit Cypress' right to bring legal action in any venue in order to protect or enforce its intellectual property rights. No failure of either party to exercise or enforce any of its rights under this Agreement will act as a waiver of such rights. If any portion of this Agreement is found to be void or unenforceable, the remaining provisions of this Agreement shall remain in full force and effect. This Agreement is the complete and exclusive agreement between the parties with respect to the subject matter hereof, superseding and replacing any and all prior agreements, communications, and understandings (both written and oral) regarding such subject matter. Any notice to Cypress will be deemed effective when actually received and must be sent to Cypress Semiconductor Corporation, ATTN: Chief Legal Officer, 198 Champion Court, San Jose, CA 95134 USA. diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/LICENSE b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/LICENSE new file mode 100644 index 0000000000..59cd3f8a32 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/LICENSE @@ -0,0 +1,165 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/README.md b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/README.md new file mode 100644 index 0000000000..17eac80954 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/README.md @@ -0,0 +1,22 @@ +# PSoC 6 GNU make Build System + +## Overview + +This repo provides the build recipe make files and scripts for building and programming PSoC 6 applications. Builds can be run either through a command-line interface (CLI) or through the ModusToolbox Integrated Devlopment Environment (IDE). + +## Prerequisite + +Builds require that the ModusToolbox tools be installed on your machine. This comes with the ModusToolbox IDE install. On Windows machines, it is recommended that CLI builds be executed using the Cygwin.bat located in ModusToolBox/tools_x.y/modus-shell install directory. This guarantees a consistent shell environment for your builds. + +## Options + +To list the build options, run the "help" target by typing "make help" in CLI. For a verbose documentation on a specific subject type "make help CY_HELP={variable/target}", where "variable" or "target" is one of the listed make variables or targets. + + +## More information +* [Cypress Semiconductor](http://www.cypress.com) +* [Cypress Semiconductor GitHub](https://github.com/cypresssemiconductorco) +* [ModusToolbox](https://www.cypress.com/products/modustoolbox-software-environment) + +--- +© Cypress Semiconductor Corporation, 2019. diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/RELEASE.md b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/RELEASE.md new file mode 100644 index 0000000000..7aefc341c5 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/RELEASE.md @@ -0,0 +1,39 @@ +### PSoC 6 GNU make Build System 1.0 +This repo provides the build recipe make files and scripts for building and programming PSoC 6 applications. Builds can be run either through a command-line interface (CLI) or through the ModusToolbox Integrated Devlopment Environment (IDE). + +### What's Included? +The this release of the PSoC 6 GNU make Build System includes complete support for building, programming, and debugging PSoC 6 application projects. It is expected that a code example contains a top level make file for itself and references a Board Support Package (BSP) that defines specifics items, like the PSoC 6 part, for the target board. This includes the following: +* Supported operations: + * Build + * Program + * Debug +* Supported toolchains: + * GCC + * IAR + * ARMv6 + +This also includes the getlibs.bash script that can be used directly, or via the make target to download additional git repo based libraries for the application. + +### Product/Asset Specific Instructions +Builds require that the ModusToolbox tools be installed on your machine. This comes with the ModusToolbox IDE install. On Windows machines, it is recommended that CLI builds be executed using the Cygwin.bat located in ModusToolBox/tools_x.y/modus-shell install directory. This guarantees a consistent shell environment for your builds. + +To list the build options, run the "help" target by typing "make help" in CLI. For a verbose documentation on a specific subject type "make help CY_HELP={variable/target}", where "variable" or "target" is one of the listed make variables or targets. + +### Supported Software and Tools +This version of the Cypress PSoC 6 Hardware Abstraction Layer was validated for compatibility with the following Software and Tools: + +| Software and Tools | Version | +| :--- | :----: | +| ModusToolbox Software Environment | 2.0 | +| GCC Compiler | 7.4 | +| IAR Compiler | 8.32 | +| ARM Compiler | 6.11 | + +### More information +Use the following links for more information, as needed: +* [Cypress Semiconductor](http://www.cypress.com) +* [Cypress Semiconductor GitHub](https://github.com/cypresssemiconductorco) +* [ModusToolbox](https://www.cypress.com/products/modustoolbox-software-environment) + +--- +© Cypress Semiconductor Corporation, 2019. \ No newline at end of file diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/build.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/build.mk new file mode 100644 index 0000000000..72a867e554 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/build.mk @@ -0,0 +1,694 @@ +################################################################################ +# \file build.mk +# \version 1.0 +# +# \brief +# Performs the compilation and linking steps. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +################################################################################ +# Target output +################################################################################ + +ifneq ($(LIBNAME),) +CY_BUILD_TARGET=$(CY_CONFIG_DIR)/$(LIBNAME).$(CY_TOOLCHAIN_SUFFIX_ARCHIVE) +else +CY_BUILD_TARGET=$(CY_CONFIG_DIR)/$(APPNAME).$(CY_TOOLCHAIN_SUFFIX_TARGET) +endif +CY_BUILD_MAPFILE=$(CY_CONFIG_DIR)/$(APPNAME).$(CY_TOOLCHAIN_SUFFIX_MAP) + + +################################################################################ +# VPATH resolution +################################################################################ + +# +# Search for relative path patterns in source list +# $(1) : Pattern +# $(2) : Sources +# +CY_MACRO_VPATH_FIND=$(foreach level,$(1),$(if $(filter $(level)%,$(2)),$(level))) + +# +# Search for relative paths in user sources and include them in the VPATH +# +CY_BUILD_VPATH_PATTERN=./ ./../ ./../../ ./../../../ ./../../../../ ./../../../../../ ./../../../../../../ ./../../../../../../../ \ + ../ ../../ ../../../ ../../../../ ../../../../../ ../../../../../../ ../../../../../../../ +VPATH+=$(call CY_MACRO_VPATH_FIND,$(CY_BUILD_VPATH_PATTERN),$(SOURCES)) + + +############################################################################## +# +# Macro to construct recursive make for dependent lib apps +# +# Arguments: +# 1: The name of the target +# 2: The lib app directory +# +define CY_MACRO_SHAREDLIB_DEPENDENCIES + +$(1)_SED_PATTERN=$(subst /,\/,$(subst .,\.,$(2))) +ifeq ($(CY_BUILD_LOC),$(CY_APP_LOCATION)/build) +$(1)_SHAREDLIB_BUILD_LOCATION?=$(2)/build/$(TARGET)/$(CONFIG) +else +$(1)_SHAREDLIB_BUILD_LOCATION?=$(CY_INTERNAL_BUILD_LOCATION)/$(1)/$(TARGET)/$(CONFIG) +endif + +# Satisfy dependencies +$$($(1)_SHAREDLIB_BUILD_LOCATION)/inclist.rsp: | shared_libs +$$($(1)_SHAREDLIB_BUILD_LOCATION)/liblist.rsp: | shared_libs +$$($(1)_SHAREDLIB_BUILD_LOCATION)/artifact.rsp: | shared_libs +$(1)_shared_lib: | $$($(1)_SHAREDLIB_BUILD_LOCATION)/inclist.rsp $$($(1)_SHAREDLIB_BUILD_LOCATION)/liblist.rsp $$($(1)_SHAREDLIB_BUILD_LOCATION)/artifact.rsp + +$(1)_shared_lib: + @inclist_read=$$$$(cat $$($(1)_SHAREDLIB_BUILD_LOCATION)/inclist.rsp | sed -e "s/I\.\//I$$($(1)_SED_PATTERN)\//g" | tr " " "\n"); \ + if [ -f "$$($(1)_SHAREDLIB_BUILD_LOCATION)/inclist_export.rsp" ]; then \ + inclist_export_read=$$$$(cat $$($(1)_SHAREDLIB_BUILD_LOCATION)/inclist_export.rsp | tr " " "\n"); \ + else \ + echo $$$$inclist_read > $$($(1)_SHAREDLIB_BUILD_LOCATION)/inclist_export.rsp ;\ + fi;\ + if [[ "$$$$inclist_read" != "$$$$inclist_export_read" ]]; then \ + echo $$$$inclist_read > $$($(1)_SHAREDLIB_BUILD_LOCATION)/inclist_export.rsp ;\ + fi; \ + liblist_read=$$$$(cat $$($(1)_SHAREDLIB_BUILD_LOCATION)/liblist.rsp | sed -e "s/\.\//$$($(1)_SED_PATTERN)\//g" | tr " " "\n"); \ + if [ -f "$$($(1)_SHAREDLIB_BUILD_LOCATION)/liblist_export.rsp" ]; then \ + liblist_export_read=$$$$(cat $$($(1)_SHAREDLIB_BUILD_LOCATION)/liblist_export.rsp | tr " " "\n"); \ + else \ + echo $$$$liblist_read > $$($(1)_SHAREDLIB_BUILD_LOCATION)/liblist_export.rsp ;\ + fi;\ + if [[ "$$$$liblist_read" != "$$$$liblist_export_read" ]]; then \ + echo $$$$liblist_read > $$($(1)_SHAREDLIB_BUILD_LOCATION)/liblist_export.rsp ;\ + fi; \ + artifact_read=$$$$(sed '1s;^;$$($(1)_SHAREDLIB_BUILD_LOCATION)/;' $$($(1)_SHAREDLIB_BUILD_LOCATION)/artifact.rsp); \ + if [ -f "$$($(1)_SHAREDLIB_BUILD_LOCATION)/artifact_export.rsp" ]; then \ + artifact_export_read=$$$$(cat $$($(1)_SHAREDLIB_BUILD_LOCATION)/artifact_export.rsp); \ + else \ + echo $$$$artifact_read > $$($(1)_SHAREDLIB_BUILD_LOCATION)/artifact_export.rsp;\ + fi;\ + if [[ "$$$$artifact_read" -nt "$(CY_BUILD_TARGET)" ]] || [[ "$$$$artifact_read" != "$$$$artifact_export_read" ]]; then\ + echo $$$$artifact_read > $$($(1)_SHAREDLIB_BUILD_LOCATION)/artifact_export.rsp;\ + fi; + +# Satisfy dependencies +$$($(1)_SHAREDLIB_BUILD_LOCATION)/inclist_export.rsp: | $(1)_shared_lib +$$($(1)_SHAREDLIB_BUILD_LOCATION)/liblist_export.rsp: | $(1)_shared_lib +$$($(1)_SHAREDLIB_BUILD_LOCATION)/artifact_export.rsp: | $(1)_shared_lib + +endef + + +################################################################################ +# Shared libraries +################################################################################ + +ifneq ($(SEARCH_LIBS_AND_INCLUDES),) + +# Construct targets for all dependent lib apps +$(foreach lib,$(SEARCH_LIBS_AND_INCLUDES),$(eval $(call CY_MACRO_SHAREDLIB_DEPENDENCIES,$(notdir $(lib)),$(lib)))) + +CY_SHAREDLIB_LIST=$(foreach lib,$(SEARCH_LIBS_AND_INCLUDES),$(notdir $(lib)_shared_lib)) +CY_SHAREDLIB_ARTIFACT_LIST=$(foreach lib,$(SEARCH_LIBS_AND_INCLUDES),$($(notdir $(lib))_SHAREDLIB_BUILD_LOCATION)/artifact.rsp) + +CY_SHAREDLIB_INCLUDES_EXPORT_LIST=$(foreach lib,$(SEARCH_LIBS_AND_INCLUDES),$($(notdir $(lib))_SHAREDLIB_BUILD_LOCATION)/inclist_export.rsp) +CY_SHAREDLIB_LIBS_EXPORT_LIST=$(foreach lib,$(SEARCH_LIBS_AND_INCLUDES),$($(notdir $(lib))_SHAREDLIB_BUILD_LOCATION)/liblist_export.rsp) +CY_SHAREDLIB_ARTIFACT_EXPORT_LIST=$(foreach lib,$(SEARCH_LIBS_AND_INCLUDES),$($(notdir $(lib))_SHAREDLIB_BUILD_LOCATION)/artifact_export.rsp) + +CY_BUILD_SHAREDLIB_INCLIST=$(foreach inc,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST),$(addprefix $(CY_TOOLCHAIN_INCRSPFILE),$(inc))) +CY_BUILD_SHAREDLIB_LIBLIST=$(foreach lib,$(CY_SHAREDLIB_LIBS_EXPORT_LIST),$(addprefix $(CY_TOOLCHAIN_OBJRSPFILE),$(lib)))\ + $(foreach artifact,$(CY_SHAREDLIB_ARTIFACT_EXPORT_LIST),$(addprefix $(CY_TOOLCHAIN_OBJRSPFILE),$(artifact))) + +# Sentinel file to always trigger link step +CY_SHAREDLIB_TIMESTAMP=$(CY_CONFIG_DIR)/shared_libs.timestamp +$(shell touch $(CY_SHAREDLIB_TIMESTAMP)) + +endif + + +################################################################################ +# Build arguments +################################################################################ + +# +# The list of C and S source files that come from the application and generated source +# +CY_BUILD_SRC_S_FILES=$(patsubst $(CY_INTERNAL_APP_PATH)/%,/%,$(patsubst $(CY_INTERNAL_EXTAPP_PATH)/%,/%,\ + $(filter %.$(CY_TOOLCHAIN_SUFFIX_S),$(CY_RECIPE_SOURCE)))) +CY_BUILD_SRC_s_FILES=$(patsubst $(CY_INTERNAL_APP_PATH)/%,/%,$(patsubst $(CY_INTERNAL_EXTAPP_PATH)/%,/%,\ + $(filter %.$(CY_TOOLCHAIN_SUFFIX_s),$(CY_RECIPE_SOURCE)))) +CY_BUILD_SRC_C_FILES=$(patsubst $(CY_INTERNAL_APP_PATH)/%,/%,$(patsubst $(CY_INTERNAL_EXTAPP_PATH)/%,/%,\ + $(filter %.$(CY_TOOLCHAIN_SUFFIX_C),$(CY_RECIPE_SOURCE)))) +CY_BUILD_SRC_CPP_FILES=$(patsubst $(CY_INTERNAL_APP_PATH)/%,/%,$(patsubst $(CY_INTERNAL_EXTAPP_PATH)/%,/%,\ + $(filter %.$(CY_TOOLCHAIN_SUFFIX_CPP),$(CY_RECIPE_SOURCE)))) +CY_BUILD_GENSRC_S_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_S),$(CY_RECIPE_GENERATED)) +CY_BUILD_GENSRC_s_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_s),$(CY_RECIPE_GENERATED)) +CY_BUILD_GENSRC_C_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_C),$(CY_RECIPE_GENERATED)) +CY_BUILD_GENSRC_CPP_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_CPP),$(CY_RECIPE_GENERATED)) +CY_BUILD_EXTSRC_S_FILES=$(patsubst $(CY_INTERNAL_APP_PATH)/%,/%,$(subst ../,,$(filter %.$(CY_TOOLCHAIN_SUFFIX_S),$(SOURCES)))) +CY_BUILD_EXTSRC_s_FILES=$(patsubst $(CY_INTERNAL_APP_PATH)/%,/%,$(subst ../,,$(filter %.$(CY_TOOLCHAIN_SUFFIX_s),$(SOURCES)))) +CY_BUILD_EXTSRC_C_FILES=$(patsubst $(CY_INTERNAL_APP_PATH)/%,/%,$(subst ../,,$(filter %.$(CY_TOOLCHAIN_SUFFIX_C),$(SOURCES)))) +CY_BUILD_EXTSRC_CPP_FILES=$(patsubst $(CY_INTERNAL_APP_PATH)/%,/%,$(subst ../,,$(filter %.$(CY_TOOLCHAIN_SUFFIX_CPP),$(SOURCES)))) + +# +# The list of object files +# +CY_BUILD_SRC_S_OBJ_FILES=$(addprefix $(CY_CONFIG_DIR)/,$(CY_BUILD_SRC_S_FILES:%.$(CY_TOOLCHAIN_SUFFIX_S)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_SRC_s_OBJ_FILES=$(addprefix $(CY_CONFIG_DIR)/,$(CY_BUILD_SRC_s_FILES:%.$(CY_TOOLCHAIN_SUFFIX_s)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_SRC_C_OBJ_FILES=$(addprefix $(CY_CONFIG_DIR)/,$(CY_BUILD_SRC_C_FILES:%.$(CY_TOOLCHAIN_SUFFIX_C)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_SRC_CPP_OBJ_FILES=$(addprefix $(CY_CONFIG_DIR)/,$(CY_BUILD_SRC_CPP_FILES:%.$(CY_TOOLCHAIN_SUFFIX_CPP)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_GENSRC_S_OBJ_FILES=$(patsubst $(CY_BUILDTARGET_DIR)/%,$(CY_CONFIG_DIR)/%,$(CY_BUILD_GENSRC_S_FILES:%.$(CY_TOOLCHAIN_SUFFIX_S)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_GENSRC_s_OBJ_FILES=$(patsubst $(CY_BUILDTARGET_DIR)/%,$(CY_CONFIG_DIR)/%,$(CY_BUILD_GENSRC_s_FILES:%.$(CY_TOOLCHAIN_SUFFIX_s)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_GENSRC_C_OBJ_FILES=$(patsubst $(CY_BUILDTARGET_DIR)/%,$(CY_CONFIG_DIR)/%,$(CY_BUILD_GENSRC_C_FILES:%.$(CY_TOOLCHAIN_SUFFIX_C)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_GENSRC_CPP_OBJ_FILES=$(patsubst $(CY_BUILDTARGET_DIR)/%,$(CY_CONFIG_DIR)/%,$(CY_BUILD_GENSRC_CPP_FILES:%.$(CY_TOOLCHAIN_SUFFIX_CPP)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_EXTSRC_S_OBJ_FILES=$(addprefix $(CY_CONFIG_DIR)/user/,$(CY_BUILD_EXTSRC_S_FILES:%.$(CY_TOOLCHAIN_SUFFIX_S)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_EXTSRC_s_OBJ_FILES=$(addprefix $(CY_CONFIG_DIR)/user/,$(CY_BUILD_EXTSRC_s_FILES:%.$(CY_TOOLCHAIN_SUFFIX_s)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_EXTSRC_C_OBJ_FILES=$(addprefix $(CY_CONFIG_DIR)/user/,$(CY_BUILD_EXTSRC_C_FILES:%.$(CY_TOOLCHAIN_SUFFIX_C)=%.$(CY_TOOLCHAIN_SUFFIX_O))) +CY_BUILD_EXTSRC_CPP_OBJ_FILES=$(addprefix $(CY_CONFIG_DIR)/user/,$(CY_BUILD_EXTSRC_CPP_FILES:%.$(CY_TOOLCHAIN_SUFFIX_CPP)=%.$(CY_TOOLCHAIN_SUFFIX_O))) + +CY_BUILD_ALL_OBJ_FILES=\ + $(call CY_MACRO_REMOVE_DOUBLESLASH,\ + $(CY_BUILD_SRC_S_OBJ_FILES)\ + $(CY_BUILD_SRC_s_OBJ_FILES)\ + $(CY_BUILD_SRC_C_OBJ_FILES)\ + $(CY_BUILD_SRC_CPP_OBJ_FILES)\ + $(CY_BUILD_GENSRC_S_OBJ_FILES)\ + $(CY_BUILD_GENSRC_s_OBJ_FILES)\ + $(CY_BUILD_GENSRC_C_OBJ_FILES)\ + $(CY_BUILD_GENSRC_CPP_OBJ_FILES)\ + $(CY_BUILD_EXTSRC_S_OBJ_FILES)\ + $(CY_BUILD_EXTSRC_s_OBJ_FILES)\ + $(CY_BUILD_EXTSRC_C_OBJ_FILES)\ + $(CY_BUILD_EXTSRC_CPP_OBJ_FILES)) + +# +# Dependency files +# +CY_DEPENDENCY_FILES=$(CY_BUILD_ALL_OBJ_FILES:%.$(CY_TOOLCHAIN_SUFFIX_O)=%.$(CY_TOOLCHAIN_SUFFIX_D)) + +# +# The list of static libraries +# +CY_BUILD_ALL_LIB_FILES=$(CY_RECIPE_LIBS) + +# +# Output directories +# +CY_BUILD_DIRS=$(sort $(call CY_MACRO_DIR,$(CY_BUILD_ALL_OBJ_FILES)) $(call CY_MACRO_DIR,$(CY_BUILD_TARGET))) + +# +# Check Windows path length limit for build directories +# +ifeq ($(OS),Windows_NT) +CY_BUILD_CHECK_STRLEN:=$(shell \ + for directory in $(CY_BUILD_DIRS); do\ + if [ "$${\#directory}" -ge 260 ]; then\ + echo "$$directory";\ + fi;\ + done) + +ifneq ($(strip $(CY_BUILD_CHECK_STRLEN)),) +$(error Detected path(s) that exceed the Windows path length: $(CY_BUILD_CHECK_STRLEN)) +endif +endif + +# +# Prints full/shortened source name +# +ifneq (,$(filter $(VERBOSE),true 1)) +CY_COMPILE_PRINT=$< +else +CY_COMPILE_PRINT=$(notdir $<) +endif + +# +# Gather the includes in inclist_export.rsp files +# $(1) : List of inclist_export.rsp files +# +CY_MACRO_ECLIPSE_PRINT=$(shell \ + for incFile in $(1); do\ + incDirs="$$incDirs $$(cat $$incFile)";\ + done;\ + echo $$incDirs) + +# +# Construct the full list of flags +# +CY_BUILD_ALL_ASFLAGS_UC=\ + $(CY_RECIPE_ASFLAGS)\ + $(CY_RECIPE_DEFINES) + +CY_BUILD_ALL_ASFLAGS_LC=\ + $(CY_RECIPE_ASFLAGS) + +CY_BUILD_ALL_CFLAGS=\ + $(CY_RECIPE_CFLAGS)\ + $(CY_RECIPE_DEFINES) + +CY_BUILD_ALL_CXXFLAGS=\ + $(CY_RECIPE_CXXFLAGS)\ + $(CY_RECIPE_DEFINES) + +# +# Compiler arguments +# +CY_BUILD_COMPILE_AS_UC=$(AS) $(CY_BUILD_ALL_ASFLAGS_UC) $(CY_TOOLCHAIN_INCRSPFILE_ASM)$(CY_CONFIG_DIR)/inclist.rsp \ + $(CY_BUILD_SHAREDLIB_INCLIST) $(CY_TOOLCHAIN_OUTPUT_OPTION) +CY_BUILD_COMPILE_AS_LC=$(AS) $(CY_BUILD_ALL_ASFLAGS_LC) $(CY_TOOLCHAIN_INCRSPFILE_ASM)$(CY_CONFIG_DIR)/inclist.rsp \ + $(CY_BUILD_SHAREDLIB_INCLIST) $(CY_TOOLCHAIN_OUTPUT_OPTION) +CY_BUILD_COMPILE_C=$(CC) $(CY_BUILD_ALL_CFLAGS) $(CY_TOOLCHAIN_INCRSPFILE)$(CY_CONFIG_DIR)/inclist.rsp \ + $(CY_BUILD_SHAREDLIB_INCLIST) $(CY_TOOLCHAIN_DEPENDENCIES) $(CY_TOOLCHAIN_OUTPUT_OPTION) +CY_BUILD_COMPILE_CPP=$(CXX) $(CY_BUILD_ALL_CXXFLAGS) $(CY_TOOLCHAIN_INCRSPFILE)$(CY_CONFIG_DIR)/inclist.rsp \ + $(CY_BUILD_SHAREDLIB_INCLIST) $(CY_TOOLCHAIN_DEPENDENCIES) $(CY_TOOLCHAIN_OUTPUT_OPTION) + +# +# Linker arguments +# +CY_BUILD_LINK=$(LD) $(CY_RECIPE_LDFLAGS) $(CY_TOOLCHAIN_OUTPUT_OPTION) $@ $(CY_TOOLCHAIN_MAPFILE)$(CY_BUILD_MAPFILE) \ + $(CY_TOOLCHAIN_OBJRSPFILE)$(CY_CONFIG_DIR)/objlist.rsp \ + $(CY_TOOLCHAIN_STARTGROUP) $(CY_RECIPE_EXTRA_LIBS) $(CY_BUILD_ALL_LIB_FILES) $(CY_BUILD_SHAREDLIB_LIBLIST) $(CY_TOOLCHAIN_ENDGROUP) + +# +# Archiver arguments +# +CY_BUILD_ARCHIVE=$(AR) $(CY_RECIPE_ARFLAGS) $(CY_TOOLCHAIN_OUTPUT_OPTION) $@ $(CY_TOOLCHAIN_OBJRSPFILE)$(CY_CONFIG_DIR)/objlist.rsp + + +################################################################################ +# Dependency construction +################################################################################ + +# +# Dependency variables for compilation +# +CY_BUILD_COMPILER_DEPS=\ + $(CY_BUILD_COMPILE_AS_UC)\ + $(CY_BUILD_COMPILE_AS_LC)\ + $(CY_BUILD_COMPILE_C)\ + $(CY_BUILD_COMPILE_CPP)\ + $(CY_RECIPE_INCLUDES) + +# +# Dependency variables for link/archive +# +CY_BUILD_LINKER_DEPS=\ + $(CY_BUILD_LINK)\ + $(CY_BUILD_ARCHIVE)\ + $(CY_SHAREDLIB_ARTIFACT_EXPORT_LIST) + +# +# Read previous build's configuration if one exists +# +CY_BUILD_COMPILER_PREV=$(shell if [ -f "$(CY_CONFIG_DIR)/.cycompiler" ]; then cat $(CY_CONFIG_DIR)/.cycompiler; fi) +CY_BUILD_LINKER_PREV=$(shell if [ -f "$(CY_CONFIG_DIR)/.cylinker" ]; then cat $(CY_CONFIG_DIR)/.cylinker; fi) + +# +# Take care of the quotes for the echo command +# +CY_BUILD_COMPILER_DEPS_FORMATTED=$(subst ',,$(subst ",,$(CY_BUILD_COMPILER_DEPS))) +CY_BUILD_LINKER_DEPS_FORMATTED=$(subst ',,$(subst ",,$(CY_BUILD_LINKER_DEPS))) + +# +# Create compilation dependency file +# +ifneq ($(strip $(CY_BUILD_COMPILER_DEPS_FORMATTED)),$(strip $(CY_BUILD_COMPILER_PREV))) +ifeq ($(CY_BUILD_COMPILER_PREV),) +$(shell mkdir -p $(CY_CONFIG_DIR)) +endif +$(shell echo "$(CY_BUILD_COMPILER_DEPS_FORMATTED)" > $(CY_CONFIG_DIR)/.cycompiler) +endif + +# +# Create link dependency file +# +ifneq ($(strip $(CY_BUILD_LINKER_DEPS_FORMATTED)),$(strip $(CY_BUILD_LINKER_PREV))) +ifneq ($(CY_BUILD_LINKER_PREV),) +$(shell mkdir -p $(CY_CONFIG_DIR)) +endif +$(shell echo "$(CY_BUILD_LINKER_DEPS_FORMATTED)" > $(CY_CONFIG_DIR)/.cylinker) +endif + + +################################################################################ +# Application source Compilation +################################################################################ + +# Compile .S source +$(CY_CONFIG_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_INTERNAL_APP_PATH)/%.$(CY_TOOLCHAIN_SUFFIX_S) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling app file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_AS_UC) $@ $< + +# Compile .s source +$(CY_CONFIG_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_INTERNAL_APP_PATH)/%.$(CY_TOOLCHAIN_SUFFIX_s) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling app file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_AS_LC) $@ $< + +# Compile .c source +$(CY_CONFIG_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_INTERNAL_APP_PATH)/%.$(CY_TOOLCHAIN_SUFFIX_C) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling app file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_C) $@ $< + +# Compile .cpp source +$(CY_CONFIG_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_INTERNAL_APP_PATH)/%.$(CY_TOOLCHAIN_SUFFIX_CPP) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling app file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_CPP) $@ $< + + +################################################################################ +# ExtApp source Compilation +################################################################################ + +# Compile .S source +$(CY_CONFIG_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_INTERNAL_EXTAPP_PATH)/%.$(CY_TOOLCHAIN_SUFFIX_S) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling extapp file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_AS_UC) $@ $< + +# Compile .s source +$(CY_CONFIG_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_INTERNAL_EXTAPP_PATH)/%.$(CY_TOOLCHAIN_SUFFIX_s) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling extapp file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_AS_LC) $@ $< + +# Compile .c source +$(CY_CONFIG_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_INTERNAL_EXTAPP_PATH)/%.$(CY_TOOLCHAIN_SUFFIX_C) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling extapp file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_C) $@ $< + +# Compile .cpp source +$(CY_CONFIG_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_INTERNAL_EXTAPP_PATH)/%.$(CY_TOOLCHAIN_SUFFIX_CPP) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling extapp file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_CPP) $@ $< + + +################################################################################ +# Generated Source Compilation +################################################################################ + +# Compile .S source +$(CY_CONFIG_DIR)/generated/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_GENERATED_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_S) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling generated file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_AS_UC) $@ $< + +# Compile .s source +$(CY_CONFIG_DIR)/generated/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_GENERATED_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_s) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling generated file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_AS_LC) $@ $< + +# Compile .c source +$(CY_CONFIG_DIR)/generated/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_GENERATED_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_C) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling generated file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_C) $@ $< + +# Compile .cpp source +$(CY_CONFIG_DIR)/generated/%.$(CY_TOOLCHAIN_SUFFIX_O) : $(CY_GENERATED_DIR)/%.$(CY_TOOLCHAIN_SUFFIX_CPP) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling generated file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_CPP) $@ $< + + +################################################################################ +# User source Compilation +################################################################################ + +# Compile .S source +$(CY_CONFIG_DIR)/user/%.$(CY_TOOLCHAIN_SUFFIX_O) : %.$(CY_TOOLCHAIN_SUFFIX_S) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling user file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_AS_UC) $@ $< + +# Compile .s source +$(CY_CONFIG_DIR)/user/%.$(CY_TOOLCHAIN_SUFFIX_O) : %.$(CY_TOOLCHAIN_SUFFIX_s) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling user file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_AS_LC) $@ $< + +# Compile .c source +$(CY_CONFIG_DIR)/user/%.$(CY_TOOLCHAIN_SUFFIX_O) : %.$(CY_TOOLCHAIN_SUFFIX_C) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling user file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_C) $@ $< + +# Compile .cpp source +$(CY_CONFIG_DIR)/user/%.$(CY_TOOLCHAIN_SUFFIX_O) : %.$(CY_TOOLCHAIN_SUFFIX_CPP) +ifneq ($(CY_MAKE_IDE),eclipse) + $(info $(CY_INDENT)Compiling user file $(CY_COMPILE_PRINT)) +else + $(info Compiling $< $(CY_RECIPE_DEFINES) $(sort $(CY_RECIPE_INCLUDES) $(call CY_MACRO_ECLIPSE_PRINT,$(CY_SHAREDLIB_INCLUDES_EXPORT_LIST)))) +endif + $(CY_NOISE)$(CY_BUILD_COMPILE_CPP) $@ $< + + +################################################################################ +# Prebuild, Postbuild and Link +################################################################################ + +# +# Top-level application dependency +# +app: CY_BUILD_sentinel + +# +# Print information before we start the build +# +CY_BUILD_preprint: | $(CY_SHAREDLIB_INCLUDES_EXPORT_LIST) $(CY_SHAREDLIB_LIBS_EXPORT_LIST) $(CY_SHAREDLIB_ARTIFACT_EXPORT_LIST) + $(info ) + $(info ==============================================================================) + $(info = Building application =) + $(info ==============================================================================) + +# +# Create the directories needed to do the build +# +CY_BUILD_mkdirs: CY_BUILD_preprint + $(CY_NOISE)mkdir -p $(CY_BUILD_DIRS) $(CY_CMD_TERM) +ifeq ($(CY_RECIPE_GENERATED_FLAG),TRUE) + $(CY_NOISE)mkdir -p $(CY_GENERATED_DIR) $(CY_CMD_TERM) +endif + +# +# Run BSP pre-build step +# +CY_BUILD_bsp_prebuild: CY_BUILD_mkdirs + $(CY_BSP_PREBUILD) + +# +# Run application pre-build step +# +CY_BUILD_app_prebuild: CY_BUILD_bsp_prebuild + $(PREBUILD) + +# +# Run generate source step +# +CY_BUILD_gensrc: CY_BUILD_app_prebuild +ifneq ($(CY_SEARCH_RESOURCE_FILES),) + @echo $(CY_RECIPE_RESOURCE_FILES) > $(CY_GENERATED_DIR)/resources.cyrsc +endif +ifeq ($(CY_RECIPE_GENERATED_FLAG),TRUE) + $(CY_NOISE)$(CY_RECIPE_GENSRC) $(CY_CMD_TERM) + $(info Generated $(words $(CY_RECIPE_GENERATED)) source file(s)) +endif + +# +# Add dependancy to support parallel builds +# +$(CY_BUILD_GENSRC_C_FILES): | CY_BUILD_gensrc + +# +# Run pre-build step +# +CY_BUILD_prebuild: CY_BUILD_gensrc + $(CY_NOISE)$(CY_RECIPE_PREBUILD) $(CY_CMD_TERM) + +# +# Print before compilation +# +CY_BUILD_precompile: CY_BUILD_prebuild + $(info Building $(words $(CY_BUILD_ALL_OBJ_FILES)) file(s)) + @echo $(CY_RECIPE_INCLUDES) | tr " " "\n" > $(CY_CONFIG_DIR)/inclist.rsp; \ + echo $(CY_BUILD_ALL_OBJ_FILES) | tr " " "\n" > $(CY_CONFIG_DIR)/objlist.rsp; \ + echo $(CY_BUILD_ALL_LIB_FILES) | tr " " "\n" > $(CY_CONFIG_DIR)/liblist.rsp; + +# +# Dependencies for compilation +# +$(CY_BUILD_ALL_OBJ_FILES): | CY_BUILD_precompile +$(CY_BUILD_ALL_OBJ_FILES): $(CY_CONFIG_DIR)/.cycompiler $(CY_SHAREDLIB_INCLUDES_EXPORT_LIST) + +# +# Dependencies for link +# +$(CY_BUILD_TARGET): | CY_BUILD_precompile +$(CY_BUILD_TARGET): $(CY_CONFIG_DIR)/.cylinker $(CY_SHAREDLIB_LIBS_EXPORT_LIST) $(CY_SHAREDLIB_ARTIFACT_EXPORT_LIST) + +# +# Link/archive the application +# +ifneq ($(LIBNAME),) +$(CY_BUILD_TARGET): $(CY_BUILD_ALL_OBJ_FILES) $(CY_BUILD_ALL_LIB_FILES) +ifneq ($(strip $(CY_BUILD_ALL_OBJ_FILES) $(CY_BUILD_ALL_LIB_FILES)),) + $(info $(CY_INDENT)Archiving output file $(notdir $@)) + $(CY_NOISE)$(CY_BUILD_ARCHIVE) $(CY_CMD_TERM) +endif +else +$(CY_BUILD_TARGET): $(CY_BUILD_ALL_OBJ_FILES) $(CY_BUILD_ALL_LIB_FILES) $(LINKER_SCRIPT) $(CY_SHAREDLIB_TIMESTAMP) +ifneq ($(SEARCH_LIBS_AND_INCLUDES),) + @libArray=($(CY_SHAREDLIB_LIBS_EXPORT_LIST)); \ + for libFile in "$${libArray[@]}"; do \ + if [ "$$libFile" -nt "$(CY_BUILD_TARGET)" ]; then \ + relink=true; \ + fi; \ + done; \ + artifactArray=($(CY_SHAREDLIB_ARTIFACT_EXPORT_LIST)); \ + for artifactFile in "$${artifactArray[@]}"; do \ + if [ "$$artifactFile" -nt "$(CY_BUILD_TARGET)" ]; then \ + relink=true; \ + fi; \ + done; \ + if [[ "$?" == *".$(CY_TOOLCHAIN_SUFFIX_O)"* ]] || [[ "$?" == *".$(CY_TOOLCHAIN_SUFFIX_A)"* ]]; then \ + relink=true; \ + fi; \ + if [ $$relink ]; then \ + echo " Linking output file $(notdir $@)"; \ + $(CY_BUILD_LINK); \ + fi +else + $(info $(CY_INDENT)Linking output file $(notdir $@)) + $(CY_NOISE)$(CY_BUILD_LINK) +endif +endif + +# +# Perform post-build step +# +CY_BUILD_postbuild: $(CY_BUILD_TARGET) + $(CY_NOISE)$(CY_RECIPE_POSTBUILD) $(CY_CMD_TERM) + +# +# Run BSP post-build step +# +CY_BUILD_bsp_postbuild: CY_BUILD_postbuild + $(CY_BSP_POSTBUILD) + +# +# Perform application post-build step +# +CY_BUILD_app_postbuild: CY_BUILD_bsp_postbuild + $(POSTBUILD) + +# +# Perform the post build print step, basically stating we are done +# +CY_BUILD_postprint: CY_BUILD_app_postbuild + $(info ==============================================================================) + $(info = Build complete =) + $(info ==============================================================================) + $(info ) + +# +# Create an artifact sentinel file for shared libs +# +ifneq ($(LIBNAME),) +CY_BUILD_sentinel: CY_BUILD_postprint +ifneq ($(strip $(CY_BUILD_ALL_OBJ_FILES) $(CY_BUILD_ALL_LIB_FILES)),) + @echo $(LIBNAME).$(CY_TOOLCHAIN_SUFFIX_ARCHIVE) > $(CY_CONFIG_DIR)/artifact.rsp +else + @touch $(CY_CONFIG_DIR)/artifact.rsp +endif +else +CY_BUILD_sentinel: CY_BUILD_postprint + +endif + +# +# Include generated dependency files (if rebuilding) +# +-include $(CY_DEPENDENCY_FILES) + +# +# Indicate all phony targets that should be built regardless +# +.PHONY: app $(CY_SHAREDLIB_LIST) +.PHONY: CY_BUILD_mkdirs +.PHONY: CY_BUILD_prebuild CY_BUILD_app_prebuild CY_BUILD_bsp_prebuild +.PHONY: CY_BUILD_postbuild CY_BUILD_app_postbuild CY_BUILD_bsp_postbuild +.PHONY: CY_BUILD_gensrc +.PHONY: CY_BUILD_genresource +.PHONY: CY_BUILD_preprint +.PHONY: CY_BUILD_postprint +.PHONY: CY_BUILD_sentinel diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/config.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/config.mk new file mode 100644 index 0000000000..dbfd07a622 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/config.mk @@ -0,0 +1,235 @@ +################################################################################ +# \file config.mk +# \version 1.0 +# +# \brief +# Configurator-related routines +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + +# +# Default file extension +# +CY_CONFIG_FILE_EXT?=modus + + +################################################################################ +# Search +################################################################################ + +CY_CONFIG_MODUS_EXT=modus +CY_CONFIG_CYBT_EXT=cybt +CY_CONFIG_CYUSBDEV_EXT=cyusbdev + +# +# Search for configuration files and filter +# +CY_CONFIG_MODUS_FILES:=$(call CY_MACRO_SEARCH,.$(CY_CONFIG_MODUS_EXT),$(CY_INTERNAL_APP_PATH))\ + $(if $(CY_INTERNAL_EXTAPP_PATH),$(call CY_MACRO_SEARCH,.$(CY_CONFIG_MODUS_EXT),$(CY_INTERNAL_EXTAPP_PATH)))\ + $(if $(SEARCH_LIBS_AND_INCLUDES),$(foreach d,$(SEARCH_LIBS_AND_INCLUDES),$(call CY_MACRO_SEARCH,.$(CY_CONFIG_MODUS_EXT),$(d)))) +CY_CONFIG_CYBT_FILES:=$(call CY_MACRO_SEARCH,.$(CY_CONFIG_CYBT_EXT),$(CY_INTERNAL_APP_PATH))\ + $(if $(CY_INTERNAL_EXTAPP_PATH),$(call CY_MACRO_SEARCH,.$(CY_CONFIG_CYBT_EXT),$(CY_INTERNAL_EXTAPP_PATH)))\ + $(if $(SEARCH_LIBS_AND_INCLUDES),$(foreach d,$(SEARCH_LIBS_AND_INCLUDES),$(call CY_MACRO_SEARCH,.$(CY_CONFIG_CYBT_EXT),$(d)))) +CY_CONFIG_CYUSBDEV_FILES:=$(call CY_MACRO_SEARCH,.$(CY_CONFIG_CYUSBDEV_EXT),$(CY_INTERNAL_APP_PATH))\ + $(if $(CY_INTERNAL_EXTAPP_PATH),$(call CY_MACRO_SEARCH,.$(CY_CONFIG_CYUSBDEV_EXT),$(CY_INTERNAL_EXTAPP_PATH)))\ + $(if $(SEARCH_LIBS_AND_INCLUDES),$(foreach d,$(SEARCH_LIBS_AND_INCLUDES),$(call CY_MACRO_SEARCH,.$(CY_CONFIG_CYUSBDEV_EXT),$(d)))) + +CY_SEARCH_PRUNED_MODUS_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_DIRS),$(filter $(d)%,$(CY_CONFIG_MODUS_FILES))),$(CY_CONFIG_MODUS_FILES)) +CY_SEARCH_PRUNED_CYBT_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_DIRS),$(filter $(d)%,$(CY_CONFIG_CYBT_FILES))),$(CY_CONFIG_CYBT_FILES)) +CY_SEARCH_PRUNED_CYUSBDEV_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_DIRS),$(filter $(d)%,$(CY_CONFIG_CYUSBDEV_FILES))),$(CY_CONFIG_CYUSBDEV_FILES)) + +CY_SEARCH_AVAILABLE_MODUS_SOURCES=$(call CY_MACRO_FILTER_FILES,MODUS) +CY_SEARCH_AVAILABLE_CYBT_SOURCES=$(call CY_MACRO_FILTER_FILES,CYBT) +CY_SEARCH_AVAILABLE_CYUSBDEV_SOURCES=$(call CY_MACRO_FILTER_FILES,CYUSBDEV) + +ifneq ($(words $(CY_SEARCH_AVAILABLE_MODUS_SOURCES)),1) +ifneq ($(words $(CY_SEARCH_AVAILABLE_MODUS_SOURCES)),0) +$(call CY_MACRO_ERROR,Multiple device configuration files detected: $(CY_SEARCH_AVAILABLE_MODUS_SOURCES)) +endif +endif +ifneq ($(words $(CY_SEARCH_AVAILABLE_CYBT_SOURCES)),1) +ifneq ($(words $(CY_SEARCH_AVAILABLE_CYBT_SOURCES)),0) +$(call CY_MACRO_ERROR,Multiple BT configuration files detected: $(CY_SEARCH_AVAILABLE_CYBT_SOURCES)) +endif +endif +ifneq ($(words $(CY_SEARCH_AVAILABLE_CYUSBDEV_SOURCES)),1) +ifneq ($(words $(CY_SEARCH_AVAILABLE_CYUSBDEV_SOURCES)),0) +$(call CY_MACRO_ERROR,Multiple USBDEV configuration files detected: $(CY_SEARCH_AVAILABLE_CYUSBDEV_SOURCES)) +endif +endif + + +################################################################################ +# Arguments constructions +################################################################################ + +########################## +# .modus (HW) +########################## + +CY_CONFIG_MODUS_FILE?=$(CY_SEARCH_AVAILABLE_MODUS_SOURCES) +CY_CONFIG_MODUS_OUTPUT=$(call CY_MACRO_DIR,$(CY_CONFIG_MODUS_FILE))/GeneratedSource + +ifeq ($(CY_DEVICESUPPORT_PATH),) +CY_CONFIG_LIBFILE= +else +CY_CONFIG_LIBFILE=--library $(CY_INTERNAL_DEVICESUPPORT_PATH)/devicesupport.xml +endif + +CY_CONFIG_MODUS_EXEC=$(CY_CFG_BACKEND_CLI_DIR)/cfg-backend-cli +CY_CONFIG_MODUS_EXEC_FLAGS=\ + $(CY_CONFIG_LIBFILE)\ + --build $(CY_CONFIG_MODUS_FILE)\ + --set-device=$(subst $(CY_SPACE),$(CY_COMMA),$(DEVICE) $(ADDITIONAL_DEVICES)) + +CY_CONFIG_MODUS_GUI=$(CY_DEVICE_CONFIGURATOR_DIR)/device-configurator +CY_CONFIG_MODUS_GUI_FLAGS=\ + --design + +########################## +# .cybt (SW) +########################## + +CY_CONFIG_CYBT_FILE?=$(CY_SEARCH_AVAILABLE_CYBT_SOURCES) +CY_CONFIG_CYBT_OUTPUT=$(call CY_MACRO_DIR,$(CY_CONFIG_CYBT_FILE))/GeneratedSource + +CY_CONFIG_CYBT_EXEC=$(CY_BT_CONFIGURATOR_DIR)/bt-configurator-cli +CY_CONFIG_CYBT_EXEC_FLAGS=\ + --config $(CY_CONFIG_CYBT_FILE) + +CY_CONFIG_CYBT_GUI=$(CY_BT_CONFIGURATOR_DIR)/bt-configurator +CY_CONFIG_CYBT_GUI_FLAGS=\ + --config + +########################## +# .cyusbdev (SW) +########################## + +CY_CONFIG_CYUSBDEV_FILE?=$(CY_SEARCH_AVAILABLE_CYUSBDEV_SOURCES) +CY_CONFIG_CYUSBDEV_OUTPUT=$(call CY_MACRO_DIR,$(CY_CONFIG_CYUSBDEV_FILE))/GeneratedSource + +CY_CONFIG_CYUSBDEV_EXEC=$(CY_USBDEV_CONFIGURATOR_DIR)/usbdev-configurator-cli +CY_CONFIG_CYUSBDEV_EXEC_FLAGS=\ + --config $(CY_CONFIG_CYUSBDEV_FILE) + +CY_CONFIG_CYUSBDEV_GUI=$(CY_USBDEV_CONFIGURATOR_DIR)/usbdev-configurator +CY_CONFIG_CYUSBDEV_GUI_FLAGS=\ + --config + + +################################################################################ +# Source generation +################################################################################ + +ifeq ($(CY_COMMENCE_BUILD),true) + +########################## +# .modus +########################## + +# Check the timestamps and re-run the configurator if it's stale +ifneq ($(CY_CONFIG_MODUS_FILE),) +CY_CONFIG_MODUS_STATE=$(shell if [ "$(CY_CONFIG_MODUS_FILE)" -nt "$(CY_CONFIG_MODUS_OUTPUT)/cycfg.timestamp" ]; then echo 1; else echo 0; fi) +ifeq ($(CY_CONFIG_MODUS_STATE),1) +$(info $(CY_INDENT)Stale device files detected. Running device configurator to regenerate files...) +ifneq ($(shell $(CY_CONFIG_MODUS_EXEC) $(CY_CONFIG_MODUS_EXEC_FLAGS) 1> /dev/null; echo $$?),0) + $(error Error(s) encountered while running the configurator on $(CY_CONFIG_MODUS_FILE)) +endif +endif +endif + +########################## +# .cybt +########################## + +# Check the timestamps and re-run the configurator if it's stale +ifneq ($(CY_CONFIG_CYBT_FILE),) +CY_CONFIG_CYBT_STATE=$(shell if [ "$(CY_CONFIG_CYBT_FILE)" -nt "$(CY_CONFIG_CYBT_OUTPUT)/cycfg_bt.timestamp" ]; then echo 1; else echo 0; fi) +ifeq ($(CY_CONFIG_CYBT_STATE),1) +$(info $(CY_INDENT)Stale BT files detected. Running BT-configurator to regenerate files...) +ifneq ($(shell $(CY_CONFIG_CYBT_EXEC) $(CY_CONFIG_CYBT_EXEC_FLAGS) 1> /dev/null; echo $$?),0) + $(error Error(s) encountered while running the configurator on $(CY_CONFIG_CYBT_FILE)) +endif +endif +endif + +########################## +# .cyusbdev +########################## + +# Check the timestamps and re-run the configurator if it's stale +ifneq ($(CY_CONFIG_CYUSBDEV_FILE),) +CY_CONFIG_CYUSBDEV_STATE=$(shell if [ "$(CY_CONFIG_CYUSBDEV_FILE)" -nt "$(CY_CONFIG_CYUSBDEV_OUTPUT)/cycfg_usbdev.timestamp" ]; then echo 1; else echo 0; fi) +ifeq ($(CY_CONFIG_CYUSBDEV_STATE),1) +$(info $(CY_INDENT)Stale USBDEV files detected. Running USBDEV-configurator to regenerate files...) +ifneq ($(shell $(CY_CONFIG_CYUSBDEV_EXEC) $(CY_CONFIG_CYUSBDEV_EXEC_FLAGS) 1> /dev/null; echo $$?),0) + $(error Error(s) encountered while running the configurator on $(CY_CONFIG_CYUSBDEV_FILE)) +endif +endif +endif + +endif + + +################################################################################ +# Targets +################################################################################ + +# Extract the names for the variable name construction +CY_CONFIG_CONVERT=$(foreach ext,$(CY_CONFIG_FILE_EXT),$(call CY_MACRO_UC,$(ext))) + +# Gather the files. Find all files that match the extensions in the design.modus location +CY_CONFIG_FILES=$(sort $(foreach ext,$(CY_CONFIG_CONVERT),$(CY_CONFIG_$(ext)_FILE))\ + $(foreach ext,$(CY_CONFIG_FILE_EXT),$(wildcard $(call CY_MACRO_DIR,$(CY_CONFIG_MODUS_FILE))/*.$(ext)))) + +config: +ifeq ($(CY_CONFIG_MODUS_FILE),) + $(info $(CY_NEWLINE)Could not find any device configuration files) + $(info Launching device-configurator for a new configuration) + $(CY_NOISE) $(CY_CONFIG_MODUS_GUI) $(CY_CONFIG_LIBFILE) +else + $(info $(CY_NEWLINE)Launching device-configurator on $(CY_CONFIG_MODUS_FILE)) + $(CY_NOISE) $(CY_CONFIG_MODUS_GUI) $(CY_CONFIG_LIBFILE) $(CY_CONFIG_MODUS_GUI_FLAGS) $(CY_CONFIG_MODUS_FILE) +endif + +config_bt: +ifeq ($(CY_CONFIG_CYBT_FILE),) + $(info $(CY_NEWLINE)Could not find any bt-configuration files) + $(info Launching bt-configurator for a new configuration) + $(CY_NOISE) $(CY_CONFIG_CYBT_GUI) +else + $(info $(CY_NEWLINE)Launching bt-configurator on $(CY_CONFIG_CYBT_FILE)) + $(CY_NOISE) $(CY_CONFIG_CYBT_GUI) $(CY_CONFIG_CYBT_GUI_FLAGS) $(CY_CONFIG_CYBT_FILE) +endif + +config_usbdev: +ifeq ($(CY_CONFIG_CYUSBDEV_FILE),) + $(info $(CY_NEWLINE)Could not find any usbdev-configuration files) + $(info Launching usbdev-configurator for a new configuration) + $(CY_NOISE) $(CY_CONFIG_CYUSBDEV_GUI) +else + $(info $(CY_NEWLINE)Launching usbdev-configurator on $(CY_CONFIG_CYUSBDEV_FILE)) + $(CY_NOISE) $(CY_CONFIG_CYUSBDEV_GUI) $(CY_CONFIG_CYUSBDEV_GUI_FLAGS) $(CY_CONFIG_CYUSBDEV_FILE) +endif + +.PHONY: config config_bt config_usbdev diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/help.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/help.mk new file mode 100644 index 0000000000..ee62eac005 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/help.mk @@ -0,0 +1,374 @@ +################################################################################ +# \file help.mk +# \version 1.0 +# +# \brief +# Default help documentation +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + +# +# General Targets +# +CY_HELP_all_VERBOSE=This target is equivalent to the "build" target. +CY_HELP_getlibs_VERBOSE=The repos are cloned to the libs directory. By default, this directory is\ + created in the application directory. It may be directed to other locations using\ + the CY_GETLIBS_PATH variable. +CY_HELP_build_VERBOSE=The build process involves source auto-discovery, code generation, prebuilds, and postbuilds.\ + For faster incremental builds, use the "qbuild" target to skip the auto-generation step. +CY_HELP_qbuild_VERBOSE=When no other sources need to be auto-discovered, this target can be used to skip\ + the auto-discovery step for a faster incremental build. +CY_HELP_program_VERBOSE=The build process performs the same operations as the "build" target. Upon completion,\ + the artifact is programmed to the board. +CY_HELP_qprogram_VERBOSE=This target allows programming an existing artifact to the board without a build step. +CY_HELP_debug_VERBOSE=Once the GDB server is launched, another shell should be opened to launch a GDB client. +CY_HELP_qdebug_VERBOSE=Once the GDB server is launched, another shell should be opened to launch a GDB client. +CY_HELP_clean_VERBOSE=The directory and all its contents are deleted from disk. +CY_HELP_help_VERBOSE=Use the CY_HELP= to see the verbose documentation for a\ + particular target or a variable. + +# +# Configurator Targets +# +CY_HELP_open_VERBOSE=This target accepts two variables – CY_OPEN_TYPE and CY_OPEN_FILE. At least one of\ + these must be provided. The tool can be specified by setting the CY_OPEN_TYPE variable.\ + A specific file can also be passed using the CY_OPEN_FILE variable. If only CY_OPEN_FILE is given,\ + the build system will launch the default tool associated with the file’s extension. +CY_HELP_config_VERBOSE=If no existing device-configuration files are found, the configurator is launched to create one. +CY_HELP_config_bt_VERBOSE=If no existing bt-configuration files are found, the configurator is launched to create one. +CY_HELP_config_usbdev_VERBOSE=If no existing usbdev-configuration files are found, the configurator is launched to create one. + +# +# Utility Targets +# +CY_HELP_eclipse_VERBOSE=This target expects the CY_IDE_PRJNAME variable to be set to the name of the project\ + as defined in the eclipse IDE. E.g. "make eclipse CY_IDE_PRJNAME=AppV1". If this variable\ + is not defined, it will use the APPNAME for the launch configs. +CY_HELP_check_VERBOSE=Not all tools are necessary for every build recipe. This target allows the user\ + to get an idea of which tools are missing if a build fails in an unexpected way. +CY_HELP_get_app_info_VERBOSE=The file types can be specified by setting the\ + CY_CONFIG_FILE_EXT variable. E.g. "make get_app_info "CY_CONFIG_FILE_EXT=modus cybt cyusbdev"". +CY_HELP_get_env_info_VERBOSE=This allows a quick printout of the current app repo and the "make" and "git"\ + tool locations and versions. +CY_HELP_printlibs_VERBOSE=This target parses through the library repos and prints the SHA1 commit id for each library.\ + It also shows whether the repo is clean (no changes) or dirty (modified or new files). + +# +# Basic configuration +# +CY_HELP_TARGET=Specifies the target board/kit. E.g. CY8CPROTO-062-4343W. +CY_HELP_TARGET_VERBOSE=Currently available target(s) in this application is/are, [ $(CY_TARGET_AVAILABLE) ]. +CY_HELP_APPNAME=Specifies the name of the application. E.g. AppV1. +CY_HELP_APPNAME_VERBOSE=This variable signifies that the application will build an artifact that is\ + intended for a target board. For applications that need to build into an archive (library),\ + use the LIBNAME variable. +CY_HELP_LIBNAME=Specifies the name of the library application. E.g. LibV1. +CY_HELP_LIBNAME_VERBOSE=This variable signifies that the application will build an archive (library).\ + These library applications can be added as a dependency to an artifact producing application\ + using the SEARCH_LIBS_AND_INCLUDES variable. +CY_HELP_TOOLCHAIN=Specifies the toolchain for building the application. E.g. GCC_ARM. +CY_HELP_TOOLCHAIN_VERBOSE=Supported toolchains for this target are, [ $(CY_SUPPORTED_TOOLCHAINS) ]. +CY_HELP_CONFIG=Specifies the configuration option for the build [Debug Release]. +CY_HELP_CONFIG_VERBOSE=The CONFIG variable is not limited to Debug/Release. It can be\ + other values. However in those instances, the build system will not configure the optimization flags.\ + Debug=lowest optimization, Release=highest optimization. The optimization flags are toolchain-specific.\ + If you go with your custom config then you can manually set the optimization flag in the CFLAGS. +CY_HELP_VERBOSE=Specifies whether the build is silent [false] or verbose [true]. +CY_HELP_VERBOSE_VERBOSE=Setting VERBOSE to true may help in debuggging build errors/warnings. + +# +# Advanced configuration +# +CY_HELP_SOURCES=Specifies C/C++ and assembly files not under the working directory. +CY_HELP_SOURCES_VERBOSE=This can be used to include files external to the application directory. +CY_HELP_INCLUDES=Specifies include paths not under the working directory. +CY_HELP_INCLUDES_VERBOSE=Note: These MUST NOT have -I prepended. +CY_HELP_DEFINES=Specifies additional defines passed to the compiler. +CY_HELP_DEFINES_VERBOSE=Note: These MUST NOT have -D prepended. +CY_HELP_VFP_SELECT=Selects hard/soft ABI for floating-point operations [softfp hardfp]. +CY_HELP_VFP_SELECT_VERBOSE=If not defined, this value defaults to softfp. +CY_HELP_CFLAGS=Prepends additional C compiler flags. +CY_HELP_CFLAGS_VERBOSE=Note: If the entire C compiler flags list needs to be replaced, define the\ + CY_RECIPE_CFLAGS make variable with the desired C flags. +CY_HELP_CXXFLAGS=Prepends additional C++ compiler flags. +CY_HELP_CXXFLAGS_VERBOSE=Note: If the entire C++ compiler flags list needs to be replaced, define the\ + CY_RECIPE_CXXFLAGS make variable with the desired C++ flags. +CY_HELP_ASFLAGS=Prepends additional assembler flags. +CY_HELP_ASFLAGS_VERBOSE=Note: If the entire assembler flags list needs to be replaced, define the\ + CY_RECIPE_ASFLAGS make variable with the desired assembly flags. +CY_HELP_LDFLAGS=Prepends additional linker flags. +CY_HELP_LDFLAGS_VERBOSE=Note: If the entire linker flags list needs to be replaced, define the\ + CY_RECIPE_LDFLAGS make variable with the desired linker flags. +CY_HELP_LDLIBS=Includes application-specific prebuilt libraries. +CY_HELP_LDLIBS_VERBOSE=Note: If additional libraries need to be added using -l or -L, add to the\ + CY_RECIPE_EXTRA_LIBS make variable. +CY_HELP_LINKER_SCRIPT=Specifies a custom linker script location. +CY_HELP_LINKER_SCRIPT_VERBOSE=This linker script overrides the default. Note: Additional\ + linker scripts can be added for GCC via the LDFLAGS variable as a -L option. +CY_HELP_PREBUILD=Specifies the location of a custom prebuild step and its arguments. +CY_HELP_PREBUILD_VERBOSE=This operation runs before the build recipe's prebuild step.\ + $(CY_NEWLINE)Note: BSPs can also define a prebuild step. This runs before the\ + application prebuild step.\ + $(CY_NEWLINE)Note: If the default prebuild step needs to be replaced, define the\ + CY_RECIPE_PREBUILD make variable with the desired prebuild step. +CY_HELP_POSTBUILD=Specifies the location of a custom postbuild step and its arguments. +CY_HELP_POSTBUILD_VERBOSE=This operation runs after the build recipe's postbuild step.\ + $(CY_NEWLINE)Note: BSPs can also define a postbuild step. This runs before the\ + application postbuild step.\ + $(CY_NEWLINE)Note: If the default postbuild step needs to be replaced, define the\ + CY_RECIPE_POSTBUILD make variable with the desired postbuild step. +CY_HELP_COMPONENTS=Adds component-specific files to the build. +CY_HELP_COMPONENTS_VERBOSE=Create a directory named COMPONENT_ and place your files.\ + Then include the to this make variable to have that feature library\ + be included in the build. E.g. Create a directory named COMPONENT_ACCELEROMETER.\ + Then include it in the make variable. COMPONENT=ACCELEROMETER. If the make variable\ + does not include the , then that library will not be included in the build.\ + $(CY_NEWLINE)Note: If the default COMPONENT list must be overridden, defined the CY_COMPONENT_LIST\ + make variable with the list of component values. +CY_HELP_DISABLE_COMPONENTS=Removes component-specific files from the build. +CY_HELP_DISABLE_COMPONENTS_VERBOSE=Include a to this make variable to have that feature library\ + be excluded in the build. E.g. To exclude the contents of COMPONENT_BSP_DESIGN_MODUS\ + directory, set DISABLE_COMPONENTS=BSP_DESIGN_MODUS. +CY_HELP_SEARCH_LIBS_AND_INCLUDES=List of dependent library application paths. E.g. ../bspLib. +CY_HELP_SEARCH_LIBS_AND_INCLUDES_VERBOSE=An artifact producing application (Defined by setting APPNAME),\ + can have a dependency on library applications (Defined by setting LIBNAME). This variable\ + defines those dependencies for the artifact producing application. The actual build invocation\ + of those libraries are handled at the application level by defining the "shared_libs" target. E.g.\ + $(CY_NEWLINE)$(CY_NEWLINE)shared_libs: $(CY_NEWLINE)$(CY_INDENT)make -C ../bspLib build -j + +# +# Path variables +# +CY_HELP_CY_APP_PATH=Relative path to the top-level of application. E.g. ./ +CY_HELP_CY_APP_PATH_VERBOSE=Settings this path to other than ./ allows the auto-discovery mechanism\ + to search from a root directory location that is higher than the app directory.\ + E.g. CY_APP_PATH=../../ allows auto-discovery of files from a location that is\ + two directories above the location of ./Makefile. +CY_HELP_CY_BASELIB_PATH=Relative path to the base library. E.g. ./libs/psoc6make +CY_HELP_CY_BASELIB_PATH_VERBOSE=This directory must be relative to CY_APP_PATH. It defines the location\ + of the library containing the recipe make files, where the expected directory structure\ + is /make. All applications must set the location of the base library. +CY_HELP_CY_GETLIBS_PATH=Absolute path to the intended location of libs directory. +CY_HELP_CY_GETLIBS_PATH_VERBOSE=The library repos are cloned into a directory named, libs (Default: /libs).\ + Setting this variable allows specifying the location of the libs directory to elsewhere on disk. +CY_HELP_CY_GETLIBS_SEARCH_PATH=Relative path to the top directory for "getlibs" operation. +CY_HELP_CY_GETLIBS_SEARCH_PATH_VERBOSE=The getlibs operation by default executes at the location of the CY_APP_PATH. This can\ + be overridden by specifying this variable to point to a specific location. +CY_HELP_CY_DEVICESUPPORT_PATH=Relative path to the devicesupport.xml file. +CY_HELP_CY_DEVICESUPPORT_PATH_VERBOSE=This path specifies the location of the devicesupport.xml file for device-configurators.\ + It is used when the configurator needs to be run in a multi-app scenario. +CY_HELP_CY_SHARED_PATH=Relative path to the location of shared .lib files. +CY_HELP_CY_SHARED_PATH_VERBOSE=This variable is used in shared library applications to point to the location of external .lib files. +CY_HELP_CY_COMPILER_PATH=Absolute path to the compiler (Default: GCC_ARM in CY_TOOLS_DIR). +CY_HELP_CY_COMPILER_PATH_VERBOSE=Setting this path allows custom toolchains to be used instead of the defaults.\ + This should be the location of the /bin directory containing the compiler, assembler and\ + linker. E.g. CY_COMPILER_PATH="C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.2/arm/bin". +CY_HELP_CY_TOOLS_DIR=Absolute path to the tools root directory. +CY_HELP_CY_TOOLS_DIR_VERBOSE=Applications must specify the directory of the tools install, which contains the\ + root makefile and the necessary tools and scripts to build an application. Application Makefiles\ + are configured to automatically search in the standard locations for various platforms.\ + If the tools are not located in the standard location, you may explicitly set this. +CY_HELP_CY_BUILD_LOCATION=Absolute path to the build output directory (Default: pwd/build). +CY_HELP_CY_BUILD_LOCATION_VERBOSE=The build output directory is structured as /TARGET/CONFIG/. Setting this variable\ + allows the build artifacts to be located in the directory pointed to by this variable. +CY_HELP_CY_EXTAPP_PATH=Relative path to an external app directory. E.g. ../external +CY_HELP_CY_EXTAPP_PATH_VERBOSE=This directory must be relative to CY_APP_PATH. Setting this path\ + allows incorporating files external to CY_APP_PATH. E.g. CY_EXTAPP_PATH=../external\ + lets the auto-discovery to pull in the contents of ../external directory into the build.\ + $(CY_NEWLINE)Note: This variable is only supported in CLI. Use the shared_libs mechanism and\ + CY_HELP_SEARCH_LIBS_AND_INCLUDES for tools and IDE support. + +# +# Miscellaneous variables +# +CY_HELP_CY_IGNORE=Adds to the directory and file ignore list. E.g. ./file1.c ./inc1 +CY_HELP_CY_IGNORE_VERBOSE=Directories and files listed in this variable are ignored in the auto-discovery.\ + This mechanism works in combination with any existing .cyignore files in the application. +CY_HELP_CY_IDE_PRJNAME=Name of the eclipse IDE project. +CY_HELP_CY_IDE_PRJNAME_VERBOSE=This variable can be used to define the file and target project name when\ + generating eclipse launch configurations in the "eclipse" target. +CY_HELP_CY_CONFIG_FILE_EXT=Specifies the configurator file extension. E.g. modus +CY_HELP_CY_CONFIG_FILE_EXT_VERBOSE=This variable accepts a space-separated list of configurator file extensions\ + that should be searched for when running the "get_app_info" target. +CY_HELP_CY_SKIP_RECIPE=Skip including the recipe make files. +CY_HELP_CY_SKIP_RECIPE_VERBOSE=This allows the application to not include any recipe makefiles and only\ + include the start.mk file from the tools install. +CY_HELP_CY_SUPPORTED_TOOL_TYPES=Defines the supported tools for a BSP. +CY_HELP_CY_SUPPORTED_TOOL_TYPES_VERBOSE=BSPs can define the supported tools that can be launched using the\ + "open" target. The supported tool types are $(CY_OPEN_TYPE_LIST). +CY_HELP_CY_LIBS_SEARCH_DEPTH=Search depth for .lib files (Default: 5). +CY_HELP_CY_LIBS_SEARCH_DEPTH_VERBOSE=This variable controls how deep (directory) the search mechanism in getlibs looks for .lib files.\ + $(CY_NEWLINE)Note: Deeper searches take longer to process. +CY_HELP_CY_UTILS_SEARCH_DEPTH=Search depth for .cyignore and TARGET.mk files (Default: 5). +CY_HELP_CY_UTILS_SEARCH_DEPTH_VERBOSE=This variable controls how deep (directory) the search mechanism looks for .cyignore\ + and TARGET.mk files. Min=1, Max=9.\ + $(CY_NEWLINE)Note: Deeper searches take longer to process. +CY_HELP_CY_EXTRA_INCLUDES=Specifies additional makefiles to add to the build. +CY_HELP_CY_EXTRA_INCLUDES_VERBOSE=The application Makefile cannot add additional make files directly. Instead, use\ + this variable to include these in the build. E.g. CY_EXTRA_INCLUDES=./custom1.mk ./custom2.mk +CY_HELP_TOOLCHAIN_MK_PATH=Specifies the location of a custom TOOLCHAIN makefile. +CY_HELP_TOOLCHAIN_MK_PATH_VERBOSE=Defining this path allows the build system to use a custom TOOLCHAIN.mk\ + pointed to by this variable.\ + $(CY_NEWLINE)Note: The make variables in this file should match the\ + variables used in existing TOOLCHAIN.mk files. + +# Pass these to CY_HELP to get the full verbose info +CY_HELP_TARGETS_ALL=all getlibs build qbuild program qprogram debug qdebug clean help open config config_bt config_usbdev \ + eclipse check get_app_info get_env_info printlibs +CY_HELP_BASIC_CFG_ALL=TARGET APPNAME LIBNAME TOOLCHAIN CONFIG VERBOSE +CY_HELP_ADVANCED_CFG_ALL=SOURCES INCLUDES DEFINES VFP_SELECT CFLAGS CXXFLAGS ASFLAGS LDFLAGS LDLIBS LINKER_SCRIPT \ + PREBUILD POSTBUILD COMPONENTS DISABLE_COMPONENTS SEARCH_LIBS_AND_INCLUDES +CY_HELP_PATHS_ALL=CY_APP_PATH CY_BASELIB_PATH CY_EXTAPP_PATH CY_GETLIBS_PATH CY_GETLIBS_SEARCH_PATH CY_DEVICESUPPORT_PATH \ + CY_SHARED_PATH CY_COMPILER_PATH CY_TOOLS_DIR CY_BUILD_LOCATION +CY_HELP_MISC_ALL=CY_IGNORE CY_IDE_PRJNAME CY_CONFIG_FILE_EXT CY_SKIP_RECIPE CY_SUPPORTED_TOOL_TYPES CY_LIBS_SEARCH_DEPTH \ + CY_UTILS_SEARCH_DEPTH CY_EXTRA_INCLUDES TOOLCHAIN_MK_PATH +CY_HELP_PRINT_ALL=$(CY_HELP_TARGETS_ALL) $(CY_HELP_BASIC_CFG_ALL) $(CY_HELP_ADVANCED_CFG_ALL) $(CY_HELP_PATHS_ALL) $(CY_HELP_MISC_ALL) + + +help_default: +ifneq ($(CY_HELP),) + @echo + $(foreach topic,$(CY_HELP),\ + $(info $(CY_NEWLINE)Topic-specific help for "$(topic)")\ + $(info $(CY_SPACE)$(CY_SPACE)Brief: $(CY_HELP_$(topic)))\ + $(info $(CY_SPACE)$(CY_SPACE)Verbose: $(CY_HELP_$(topic)_VERBOSE))) +else + @echo + $(info ) + $(info ============================================================================== ) + $(info $(CY_SPACE)Cypress Build System ) + $(info ============================================================================== ) + $(info $(CY_SPACE)Copyright 2018-2019 Cypress Semiconductor Corporation ) + $(info $(CY_SPACE)SPDX-License-Identifier: Apache-2.0 ) + $(info ) + $(info $(CY_SPACE)Licensed under the Apache License, Version 2.0 (the "License"); ) + $(info $(CY_SPACE)you may not use this file except in compliance with the License. ) + $(info $(CY_SPACE)You may obtain a copy of the License at ) + $(info ) + $(info $(CY_SPACE)$(CY_SPACE) http://www.apache.org/licenses/LICENSE-2.0 ) + $(info ) + $(info $(CY_SPACE)Unless required by applicable law or agreed to in writing, software ) + $(info $(CY_SPACE)distributed under the License is distributed on an "AS IS" BASIS, ) + $(info $(CY_SPACE)WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.) + $(info $(CY_SPACE)See the License for the specific language governing permissions and ) + $(info $(CY_SPACE)limitations under the License. ) + $(info ============================================================================== ) + $(info ) + $(info $(CY_SPACE)This is the help documentation for the Cypress build system. ) + $(info $(CY_SPACE)It lists the supported make targets and make variables. ) + $(info ) + $(info $(CY_SPACE)Usage: make [target][variable] ) + $(info $(CY_SPACE)Example: make help CY_HELP=TOOLCHAIN ) + $(info ) + $(info ======================================= ) + $(info $(CY_SPACE)General make targets ) + $(info ======================================= ) + $(info $(CY_SPACE)all $(CY_HELP_all)) + $(info $(CY_SPACE)getlibs $(CY_HELP_getlibs)) + $(info $(CY_SPACE)build $(CY_HELP_build)) + $(info $(CY_SPACE)qbuild $(CY_HELP_qbuild)) + $(info $(CY_SPACE)program $(CY_HELP_program)) + $(info $(CY_SPACE)qprogram $(CY_HELP_qprogram)) + $(info $(CY_SPACE)debug $(CY_HELP_debug)) + $(info $(CY_SPACE)qdebug $(CY_HELP_qdebug)) + $(info $(CY_SPACE)clean $(CY_HELP_clean)) + $(info $(CY_SPACE)help $(CY_HELP_help)) + $(info ) + $(info ======================================= ) + $(info $(CY_SPACE)Tools make targets ) + $(info ======================================= ) + $(info $(CY_SPACE)open $(CY_HELP_open)) + $(info $(CY_SPACE)config $(CY_HELP_config)) + $(info $(CY_SPACE)config_bt $(CY_HELP_config_bt)) + $(info $(CY_SPACE)config_usbdev $(CY_HELP_config_usbdev)) + $(info ) + $(info ======================================= ) + $(info $(CY_SPACE)Utility make targets ) + $(info ======================================= ) + $(info $(CY_SPACE)eclipse $(CY_HELP_eclipse)) + $(info $(CY_SPACE)check $(CY_HELP_check)) + $(info $(CY_SPACE)get_app_info $(CY_HELP_get_app_info)) + $(info $(CY_SPACE)get_env_info $(CY_HELP_get_env_info)) + $(info $(CY_SPACE)printlibs $(CY_HELP_printlibs)) + $(info ) + $(info ======================================= ) + $(info $(CY_SPACE)Basic configuration make variables ) + $(info ======================================= ) + $(info $(CY_SPACE)TARGET $(CY_HELP_TARGET)) + $(info $(CY_SPACE)APPNAME $(CY_HELP_APPNAME)) + $(info $(CY_SPACE)LIBNAME $(CY_HELP_LIBNAME)) + $(info $(CY_SPACE)TOOLCHAIN $(CY_HELP_TOOLCHAIN)) + $(info $(CY_SPACE)CONFIG $(CY_HELP_CONFIG)) + $(info $(CY_SPACE)VERBOSE $(CY_HELP_VERBOSE)) + $(info ) + $(info ======================================= ) + $(info $(CY_SPACE)Advanced configuration make variables ) + $(info ======================================= ) + $(info $(CY_SPACE)SOURCES $(CY_HELP_SOURCES)) + $(info $(CY_SPACE)INCLUDES $(CY_HELP_INCLUDES)) + $(info $(CY_SPACE)DEFINES $(CY_HELP_DEFINES)) + $(info $(CY_SPACE)VFP_SELECT $(CY_HELP_VFP_SELECT)) + $(info $(CY_SPACE)CFLAGS $(CY_HELP_CFLAGS)) + $(info $(CY_SPACE)CXXFLAGS $(CY_HELP_CXXFLAGS)) + $(info $(CY_SPACE)ASFLAGS $(CY_HELP_ASFLAGS)) + $(info $(CY_SPACE)LDFLAGS $(CY_HELP_LDFLAGS)) + $(info $(CY_SPACE)LDLIBS $(CY_HELP_LDLIBS)) + $(info $(CY_SPACE)LINKER_SCRIPT $(CY_HELP_LINKER_SCRIPT)) + $(info $(CY_SPACE)PREBUILD $(CY_HELP_PREBUILD)) + $(info $(CY_SPACE)POSTBUILD $(CY_HELP_POSTBUILD)) + $(info $(CY_SPACE)COMPONENTS $(CY_HELP_COMPONENTS)) + $(info $(CY_SPACE)DISABLE_COMPONENTS $(CY_HELP_DISABLE_COMPONENTS)) + $(info $(CY_SPACE)SEARCH_LIBS_AND_INCLUDES $(CY_HELP_SEARCH_LIBS_AND_INCLUDES)) + $(info ) + $(info ======================================= ) + $(info $(CY_SPACE)Path make variables ) + $(info ======================================= ) + $(info $(CY_SPACE)CY_APP_PATH $(CY_HELP_CY_APP_PATH)) + $(info $(CY_SPACE)CY_BASELIB_PATH $(CY_HELP_CY_BASELIB_PATH)) + $(info $(CY_SPACE)CY_EXTAPP_PATH $(CY_HELP_CY_EXTAPP_PATH)) + $(info $(CY_SPACE)CY_GETLIBS_PATH $(CY_HELP_CY_GETLIBS_PATH)) + $(info $(CY_SPACE)CY_GETLIBS_SEARCH_PATH $(CY_HELP_CY_GETLIBS_SEARCH_PATH)) + $(info $(CY_SPACE)CY_DEVICESUPPORT_PATH $(CY_HELP_CY_DEVICESUPPORT_PATH)) + $(info $(CY_SPACE)CY_SHARED_PATH $(CY_HELP_CY_SHARED_PATH)) + $(info $(CY_SPACE)CY_COMPILER_PATH $(CY_HELP_CY_COMPILER_PATH)) + $(info $(CY_SPACE)CY_TOOLS_DIR $(CY_HELP_CY_TOOLS_DIR)) + $(info $(CY_SPACE)CY_BUILD_LOCATION $(CY_HELP_CY_BUILD_LOCATION)) + $(info ) + $(info ======================================= ) + $(info $(CY_SPACE)Miscellaneous make variables ) + $(info ======================================= ) + $(info $(CY_SPACE)CY_IGNORE $(CY_HELP_CY_IGNORE)) + $(info $(CY_SPACE)CY_IDE_PRJNAME $(CY_HELP_CY_IDE_PRJNAME)) + $(info $(CY_SPACE)CY_CONFIG_FILE_EXT $(CY_HELP_CY_CONFIG_FILE_EXT)) + $(info $(CY_SPACE)CY_SKIP_RECIPE $(CY_HELP_CY_SKIP_RECIPE)) + $(info $(CY_SPACE)CY_SUPPORTED_TOOL_TYPES $(CY_HELP_CY_SUPPORTED_TOOL_TYPES)) + $(info $(CY_SPACE)CY_LIBS_SEARCH_DEPTH $(CY_HELP_CY_LIBS_SEARCH_DEPTH)) + $(info $(CY_SPACE)CY_UTILS_SEARCH_DEPTH $(CY_HELP_CY_UTILS_SEARCH_DEPTH)) + $(info $(CY_SPACE)CY_EXTRA_INCLUDES $(CY_HELP_CY_EXTRA_INCLUDES)) + $(info $(CY_SPACE)TOOLCHAIN_MK_PATH $(CY_HELP_TOOLCHAIN_MK_PATH)) +endif + +# +# Identify the phony targets +# +.PHONY: help help_default diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/main.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/main.mk new file mode 100644 index 0000000000..3defc841a9 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/main.mk @@ -0,0 +1,317 @@ +################################################################################ +# \file main.mk +# \version 1.0 +# +# \brief +# Defines the public facing build targets common to all recipes and includes +# the core makefiles. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +################################################################################ +# Paths +################################################################################ + +# +# Set the build location. Append app dir if CY_BUILD_LOCATION is defined +# +ifneq ($(CY_BUILD_LOCATION),) +CY_BUILD_LOC=$(CY_BUILD_LOCATION)/$(notdir $(CY_APP_LOCATION)) +else +CY_BUILD_LOC=$(CY_APP_LOCATION)/build +endif + +# +# Windows paths +# +ifeq ($(OS),Windows_NT) + +# +# CygWin/MSYS +# +ifneq ($(CY_WHICH_CYGPATH),) +CY_INTERNAL_BUILD_LOC:=$(shell cygpath -m --absolute $(subst \,/,$(CY_BUILD_LOC))) +ifneq ($(CY_BUILD_LOCATION),) +CY_INTERNAL_BUILD_LOCATION:=$(shell cygpath -m --absolute $(subst \,/,$(CY_BUILD_LOCATION))) +endif +ifneq ($(CY_DEVICESUPPORT_PATH),) +CY_INTERNAL_DEVICESUPPORT_PATH:=$(shell cygpath -m --absolute $(subst \,/,$(CY_DEVICESUPPORT_PATH))) +endif + +# +# Other Windows environments +# +else +CY_INTERNAL_BUILD_LOC:=$(subst \,/,$(CY_BUILD_LOC)) +CY_INTERNAL_BUILD_LOCATION:=$(subst \,/,$(CY_BUILD_LOCATION)) +CY_INTERNAL_DEVICESUPPORT_PATH:=$(abspath $(subst \,/,$(CY_DEVICESUPPORT_PATH))) +endif + +# +# Linux and macOS paths +# +else +CY_INTERNAL_BUILD_LOC:=$(CY_BUILD_LOC) +CY_INTERNAL_BUILD_LOCATION:=$(CY_BUILD_LOCATION) +CY_INTERNAL_DEVICESUPPORT_PATH:=$(abspath $(CY_DEVICESUPPORT_PATH)) +endif + +# +# Build directories +# +CY_RECIPE_DIR=$(CY_INTERNAL_BUILD_LOC) +CY_BUILDTARGET_DIR=$(CY_RECIPE_DIR)/$(TARGET) +CY_CONFIG_DIR=$(CY_BUILDTARGET_DIR)/$(CONFIG) +CY_GENERATED_DIR=$(CY_BUILDTARGET_DIR)/generated + +# +# Default toolchain locations +# +CY_COMPILER_GCC_ARM_DEFAULT_DIR=$(CY_COMPILER_DEFAULT_DIR) +CY_COMPILER_IAR_DEFAULT_DIR="C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.2/arm" +CY_COMPILER_ARM_DEFAULT_DIR="C:/Program Files/ARMCompiler6.11" +CY_COMPILER_A_Clang_DEFAULT_DIR=/Library/Developer/CommandLineTools/usr/lib/clang/10.0.0 + +# +# Toolchain locations +# +CY_COMPILER_GCC_ARM_DIR?=$(CY_COMPILER_GCC_ARM_DEFAULT_DIR) +CY_COMPILER_IAR_DIR?=$(CY_COMPILER_IAR_DEFAULT_DIR) +CY_COMPILER_ARM_DIR?=$(CY_COMPILER_ARM_DEFAULT_DIR) +CY_COMPILER_A_Clang_DIR?=$(CY_COMPILER_A_Clang_DEFAULT_DIR) + + +################################################################################ +# User-facing make targets +################################################################################ + +CY_HELP_all=Same as build. i.e. Builds the application. +all: build + +CY_HELP_getlibs=Clones the repositories, and checks out the identified commit. +getlibs: + +CY_HELP_build=Builds the application. +build: app memcalc + +CY_HELP_qbuild=Builds the application using the previous build's source list. +qbuild: app memcalc + +CY_HELP_program=Builds the application and programs it to the target device. +program: + +CY_HELP_qprogram=Programs a built application to the target device without rebuilding. +qprogram: + +CY_HELP_debug=Builds and programs. Then launches a GDB server. +debug: + +CY_HELP_qdebug=Skips the build and program step. Launches a GDB server. +qdebug: + +CY_HELP_clean=Cleans the /build/ directory. +clean: shared_libs + rm -rf $(CY_BUILDTARGET_DIR) + +# Note: Define the help target in BSP/recipe for custom help +CY_HELP_help=Prints the help documentation. +help: help_default + +CY_HELP_open=Opens/launches a specified tool. +open: + +CY_HELP_config=Runs the configurator on the target .modus file. +config: + +CY_HELP_config_bt=Runs the bt-configurator on the target .cybt file. +config_bt: + +CY_HELP_config_usbdev=Runs the usbdev-configurator on the target .cyusbdev file. +config_usbdev: + + +################################################################################ +# Include make files +################################################################################ + +# Make a decision on including logic pertinent to builds. +# If it's not any of these targets, then it's an actual build. +CY_COMMENCE_BUILD=false +ifneq ($(findstring clean,$(MAKECMDGOALS)),clean) +ifneq ($(findstring qprogram,$(MAKECMDGOALS)),qprogram) +ifneq ($(findstring qdebug,$(MAKECMDGOALS)),qdebug) +ifneq ($(findstring erase,$(MAKECMDGOALS)),erase) +ifneq ($(findstring attach,$(MAKECMDGOALS)),attach) +ifneq ($(findstring eclipse,$(MAKECMDGOALS)),eclipse) +ifneq ($(findstring check,$(MAKECMDGOALS)),check) +ifneq ($(findstring get_env_info,$(MAKECMDGOALS)),get_env_info) +ifneq ($(findstring get_app_info,$(MAKECMDGOALS)),get_app_info) +ifneq ($(findstring help,$(MAKECMDGOALS)),help) +# Note: covers config config_bt and config_usbdev +ifneq ($(findstring config,$(MAKECMDGOALS)),config) +ifneq ($(findstring open,$(MAKECMDGOALS)),open) +CY_COMMENCE_BUILD=true +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif + +ifeq ($(CY_COMMENCE_BUILD),true) +$(info ) +$(info Initializing build: $(APPNAME)$(LIBNAME) $(CONFIG) $(TARGET) $(TOOLCHAIN)) +ifeq ($(wildcard $(CY_INTERNAL_BASELIB_PATH)),) +$(info ) +$(error Cannot find the base library. Run "make getlibs" and/or check\ +that the library location is correct in the CY_BASELIB_PATH variable) +endif +endif + +# +# Include utilities used by all make files +# +include $(CY_BASELIB_CORE_PATH)/make/core/utils.mk + +# +# Include any extra makefiles defined by app +# +include $(CY_EXTRA_INCLUDES) + +# +# Find the target and check that the device is valid +# +include $(CY_BASELIB_CORE_PATH)/make/core/target.mk +-include $(CY_INTERNAL_BASELIB_PATH)/make/udd/features.mk +include $(CY_INTERNAL_BASELIB_PATH)/make/recipe/defines.mk + +# +# Check if the user-data is correct +# +ifneq ($(APPNAME),) +ifneq ($(LIBNAME),) +$(error An application cannot define both APPNAME and LIBNAME. Define one or the other) +endif +endif +ifneq ($(findstring -I,$(INCLUDES)),) +$(error INCLUDES must be directories without -I prepended) +endif +ifneq ($(findstring -D,$(DEFINES)),) +$(error DEFINES must be specified without -D prepended) +endif +ifneq ($(findstring -I,$(CFLAGS)),) +$(error Include paths must be specified in the INCLUDES variable instead\ +of directly in CFLAGS. These must be directories without -I prepended) +endif +ifneq ($(findstring -D,$(CFLAGS)),) +$(error Defines must be specified in the DEFINES variable instead\ +of directly in CFLAGS. These must be specified without -D prepended) +endif +ifneq ($(findstring -I,$(CXXFLAGS)),) +$(error Include paths must be specified in the INCLUDES variable instead\ +of directly in CXXFLAGS. These must be directories without -I prepended) +endif +ifneq ($(findstring -D,$(CXXFLAGS)),) +$(error Defines must be specified in the DEFINES variable instead\ +of directly in CXXFLAGS. These must be specified without -D prepended) +endif +ifneq ($(findstring -I,$(ASFLAGS)),) +$(error Include paths must be specified in the INCLUDES variable instead\ +of directly in ASFLAGS. These must be directories without -I prepended) +endif +ifneq ($(findstring -D,$(ASFLAGS)),) +$(error Defines must be specified in the DEFINES variable instead\ +of directly in ASFLAGS. These must be specified without -D prepended) +endif + +# +# Choose local or default toolchain makefile +# +ifeq ($(TOOLCHAIN_MK_PATH),) +include $(CY_INTERNAL_BASELIB_PATH)/make/toolchains/$(TOOLCHAIN).mk +else +# Include the custom app-specific toolchain file +include $(TOOLCHAIN_MK_PATH) +endif + +# +# Configurator-related routines +# +ifeq ($(CY_SKIP_CONFIGURATOR),) +include $(CY_BASELIB_CORE_PATH)/make/core/config.mk +endif + +# +# Build-related routines +# +ifeq ($(CY_COMMENCE_BUILD),true) + +ifneq ($(findstring qbuild,$(MAKECMDGOALS)),qbuild) +include $(CY_BASELIB_CORE_PATH)/make/core/search.mk +else +# Skip the auto-discovery and re-use the last build's source list +-include $(CY_CONFIG_DIR)/cyqbuild.mk +CY_QBUILD=$(shell if [ -f $(CY_CONFIG_DIR)/cyqbuild.mk ]; then echo "true"; fi;) +ifneq ($(CY_QBUILD),true) +$(info WARNING: Cannot find the auto-discovery make file. Run "make build" to generate it.) +endif +endif + +include $(CY_INTERNAL_BASELIB_PATH)/make/recipe/recipe.mk + +ifneq ($(findstring vscode,$(MAKECMDGOALS)),vscode) +include $(CY_BASELIB_CORE_PATH)/make/core/build.mk +endif + +endif + +# +# Optional recipe-specific program routine +# +ifndef CY_BSP_PROGRAM +-include $(CY_INTERNAL_BASELIB_PATH)/make/recipe/program.mk +endif + +# +# Launch tools +# +-include $(CY_INTERNAL_TOOLS)/make/tools.mk +include $(CY_BASELIB_CORE_PATH)/make/core/open.mk + +# +# Help documentation +# +include $(CY_BASELIB_CORE_PATH)/make/core/help.mk + +# +# Identify the phony targets +# +.PHONY: all build qbuild getlibs clean program quickprogram help +.PHONY: app memcalc diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/open.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/open.mk new file mode 100644 index 0000000000..6be2460f2d --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/open.mk @@ -0,0 +1,126 @@ +################################################################################ +# \file open.mk +# \version 1.0 +# +# \brief +# Opens/launches a specified tool +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +# Verify that the tool is supported +ifneq ($(CY_OPEN_TYPE),) +ifeq ($(filter $(CY_OPEN_TYPE),$(CY_OPEN_TYPE_LIST)),) +$(error Unsupported tool type - $(CY_OPEN_TYPE). $(CY_NEWLINE)Supported types are: $(CY_OPEN_TYPE_LIST)) +endif +endif + +# Extension construction from given file +ifneq ($(CY_OPEN_FILE)),) +CY_OPEN_EXT=$(subst .,,$(suffix $(CY_OPEN_FILE))) +endif + + +################################################################################ +# New configurations +################################################################################ + +# Limit this as it can be a performance hit +ifneq ($(filter get_app_info open,$(MAKECMDGOALS)),) + +# Look for tools that DISALLOW new configurations +CY_OPEN_NEWCFG_XML_TYPES+=$(shell \ + xmlFileArray=($$(find $(CY_INTERNAL_TOOLS) -maxdepth 2 -name "configurator.xml" \ + -exec grep "false" {} +));\ + for xmlFile in "$${xmlFileArray[@]}"; do\ + if [[ "$$xmlFile" == *"configurator.xml"* ]]; then\ + toolNameDir="$${xmlFile%/*}";\ + toolName="$${toolNameDir\#\#*/}";\ + echo "$$toolName";\ + fi;\ + done;\ +) + +endif + +# Tools for existing files +CY_OPEN_NEWCFG_EXISTING_TYPES=$(foreach ext,$(subst .,,$(suffix $(CY_CONFIG_FILES))),$($(addsuffix _DEFAULT_TYPE,$(ext)))) +# Tools that do not have an existing file +CY_OPEN_NEWCFG_POSSIBLE_TYPES=$(filter-out $(CY_OPEN_NEWCFG_EXISTING_TYPES) $(CY_OPEN_NEWCFG_XML_TYPES),$(CY_SUPPORTED_TOOL_TYPES)) +# Complete list of supported files +CY_OPEN_FILTERED_SUPPORTED_TYPES=$(sort $(CY_OPEN_NEWCFG_POSSIBLE_TYPES) $(CY_OPEN_NEWCFG_EXISTING_TYPES)) + + +################################################################################ +# Prepare tool launch +################################################################################ + +# Only file is given. Use the default type for that file extension +ifneq ($(CY_OPEN_FILE),) +ifeq ($(CY_OPEN_TYPE),) +CY_OPEN_TYPE=$(firstword $($(CY_OPEN_EXT)_DEFAULT_TYPE)) +endif +endif + +# Set the tool and its arguments +CY_OPEN_TOOL_FILE=$(CY_OPEN_$(subst -,_,$(CY_OPEN_TYPE))_FILE) +CY_OPEN_TOOL_LAUNCH=$(CY_OPEN_$(subst -,_,$(CY_OPEN_TYPE))_TOOL) +CY_OPEN_TOOL_FLAGS=$(CY_OPEN_$(subst -,_,$(CY_OPEN_TYPE))_TOOL_FLAGS) +CY_OPEN_TOOL_ARGS=$(CY_OPEN_$(subst -,_,$(CY_OPEN_TYPE))_TOOL_ARGS) +CY_OPEN_TOOL_NEWCFG_FLAGS=$(CY_OPEN_$(subst -,_,$(CY_OPEN_TYPE))_TOOL_NEWCFG_FLAGS) + +# Use the file if provided +ifneq ($(CY_OPEN_FILE),) +CY_OPEN_TOOL_FILE=$(CY_OPEN_FILE) +endif + +ifneq ($(CY_MAKE_IDE),) +CY_OPEN_STDOUT=>& /dev/null +endif + + +################################################################################ +# Tool launch target +################################################################################ + +open: +ifeq ($(CY_OPEN_FILE),) +ifeq ($(CY_OPEN_TYPE),) + $(error Neither tool type or file specified to launch a tool) +endif +endif +ifeq ($(CY_OPEN_TOOL_LAUNCH),) + $(error Unable to find a default tool to launch .$(CY_OPEN_EXT) file extension) +endif +ifeq ($(CY_OPEN_TOOL_FILE),) + $(info Launching $(notdir $(CY_OPEN_TOOL_LAUNCH)) tool for a new configuration) + $(CY_NOISE) $(CY_OPEN_TOOL_LAUNCH) $(CY_OPEN_TOOL_ARGS) $(CY_OPEN_TOOL_NEWCFG_FLAGS) $(CY_OPEN_STDOUT) & +else + $(info $(CY_NEWLINE)Launching $(notdir $(CY_OPEN_TOOL_LAUNCH)) tool on $(CY_OPEN_TOOL_FILE)) + $(CY_NOISE) $(CY_OPEN_TOOL_LAUNCH) $(CY_OPEN_TOOL_ARGS) $(CY_OPEN_TOOL_FLAGS) $(CY_OPEN_TOOL_FILE) $(CY_OPEN_STDOUT) & +endif + +# +# Identify the phony targets +# +.PHONY: open diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/search.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/search.mk new file mode 100644 index 0000000000..5e11ec073b --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/search.mk @@ -0,0 +1,158 @@ +################################################################################ +# \file search.mk +# \version 1.0 +# +# \brief +# Performs auto-discovery of files in the project directories. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +################################################################################ +# Search Files +################################################################################ + +$(info ) +$(info Auto-discovery in progress...) + +# +# Search for files. Use := assignment for better performance. Need to look in both project and shared lib. +# +CY_SEARCH_ALL_FILES:=$(sort $(shell $(CY_FIND) -L $(CY_INTERNAL_APP_PATH) $(CY_INTERNAL_EXTAPP_PATH) \ + \( $(CY_IGNORE_PRUNE) \) -prune \ + -o -type f -name "*.$(CY_TOOLCHAIN_SUFFIX_C)" -print \ + -o -type f -name "*.$(CY_TOOLCHAIN_SUFFIX_S)" -print \ + -o -type f -name "*.$(CY_TOOLCHAIN_SUFFIX_s)" -print \ + -o -type f -name "*.$(CY_TOOLCHAIN_SUFFIX_CPP)" -print \ + -o -type f -name "*.$(CY_TOOLCHAIN_SUFFIX_O)" -print \ + -o -type f -name "*.$(CY_TOOLCHAIN_SUFFIX_A)" -print \ + -o -type f -name "*.$(CY_TOOLCHAIN_SUFFIX_H)" -print \ + -o -type f -name "*.$(CY_TOOLCHAIN_SUFFIX_HPP)" -print \ + -o -type d -name "COMPONENT_RESOURCE" -print \ + -o -type d -name "* *" -print)) + +CY_SEARCH_C_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_C),$(CY_SEARCH_ALL_FILES)) +CY_SEARCH_S_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_S),$(CY_SEARCH_ALL_FILES)) +CY_SEARCH_s_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_s),$(CY_SEARCH_ALL_FILES)) +CY_SEARCH_CPP_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_CPP),$(CY_SEARCH_ALL_FILES)) +CY_SEARCH_O_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_O),$(CY_SEARCH_ALL_FILES)) +CY_SEARCH_A_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_A),$(CY_SEARCH_ALL_FILES)) +CY_SEARCH_H_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_H),$(CY_SEARCH_ALL_FILES)) +CY_SEARCH_HPP_FILES=$(filter %.$(CY_TOOLCHAIN_SUFFIX_HPP),$(CY_SEARCH_ALL_FILES)) + +# +# Search for resource directories and gather the files +# +CY_SEARCH_RESOURCE_DIR=$(filter %/COMPONENT_RESOURCE,$(CY_SEARCH_ALL_FILES)) +CY_SEARCH_RESOURCE_FILES=$(foreach dir,$(CY_SEARCH_RESOURCE_DIR),$(wildcard $(dir)/*)) + +# +# Check that the directories do not contain spaces +# +CY_SEARCH_EMPTY_DIRS=$(filter-out $(CY_SEARCH_C_FILES) $(CY_SEARCH_S_FILES) $(CY_SEARCH_s_FILES) $(CY_SEARCH_CPP_FILES)\ + $(CY_SEARCH_O_FILES) $(CY_SEARCH_A_FILES) $(CY_SEARCH_H_FILES) $(CY_SEARCH_HPP_FILES)\ + $(CY_SEARCH_RESOURCE_DIR),$(CY_SEARCH_ALL_FILES)) + +# +# Print the number of discovered files +# +ifneq ($(CY_SEARCH_EMPTY_DIRS),) +$(error The application must not contain spaces in the paths. Detected dir(s): $(CY_SEARCH_EMPTY_DIRS)) +else +$(info -> Found $(words $(CY_SEARCH_C_FILES)) .$(CY_TOOLCHAIN_SUFFIX_C) file(s)) +$(info -> Found $(words $(CY_SEARCH_S_FILES)) .$(CY_TOOLCHAIN_SUFFIX_S) file(s)) +$(info -> Found $(words $(CY_SEARCH_s_FILES)) .$(CY_TOOLCHAIN_SUFFIX_s) file(s)) +$(info -> Found $(words $(CY_SEARCH_CPP_FILES)) .$(CY_TOOLCHAIN_SUFFIX_CPP) file(s)) +$(info -> Found $(words $(CY_SEARCH_O_FILES)) .$(CY_TOOLCHAIN_SUFFIX_O) file(s)) +$(info -> Found $(words $(CY_SEARCH_A_FILES)) .$(CY_TOOLCHAIN_SUFFIX_A) file(s)) +$(info -> Found $(words $(CY_SEARCH_H_FILES)) .$(CY_TOOLCHAIN_SUFFIX_H) file(s)) +$(info -> Found $(words $(CY_SEARCH_HPP_FILES)) .$(CY_TOOLCHAIN_SUFFIX_HPP) file(s)) +$(info -> Found $(words $(CY_SEARCH_RESOURCE_FILES)) resource file(s)) +endif + + +################################################################################ +# Filter lists +################################################################################ + +$(info Applying filters...) + +# +# Apply the filtering for files in .cyignore +# +CY_SEARCH_PRUNED_C_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_FILES),$(filter $(d)%,$(CY_SEARCH_C_FILES))),$(CY_SEARCH_C_FILES)) +CY_SEARCH_PRUNED_S_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_FILES),$(filter $(d)%,$(CY_SEARCH_S_FILES))),$(CY_SEARCH_S_FILES)) +CY_SEARCH_PRUNED_s_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_FILES),$(filter $(d)%,$(CY_SEARCH_s_FILES))),$(CY_SEARCH_s_FILES)) +CY_SEARCH_PRUNED_CPP_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_FILES),$(filter $(d)%,$(CY_SEARCH_CPP_FILES))),$(CY_SEARCH_CPP_FILES)) +CY_SEARCH_PRUNED_O_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_FILES),$(filter $(d)%,$(CY_SEARCH_O_FILES))),$(CY_SEARCH_O_FILES)) +CY_SEARCH_PRUNED_A_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_FILES),$(filter $(d)%,$(CY_SEARCH_A_FILES))),$(CY_SEARCH_A_FILES)) +CY_SEARCH_PRUNED_H_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_FILES),$(filter $(d)%,$(CY_SEARCH_H_FILES))),$(CY_SEARCH_H_FILES)) +CY_SEARCH_PRUNED_HPP_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_FILES),$(filter $(d)%,$(CY_SEARCH_HPP_FILES))),$(CY_SEARCH_HPP_FILES)) + +# +# Apply the COMPONENT and configuration filtering +# +CY_SEARCH_AVAILABLE_C_SOURCES=$(call CY_MACRO_FILTER_FILES,C) +CY_SEARCH_AVAILABLE_S_SOURCES=$(call CY_MACRO_FILTER_FILES,S) +CY_SEARCH_AVAILABLE_s_SOURCES=$(call CY_MACRO_FILTER_FILES,s) +CY_SEARCH_AVAILABLE_CPP_SOURCES=$(call CY_MACRO_FILTER_FILES,CPP) +CY_SEARCH_AVAILABLE_O_SOURCES=$(call CY_MACRO_FILTER_FILES,O) +CY_SEARCH_AVAILABLE_A_LIBS=$(call CY_MACRO_FILTER_FILES,A) + +CY_SEARCH_AVAILABLE_H_INCLUDES=$(sort $(call CY_MACRO_DIR,$(call CY_MACRO_FILTER_FILES,H))) +CY_SEARCH_AVAILABLE_HPP_INCLUDES=$(sort $(call CY_MACRO_DIR,$(call CY_MACRO_FILTER_FILES,HPP))) + +# +# Combine the directories of the header files and its parent directories +# +CY_SEARCH_AVAILABLE_INCLUDES=\ + $(CY_SEARCH_AVAILABLE_H_INCLUDES)\ + $(call CY_MACRO_SEARCH_PARENT,$(CY_SEARCH_AVAILABLE_H_INCLUDES))\ + $(CY_SEARCH_AVAILABLE_HPP_INCLUDES)\ + $(call CY_MACRO_SEARCH_PARENT,$(CY_SEARCH_AVAILABLE_HPP_INCLUDES))\ + +# Conditionally add the generated source includes +ifneq ($(CY_SEARCH_RESOURCE_FILES),) +CY_SEARCH_AVAILABLE_INCLUDES+=$(CY_GENERATED_DIR) +endif + +# +# Add to the list +# +CY_SEARCH_APP_SOURCE=$(sort $(CY_SEARCH_AVAILABLE_S_SOURCES) $(CY_SEARCH_AVAILABLE_s_SOURCES)\ + $(CY_SEARCH_AVAILABLE_C_SOURCES) $(CY_SEARCH_AVAILABLE_CPP_SOURCES)) +CY_SEARCH_APP_LIBS=$(sort $(CY_SEARCH_AVAILABLE_O_SOURCES) $(CY_SEARCH_AVAILABLE_A_LIBS)) +CY_SEARCH_APP_INCLUDES=$(sort $(CY_SEARCH_AVAILABLE_INCLUDES)) + +# +# Create cyqbuild makefile +# +$(shell \ +mkdir -p $(CY_CONFIG_DIR); \ +echo "CY_COMPONENT_LIST:=$(CY_COMPONENT_LIST)" > $(CY_CONFIG_DIR)/cyqbuild.mk; \ +echo "CY_SEARCH_APP_SOURCE:=$(CY_SEARCH_APP_SOURCE)" >> $(CY_CONFIG_DIR)/cyqbuild.mk; \ +echo "CY_SEARCH_APP_LIBS:=$(CY_SEARCH_APP_LIBS)" >> $(CY_CONFIG_DIR)/cyqbuild.mk; \ +echo "CY_SEARCH_APP_INCLUDES:=$(CY_SEARCH_APP_INCLUDES)" >> $(CY_CONFIG_DIR)/cyqbuild.mk; \ +) + +$(info Auto-discovery complete) diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/target.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/target.mk new file mode 100644 index 0000000000..5c005cc1c0 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/target.mk @@ -0,0 +1,79 @@ +################################################################################ +# \file target.mk +# \version 1.0 +# +# \brief +# Finds available targets in the design. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +# +# Search for target make files and BSPs. Use := assignment for better performance. +# +CY_TARGET_MAKEFILE_SEARCH:=$(call CY_MACRO_SEARCH,$(TARGET).mk,$(CY_INTERNAL_APP_PATH))\ + $(if $(CY_INTERNAL_EXTAPP_PATH),$(call CY_MACRO_SEARCH,$(TARGET).mk,$(CY_INTERNAL_EXTAPP_PATH)))\ + $(if $(SEARCH_LIBS_AND_INCLUDES),$(foreach d,$(SEARCH_LIBS_AND_INCLUDES),$(call CY_MACRO_SEARCH,$(TARGET).mk,$(d)))) +CY_TARGET_AVAILABLE_SEARCH:=$(call CY_MACRO_SEARCH,.mk,$(CY_INTERNAL_APP_PATH))\ + $(if $(CY_INTERNAL_EXTAPP_PATH),$(call CY_MACRO_SEARCH,.mk,$(CY_INTERNAL_EXTAPP_PATH)))\ + $(if $(SEARCH_LIBS_AND_INCLUDES),$(foreach d,$(SEARCH_LIBS_AND_INCLUDES),$(call CY_MACRO_SEARCH,.mk,$(d))))\ + +# Gather and filter the found files +CY_SEARCH_PRUNED_MAKE_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_DIRS),$(filter $(d)%,$(CY_TARGET_MAKEFILE_SEARCH))),$(CY_TARGET_MAKEFILE_SEARCH)) +CY_SEARCH_PRUNED_AVAILABLEMAKE_FILES:=$(filter-out $(foreach d,$(CY_IGNORE_DIRS),$(filter $(d)%,$(CY_TARGET_AVAILABLE_SEARCH))),$(CY_TARGET_AVAILABLE_SEARCH)) + +# Target makefile +CY_TARGET_MAKEFILE=$(call CY_MACRO_FILTER_FILES,MAKE) + +# Check if the TARGET.mk was brought in through CY_EXTRA_INCLUDES or directly in the app makefile +CY_TARGET_EXTRA_INCLUDES=$(filter %/$(TARGET).mk,$(MAKEFILE_LIST)) +CY_TARGET_EXTRA_FILTERED=$(filter-out $(CY_TARGET_EXTRA_INCLUDES),$(CY_TARGET_MAKEFILE)) + +# Full list of available targets +CY_TARGET_AVAILABLE_DIRS=$(notdir $(call CY_MACRO_DIR,$(CY_SEARCH_PRUNED_AVAILABLEMAKE_FILES) $(CY_TARGET_EXTRA_INCLUDES))) +CY_TARGET_AVAILABLE=$(sort $(subst TARGET_,,$(foreach item,$(CY_TARGET_AVAILABLE_DIRS),$(if $(findstring /TARGET_,/$(item)),$(item),)))) + +# +# Set the target makefile and directory +# +ifneq ($(CY_TARGET_EXTRA_INCLUDES),) + +ifneq ($(CY_TARGET_EXTRA_FILTERED),) +$(call CY_MACRO_ERROR,Found multiple identical targets: $(CY_TARGET_EXTRA_INCLUDES) $(CY_TARGET_EXTRA_FILTERED)) +else +CY_TARGET_DIR=$(call CY_MACRO_DIR,$(CY_TARGET_EXTRA_INCLUDES)) +endif + +else + +ifeq ($(words $(CY_TARGET_MAKEFILE)),0) +$(info Available target(s): $(CY_TARGET_AVAILABLE)) +$(call CY_MACRO_ERROR,Target "$(TARGET)" not found) +else ifeq ($(words $(CY_TARGET_MAKEFILE)),1) +CY_TARGET_DIR=$(call CY_MACRO_DIR,$(CY_TARGET_MAKEFILE)$(CY_TARGET_MAKEFILE_SEARCH_LIBS)) +include $(CY_TARGET_MAKEFILE) $(CY_TARGET_MAKEFILE_SEARCH_LIBS) +else +$(call CY_MACRO_ERROR,Found multiple identical targets:$(CY_TARGET_MAKEFILE)) +endif + +endif diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/utils.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/utils.mk new file mode 100644 index 0000000000..16b3a6413a --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/core/utils.mk @@ -0,0 +1,358 @@ +################################################################################ +# \file utils.mk +# \version 1.0 +# +# \brief +# Global utilities used across the application recipes and BSPs +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +################################################################################ +# Components +################################################################################ + +# +# VFP-specific component +# +ifeq ($(VFP_SELECT),hardfp) +CY_COMPONENT_VFP=HARDFP +else +CY_COMPONENT_VFP=SOFTFP +endif + +# +# Component list +# +CY_COMPONENT_LIST_DEFAULT=$(CORE) $(CY_COMPONENT_VFP) $(COMPONENTS) +# Note: CY_DEFAULT_COMPONENT is needed as DISABLE_COMPONENTS cannot be empty +DISABLE_COMPONENTS+=CY_DEFAULT_COMPONENT +CY_COMPONENT_LIST?=$(sort $(filter-out $(DISABLE_COMPONENTS),$(CY_COMPONENT_LIST_DEFAULT))) + + +################################################################################ +# Utility variables +################################################################################ + +# Create a make variable that contains a space +CY_SPACE= +CY_SPACE+= + +# Create a make variable that contains a soft tab +CY_INDENT=$(CY_SPACE)$(CY_SPACE)$(CY_SPACE)$(CY_SPACE) + +# Create a make variable that contains a line break +define CY_NEWLINE + + +endef + +# Create a make variable that contains a comma +CY_COMMA=, + +# Displays/Hides the build steps +ifneq (,$(filter $(VERBOSE),true 1)) +CY_NOISE= +CY_CMD_TERM= +else +CY_NOISE=@ +CY_CMD_TERM= > /dev/null 2>&1 +endif + +# Set the location of the find utility (Avoid conflict with Windows system32/find.exe) +CY_QUERY_FIND=$(findstring /usr/bin/find,$(shell whereis find)) +ifeq ($(CY_QUERY_FIND),) +CY_FIND=find +else +CY_FIND=/usr/bin/find +endif + +# +# Prints for bypassing TARGET/DEVICE checks +# $(1) : String to print +# +ifeq ($(CY_COMMENCE_BUILD),true) +CY_MACRO_ERROR=$(error $(1)) +else +CY_MACRO_ERROR=$(info WARNING: $(1)) +endif + + +################################################################################ +# Search macros +################################################################################ + +# +# Macros to find all COMPONENTS not listed in the component list. +# Step 1: Find all COMPONENT directories in app +# Step 2: Process the list and get a list of all COMPONENTS +# Step 3: Compare the found COMPONENTS with the expected components list +# +# $(1): List of files of a certain file type +# +CY_MACRO_FIND_COMPONENTS=$(strip $(foreach item,$(1),$(if $(findstring /COMPONENT_,/$(item)),$(item),))) +CY_MACRO_PROCESS_COMPONENTS=\ +$(foreach item,$(1),\ + $(if $(findstring /COMPONENT_,/$(notdir $(item))),$(subst COMPONENT_,,$(notdir $(item))),)\ + $(if $(call CY_MACRO_EQUALITY,$(CY_INTERNAL_APP_PATH),$(item)),,$(call CY_MACRO_PROCESS_COMPONENTS,$(call CY_MACRO_DIR,$(item))))\ +) +CY_MACRO_COMPARE_COMPONENTS=$(filter-out $(CY_COMPONENT_LIST),$(sort $(call CY_MACRO_PROCESS_COMPONENTS,$(call CY_MACRO_FIND_COMPONENTS,$(1))))) + +# +# Filters for components. Iterates through CY_COMPONENT_LIST +# $(1) : List of files of a certain file type +# +CY_MACRO_MATCH_COMPONENT=$(sort $(foreach component,$(2),\ + $(foreach item,$(1),$(if $(findstring /COMPONENT_$(component)/,/$(item)/),$(item),)))) +CY_MACRO_GET_COMPONENT=$(filter-out \ + $(call CY_MACRO_MATCH_COMPONENT,$(1),$(call CY_MACRO_COMPARE_COMPONENTS,$(1))),\ + $(call CY_MACRO_MATCH_COMPONENT,$(1),$(CY_COMPONENT_LIST))) +CY_MACRO_REMOVE_COMPONENT=$(strip $(foreach item,$(1),$(if $(findstring /COMPONENT_,/$(item)),,$(item)))) +CY_MACRO_FILTER_COMPONENT=$(call CY_MACRO_REMOVE_COMPONENT,$(1)) $(call CY_MACRO_GET_COMPONENT,$(1)) + +# +# Filters for configurations +# $(1) : List of files of a certain file type +# $(2) : Filter string +# +CY_MACRO_MATCH_CONFIGURATION=$(strip $(foreach item,$(1),$(if $(findstring $(2),/$(item)/),$(item),))) +CY_MACRO_REMOVE_CONFIGURATION=$(strip $(foreach item,$(1),$(if $(findstring $(2),/$(item)),,$(item)))) +CY_MACRO_FILTER_CONFIGURATION=$(call CY_MACRO_REMOVE_CONFIGURATION,$(1),/$(strip $(2))_)\ + $(call CY_MACRO_MATCH_CONFIGURATION,$(1),/$(strip $(2))_$($(strip $(2)))/) + +# +# Filter for defined components and configurations +# $(1) : List of files of a certain file type +# +CY_MACRO_FILTER=\ + $(strip \ + $(call CY_MACRO_FILTER_COMPONENT,\ + $(call CY_MACRO_FILTER_CONFIGURATION,\ + $(call CY_MACRO_FILTER_CONFIGURATION,\ + $(call CY_MACRO_FILTER_CONFIGURATION,\ + $(1),\ + TOOLCHAIN),\ + TARGET),\ + CONFIG))) + +# +# Search for files +# $(1) : File type +# +CY_MACRO_FILTER_FILES=$(call CY_MACRO_FILTER,$(CY_SEARCH_PRUNED_$(1)_FILES)) + +# +# Test for equality +# $(1) : Base path +# $(2) : Directory containing header file +# +CY_MACRO_EQUALITY=$(if $(and $(findstring $1,$2),$(findstring $2,$1)),TRUE) + +# +# Recursively search for the parent directories up to the project root directory +# $(1) : Directories containing header files +# +CY_MACRO_SEARCH_PARENT=\ +$(foreach item,$(1),\ + $(if $(call CY_MACRO_EQUALITY,.,$(item)),\ + .\ + ,\ + $(call CY_MACRO_DIR,$(item))\ + $(call CY_MACRO_SEARCH_PARENT,$(call CY_MACRO_DIR,$(item)))\ + )\ +) + +# +# Convert to lower case +# $(1) : String to convert to lower case +# +CY_MACRO_LC=$(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst \ + H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst \ + Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst \ + W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) + +# +# Convert to upper case +# $(1) : String to convert to upper case +# +CY_MACRO_UC=$(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst \ + h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst \ + q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst \ + w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1)))))))))))))))))))))))))) + + +################################################################################ +# IDE-specifc targets +################################################################################ + +CY_VSCODE_OUT_PATH=$(CY_INTERNAL_APP_PATH)/.vscode +CY_VSCODE_OUT_TEMPLATE_PATH=$(CY_VSCODE_OUT_PATH)/cytemplates +CY_VSCODE_BACKUP_PATH=$(CY_VSCODE_OUT_PATH)/backup +CY_VSCODE_TEMPLATE_PATH=$(CY_INTERNAL_BASELIB_PATH)/make/scripts/vscode +CY_VSCODE_TEMPFILE=$(CY_CONFIG_DIR)/vscode_launch.temp + +CY_ECLIPSE_OUT_PATH=$(CY_INTERNAL_APP_PATH)/.mtbLaunchConfigs +CY_ECLIPSE_TEMPLATE_PATH=$(CY_INTERNAL_BASELIB_PATH)/make/scripts/eclipse +CY_ECLIPSE_TEMPFILE=$(CY_CONFIG_DIR)/eclipse_launch.temp +CY_ECLIPSE_TEMPLATES_WILDCARD?=* + +ifeq ($(CY_IDE_PRJNAME),) +CY_IDE_PRJNAME=$(APPNAME) +endif + +vscode: +ifeq ($(LIBNAME),) + @mkdir -p $(CY_CONFIG_DIR);\ + mkdir -p $(CY_VSCODE_OUT_TEMPLATE_PATH);\ + mkdir -p $(CY_VSCODE_BACKUP_PATH);\ + echo $(CY_VSCODE_ARGS) > $(CY_VSCODE_TEMPFILE);\ + echo "s|&&JSONINCLUDELIST&&|$(foreach onedef,$(subst -I,,$(CY_RECIPE_INCLUDES)),\"$(onedef)\",)|" >> $(CY_VSCODE_TEMPFILE);\ + echo "s|&&JSONDEFINELIST&&|$(foreach onedef,$(subst -D,,$(CY_RECIPE_DEFINES)),\"$(onedef)\",)|" >> $(CY_VSCODE_TEMPFILE);\ + for json in $(CY_VSCODE_TEMPLATE_PATH)/*; do\ + jsonFile="$${json##*/}";\ + if [[ $$jsonFile == *"c_cpp_properties"* ]] && [[ $$jsonFile != *"c_cpp_properties_$(TOOLCHAIN).json" ]]; then\ + continue;\ + fi;\ + sed -f $(CY_VSCODE_TEMPFILE) $(CY_VSCODE_TEMPLATE_PATH)/$$jsonFile > $(CY_VSCODE_OUT_TEMPLATE_PATH)/$$jsonFile;\ + jsonFiles="$$jsonFiles $$jsonFile";\ + if [ -f $(CY_VSCODE_OUT_PATH)/$$jsonFile ] && [[ $$jsonFile == *"settings.json" ]]; then\ + echo "Modifying existing settings.json file";\ + mv $(CY_VSCODE_OUT_PATH)/$$jsonFile $(CY_VSCODE_BACKUP_PATH)/$$jsonFile;\ + sed \ + -e /cortex-debug\\.armToolchainPath/s%:.*%:\ \"$(CY_COMPILER_DIR)/bin\",% \ + -e /cortex-debug\\.openocdPath/s%:.*%:\ \"$(CY_OPENOCD_DIR)/bin/openocd\",% \ + $(CY_VSCODE_BACKUP_PATH)/$$jsonFile > $(CY_VSCODE_OUT_PATH)/$$jsonFile;\ + else\ + cp $(CY_VSCODE_OUT_TEMPLATE_PATH)/$$jsonFile $(CY_VSCODE_OUT_PATH)/$$jsonFile;\ + fi;\ + done;\ + mv $(CY_VSCODE_OUT_PATH)/c_cpp_properties_$(TOOLCHAIN).json $(CY_VSCODE_OUT_PATH)/c_cpp_properties.json;\ + mv $(CY_VSCODE_OUT_PATH)/openocd.tcl $(CY_INTERNAL_APP_PATH)/openocd.tcl;\ + rm $(CY_VSCODE_TEMPFILE);\ + rm -rf $(CY_VSCODE_OUT_TEMPLATE_PATH);\ + echo;\ + echo Generated Visual Studio Code files: $$jsonFiles;\ + echo;\ + echo WARNING: The vscode target is preliminary... +else + @echo +endif + +CY_HELP_eclipse=Generates eclipse IDE launch configs. +eclipse: +ifeq ($(LIBNAME),) + @mkdir -p $(CY_CONFIG_DIR);\ + mkdir -p $(CY_ECLIPSE_OUT_PATH);\ + echo $(CY_ECLIPSE_ARGS) > $(CY_ECLIPSE_TEMPFILE);\ + for launch in $(CY_ECLIPSE_TEMPLATE_PATH)/$(CY_ECLIPSE_TEMPLATES_WILDCARD); do\ + launchFile="$${launch##*/}";\ + launchFileName="$${launchFile%.*}";\ + sed -f $(CY_ECLIPSE_TEMPFILE) "$(CY_ECLIPSE_TEMPLATE_PATH)/$$launchFileName.xml" > "$(CY_ECLIPSE_OUT_PATH)/$(CY_IDE_PRJNAME) $$launchFileName.launch";\ + launchConfigs="$$launchConfigs \"$(CY_IDE_PRJNAME) $$launchFileName.launch"\";\ + done;\ + rm $(CY_ECLIPSE_TEMPFILE);\ + echo;\ + echo Generated Eclipse launch config files: "$$launchConfigs" +else + @echo +endif + +ifneq ($(SEARCH_LIBS_AND_INCLUDES),) +CY_SHARED_ALL_LIB_FILES=$(call CY_MACRO_SEARCH,.lib,$(CY_SHARED_PATH)) +CY_SHARED_USED_LIB_NAMES=$(foreach item,$(SEARCH_LIBS_AND_INCLUDES),$(notdir $(item).lib)) +CY_SHARED_USED_LIB_FILES=$(foreach name,$(CY_SHARED_USED_LIB_NAMES),$(filter %/$(name),$(CY_SHARED_ALL_LIB_FILES))) +endif + +CY_HELP_get_app_info=Prints the app info for the eclipse IDE. +get_app_info: + @echo;\ + echo "APP_NAME=$(APPNAME)";\ + echo "LIB_NAME=$(LIBNAME)";\ + echo "TARGET=$(TARGET)";\ + echo "TARGET_DEVICE=$(DEVICE)";\ + echo "CONFIGURATOR_FILES=$(CY_CONFIG_FILES)";\ + echo "SUPPORTED_TOOL_TYPES=$(CY_OPEN_FILTERED_SUPPORTED_TYPES)";\ + echo "CY_TOOLS_PATH=$(CY_TOOLS_DIR)";\ + echo "CY_GETLIBS_PATH=$(CY_INTERNAL_GETLIBS_PATH)";\ + echo "SHAREDLIBS_ROOT=$(CY_SHARED_PATH)";\ + echo "SHAREDLIBS=$(SEARCH_LIBS_AND_INCLUDES)";\ + echo "SHAREDLIBS_FILES=$(CY_SHARED_USED_LIB_FILES)";\ + echo "CY_DEPENDENT_PROJECTS=$(CY_DEPENDENT_PROJECTS)" + + +################################################################################ +# Test/debug targets +################################################################################ + +CY_TOOLS_LIST+=bash git find ls cp mkdir rm cat sed awk perl file whereis + +CY_HELP_check=Checks for the necessary tools. +check: + $(info ) + $(foreach tool,$(CY_TOOLS_LIST),$(if $(shell which $(tool)),,$(error "$(tool) was not found in user's PATH"))) + @if [ ! -d $(CY_BT_CONFIGURATOR_DIR) ]; then toolsTest+=("bt-configurator could not be found"); fi;\ + if [ ! -d $(CY_CAPSENSE_CONFIGURATOR_DIR) ]; then toolsTest+=("capsense-configurator could not be found"); fi;\ + if [ ! -d $(CY_CFG_BACKEND_CLI_DIR) ]; then toolsTest+=("cfg-backend-cli could not be found"); fi;\ + if [ ! -d $(CY_MCUELFTOOL_DIR) ]; then toolsTest+=("cymcuelftool could not be found"); fi;\ + if [ ! -d $(CY_PE_TOOL_DIR) ]; then toolsTest+=("cype-tool could not be found"); fi;\ + if [ ! -d $(CY_DEVICE_CONFIGURATOR_DIR) ]; then toolsTest+=("device-configurator could not be found"); fi;\ + if [ ! -d $(CY_DFUH_TOOL_DIR) ]; then toolsTest+=("dfuh-tool could not be found"); fi;\ + if [ ! -d $(CY_FW_LOADER_DIR) ]; then toolsTest+=("fw-loader could not be found"); fi;\ + if [ ! -d $(CY_COMPILER_DIR) ]; then toolsTest+=("Default ARM GCC toolchain could not be found"); fi;\ + if [ ! -d $(CY_JRE_DIR) ]; then toolsTest+=("Java Runtime Environment tool could not be found"); fi;\ + if [ ! -d $(CY_LIBRARY_MANAGER_DIR) ]; then toolsTest+=("Library Manager could not be found"); fi;\ + if [ ! -d $(CY_MODUS_SHELL_DIR) ]; then toolsTest+=("modus-shell could not be found"); fi;\ + if [ ! -d $(CY_OPENOCD_DIR) ]; then toolsTest+=("openocd could not be found"); fi;\ + if [ ! -d $(CY_PROJECT_CREATOR_DIR) ]; then toolsTest+=("Project Creator could not be found"); fi;\ + if [ ! -d $(CY_QSPI_CONFIGURATOR_DIR) ]; then toolsTest+=("qspi-configurator could not be found"); fi;\ + if [ ! -d $(CY_SEGLCD_CONFIGURATOR_DIR) ]; then toolsTest+=("seglcd-configurator could not be found"); fi;\ + if [ ! -d $(CY_SMARTIO_CONFIGURATOR_DIR) ]; then toolsTest+=("smartio-configurator could not be found"); fi;\ + if [ ! -d $(CY_MAKEFILES_DIR) ]; then toolsTest+=("Tools make files could not be found"); fi;\ + if [ $${#toolsTest[@]} -eq 0 ]; then\ + printf "SUCCESS: All tools are present";\ + else\ + printf "FAILED: The following tools are missing\n";\ + printf ' %s\n' "$${toolsTest[@]}";\ + fi; + +CY_HELP_get_env_info=Prints the make, git, and app repo info. +get_env_info: + @echo;\ + echo "make location :" $$(which make);\ + echo "make version :" $(MAKE_VERSION);\ + echo "git location :" $$(which git);\ + echo "git version :" $$(git --version);\ + echo "git remote :";\ + git remote -v;\ + echo "git rev-parse :" $$(git rev-parse HEAD) + +# Empty libs on purpose. May be defined by the application +shared_libs: + +CY_HELP_printlibs=Prints the status of the library repos. +printlibs: + +# +# Identify the phony targets +# +.PHONY: help help_default vscode eclipse check shared_libs get_env_info get_app_info diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/defines.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/defines.mk new file mode 100644 index 0000000000..c57aca5992 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/defines.mk @@ -0,0 +1,295 @@ +################################################################################ +# \file defines.mk +# \version 1.0 +# +# \brief +# Defines, needed for the PSoC 6 build recipe. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +# +# List the supported toolchains +# +CY_SUPPORTED_TOOLCHAINS=GCC_ARM IAR ARM A_Clang + +# +# Define the default core +# +CORE?=CM4 +CY_START_FLASH=0x10000000 +CY_START_SRAM=0x08000000 + +CY_OPEN_bt_configurator_DEVICE=--device PSoC6 +CY_OPENOCD_CHIP_NAME=psoc6 +CY_OPENOCD_SECOND_RESET_TYPE=run +CY_OPENOCD_OTHER_RUN_CMD=mon psoc6 reset_halt sysresetreq +CY_OPENOCD_OTHER_RUN_CMD_ECLIPSE=$(CY_OPENOCD_OTHER_RUN_CMD)\&\#13;\&\#10; + +# +# Core specifics +# +ifeq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_M0P))) +ifeq ($(CORE),CM0P) +$(call CY_MACRO_ERROR,$(DEVICE) does not have a CM0+ core) +endif +CY_LINKERSCRIPT_SUFFIX=cm4 +CY_OPENOCD_EXTRA_PORT_FLAG= +CY_OPENOCD_EXTRA_PORT_ECLIPSE= +CY_OPENOCD_CM0_DISABLE_FLAG=set ENABLE_CM0 0 +CY_OPENOCD_CM0_DISABLE_ECLIPSE=-c \"$(CY_OPENOCD_CM0_DISABLE_FLAG)\"\&\#13;\&\#10; +else +ifeq ($(CORE),CM0P) +CY_LINKERSCRIPT_SUFFIX=cm0plus +else +CY_LINKERSCRIPT_SUFFIX=cm4_dual +CY_OPENOCD_EXTRA_PORT_FLAG=gdb_port 3332 +CY_OPENOCD_EXTRA_PORT_ECLIPSE=-c \"$(CY_OPENOCD_EXTRA_PORT_FLAG)\"\&\#13;\&\#10; +CY_OPENOCD_CM0_DISABLE_FLAG= +CY_OPENOCD_CM0_DISABLE_ECLIPSE= +endif +endif + +# +# Architecure specifics +# +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_DIE_PSOC6ABLE2))) + +CY_PSOC_ARCH=psoc6_01 +CY_PSOC_DIE_NAME=PSoC6ABLE2 +CY_OPENOCD_DEVICE_CFG=psoc6.cfg +CY_JLINK_DEVICE_CFG_PROGRAM=CY8C6xx7_CM0p_sect256KB_tm +CY_JLINK_DEVICE_CFG_DEBUG=CY8C6xx7_CM4_sect256KB +ifeq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_M0P))) +CY_JLINK_DEVICE_CFG_PROGRAM=CY8C6xx6_CM4_sect256KB +CY_JLINK_DEVICE_CFG_DEBUG=CY8C6xx6_CM4_sect256KB +endif +ifneq (,$(findstring CYB0,$(DEVICE))) +CY_PSOC_ARCH=psoc6_secure +CY_PSOC_DIE_NAME=PSoC6ABLE2Secure +CY_OPENOCD_CHIP_NAME=psoc64 +CY_OPENOCD_DEVICE_CFG=psoc6_secure.cfg +CY_OPENOCD_CM0_DISABLE_FLAG=set TARGET_AP cm4_ap +CY_OPENOCD_EXTRA_PORT_FLAG= +CY_OPENOCD_CM0_DISABLE_ECLIPSE=-c \"$(CY_OPENOCD_CM0_DISABLE_FLAG)\"\&\#13;\&\#10; +CY_OPENOCD_EXTRA_PORT_ECLIPSE= +CY_OPENOCD_SECOND_RESET_TYPE=init +CY_OPENOCD_OTHER_RUN_CMD= +CY_OPENOCD_OTHER_RUN_CMD_ECLIPSE= +CY_OPENOCD_SMIF_DISABLE=set DISABLE_SMIF 1 +CY_OPENOCD_SMIF_DISABLE_ECLIPSE=-c \"$(CY_OPENOCD_SMIF_DISABLE)\"\&\#13;\&\#10; +endif + +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_DIE_PSOC6A2M))) + +CY_PSOC_ARCH=psoc6_02 +CY_PSOC_DIE_NAME=PSoC6A2M +CY_OPENOCD_DEVICE_CFG=psoc6_2m.cfg +CY_JLINK_DEVICE_CFG_PROGRAM=CY8C6xxA_CM0p_sect256KB_tm +CY_JLINK_DEVICE_CFG_DEBUG=CY8C6xxA_CM4_sect256KB +ifneq (,$(findstring CYB0,$(DEVICE))) +CY_PSOC_ARCH=psoc6_2m_secure +CY_PSOC_DIE_NAME=PSoC6A2MSecure +CY_OPENOCD_CHIP_NAME=psoc64_2m +CY_OPENOCD_DEVICE_CFG=psoc6_2m_secure.cfg +CY_OPENOCD_CM0_DISABLE_FLAG=set TARGET_AP cm4_ap +CY_OPENOCD_EXTRA_PORT_FLAG= +CY_OPENOCD_CM0_DISABLE_ECLIPSE=-c \"$(CY_OPENOCD_CM0_DISABLE_FLAG)\"\&\#13;\&\#10; +CY_OPENOCD_EXTRA_PORT_ECLIPSE= +CY_OPENOCD_SECOND_RESET_TYPE=init +CY_OPENOCD_OTHER_RUN_CMD= +CY_OPENOCD_OTHER_RUN_CMD_ECLIPSE= +CY_OPENOCD_SMIF_DISABLE=set DISABLE_SMIF 1 +CY_OPENOCD_SMIF_DISABLE_ECLIPSE=-c \"$(CY_OPENOCD_SMIF_DISABLE)\"\&\#13;\&\#10; +endif + +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_DIE_PSOC6A512K))) + +CY_PSOC_ARCH=psoc6_03 +CY_PSOC_DIE_NAME=PSoC6A512K +CY_OPENOCD_DEVICE_CFG=psoc6_512k.cfg +CY_JLINK_DEVICE_CFG_PROGRAM=CY8C6xx5_CM0p_sect256KB_tm +CY_JLINK_DEVICE_CFG_DEBUG=CY8C6xx5_CM4_sect256KB + +else +$(call CY_MACRO_ERROR,Incorrect part number $(DEVICE). Check DEVICE variable.) +endif + +# +# Flash memory specifics +# +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_512))) +CY_MEMORY_FLASH=524288 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_832))) +CY_MEMORY_FLASH=850944 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_1024))) +CY_MEMORY_FLASH=1048576 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_1856))) +CY_MEMORY_FLASH=1899520 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_2048))) +CY_MEMORY_FLASH=2097152 +else +$(call CY_MACRO_ERROR,No Flash memory size defined for $(DEVICE)) +endif + +# +# SRAM memory specifics +# +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_SRAM_KB_128))) +CY_MEMORY_SRAM=129024 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_SRAM_KB_256))) +CY_MEMORY_SRAM=260096 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_SRAM_KB_288))) +CY_MEMORY_SRAM=292864 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_SRAM_KB_512))) +CY_MEMORY_SRAM=522240 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_SRAM_KB_1024))) +CY_MEMORY_SRAM=1046528 +else +$(call CY_MACRO_ERROR,No SRAM memory size defined for $(DEVICE)) +endif + +# +# linker scripts +# + +# Secure parts +ifneq (,$(findstring CYB06,$(DEVICE))) + +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_DIE_PSOC6ABLE2))) +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_832))) +CY_LINKER_SCRIPT_NAME=cyb06xx7 +endif +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_DIE_PSOC6A2M))) +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_1856))) +CY_LINKER_SCRIPT_NAME=cyb06xxa +endif +endif + +# Non-secure part +else + +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_DIE_PSOC6A512K))) +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_512))) +CY_LINKER_SCRIPT_NAME=cy8c6xx5 +endif +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_DIE_PSOC6ABLE2))) +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_512))) +CY_LINKER_SCRIPT_NAME=cy8c6xx6 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_1024))) +CY_LINKER_SCRIPT_NAME=cy8c6xx7 +endif +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_DIE_PSOC6A2M))) +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_1024))) +CY_LINKER_SCRIPT_NAME=cy8c6xx8 +else ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FLASH_KB_2048))) +CY_LINKER_SCRIPT_NAME=cy8c6xxa +endif +endif + +endif + +ifeq ($(CY_LINKER_SCRIPT_NAME),) +$(call CY_MACRO_ERROR,Could not resolve device series for linker script) +endif + +# +# Paths used in program/debug +# +ifeq ($(CY_DEVICESUPPORT_PATH),) +CY_OPENOCD_SVD_PATH?= +else +CY_OPENOCD_SVD_PATH?= +endif +CY_OPENOCD_QSPI_CFG_PATH=$(CY_TARGET_DIR)/COMPONENT_BSP_DESIGN_MODUS/GeneratedSource + +# +# Set the output file paths +# +ifneq ($(CY_BUILD_LOCATION),) +CY_SYM_FILE?=$(CY_INTERNAL_BUILD_LOCATION)/$(APPNAME)/$(TARGET)/$(CONFIG)/$(APPNAME).elf +CY_PROG_FILE?=$(CY_INTERNAL_BUILD_LOCATION)/$(APPNAME)/$(TARGET)/$(CONFIG)/$(APPNAME).hex +else +CY_SYM_FILE?=\$$\{cy_prj_path\}/$(notdir $(CY_INTERNAL_BUILD_LOC))/$(TARGET)/$(CONFIG)/$(APPNAME).elf +CY_PROG_FILE?=\$$\{cy_prj_path\}/$(notdir $(CY_INTERNAL_BUILD_LOC))/$(TARGET)/$(CONFIG)/$(APPNAME).hex +endif + +# +# IDE specifics +# +ifneq (,$(findstring CYB0,$(DEVICE))) +CY_ECLIPSE_TEMPLATES_WILDCARD=*KitProg3* +endif + +CY_VSCODE_ARGS="s|&&RELEASETARGET&&|build/$(TARGET)/Release/$(APPNAME).elf|g;"\ + "s|&&DEBUGTARGET&&|build/$(TARGET)/Debug/$(APPNAME).elf|g;"\ + "s|&&PSOCFAMILY&&|$(CY_PSOC_ARCH)|g;"\ + "s|&&MODUSSHELL&&|$(CY_MODUS_SHELL_DIR)|g;"\ + "s|&&OPENOCDFILE&&|$(CY_OPENOCD_DEVICE_CFG)|g;"\ + "s|&&SVDFILENAME&&|$(CY_OPENOCD_SVD_PATH)|g;"\ + "s|&&MODUSTOOLCHAIN&&|$(CY_COMPILER_DIR)|g;"\ + "s|&&MODUSTOOLCHAINVERSION&&|$(notdir $(CY_COMPILER_DIR))|g;"\ + "s|&&MODUSOPENCOD&&|$(CY_OPENOCD_DIR)|g;"\ + "s|&&MODUSLIBMANAGER&&|$(CY_LIBRARY_MANAGER_DIR)|g;"\ + +CY_ECLIPSE_ARGS="s|&&CY_OPENOCD_CFG&&|$(CY_OPENOCD_DEVICE_CFG)|;"\ + "s|&&CY_OPENOCD_CHIP&&|$(CY_OPENOCD_CHIP_NAME)|;"\ + "s|&&CY_OPENOCD_SECOND_RESET&&|$(CY_OPENOCD_SECOND_RESET_TYPE)|;"\ + "s|&&CY_OPENOCD_OTHER_RUN_CMD&&|$(CY_OPENOCD_OTHER_RUN_CMD_ECLIPSE)|;"\ + "s|&&CY_JLINK_CFG_PROGRAM&&|$(CY_JLINK_DEVICE_CFG_PROGRAM)|;"\ + "s|&&CY_JLINK_CFG_DEBUG&&|$(CY_JLINK_DEVICE_CFG_DEBUG)|;"\ + "s|&&CY_OPENOCD_PORT_SELECT&&|$(CY_OPENOCD_EXTRA_PORT_ECLIPSE)|;"\ + "s|&&CY_OPENOCD_CM0_FLAG&&|$(CY_OPENOCD_CM0_DISABLE_ECLIPSE)|;"\ + "s|&&CY_OPENOCD_SMIF_DISABLE&&|$(CY_OPENOCD_SMIF_DISABLE_ECLIPSE)|;"\ + "s|&&CY_APPNAME&&|$(CY_IDE_PRJNAME)|;"\ + "s|&&CY_CONFIG&&|$(CONFIG)|;"\ + "s|&&CY_QSPI_CFG_PATH&&|$(CY_OPENOCD_QSPI_CFG_PATH)|;"\ + "s|&&CY_SVD_PATH&&|$(CY_OPENOCD_SVD_PATH)|;"\ + "s|&&CY_SYM_FILE&&|$(CY_SYM_FILE)|;"\ + "s|&&CY_PROG_FILE&&|$(CY_PROG_FILE)|;" + +# +# Tools specifics +# +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_CAPSENSE))) +CY_SUPPORTED_TOOL_TYPES+=capsense-configurator capsense-tuner +endif +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_BLE))) +CY_SUPPORTED_TOOL_TYPES+=bt-configurator +endif +ifneq (,$(findstring $(DEVICE),$(CY_DEVICES_WITH_FS_USB))) +CY_SUPPORTED_TOOL_TYPES+=usbdev-configurator +endif +CY_SUPPORTED_TOOL_TYPES+=\ + device-configurator\ + qspi-configurator\ + seglcd-configurator\ + smartio-configurator\ + cype-tool\ + dfuh-tool + +# PSoC 6 smartio also uses the .modus extension +modus_DEFAULT_TYPE+=device-configurator smartio-configurator + +# PSoC 6 capsense-tuner shares its existence with capsense-configurator +CY_OPEN_NEWCFG_XML_TYPES+=capsense-tuner diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/program.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/program.mk new file mode 100644 index 0000000000..8697f39152 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/program.mk @@ -0,0 +1,104 @@ +################################################################################ +# \file program.mk +# \version 1.0 +# +# \brief +# This make file is called recursively and is used to build the +# resoures file system. It is expected to be run from the example directory. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +CY_GDB_CLIENT=$(CY_COMPILER_DIR)/bin/arm-none-eabi-gdb +CY_GDB_ARGS=$(CY_INTERNAL_BASELIB_PATH)/make/scripts/gdbinit + +ifeq ($(TOOLCHAIN),A_Clang) +CY_OPENOCD_PROGRAM_IMG=$(CY_CONFIG_DIR)/$(APPNAME).bin $(TOOLCHAIN_VECT_BASE_CM4) +else +CY_OPENOCD_SYMBOL_IMG=$(CY_CONFIG_DIR)/$(APPNAME).elf +CY_OPENOCD_PROGRAM_IMG=$(CY_CONFIG_DIR)/$(APPNAME).hex +endif + +CY_OPENOCD_SCRIPTS=-s $(CY_OPENOCD_DIR)/scripts +CY_OPENOCD_QSPI=-s $(CY_OPENOCD_QSPI_CFG_PATH) +CY_OPENOCD_INTERFACE=source [find interface/kitprog3.cfg]; +CY_OPENOCD_TARGET=source [find target/$(CY_OPENOCD_DEVICE_CFG)]; +ifeq (,$(findstring CYB0,$(DEVICE))) +CY_OPENOCD_CUSTOM_COMMAND?=psoc6 allow_efuse_program off; +else +CY_GDB_ARGS=$(CY_INTERNAL_BASELIB_PATH)/make/scripts/gdbinit_secure +endif + +CY_OPENOCD_ERASE=init; reset init; psoc6 sflash_restrictions 1; erase_all; exit; +CY_OPENOCD_PROGRAM=psoc6 sflash_restrictions 1; program $(CY_OPENOCD_PROGRAM_IMG) verify reset exit; +CY_OPENOCD_DEBUG=$(CY_OPENOCD_CHIP_NAME).cpu.cm4 configure -rtos auto -rtos-wipe-on-reset-halt 1; $(CY_OPENOCD_EXTRA_PORT_FLAG); init; reset init; + +CY_OPENOCD_ERASE_ARGS=$(CY_OPENOCD_SCRIPTS) -c \ + "$(CY_OPENOCD_INTERFACE) $(CY_OPENOCD_CM0_DISABLE_FLAG); $(CY_OPENOCD_SMIF_DISABLE); $(CY_OPENOCD_TARGET) $(CY_OPENOCD_CUSTOM_COMMAND) $(CY_OPENOCD_ERASE)" +CY_OPENOCD_PROGRAM_ARGS=$(CY_OPENOCD_SCRIPTS) $(CY_OPENOCD_QSPI) -c \ + "$(CY_OPENOCD_INTERFACE) $(CY_OPENOCD_CM0_DISABLE_FLAG); $(CY_OPENOCD_TARGET) $(CY_OPENOCD_CUSTOM_COMMAND) $(CY_OPENOCD_PROGRAM)" +CY_OPENOCD_DEBUG_ARGS=$(CY_OPENOCD_SCRIPTS) $(CY_OPENOCD_QSPI) -c \ + "$(CY_OPENOCD_INTERFACE) $(CY_OPENOCD_CM0_DISABLE_FLAG); $(CY_OPENOCD_TARGET) $(CY_OPENOCD_CUSTOM_COMMAND) $(CY_OPENOCD_DEBUG)" + +erase: + @echo;\ + echo "Erasing target device... ";\ + $(CY_OPENOCD_DIR)/bin/openocd $(CY_OPENOCD_ERASE_ARGS) + +program: build qprogram + +qprogram: memcalc +ifeq ($(LIBNAME),) + @echo;\ + echo "Programming target device... ";\ + $(CY_OPENOCD_DIR)/bin/openocd $(CY_OPENOCD_PROGRAM_ARGS) +else + @echo "Library application detected. Skip programming... ";\ + echo +endif + +debug: program qdebug + +qdebug: qprogram +ifeq ($(LIBNAME),) + @echo;\ + echo ==============================================================================;\ + echo "Instruction:";\ + echo "Open a separate shell and run the attach target (make attach)";\ + echo "to start the GDB client. Then use the GDB commands to debug.";\ + echo ==============================================================================;\ + echo;\ + echo "Opening GDB port ... ";\ + $(CY_OPENOCD_DIR)/bin/openocd $(CY_OPENOCD_DEBUG_ARGS) +else + @echo "Library application detected. Skip debug... ";\ + echo +endif + +attach: + @echo;\ + echo "Starting GDB Client... ";\ + $(CY_GDB_CLIENT) $(CY_OPENOCD_SYMBOL_IMG) -x $(CY_GDB_ARGS) + + +.PHONY: erase program qprogram debug qdebug attach diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/recipe.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/recipe.mk new file mode 100644 index 0000000000..ed0f70866e --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/recipe/recipe.mk @@ -0,0 +1,202 @@ +################################################################################ +# \file recipe.mk +# \version 1.0 +# +# \brief +# Set up a set of defines, includes, software components, linker script, +# Pre and Post build steps and call a macro to create a specific ELF file. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + + +# +# linker script construction +# +ifeq ($(LINKER_SCRIPT),) +LINKER_SCRIPT=$(CY_TARGET_DIR)/linker/TOOLCHAIN_$(TOOLCHAIN)/$(CY_LINKER_SCRIPT_NAME)_$(CY_LINKERSCRIPT_SUFFIX).$(CY_TOOLCHAIN_SUFFIX_LS) +endif + +ifeq ($(shell if [ -f $(LINKER_SCRIPT) ]; then echo 1; else echo 0; fi;),0) +$(error The specified linker script could not be found at $(LINKER_SCRIPT)) +endif + +ifeq ($(TOOLCHAIN),A_Clang) +include $(LINKER_SCRIPT) +else +CY_RECIPE_LSFLAG=$(CY_TOOLCHAIN_LSFLAGS)$(LINKER_SCRIPT) +endif + +# +# Flags construction +# +CY_RECIPE_CFLAGS?=\ + $(CFLAGS)\ + $(CY_TOOLCHAIN_CFLAGS) + +CY_RECIPE_CXXFLAGS?=\ + $(CXXFLAGS)\ + $(CY_TOOLCHAIN_CXXFLAGS) + +CY_RECIPE_ASFLAGS?=\ + $(ASFLAGS)\ + $(CY_TOOLCHAIN_ASFLAGS) + +CY_RECIPE_ARFLAGS?=\ + $(CY_TOOLCHAIN_ARFLAGS) + +CY_RECIPE_LDFLAGS?=\ + $(LDFLAGS)\ + $(CY_TOOLCHAIN_LDFLAGS)\ + $(CY_RECIPE_LSFLAG) + +# +# Defines construction +# +ifneq ($(DEFINES),) +CY_RECIPE_USER_DEFINES=$(addprefix -D,$(DEFINES)) +endif +ifneq ($(LIBNAME),) +CY_RECIPE_USER_NAME=-DCY_LIBNAME_$(subst -,_,$(LIBNAME)) +else +CY_RECIPE_USER_NAME=-DCY_APPNAME_$(subst -,_,$(APPNAME)) +endif + +CY_RECIPE_DEFINES=\ + $(CY_RECIPE_USER_DEFINES)\ + $(CY_RECIPE_USER_NAME)\ + -D$(subst -,_,$(DEVICE))\ + -DCY_TARGET_DEVICE=$(subst -,_,$(DEVICE))\ + -DTARGET_$(subst -,_,$(TARGET))\ + -DCY_TARGET_BOARD=$(subst -,_,$(TARGET))\ + $(foreach feature,$(CY_COMPONENT_LIST),-DCOMPONENT_$(subst -,_,$(feature)))\ + $(CY_TOOLCHAIN_DEBUG_FLAG)\ + $(CY_TOOLCHAIN_DEFINES) + +# +# Includes construction +# +CY_RECIPE_INCLUDES=\ + $(addprefix -I,$(INCLUDES))\ + $(addprefix -I,$(CY_SEARCH_APP_INCLUDES))\ + $(addprefix -I,$(CY_TOOLCHAIN_INCLUDES)) + +# +# Sources construction +# +CY_RECIPE_SOURCE=$(CY_SEARCH_APP_SOURCE) + +# +# Libraries construction +# +CY_RECIPE_LIBS=$(LDLIBS) $(CY_SEARCH_APP_LIBS) + +# +# Generate source step +# +ifneq ($(CY_SEARCH_RESOURCE_FILES),) +CY_RECIPE_RESOURCE_FILES=$(CY_SEARCH_RESOURCE_FILES) +CY_RECIPE_GENERATED_FLAG=TRUE + +# Define the generated source file. Use := for better performance +CY_RECIPE_GENERATED:=$(addprefix $(CY_GENERATED_DIR)/,$(addsuffix .$(CY_TOOLCHAIN_SUFFIX_C),\ + $(basename $(notdir $(subst .,_,$(CY_SEARCH_RESOURCE_FILES)))))) + +CY_RECIPE_GENSRC=\ + bash --norc --noprofile\ + $(CY_INTERNAL_BASELIB_PATH)/make/scripts/genresources.bash\ + $(CY_INTERNAL_BASELIB_PATH)/make/scripts\ + $(CY_GENERATED_DIR)/resources.cyrsc\ + $(CY_INTERNAL_APP_PATH)\ + $(CY_GENERATED_DIR)\ + "MEM" +endif + +# +# Prebuild step +# +CY_RECIPE_PREBUILD?= + +# +# Postbuild step +# +ifeq ($(LIBNAME),) + +ifeq ($(TOOLCHAIN),A_Clang) +CY_RECIPE_POSTBUILD?=\ + $(CY_TOOLCHAIN_M2BIN)\ + --verbose --vect $(VECT_BASE_CM4) --text $(TEXT_BASE_CM4) --data $(RAM_BASE_CM4) --size $(TEXT_SIZE_CM4)\ + $(CY_CONFIG_DIR)/$(APPNAME).mach_o\ + $(CY_CONFIG_DIR)/$(APPNAME).bin + +else ifeq ($(TOOLCHAIN),ARM) +ifeq ($(CY_COMPILER_PATH),) +CY_RECIPE_POSTBUILD?=$(CY_COMPILER_ARM_DIR)/bin/fromelf --output $(CY_CONFIG_DIR)/$(APPNAME).hex --i32combined $(CY_CONFIG_DIR)/$(APPNAME).elf +else +CY_RECIPE_POSTBUILD?=$(CY_COMPILER_PATH)/bin/fromelf --output $(CY_CONFIG_DIR)/$(APPNAME).hex --i32combined $(CY_CONFIG_DIR)/$(APPNAME).elf +endif + +else ifeq ($(TOOLCHAIN),IAR) +CY_RECIPE_POSTBUILD?=$(CY_COMPILER_GCC_ARM_DIR)/bin/arm-none-eabi-objcopy -O ihex $(CY_CONFIG_DIR)/$(APPNAME).elf $(CY_CONFIG_DIR)/$(APPNAME).hex + +else ifeq ($(TOOLCHAIN),GCC_ARM) +ifeq ($(CY_COMPILER_PATH),) +CY_RECIPE_POSTBUILD?=$(CY_COMPILER_GCC_ARM_DIR)/bin/arm-none-eabi-objcopy -O ihex $(CY_CONFIG_DIR)/$(APPNAME).elf $(CY_CONFIG_DIR)/$(APPNAME).hex +else +CY_RECIPE_POSTBUILD?=$(CY_COMPILER_PATH)/bin/arm-none-eabi-objcopy -O ihex $(CY_CONFIG_DIR)/$(APPNAME).elf $(CY_CONFIG_DIR)/$(APPNAME).hex +endif +endif + +endif + +################################################################################ +# Memory Consumption +################################################################################ + +ifeq ($(TOOLCHAIN),A_Clang) +CY_GEN_READELF= +CY_MEMORY_CALC= +else +CY_GEN_READELF=$(CY_COMPILER_DIR)/bin/arm-none-eabi-readelf -Sl $(CY_CONFIG_DIR)/$(APPNAME).elf > $(CY_CONFIG_DIR)/$(APPNAME).readelf +CY_MEM_CALC=\ + bash --norc --noprofile\ + $(CY_INTERNAL_BASELIB_PATH)/make/scripts/memcalc.bash\ + $(CY_CONFIG_DIR)/$(APPNAME).readelf\ + $(CY_MEMORY_FLASH)\ + $(CY_MEMORY_SRAM)\ + $(CY_START_FLASH)\ + $(CY_START_SRAM) +endif + +memcalc: app +ifneq ($(LIBNAME),) +else + @echo Calculating memory consumption: $(DEVICE) $(TOOLCHAIN) $(CY_TOOLCHAIN_OPTIMIZATION) + @echo + $(CY_NOISE)$(CY_GEN_READELF) + $(CY_NOISE)$(CY_MEM_CALC) +endif + +# +# Identify the phony targets +# +.PHONY: memcalc diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/bin_to_resource_c.pl b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/bin_to_resource_c.pl new file mode 100644 index 0000000000..20b6c767f0 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/bin_to_resource_c.pl @@ -0,0 +1,107 @@ +#!/usr/bin/perl + +# +# Copyright 2019, Cypress Semiconductor Corporation or a subsidiary of +# Cypress Semiconductor Corporation. All Rights Reserved. +# +# This software, including source code, documentation and related +# materials ("Software"), is owned by Cypress Semiconductor Corporation +# or one of its subsidiaries ("Cypress") and is protected by and subject to +# worldwide patent protection (United States and foreign), +# United States copyright laws and international treaty provisions. +# Therefore, you may use this Software only as provided in the license +# agreement accompanying the software package from which you +# obtained this Software ("EULA"). +# If no EULA applies, Cypress hereby grants you a personal, non-exclusive, +# non-transferable license to copy, modify, and compile the Software +# source code solely for use in connection with Cypress's +# integrated circuit products. Any reproduction, modification, translation, +# compilation, or representation of this Software except as specified +# above is prohibited without the express written permission of Cypress. +# +# Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress +# reserves the right to make changes to the Software without notice. Cypress +# does not assume any liability arising out of the application or use of the +# Software or any product or circuit described in the Software. Cypress does +# not authorize its products for use in any products where a malfunction or +# failure of the Cypress product may reasonably be expected to result in +# significant property damage, injury or death ("High Risk Product"). By +# including Cypress's product in a High Risk Product, the manufacturer +# of such system or application assumes all risk of such use and in doing +# so agrees to indemnify Cypress against all liability. +# + +if (! $ARGV[0] ) +{ + print "Usage ./bin_to_resource_c.pl "; + exit; +} + +# Print start of output +my $location = shift @ARGV; +my $variable_name = shift @ARGV; +my $original_variable_name = $variable_name; +my $file = shift @ARGV; + +#open the file +open INFILE, "<:raw", $file or die "cant open " . $file; +@file_cont_array = ; +close INFILE; +$file_cont = join('',@file_cont_array); + + +print "#include \"cy_abs_resource.h\"\n"; +print "\n"; +$name = $file; +$name=~s/^.+\/(.*?)/$1/; + +if ( $location ne "MEM" ) +{ + print "const cy_resource_handle_t ${variable_name} = { CY_RESOURCE_IN_FILESYSTEM, " . (length( $file_cont )) . ", {.fs = { 0, \"$name\" } }};\n"; + print "\n"; +} +else +{ + print "const uint8_t ${variable_name}_data[" . (length( $file_cont )) . "] = {\n"; + my @vals = unpack( "C*", $file_cont ); + + my $linepos; + my $firstval = 1; + + foreach $val (@vals) + { + my $valsize = 1; + if ( ( $val >= 10 ) && ( $val < 100 ) ) + { + $valsize = 2; + } + elsif ( $val >= 100 ) + { + $valsize = 3; + } + + if ( $firstval == 1 ) + { + print " $val"; + $linepos = 8 + $valsize; + $firstval = 0; + } + elsif ( $linepos + 5 >= 79 ) + { + print ",\n $val"; + $linepos = 8 + $valsize; + } + else + { + print ", $val"; + $linepos += 2 + $valsize; + } + } + + print "\n};\n"; + print "const cy_resource_handle_t ${variable_name} = { CY_RESOURCE_IN_MEMORY, " . (length( $file_cont )) . ", {.mem_data = ${variable_name}_data }};\n"; + print "\n"; +} + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Attach (JLink).xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Attach (JLink).xml new file mode 100644 index 0000000000..ca684385bd --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Attach (JLink).xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Attach (KitProg3).xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Attach (KitProg3).xml new file mode 100644 index 0000000000..f3ab745d53 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Attach (KitProg3).xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Debug (JLink).xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Debug (JLink).xml new file mode 100644 index 0000000000..5247c6f900 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Debug (JLink).xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Debug (KitProg3).xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Debug (KitProg3).xml new file mode 100644 index 0000000000..1751625564 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Debug (KitProg3).xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Erase (JLink).xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Erase (JLink).xml new file mode 100644 index 0000000000..ad502c5693 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Erase (JLink).xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Erase (KitProg3).xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Erase (KitProg3).xml new file mode 100644 index 0000000000..43f7970efd --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Erase (KitProg3).xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Program (JLink).xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Program (JLink).xml new file mode 100644 index 0000000000..590852931a --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Program (JLink).xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Program (KitProg3).xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Program (KitProg3).xml new file mode 100644 index 0000000000..d597267bf2 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/eclipse/Program (KitProg3).xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/gdbinit b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/gdbinit new file mode 100644 index 0000000000..03e0e87df8 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/gdbinit @@ -0,0 +1,32 @@ +# CM4 port +target remote:3333 + +# Open all memory +set mem inaccessible-by-default off + +# Enable semihosting +monitor arm semihosting enable + +# Load the executable +# load + +# Reset device +monitor reset run + +# Halt device +monitor halt + +# Reset device via dedicated reset method +monitor psoc6 reset_halt sysresetreq +flushregs +mon gdb_sync +stepi + +# Set temporary breakpoint at main +tbreak main + +# Print registers +monitor reg + +# Continue program execution +continue \ No newline at end of file diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/gdbinit_secure b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/gdbinit_secure new file mode 100644 index 0000000000..c107ba49b3 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/gdbinit_secure @@ -0,0 +1,34 @@ +# CM4 port +target remote:3333 + +# Open all memory +set mem inaccessible-by-default off + +# Target acquisition timeout +set remotetimeout 15 + +# Enable semihosting +monitor arm semihosting enable + +# Load the executable +# load + +# Reset device +monitor reset init + +# Halt device +monitor halt + +# Synchronize client and server +flushregs +mon gdb_sync +stepi + +# Set temporary breakpoint at main +tbreak main + +# Print registers +monitor reg + +# Continue program execution +continue \ No newline at end of file diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/genresources.bash b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/genresources.bash new file mode 100644 index 0000000000..3aa2083628 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/genresources.bash @@ -0,0 +1,177 @@ +#!/bin/bash +(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required +set -$-ue${DEBUG+x} + +####################################################################################################################### +# This script is designed to process resource files that are necessary for a single component. It converts each +# resource file into a binary object and then stores that into an array in a .c file. The .c file can then be compiled +# with and linked into an application image. +# +# Once all resources files have been converted it will generate a header file that references each of them. +# +# usage: +# genresources.bash [s] +# +####################################################################################################################### + +RECIPE_DIR=$1 #eg: ./tools +RESOURCE_FILE=$2 #eg: ./generated/temp.cyrsc +PROJECT_DIR=$3 #eg: ./project_mainapp +TARGET_DIR=$4 #eg: ./project_resources +RESOURCE_TYPE=$5 #eg: FILESYSTEM or MEM + +echo Script: genresources.bash +echo " 1: Recipe Dir : '"$RECIPE_DIR"'" +echo " 3: Resource Files : '"$RESOURCE_FILE"'" +echo " 4: Project Dir : '"$PROJECT_DIR"'" +echo " 5: Target Dir : '"$TARGET_DIR"'" +echo " 6: Resource Type : '"$RESOURCE_TYPE"'" + +# +# File in the target directory +# +RES_FILE="$TARGET_DIR/cy_resources.h" + +# array of c source files parsed for declarations to generate resources.h +declare SOURCE_ARRAY=() + +# +# Print nice error messages +# +function error() { + echo "ERROR: $1" + shift + + while (( $# > 0 )); do + echo " : $1:" + shift + done + + echo "—ABORTING--" + exit 1 +} + +# +# Checks if the value $1 is in the array $element +# +array_contains () { + local seeking=$1; shift + local in=0 + for element; do + if [[ $element == $seeking ]]; then + in=1 + break + fi + done + echo $in +} + +# +# Prepares the resource file for outputing as c-file +# +convert_resource_name() { + local input=$1 + local result=${input//\//_DIR_} #replace '/' with '_DIR_' + result=${result//./_} #replace '.' with '_' + result=${result//-/_} #replace '-' with '_' + result=${result//resources_DIR/resources} #replace 'resources_DIR' with 'resources' + echo $result +} + +# +# Process the resources listed in the .cyrsc file by converting them to .c and creating +# a list of files for the resource header script +# +processResources() { + local TEXT_FILTERS=(html htm txt eml js css dat cer pem json xml py key) + local BINARY_FILTERS=(jpg jpeg png ico gif bin flac wav clm_blob gz mp3 wmfw) + + local TEXT_TO_RES="$RECIPE_DIR/text_to_resource_c.pl" + local BIN_TO_RES="$RECIPE_DIR/bin_to_resource_c.pl" + + local resourceList=($(<$1)) + + # Parse through each element in the .cyrsc file + for ((i = 0; i < ${#resourceList[@]}; i++)); do + + # Evaluate the file + local resourceFile="${resourceList[$i]}" + local filename="${resourceFile##*/}" + local extension="${filename##*.}" + + # only process the file if it exists + if [ -f "$resourceFile" ]; then + + local resourceName=$(convert_resource_name "$resourceFile") + local outputFile="$TARGET_DIR/$(convert_resource_name $filename).c" + + SOURCE_ARRAY+=("$TARGET_DIR/$(convert_resource_name $filename).c") + + local script + local isText=$(array_contains $extension "${TEXT_FILTERS[@]}") + if [ "1" == "$isText" ]; then + script=$TEXT_TO_RES + fi + + local isBinary=$(array_contains $extension "${BINARY_FILTERS[@]}") + if [ "1" == "$isBinary" ]; then + script=$BIN_TO_RES + fi + + local outputFileTmp="$TARGET_DIR/$(convert_resource_name $filename).c" + perl "$script" "$RESOURCE_TYPE" "$resourceName" "$resourceFile" > "$outputFileTmp" + else + error "Listed resource $resourceFile does not exist" + fi + done +} + +# +# Remove stale files from previous run +# +cleanStale() { + local staleList=($(find $TARGET_DIR -name "*.c")) + local resourceList=($(<$1)) + local fileFound=0 + + for ((j = 0; j < ${#staleList[@]}; j++)); do + for ((i = 0; i < ${#resourceList[@]}; i++)); do + local file="${resourceList[$i]}" + local filename="${file##*/}" + local outputFile="$TARGET_DIR/$(convert_resource_name $filename).c" + + if [[ $(basename $outputFile) == $(basename "${staleList[$j]}") ]]; then + fileFound=1 + fi + done + if [[ $fileFound == 0 ]]; then + rm -rf "${staleList[$j]}" + fi + fileFound=0 + done +} + +# +# Call the perl script that creates resources.h +# +generateResourceHeader() { + perl "$RECIPE_DIR/resources_header.pl" ${SOURCE_ARRAY[*]} > "$RES_FILE" +} + +####################################################################################################################### + +# +# Clean files from previous run that aren't in the current list +# +cleanStale $RESOURCE_FILE + +# +# Process all the resources in the cyrsc file +# +processResources $RESOURCE_FILE + +# +# Create the resource header +# +generateResourceHeader + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/memcalc.bash b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/memcalc.bash new file mode 100644 index 0000000000..47dac7b555 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/memcalc.bash @@ -0,0 +1,78 @@ +#!/bin/bash +(set -o igncr) 2>/dev/null && set -o igncr; # this comment is required +set -$-ue${DEBUG+xv} + +####################################################################################################################### +# This script processes the memory consumption of an application and prints it out to the console. +# +# usage: +# memcalc.bash +# +####################################################################################################################### + +READELFFILE=$1 # file location of readelf output +AVAILABLEFLASH=$2 # Max available internal flash +AVAILABLESRAM=$3 # Max available internal SRAM +STARTFLASH=$4 # Start of internal flash +STARTSRAM=$5 # Start of internal SRAM + +ENDFLASH=$((STARTFLASH + AVAILABLEFLASH)) +ENDSRAM=$((STARTSRAM + AVAILABLESRAM)) + +# Gather the numbers +memcalc() { + local internalFlash=0 + local internalSram=0 + + printf " -------------------------------------------------- \n" + printf " | %-20s | %-10s | %-8s | \n" 'Section Name' 'Address' 'Size' + printf " -------------------------------------------------- \n" + + while IFS=$' \t\n\r' read -r line; do + local lineArray=($line) + local numElem=${#lineArray[@]} + + # Only look at potentially valid lines + if [[ $numElem -ge 6 ]]; then + # Section headers + if [[ ${lineArray[0]} == "["* ]]; then + local sectionElement=NULL + local addrElement=00000000 + local sizeElement=000000 + for (( idx = 0 ; idx <= $numElem-4 ; idx = $idx+1 )); + do + if [[ ${lineArray[$idx]} == *"]" ]]; then + sectionElement=${lineArray[$idx+1]} + fi + # Look for regions with SHF_ALLOC = A + if [[ ${#lineArray[idx]} -eq 8 ]] && [[ ${#lineArray[idx+1]} -eq 6 ]] && [[ ${#lineArray[idx+2]} -eq 6 ]] \ + && [[ ${lineArray[$idx+4]} == *"A"* ]] ; then + addrElement=${lineArray[$idx]} + sizeElement=${lineArray[$idx+2]} + fi + done + # Only consider non-zero size sections + if [[ $addrElement != "00000000" ]]; then + printf " | %-20s | 0x%-10s | %-8s | \n" $sectionElement $addrElement $((16#$sizeElement)) + # Use the section headers for SRAM tally + if [[ "0x$addrElement" -ge "$STARTSRAM" ]] && [[ "0x$addrElement" -lt "$ENDSRAM" ]]; then + internalSram=$((internalSram+$((16#$sizeElement)))) + fi + fi + # Program headers + elif [[ ${lineArray[1]} == "0x"* ]] && [[ ${lineArray[2]} == "0x"* ]] && [[ ${lineArray[3]} == "0x"* ]] && [[ ${lineArray[4]} == "0x"* ]]\ + && [[ ${lineArray[3]} -ge "$STARTFLASH" ]] && [[ ${lineArray[3]} -lt "$ENDFLASH" ]]; then + # Use the program headers for Flash tally + internalFlash=$((internalFlash+${lineArray[4]})) + fi + fi + done < "$READELFFILE" + + printf " -------------------------------------------------- \n\n" + printf " %-41s %-8s \n" 'Total Internal Flash (Available)' $AVAILABLEFLASH + printf " %-41s %-8s \n\n" 'Total Internal Flash (Utilized)' $internalFlash + printf " %-41s %-8s \n" 'Total Internal SRAM (Available)' $AVAILABLESRAM + printf " %-41s %-8s \n" 'Total Internal SRAM (Utilized)' $internalSram +} + +memcalc diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/resources_header.pl b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/resources_header.pl new file mode 100644 index 0000000000..8579477890 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/resources_header.pl @@ -0,0 +1,83 @@ +#!/usr/bin/perl + +# +# Copyright 2019, Cypress Semiconductor Corporation or a subsidiary of +# Cypress Semiconductor Corporation. All Rights Reserved. +# +# This software, including source code, documentation and related +# materials ("Software"), is owned by Cypress Semiconductor Corporation +# or one of its subsidiaries ("Cypress") and is protected by and subject to +# worldwide patent protection (United States and foreign), +# United States copyright laws and international treaty provisions. +# Therefore, you may use this Software only as provided in the license +# agreement accompanying the software package from which you +# obtained this Software ("EULA"). +# If no EULA applies, Cypress hereby grants you a personal, non-exclusive, +# non-transferable license to copy, modify, and compile the Software +# source code solely for use in connection with Cypress's +# integrated circuit products. Any reproduction, modification, translation, +# compilation, or representation of this Software except as specified +# above is prohibited without the express written permission of Cypress. +# +# Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress +# reserves the right to make changes to the Software without notice. Cypress +# does not assume any liability arising out of the application or use of the +# Software or any product or circuit described in the Software. Cypress does +# not authorize its products for use in any products where a malfunction or +# failure of the Cypress product may reasonably be expected to result in +# significant property damage, injury or death ("High Risk Product"). By +# including Cypress's product in a High Risk Product, the manufacturer +# of such system or application assumes all risk of such use and in doing +# so agrees to indemnify Cypress against all liability. +# + +if (! $ARGV[0] ) +{ + print "Usage ./resources_header.pl ..."; + exit; +} + +print "/* Auto-generated header file. Do not edit */\n"; +print "\n"; +print "#pragma once\n"; +print "\n"; +print "#include \n"; +print "#include \"cy_abs_resource.h\"\n"; +print "\n"; +print "#ifdef __cplusplus\n"; +print "extern \"C\" {\n"; +print "#endif\n"; +print "\n"; + + +my $mem_resources = ""; +my $filesystem_resources = ""; + +foreach $file (@ARGV) +{ + #open the file + open INFILE, $file or die "cant open " . $file; + + @file_cont_array = ; + close INFILE; + $file_cont = join('',@file_cont_array); + + while ( $file_cont =~ m/(const cy_resource_handle_t \S+)/sgi ) + { + $resources .= "extern $1;\n"; + } + while ( $file_cont =~ m/(const uint8_t \S+\[\d+\])/sgi ) + { + $resources .= "extern $1;\n"; + } +} + +print "\n"; +print "$resources"; +print "\n"; +print "/* @} */\n"; +print "#ifdef __cplusplus\n"; +print "} /*extern \"C\" */\n"; +print "#endif\n"; diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/text_to_resource_c.pl b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/text_to_resource_c.pl new file mode 100644 index 0000000000..a9115aff83 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/text_to_resource_c.pl @@ -0,0 +1,132 @@ +#!/usr/bin/perl + +# +# Copyright 2019, Cypress Semiconductor Corporation or a subsidiary of +# Cypress Semiconductor Corporation. All Rights Reserved. +# +# This software, including source code, documentation and related +# materials ("Software"), is owned by Cypress Semiconductor Corporation +# or one of its subsidiaries ("Cypress") and is protected by and subject to +# worldwide patent protection (United States and foreign), +# United States copyright laws and international treaty provisions. +# Therefore, you may use this Software only as provided in the license +# agreement accompanying the software package from which you +# obtained this Software ("EULA"). +# If no EULA applies, Cypress hereby grants you a personal, non-exclusive, +# non-transferable license to copy, modify, and compile the Software +# source code solely for use in connection with Cypress's +# integrated circuit products. Any reproduction, modification, translation, +# compilation, or representation of this Software except as specified +# above is prohibited without the express written permission of Cypress. +# +# Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress +# reserves the right to make changes to the Software without notice. Cypress +# does not assume any liability arising out of the application or use of the +# Software or any product or circuit described in the Software. Cypress does +# not authorize its products for use in any products where a malfunction or +# failure of the Cypress product may reasonably be expected to result in +# significant property damage, injury or death ("High Risk Product"). By +# including Cypress's product in a High Risk Product, the manufacturer +# of such system or application assumes all risk of such use and in doing +# so agrees to indemnify Cypress against all liability. +# + +if (! $ARGV[0] ) +{ + print "Usage ./text_to_resource__c.pl "; + exit; +} + +# Print start of output +my $location = shift @ARGV; +my $variable_name = shift @ARGV; +my $original_variable_name = $variable_name; +my $file = shift @ARGV; + +#open the file +open INFILE, "<:raw", $file or die "cant open " . $file; +@file_cont_array = ; +close INFILE; +$file_cont = join('',@file_cont_array); + + +print "#include \"cy_abs_resource.h\"\n"; +print "\n"; + +my $pos = 0; + +if ( ( $file =~ m/\.html$/sgi ) || + ( $file =~ m/\.txt$/sgi ) ) +{ + while ( $file_cont =~ s/^(.*?)\r?\n?\\r?\n?(.*)$/$3/sgi ) + { + my $substr = $1; + my $variable_suffix = $2; + my $nextpos = $-[3]; + + print "\n"; + if ( $location ne "MEM" ) + { + $name = $file; + $name=~s/^.+\/(.*?)/$1/; + print "const cy_resource_handle_t ${variable_name} = { CY_RESOURCE_IN_FILESYSTEM, " . (length( $substr )) . ", { .fs = { $pos, \"$name\" }}};\n"; + print "\n"; + } + else + { + print "const uint8_t ${variable_name}_data[" . (length( $substr )+1) . "] = "; + my $section_length = length( $substr ); + while ( $substr =~ s/^(.*?\n)(.*)$/$2/sgi ) + { + print "\"" . escape_string( $1 ) . "\" \\\n"; + } + print "\"" . escape_string( $substr ) . "\";\n"; + + print "const cy_resource_handle_t ${variable_name} = { CY_RESOURCE_IN_MEMORY, $section_length, { .mem_data = ${variable_name}_data}};"; + print "\n"; + } + + $variable_name = $original_variable_name . $variable_suffix; + $pos += $nextpos; + } +} + +if ( $location ne "MEM" ) +{ + print "\n"; + $name = $file; + $name=~s/^.+\/(.*?)/$1/; + print "const cy_resource_handle_t ${variable_name} = { CY_RESOURCE_IN_FILESYSTEM, " . (length( $file_cont )) . ", { .fs = { $pos, \"$name\" }}};\n"; + print "\n"; +} +else +{ + print "const uint8_t ${variable_name}_data[" . (length( $file_cont ) + 1) . "] = "; + my $section_length = length( $file_cont ); + while ( $file_cont =~ s/^(.*?\n)(.*)$/$2/sgi ) + { + print "\"" . escape_string( $1 ) . "\" \\\n"; + } + print "\"" . escape_string( $file_cont ) . "\";\n"; + print "const cy_resource_handle_t ${variable_name} = { CY_RESOURCE_IN_MEMORY, $section_length, { .mem_data = ${variable_name}_data }};"; + print "\n"; +} + +sub escape_string( $escstring ) +{ + my $escstring = shift; + # Escape characters for C string + $escstring =~ s/\\/\\\\/sgi; # backslash + $escstring =~ s/\a/\\a/sgi; # bell + $escstring =~ s/\x8/\\b/sgi; # backspace + $escstring =~ s/\f/\\f/sgi; # formfeed + $escstring =~ s/\n/\\n/sgi; # linefeed + $escstring =~ s/\r/\\r/sgi; # carriage return + $escstring =~ s/\t/\\t/sgi; # tab + $escstring =~ s/\xB/\\v/sgi; # vertical tab + $escstring =~ s/\'/\\'/sgi; # single quote + $escstring =~ s/\"/\\"/sgi; # double quote + return $escstring; +} diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/c_cpp_properties_GCC_ARM.json b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/c_cpp_properties_GCC_ARM.json new file mode 100644 index 0000000000..3d2d96fd93 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/c_cpp_properties_GCC_ARM.json @@ -0,0 +1,71 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + &&JSONINCLUDELIST&& + "&&MODUSTOOLCHAIN&&/lib/gcc/arm-none-eabi/&&MODUSTOOLCHAINVERSION&&/include", + "&&MODUSTOOLCHAIN&&/lib/gcc/arm-none-eabi/&&MODUSTOOLCHAINVERSION&&/include-fixed", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&/backward" + ], + "browse": { + "path": [ + &&JSONINCLUDELIST&& + "&&MODUSTOOLCHAIN&&/lib/gcc/arm-none-eabi/&&MODUSTOOLCHAINVERSION&&/include", + "&&MODUSTOOLCHAIN&&/lib/gcc/arm-none-eabi/&&MODUSTOOLCHAINVERSION&&/include-fixed", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&/backward" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "defines": [ + &&JSONDEFINELIST&& + "EMPTY_ENTRY" + ], + "intelliSenseMode": "clang-x64", + "compilerPath": "&&MODUSTOOLCHAIN&&/bin/arm-none-eabi-gcc.exe -mcpu=cortex-m4 -mthumb -mfloat-abi=soft", + "cStandard": "c99", + "cppStandard": "c++11" + }, + { + "name": "macOS", + "includePath": [ + &&JSONINCLUDELIST&& + "&&MODUSTOOLCHAIN&&/lib/gcc/arm-none-eabi/&&MODUSTOOLCHAINVERSION&&/include", + "&&MODUSTOOLCHAIN&&/lib/gcc/arm-none-eabi/&&MODUSTOOLCHAINVERSION&&/include-fixed", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&/backward" + ], + "browse": { + "path": [ + &&JSONINCLUDELIST&& + "&&MODUSTOOLCHAIN&&/lib/gcc/arm-none-eabi/&&MODUSTOOLCHAINVERSION&&/include", + "&&MODUSTOOLCHAIN&&/lib/gcc/arm-none-eabi/&&MODUSTOOLCHAINVERSION&&/include-fixed", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard", + "&&MODUSTOOLCHAIN&&/arm-none-eabi/include/c++/&&MODUSTOOLCHAINVERSION&&/backward" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "defines": [ + &&JSONDEFINELIST&& + "EMPTY_ENTRY" + ], + "intelliSenseMode": "clang-x64", + "compilerPath": "&&MODUSTOOLCHAIN&&/bin/arm-none-eabi-gcc.exe -mcpu=cortex-m4 -mthumb -mfloat-abi=soft", + "cStandard": "c99", + "cppStandard": "c++11" + } + ], + "version": 4 +} diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/launch.json b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/launch.json new file mode 100644 index 0000000000..4ad1e853d7 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/launch.json @@ -0,0 +1,138 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch PSoC6 CM4 (OpenOCD)", + "type": "cortex-debug", + "request": "launch", + "cwd": "${workspaceRoot}", + "executable": "&&DEBUGTARGET&&", + "servertype": "openocd", + "searchDir": [ + "${workspaceRoot}", + "&&MODUSOPENCOD&&/scripts/" + ], + "configFiles": [ + "openocd.tcl" + ], + "overrideLaunchCommands": [ + "set mem inaccessible-by-default off", + "-enable-pretty-printing", + "monitor reset init", + "-target-download", // Comment this out if you don't want to reload program + "monitor reset run", + "monitor sleep 200", + "monitor psoc6 reset_halt sysresetreq" + ], + "postStartSessionCommands": [ // Needed if runToMain is false + /* + // Following two commands are needed to get gdb and openocd and HW all in sync. + // Or, execution context (PC, stack, registers, etc.) look like they are from before reset. + // The stepi, is a pretend instruction that does not actually do a stepi, but MUST be done + // Its a documented workaround in openocd. Do a 'monitor help' to see more info + // + // An alternative command to use is "continue" instead of the following two + */ + "monitor gdb_sync", + "stepi" + ], + "overrideRestartCommands": [ + "monitor reset init", + "monitor reset run", + "monitor sleep 200", + "monitor psoc6 reset_halt sysresetreq" + ], + "postRestartSessionCommands": [ + "monitor gdb_sync", + "stepi" + ], + // svdFile is optional, it can be very large. + "svdFile": "&&SVDFILENAME&&", + "runToMain": true, // if true, program will halt at main. Not used for a restart + "preLaunchTask": "", // Set this to run a task from tasks.json before starting a debug session + "showDevDebugOutput": false,// Shows output of GDB, helpful when something is not working right + }, + // When using 'attach', make sure your program is running on the board and that your executable matches + // the image in the chip exactly, or else strange things can happen with breakpoint, variables, etc. + { + "name": "Attach PSoC6 CM4 (OpenOCD)", + "type": "cortex-debug", + "request": "attach", + "cwd": "${workspaceRoot}", + "executable": "&&DEBUGTARGET&&", + "servertype": "openocd", + "searchDir": [ + "${workspaceRoot}", + "&&MODUSOPENCOD&&/scripts/" + ], + "openOCDPreConfigLaunchCommands": [ + "set ENABLE_ACQUIRE 0" + ], + "configFiles": [ + "openocd.tcl" + ], + "overrideAttachCommands": [ + "set mem inaccessible-by-default off", + "-enable-pretty-printing", + "monitor halt" + ], + "overrideRestartCommands": [ + "monitor reset init", + "monitor reset run", + "monitor sleep 200", + "monitor psoc6 reset_halt sysresetreq" + ], + "postRestartSessionCommands": [ + "monitor gdb_sync", + "stepi" + ], + // svdFile is optional, it can be very large. + "svdFile": "&&SVDFILENAME&&", + "showDevDebugOutput": false,// Shows output of GDB, helpful when something is not working right + }, + { + "name": "Erase (OpenOCD)", + "type": "cortex-debug", + "request": "launch", + "cwd": "${workspaceRoot}", + "executable": "&&DEBUGTARGET&&", + "servertype": "openocd", + "searchDir": [ + "${workspaceRoot}", + "&&MODUSOPENCOD&&/scripts/" + ], + "configFiles": [ + "openocd.tcl" + ], + "overrideLaunchCommands": [ + "monitor reset init", + "monitor psoc6 sflash_restrictions 1", + "monitor erase_all", + "-gdb-exit" + ] + }, + { + "name": "Program (OpenOCD)", + "type": "cortex-debug", + "request": "launch", + "cwd": "${workspaceRoot}", + "executable": "&&DEBUGTARGET&&", + "servertype": "openocd", + "searchDir": [ + "${workspaceRoot}", + "&&MODUSOPENCOD&&/scripts/" + ], + "configFiles": [ + "openocd.tcl" + ], + "overrideLaunchCommands": [ + "monitor psoc6 sflash_restrictions 1", + "monitor program {&&DEBUGTARGET&&}", + "monitor reset_config srst_only", + "monitor reset run", + "monitor psoc6.dap dpreg 0x04 0x00", + "-gdb-exit" + ], + } + ] +} diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/openocd.tcl b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/openocd.tcl new file mode 100644 index 0000000000..142b1bbd35 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/openocd.tcl @@ -0,0 +1,4 @@ +source [find interface/kitprog3.cfg] +source [find target/&&OPENOCDFILE&&] +${TARGET}.cm0 configure -gdb-port disabled +${TARGET}.cm4 configure -rtos auto -rtos-wipe-on-reset-halt 1 diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/settings.json b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/settings.json new file mode 100644 index 0000000000..d612b0c4c3 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cortex-debug.armToolchainPath": "&&MODUSTOOLCHAIN&&/bin", + "cortex-debug.openocdPath": "&&MODUSOPENCOD&&/bin/openocd", + "cortex-debug.JLinkGDBServerPath": "", +} diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/tasks.json b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/tasks.json new file mode 100644 index 0000000000..034adfefc0 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/scripts/vscode/tasks.json @@ -0,0 +1,325 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "GetLibs", + "type": "shell", + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe getlibs" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make getlibs" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make getlibs" + ] + }, + "problemMatcher": [] + }, + { + "label": "Refresh", + "type": "shell", + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe vscode" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make vscode" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make vscode" + ] + }, + "problemMatcher": [] + }, + { + "label": "Build Debug", + "type": "shell", + + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe -j CONFIG=Debug build" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Debug build" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Debug build" + ] + }, + "problemMatcher": "$gcc", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Rebuild Debug", + "type": "shell", + + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe -j CONFIG=Debug clean ; &&MODUSSHELL&&/bin/make.exe -j CONFIG=Debug build" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Debug clean ; make -j CONFIG=Debug build" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Debug clean ; make -j CONFIG=Debug build" + ] + }, + "problemMatcher": "$gcc", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Clean Debug", + "type": "shell", + + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe -j CONFIG=Debug clean" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Debug clean" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Debug clean" + ] + }, + "problemMatcher": "$gcc", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Build Release", + "type": "shell", + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe -j CONFIG=Release build" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Release build" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Release build" + ] + }, + "problemMatcher": "$gcc", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Rebuild Release", + "type": "shell", + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe -j CONFIG=Release clean ; &&MODUSSHELL&&/bin/make.exe -j CONFIG=Release build" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Release clean ; make -j CONFIG=Release build" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Release clean ; make -j CONFIG=Release build" + ] + }, + "problemMatcher": "$gcc", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Clean Release", + "type": "shell", + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe -j CONFIG=Release clean" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Release clean" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make -j CONFIG=Release clean" + ] + }, + "problemMatcher": "$gcc", + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Base Configurator", + "type": "shell", + "windows" : { + "command": "&&MODUSSHELL&&/bin/bash.exe" , + "args": [ + "--norc", + "-c", + "export PATH=/bin:/usr/bin ; &&MODUSSHELL&&/bin/make.exe config" + ] + }, + "linux" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make config" + ] + }, + "osx" : { + "command": "bash", + "args": [ + "--norc", + "-c", + "make config" + ] + }, + "problemMatcher": "$gcc" + }, + { + "label": "Library Manager", + "type": "shell", + "windows" : { + "command": "&&MODUSLIBMANAGER&&/library-manager.exe", + "args" : [ + "-d", + "${workspaceRoot}" + ] + }, + "linux" : { + "command": "&&MODUSLIBMANAGER&&/library-manager", + "args" : [ + "-d", + "${workspaceRoot}" + ] + }, + "osx" : { + "command": "&&MODUSLIBMANAGER&&/library-manager -d ${workspaceRoot}", + "args" : [ + "-d", + "${workspaceRoot}" + ] + }, + "problemMatcher": "$gcc", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/ARM.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/ARM.mk new file mode 100644 index 0000000000..7a2e9c2981 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/ARM.mk @@ -0,0 +1,168 @@ +############################################################################### +# \file ARM.mk +# \version 1.0 +# +# \brief +# ARM Compiler (Clang) toolchain configuration. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + +# +# The base path to the ARM Compiler (Clang) cross compilation executables +# +ifeq ($(CY_COMPILER_PATH),) +CY_CROSSPATH=$(CY_COMPILER_ARM_DIR)/bin +else +CY_CROSSPATH=$(CY_COMPILER_PATH)/bin +endif + +# +# Build tools +# +CC=$(CY_CROSSPATH)/armclang +CXX=$(CC) +AS=$(CY_CROSSPATH)/armasm +AR=$(CY_CROSSPATH)/armar +LD=$(CY_CROSSPATH)/armlink + +# +# DEBUG/NDEBUG selection +# +ifeq ($(CONFIG),Debug) +CY_TOOLCHAIN_DEBUG_FLAG=-DDEBUG +CY_TOOLCHAIN_OPTIMIZATION=-O1 +else +ifeq ($(CONFIG),Release) +CY_TOOLCHAIN_DEBUG_FLAG=-DNDEBUG +CY_TOOLCHAIN_OPTIMIZATION=-Oz +else +CY_TOOLCHAIN_DEBUG_FLAG= +CY_TOOLCHAIN_OPTIMIZATION= +endif +endif + +# +# Flags common to compile and link +# +CY_TOOLCHAIN_COMMON_FLAGS=--target=arm-arm-none-eabi + +# +# CPU core specifics +# +ifeq ($(CORE),CM0P) +CY_TOOLCHAIN_CFLAGS_CORE=-mcpu=cortex-m0plus +CY_TOOLCHAIN_FLAGS_CORE=--cpu=Cortex-M0plus +CY_TOOLCHAIN_VFP_FLAGS= +else +CY_TOOLCHAIN_CFLAGS_CORE=-mcpu=cortex-m4 +CY_TOOLCHAIN_FLAGS_CORE=--cpu=Cortex-M4 +ifeq ($(VFP_SELECT),hardfp) +CY_TOOLCHAIN_VFP_CFLAGS=-mfloat-abi=hard -mfpu=fpv4-sp-d16 +CY_TOOLCHAIN_VFP_FLAGS=--fpu=FPv4-SP +else +CY_TOOLCHAIN_VFP_CFLAGS=-mfloat-abi=softfp -mfpu=fpv4-sp-d16 +CY_TOOLCHAIN_VFP_FLAGS=--fpu=SoftVFP+FPv4-SP +endif +endif + +# +# Command line flags for c-files +# +CY_TOOLCHAIN_CFLAGS=\ + -c\ + $(CY_TOOLCHAIN_CFLAGS_CORE)\ + $(CY_TOOLCHAIN_OPTIMIZATION)\ + $(CY_TOOLCHAIN_VFP_CFLAGS)\ + $(CY_TOOLCHAIN_COMMON_FLAGS)\ + -g\ + -fshort-enums\ + -fshort-wchar + +# +# Command line flags for cpp-files +# +CY_TOOLCHAIN_CXXFLAGS=$(CY_TOOLCHAIN_CFLAGS) + +# +# Command line flags for s-files +# +CY_TOOLCHAIN_ASFLAGS=\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_VFP_FLAGS) + +# +# Command line flags for linking +# +CY_TOOLCHAIN_LDFLAGS=\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_VFP_FLAGS)\ + --info=totals\ + --stdlib=libc++ + +# +# Command line flags for archiving +# +CY_TOOLCHAIN_ARFLAGS=-rvs + +# +# Toolchain-specific suffixes +# +CY_TOOLCHAIN_SUFFIX_S=S +CY_TOOLCHAIN_SUFFIX_s=s +CY_TOOLCHAIN_SUFFIX_C=c +CY_TOOLCHAIN_SUFFIX_H=h +CY_TOOLCHAIN_SUFFIX_CPP=cpp +CY_TOOLCHAIN_SUFFIX_HPP=hpp +CY_TOOLCHAIN_SUFFIX_O=o +CY_TOOLCHAIN_SUFFIX_A=ar +CY_TOOLCHAIN_SUFFIX_D=d +CY_TOOLCHAIN_SUFFIX_LS=sct +CY_TOOLCHAIN_SUFFIX_MAP=map +CY_TOOLCHAIN_SUFFIX_TARGET=elf +CY_TOOLCHAIN_SUFFIX_ARCHIVE=ar + +# +# Toolchain specific flags +# +CY_TOOLCHAIN_OUTPUT_OPTION=-o +CY_TOOLCHAIN_MAPFILE=--map --list +CY_TOOLCHAIN_LSFLAGS=--scatter +CY_TOOLCHAIN_INCRSPFILE=@ +CY_TOOLCHAIN_INCRSPFILE_ASM=--via +CY_TOOLCHAIN_OBJRSPFILE=--via + +# +# Produce a makefile dependency rule for each input file +# +CY_TOOLCHAIN_DEPENDENCIES=-MMD -MP -MF "$(subst .$(CY_TOOLCHAIN_SUFFIX_O),.$(CY_TOOLCHAIN_SUFFIX_D),$@)" -MT "$@" + +# +# Additional includes in the compilation process based on this +# toolchain +# +CY_TOOLCHAIN_INCLUDES= + +# +# Additional libraries in the link process based on this toolchain +# +CY_TOOLCHAIN_DEFINES= diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/A_Clang.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/A_Clang.mk new file mode 100644 index 0000000000..45bd0cc294 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/A_Clang.mk @@ -0,0 +1,218 @@ +################################################################################ +# \file AppleClang.mk +# \version 1.0 +# +# \brief +# Apple Clang toolchain configuration +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + +# +# The base path to the Clang cross compilation executables +# +ifeq ($(CY_COMPILER_PATH),) +CY_CROSSPATH=$(CY_COMPILER_A_Clang_DIR) +else +CY_CROSSPATH=$(CY_COMPILER_PATH) +endif + +# +# Build tools +# +CC=clang +CXX=$(CC) +AS=$(CC) +AR=libtool +LD=ld + +# +# DEBUG/NDEBUG selection +# +ifeq ($(CONFIG),Debug) +CY_TOOLCHAIN_DEBUG_FLAG=-DDEBUG +CY_TOOLCHAIN_OPTIMIZATION=-Og +else ifeq ($(CONFIG),Release) +CY_TOOLCHAIN_DEBUG_FLAG=-DNDEBUG +CY_TOOLCHAIN_OPTIMIZATION=-Os +else +CY_TOOLCHAIN_DEBUG_FLAG= +CY_TOOLCHAIN_OPTIMIZATION= +endif + +# +# Flags common to compile and link +# +CY_TOOLCHAIN_COMMON_FLAGS=\ + -mthumb\ + -ffunction-sections\ + -fdata-sections\ + -g\ + -Wall + +# +# CPU core specifics +# +ifeq ($(CORE),CM0P) +CY_TOOLCHAIN_FLAGS_CORE=\ + -arch armv6m\ + -mcpu=cortex-m0plus\ + --target=arm-none-macho +CY_TOOLCHAIN_LDFLAGS_CORE=\ + -arch armv6m\ + -lclang_rt.soft_static +CY_TOOLCHAIN_VFP_FLAGS= +else +ifeq ($(VFP_SELECT),hardfp) +CY_TOOLCHAIN_LD_VFP_FLAGS=-lclang_rt.hard_static +CY_TOOLCHAIN_VFP_FLAGS=-mfloat-abi=hard -mfpu=fpv4-sp-d16 +else +CY_TOOLCHAIN_LD_VFP_FLAGS=-lclang_rt.soft_static +CY_TOOLCHAIN_VFP_FLAGS=-mfloat-abi=softfp -mfpu=fpv4-sp-d16 +endif # ($(VFP_SELECT),hardfp) +CY_TOOLCHAIN_FLAGS_CORE=\ + -arch armv7em\ + -mcpu=cortex-m4\ + --target=armv7m-none-macho +CY_TOOLCHAIN_LDFLAGS_CORE=\ + -arch armv7em\ + $(CY_TOOLCHAIN_LD_VFP_FLAGS) +endif # ($(CORE),CM0P) + +# +# Command line flags for c-files +# +CY_TOOLCHAIN_CFLAGS=\ + -c\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_OPTIMIZATION)\ + $(CY_TOOLCHAIN_VFP_FLAGS)\ + $(CY_TOOLCHAIN_COMMON_FLAGS)\ + --no-standard-includes\ + -fasm-blocks\ + -integrated-as\ + -Wall\ + -Wno-int-to-pointer-cast\ + -static\ + -fno-stack-protector\ + -fno-common\ + -ffreestanding\ + -mlong-calls + +# +# Command line flags for cpp-files +# +CY_TOOLCHAIN_CXXFLAGS=$(CY_TOOLCHAIN_CFLAGS) + +# +# Command line flags for s-files +# +CY_TOOLCHAIN_ASFLAGS=\ + -c\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_COMMON_FLAGS)\ + -fasm-blocks\ + -integrated-as\ + -Wall\ + -Wno-int-to-pointer-cast\ + -static\ + -fno-stack-protector\ + -fno-common\ + -ffreestanding\ + -mlong-calls + +# +# Command line flags for linking +# +CY_TOOLCHAIN_LDFLAGS=\ + $(CY_TOOLCHAIN_LDFLAGS_CORE)\ + $(CY_TOOLCHAIN_LD_VFP_FLAGS)\ + -static\ + -segalign 4\ + -e Reset_Handler\ + -merge_zero_fill_sections\ + -pagezero_size 0\ + -ios_version_min 4.3\ + -preload\ + -v\ + -read_only_relocs suppress\ + -dead_strip\ + -dead_strip_dylibs\ + -no_branch_islands\ + -no_zero_fill_sections\ + -L$(CY_CROSSPATH)/lib/macho_embedded + +# +# Command line flags for archiving +# +CY_TOOLCHAIN_ARFLAGS=rvs + +# +# Toolchain-specific suffixes +# +CY_TOOLCHAIN_SUFFIX_S=S +CY_TOOLCHAIN_SUFFIX_s=s +CY_TOOLCHAIN_SUFFIX_C=c +CY_TOOLCHAIN_SUFFIX_H=h +CY_TOOLCHAIN_SUFFIX_CPP=cpp +CY_TOOLCHAIN_SUFFIX_HPP=hpp +CY_TOOLCHAIN_SUFFIX_O=o +CY_TOOLCHAIN_SUFFIX_A=a +CY_TOOLCHAIN_SUFFIX_D=d +CY_TOOLCHAIN_SUFFIX_LS=mk +CY_TOOLCHAIN_SUFFIX_MAP=map +CY_TOOLCHAIN_SUFFIX_TARGET=mach_o +CY_TOOLCHAIN_SUFFIX_ARCHIVE=a + +# +# Toolchain specific flags +# +CY_TOOLCHAIN_OUTPUT_OPTION=-o +CY_TOOLCHAIN_MAPFILE=-map +CY_TOOLCHAIN_LSFLAGS= +CY_TOOLCHAIN_INCRSPFILE=@ +CY_TOOLCHAIN_INCRSPFILE_ASM=@ +CY_TOOLCHAIN_OBJRSPFILE=-filelist + +# +# Produce a makefile dependency rule for each input file +# +CY_TOOLCHAIN_DEPENDENCIES=-MMD -MP -MF "$(subst .$(CY_TOOLCHAIN_SUFFIX_O),.$(CY_TOOLCHAIN_SUFFIX_D),$@)" -MT "$@" + +# +# Additional includes in the compilation process based on this +# toolchain +# +CY_TOOLCHAIN_INCLUDES=\ + $(CY_COMPILER_GCC_ARM_DIR)/arm-none-eabi/include\ + $(CY_COMPILER_GCC_ARM_DIR)/lib/gcc/arm-none-eabi/7.2.1/include\ + $(CY_COMPILER_GCC_ARM_DIR)/lib/gcc/arm-none-eabi/7.2.1/include-fixed + +# +# Additional libraries in the link process based on this toolchain +# +CY_TOOLCHAIN_DEFINES= + +# +# M2BIN tool is used to convert Mach-O to binary +# +CY_TOOLCHAIN_M2BIN=$(CY_BASELIB_PATH)/make/scripts/m2bin diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/GCC_ARM.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/GCC_ARM.mk new file mode 100644 index 0000000000..52ec8bcaa5 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/GCC_ARM.mk @@ -0,0 +1,174 @@ +################################################################################ +# \file GCC_ARM.mk +# \version 1.0 +# +# \brief +# GCC ARM toolchain configuration. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + +# +# The base path to the GCC cross compilation executables +# +ifeq ($(CY_COMPILER_PATH),) +CY_CROSSPATH=$(CY_COMPILER_GCC_ARM_DIR)/bin +else +CY_CROSSPATH=$(CY_COMPILER_PATH)/bin +endif + +# +# Build tools +# +CC=$(CY_CROSSPATH)/arm-none-eabi-gcc +CXX=$(CY_CROSSPATH)/arm-none-eabi-g++ +AS=$(CC) +AR=$(CY_CROSSPATH)/arm-none-eabi-ar +LD=$(CXX) + +# +# DEBUG/NDEBUG selection +# +ifeq ($(CONFIG),Debug) +CY_TOOLCHAIN_DEBUG_FLAG=-DDEBUG +CY_TOOLCHAIN_OPTIMIZATION=-Og +else ifeq ($(CONFIG),Release) +CY_TOOLCHAIN_DEBUG_FLAG=-DNDEBUG +CY_TOOLCHAIN_OPTIMIZATION=-Os +else +CY_TOOLCHAIN_DEBUG_FLAG= +CY_TOOLCHAIN_OPTIMIZATION= +endif + +# +# Flags common to compile and link +# +CY_TOOLCHAIN_COMMON_FLAGS=\ + -mthumb\ + -ffunction-sections\ + -fdata-sections\ + -ffat-lto-objects\ + -g\ + -Wall + +# +# CPU core specifics +# +ifeq ($(CORE),CM0P) +CY_TOOLCHAIN_FLAGS_CORE=-mcpu=cortex-m0plus +CY_TOOLCHAIN_VFP_FLAGS= +else +CY_TOOLCHAIN_FLAGS_CORE=-mcpu=cortex-m4 +ifeq ($(VFP_SELECT),hardfp) +CY_TOOLCHAIN_VFP_FLAGS=-mfloat-abi=hard -mfpu=fpv4-sp-d16 +else +CY_TOOLCHAIN_VFP_FLAGS=-mfloat-abi=softfp -mfpu=fpv4-sp-d16 +endif +endif + +# +# Command line flags for c-files +# +CY_TOOLCHAIN_CFLAGS=\ + -c\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_OPTIMIZATION)\ + $(CY_TOOLCHAIN_VFP_FLAGS)\ + $(CY_TOOLCHAIN_COMMON_FLAGS) + +# +# Command line flags for cpp-files +# +CY_TOOLCHAIN_CXXFLAGS=\ + $(CY_TOOLCHAIN_CFLAGS)\ + -fno-rtti\ + -fno-exceptions + +# +# Command line flags for s-files +# +CY_TOOLCHAIN_ASFLAGS=\ + -c\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_COMMON_FLAGS) + +# +# Command line flags for linking +# +CY_TOOLCHAIN_LDFLAGS=\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_VFP_FLAGS)\ + $(CY_TOOLCHAIN_COMMON_FLAGS)\ + --enable-objc-gc\ + --specs=nano.specs\ + -Wl,--gc-sections + +# +# Command line flags for archiving +# +CY_TOOLCHAIN_ARFLAGS=rvs + +# +# Toolchain-specific suffixes +# +CY_TOOLCHAIN_SUFFIX_S=S +CY_TOOLCHAIN_SUFFIX_s=s +CY_TOOLCHAIN_SUFFIX_C=c +CY_TOOLCHAIN_SUFFIX_H=h +CY_TOOLCHAIN_SUFFIX_CPP=cpp +CY_TOOLCHAIN_SUFFIX_HPP=hpp +CY_TOOLCHAIN_SUFFIX_O=o +CY_TOOLCHAIN_SUFFIX_A=a +CY_TOOLCHAIN_SUFFIX_D=d +CY_TOOLCHAIN_SUFFIX_LS=ld +CY_TOOLCHAIN_SUFFIX_MAP=map +CY_TOOLCHAIN_SUFFIX_TARGET=elf +CY_TOOLCHAIN_SUFFIX_ARCHIVE=a + +# +# Toolchain specific flags +# +CY_TOOLCHAIN_OUTPUT_OPTION=-o +CY_TOOLCHAIN_MAPFILE=-Wl,-Map, +CY_TOOLCHAIN_STARTGROUP=-Wl,--start-group +CY_TOOLCHAIN_ENDGROUP=-Wl,--end-group +CY_TOOLCHAIN_LSFLAGS=-T +CY_TOOLCHAIN_INCRSPFILE=@ +CY_TOOLCHAIN_INCRSPFILE_ASM=@ +CY_TOOLCHAIN_OBJRSPFILE=@ + +# +# Produce a makefile dependency rule for each input file +# +CY_TOOLCHAIN_DEPENDENCIES=-MMD -MP -MF "$(subst .$(CY_TOOLCHAIN_SUFFIX_O),.$(CY_TOOLCHAIN_SUFFIX_D),$@)" -MT "$@" + +# +# Additional includes in the compilation process based on this +# toolchain +# +CY_TOOLCHAIN_INCLUDES= + +# +# Additional libraries in the link process based on this toolchain +# +CY_TOOLCHAIN_DEFINES= + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/IAR.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/IAR.mk new file mode 100644 index 0000000000..64c5155ee5 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/toolchains/IAR.mk @@ -0,0 +1,187 @@ +################################################################################ +# \file IAR.mk +# \version 1.0 +# +# \brief +# IAR toolchain configuration. +# +################################################################################ +# \copyright +# Copyright 2018-2019 Cypress Semiconductor Corporation +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +################################################################################ + +ifeq ($(WHICHFILE),true) +$(info Processing $(lastword $(MAKEFILE_LIST))) +endif + +# +# The base path to the IAR cross compilation executables +# +ifeq ($(CY_COMPILER_PATH),) +CY_CROSSPATH=$(CY_COMPILER_IAR_DIR)/bin +else +CY_CROSSPATH=$(CY_COMPILER_PATH)/bin +endif + +# +# Build tools +# +CC=$(CY_CROSSPATH)/iccarm.exe +CXX=$(CC) +AS=$(CY_CROSSPATH)/iasmarm.exe +AR=$(CY_CROSSPATH)/iarchive.exe +LD=$(CY_CROSSPATH)/ilinkarm.exe + +# +# DEBUG/NDEBUG selection +# +ifeq ($(CONFIG),Debug) +CY_TOOLCHAIN_DEBUG_FLAG=-DDEBUG +CY_TOOLCHAIN_OPTIMIZATION=-Ol +else +ifeq ($(CONFIG),Release) +CY_TOOLCHAIN_DEBUG_FLAG=-DNDEBUG +CY_TOOLCHAIN_OPTIMIZATION=-Ohs +else +CY_TOOLCHAIN_DEBUG_FLAG= +CY_TOOLCHAIN_OPTIMIZATION= +endif +endif + +# +# Flags common to compile and link +# +ifneq ($(VERBOSE),) +CY_TOOLCHAIN_SILENT_CFLAGS= +CY_TOOLCHAIN_SILENT_SFLAGS= +else +CY_TOOLCHAIN_SILENT_CFLAGS=--silent +CY_TOOLCHAIN_SILENT_SFLAGS=-S +endif + +# +# CPU core specifics +# +ifeq ($(CORE),CM0P) +CY_TOOLCHAIN_FLAGS_CORE=--cpu Cortex-M0+ +CY_TOOLCHAIN_VFP_FLAGS= +else +CY_TOOLCHAIN_FLAGS_CORE=--cpu Cortex-M4 +CY_TOOLCHAIN_VFP_FLAGS=--fpu FPv4-SP +ifeq ($(VFP_SELECT),hardfp) +CY_TOOLCHAIN_VFP_CFLAGS=$(CY_TOOLCHAIN_VFP_FLAGS) --aapcs vfp +else +CY_TOOLCHAIN_VFP_CFLAGS=$(CY_TOOLCHAIN_VFP_FLAGS) --aapcs std +endif +endif + +# +# Command line flags for c-files +# +CY_TOOLCHAIN_CFLAGS=\ + -c\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_OPTIMIZATION)\ + $(CY_TOOLCHAIN_VFP_CFLAGS)\ + $(CY_TOOLCHAIN_SILENT_CFLAGS)\ + --endian=little\ + -e\ + --enable_restrict\ + --no_wrap_diagnostics + +ifeq ($(CONFIG),Debug) +CY_TOOLCHAIN_CFLAGS+=--debug +endif + +# +# Command line flags for cpp-files +# +CY_TOOLCHAIN_CXXFLAGS=\ + $(CY_TOOLCHAIN_CFLAGS)\ + --c++\ + --no_rtti\ + --no_exceptions + +# +# Command line flags for s-files +# +CY_TOOLCHAIN_ASFLAGS=\ + -c\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_VFP_FLAGS)\ + $(CY_TOOLCHAIN_SILENT_SFLAGS)\ + -s+\ + -w+\ + -r + +# +# Command line flags for linking +# +CY_TOOLCHAIN_LDFLAGS=\ + $(CY_TOOLCHAIN_FLAGS_CORE)\ + $(CY_TOOLCHAIN_VFP_FLAGS)\ + $(CY_TOOLCHAIN_SILENT_CFLAGS)\ + +# +# Command line flags for archiving +# +CY_TOOLCHAIN_ARFLAGS=\ + --create\ + --verbose + +# +# Toolchain-specific suffixes +# +CY_TOOLCHAIN_SUFFIX_S=S +CY_TOOLCHAIN_SUFFIX_s=s +CY_TOOLCHAIN_SUFFIX_C=c +CY_TOOLCHAIN_SUFFIX_H=h +CY_TOOLCHAIN_SUFFIX_CPP=cpp +CY_TOOLCHAIN_SUFFIX_HPP=hpp +CY_TOOLCHAIN_SUFFIX_O=o +CY_TOOLCHAIN_SUFFIX_A=a +CY_TOOLCHAIN_SUFFIX_D=d +CY_TOOLCHAIN_SUFFIX_LS=icf +CY_TOOLCHAIN_SUFFIX_MAP=map +CY_TOOLCHAIN_SUFFIX_TARGET=elf +CY_TOOLCHAIN_SUFFIX_ARCHIVE=a + +# +# Toolchain specific flags +# +CY_TOOLCHAIN_OUTPUT_OPTION=-o +CY_TOOLCHAIN_MAPFILE=--map= +CY_TOOLCHAIN_LSFLAGS=--config= +CY_TOOLCHAIN_INCRSPFILE=-f +CY_TOOLCHAIN_INCRSPFILE_ASM=-f +CY_TOOLCHAIN_OBJRSPFILE=-f + +# +# Produce a makefile dependency rule for each input file +# +CY_TOOLCHAIN_DEPENDENCIES=--dependencies=m "$(subst .$(CY_TOOLCHAIN_SUFFIX_O),.$(CY_TOOLCHAIN_SUFFIX_D),$@)" + +# +# Additional includes in the compilation process based on this +# toolchain +# +CY_TOOLCHAIN_INCLUDES= + +# +# Additional libraries in the link process based on this toolchain +# +CY_TOOLCHAIN_DEFINES= + diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/udd/features.mk b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/udd/features.mk new file mode 100644 index 0000000000..d5e95c0287 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/make/udd/features.mk @@ -0,0 +1,45 @@ +# This file defines variables for various sets of devices. Each variable is a +# list of the MPNs that have that capability or feature. + +# Major device capabilities. +CY_DEVICES_WITH_M0P=CY8C6246BZI-D04 CY8C6247BZI-D44 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C6336BZI-BLD13 CY8C6347BZI-BLD43 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C6347FMI-BLD13 CY8C6347FMI-BLD43 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637BZI-MD76 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C68237BZ-BLE CY8C68237FM-BLE CY8C6247FDI-D02 CY8C6247FDI-D32 CY8C6336BZI-BUD13 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6247FDI-D52 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6336BZI-BLD14 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 CY8C6247WI-D54 CYB06447BZI-BLD54 CYB06447BZI-BLD53 CYB06447BZI-D54 CY8C6347LQI-BLD52 CY8C624ABZI-D44 CY8C624AAZI-D44 CY8C624AFNI-D43 CY8C624ABZI-D04 CY8C624ABZI-D14 CY8C624AAZI-D14 CY8C6248AZI-D14 CY8C6248BZI-D44 CY8C6248AZI-D44 CY8C6248FNI-D43 CY8C624ALQI-D42 CYB0644ABZI-S2D44 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624AAZI-S2D44 CY8C624AFNI-S2D43 CY8C624ABZI-S2D04 CY8C624ABZI-S2D14 CY8C624AAZI-S2D14 CY8C6248AZI-S2D14 CY8C6248BZI-S2D44 CY8C6248AZI-S2D44 CY8C6248FNI-S2D43 CY8C6245AZI-S3D72 CY8C6245LQI-S3D72 CY8C6245FNI-S3D71 CY8C6245AZI-S3D62 CY8C6245LQI-S3D62 CY8C6245AZI-S3D42 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245FNI-S3D41 CY8C6245AZI-S3D12 CY8C6245LQI-S3D12 CY8C6245FNI-S3D11 CY8C6245AZI-S3D02 CY8C6245LQI-S3D02 CY8C6245W-S3D72 +CY_DEVICES_WITH_BLE=CY8C6336BZI-BLF03 CY8C6316BZI-BLF03 CY8C6316BZI-BLF53 CY8C6336BZI-BLD13 CY8C6347BZI-BLD43 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C6347FMI-BLD13 CY8C6347FMI-BLD43 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C68237BZ-BLE CY8C68237FM-BLE CY8C6336BZI-BUD13 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6337BZI-BLF13 CY8C6336BZI-BLF04 CY8C6316BZI-BLF04 CY8C6316BZI-BLF54 CY8C6336BZI-BLD14 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 CYB06447BZI-BLD54 CYB06447BZI-BLD53 CY8C6336LQI-BLF02 CY8C6336LQI-BLF42 CY8C6347LQI-BLD52 +CY_DEVICES_WITH_UDBS=CY8C6116BZI-F54 CY8C6136BZI-F34 CY8C6137BZI-F34 CY8C6137BZI-F54 CY8C6117BZI-F34 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C6316BZI-BLF53 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637BZI-MD76 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C6247FDI-D32 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6247FDI-D52 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6316BZI-BLF54 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD33 CY8C6137WI-F54 CY8C6117WI-F34 CY8C6247WI-D54 CYB06447BZI-BLD54 CYB06447BZI-BLD53 CYB06447BZI-D54 CY8C6347LQI-BLD52 +CY_DEVICES_WITH_FS_USB=CY8C6036BZI-F04 CY8C6016BZI-F04 CY8C6116BZI-F54 CY8C6136BZI-F14 CY8C6136BZI-F34 CY8C6137BZI-F14 CY8C6137BZI-F34 CY8C6137BZI-F54 CY8C6117BZI-F34 CY8C6246BZI-D04 CY8C6247BZI-D44 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C637BZI-MD76 CY8C6137FDI-F02 CY8C6117FDI-F02 CY8C6247FDI-D02 CY8C6247FDI-D32 CY8C6336BZI-BUD13 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6136FDI-F42 CY8C6247FDI-D52 CY8C6136FTI-F42 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6336BZI-BLF04 CY8C6316BZI-BLF04 CY8C6316BZI-BLF54 CY8C6336BZI-BLD14 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 CY8C6137WI-F54 CY8C6117WI-F34 CY8C6247WI-D54 CYB06447BZI-BLD54 CYB06447BZI-D54 CY8C624ABZI-D44 CY8C624AAZI-D44 CY8C624AFNI-D43 CY8C624ABZI-D04 CY8C624ABZI-D14 CY8C624AAZI-D14 CY8C6248AZI-D14 CY8C6248BZI-D44 CY8C6248AZI-D44 CY8C6248FNI-D43 CY8C624ALQI-D42 CYB0644ABZI-S2D44 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624AAZI-S2D44 CY8C624AFNI-S2D43 CY8C624ABZI-S2D04 CY8C624ABZI-S2D14 CY8C624AAZI-S2D14 CY8C6248AZI-S2D14 CY8C6248BZI-S2D44 CY8C6248AZI-S2D44 CY8C6248FNI-S2D43 CY8C6245AZI-S3D72 CY8C6245LQI-S3D72 CY8C6245FNI-S3D71 CY8C6245AZI-S3D62 CY8C6245LQI-S3D62 CY8C6245AZI-S3D42 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245FNI-S3D41 CY8C6245AZI-S3D12 CY8C6245LQI-S3D12 CY8C6245FNI-S3D11 CY8C6245AZI-S3D02 CY8C6245LQI-S3D02 CY8C6245W-S3D72 +CY_DEVICES_WITH_CAPSENSE=CY8C6116BZI-F54 CY8C6136BZI-F14 CY8C6136BZI-F34 CY8C6137BZI-F14 CY8C6137BZI-F34 CY8C6137BZI-F54 CY8C6117BZI-F34 CY8C6247BZI-D44 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C6316BZI-BLF53 CY8C6336BZI-BLD13 CY8C6347BZI-BLD43 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C6347FMI-BLD13 CY8C6347FMI-BLD43 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637BZI-MD76 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C68237BZ-BLE CY8C68237FM-BLE CY8C6247FDI-D32 CY8C6336BZI-BUD13 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6337BZI-BLF13 CY8C6136FDI-F42 CY8C6247FDI-D52 CY8C6136FTI-F42 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6316BZI-BLF54 CY8C6336BZI-BLD14 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 CY8C6137WI-F54 CY8C6117WI-F34 CY8C6247WI-D54 CYB06447BZI-BLD54 CYB06447BZI-BLD53 CYB06447BZI-D54 CY8C6336LQI-BLF42 CY8C6347LQI-BLD52 CY8C624ABZI-D44 CY8C624AAZI-D44 CY8C624AFNI-D43 CY8C624ABZI-D14 CY8C624AAZI-D14 CY8C6248AZI-D14 CY8C6248BZI-D44 CY8C6248AZI-D44 CY8C6248FNI-D43 CY8C624ALQI-D42 CYB0644ABZI-S2D44 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624AAZI-S2D44 CY8C624AFNI-S2D43 CY8C624ABZI-S2D14 CY8C624AAZI-S2D14 CY8C6248AZI-S2D14 CY8C6248BZI-S2D44 CY8C6248AZI-S2D44 CY8C6248FNI-S2D43 CY8C6245AZI-S3D72 CY8C6245LQI-S3D72 CY8C6245FNI-S3D71 CY8C6245AZI-S3D42 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245FNI-S3D41 CY8C6245AZI-S3D12 CY8C6245LQI-S3D12 CY8C6245FNI-S3D11 CY8C6245W-S3D72 +CY_DEVICES_WITH_CRYPTO=CY8C6116BZI-F54 CY8C6137BZI-F54 CY8C6247BZI-D44 CY8C6247BZI-D54 CY8C6316BZI-BLF53 CY8C6347BZI-BLD43 CY8C6347BZI-BLD53 CY8C6347FMI-BLD43 CY8C6347FMI-BLD53 CY8C637BZI-MD76 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C68237BZ-BLE CY8C68237FM-BLE CY8C6347BZI-BUD43 CY8C6347BZI-BUD53 CY8C6136FDI-F42 CY8C6247FDI-D52 CY8C6136FTI-F42 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6316BZI-BLF54 CY8C6347BZI-BLD44 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD43 CY8C6137WI-F54 CY8C6247WI-D54 CYB06447BZI-BLD54 CYB06447BZI-BLD53 CYB06447BZI-D54 CY8C6336LQI-BLF42 CY8C6347LQI-BLD52 CY8C624ABZI-D44 CY8C624AAZI-D44 CY8C624AFNI-D43 CY8C6248BZI-D44 CY8C6248AZI-D44 CY8C6248FNI-D43 CY8C624ALQI-D42 CYB0644ABZI-S2D44 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624AAZI-S2D44 CY8C624AFNI-S2D43 CY8C6248BZI-S2D44 CY8C6248AZI-S2D44 CY8C6248FNI-S2D43 CY8C6245AZI-S3D72 CY8C6245LQI-S3D72 CY8C6245FNI-S3D71 CY8C6245AZI-S3D42 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245FNI-S3D41 CY8C6245W-S3D72 + +# Different classifications of devices. +CY_DEVICES_WITH_DIE_PSOC6ABLE2=CY8C6036BZI-F04 CY8C6016BZI-F04 CY8C6116BZI-F54 CY8C6136BZI-F14 CY8C6136BZI-F34 CY8C6137BZI-F14 CY8C6137BZI-F34 CY8C6137BZI-F54 CY8C6117BZI-F34 CY8C6246BZI-D04 CY8C6247BZI-D44 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C6336BZI-BLF03 CY8C6316BZI-BLF03 CY8C6316BZI-BLF53 CY8C6336BZI-BLD13 CY8C6347BZI-BLD43 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C6347FMI-BLD13 CY8C6347FMI-BLD43 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637BZI-MD76 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C68237BZ-BLE CY8C68237FM-BLE CY8C6137FDI-F02 CY8C6117FDI-F02 CY8C6247FDI-D02 CY8C6247FDI-D32 CY8C6336BZI-BUD13 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6337BZI-BLF13 CY8C6136FDI-F42 CY8C6247FDI-D52 CY8C6136FTI-F42 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6336BZI-BLF04 CY8C6316BZI-BLF04 CY8C6316BZI-BLF54 CY8C6336BZI-BLD14 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 CY8C6137WI-F54 CY8C6117WI-F34 CY8C6247WI-D54 CYB06447BZI-BLD54 CYB06447BZI-BLD53 CYB06447BZI-D54 CY8C6336LQI-BLF02 CY8C6336LQI-BLF42 CY8C6347LQI-BLD52 +CY_DEVICES_WITH_DIE_PSOC6A2M=CY8C624ABZI-D44 CY8C624AAZI-D44 CY8C624AFNI-D43 CY8C624ABZI-D04 CY8C624ABZI-D14 CY8C624AAZI-D14 CY8C6248AZI-D14 CY8C6248BZI-D44 CY8C6248AZI-D44 CY8C6248FNI-D43 CY8C624ALQI-D42 CYB0644ABZI-S2D44 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624AAZI-S2D44 CY8C624AFNI-S2D43 CY8C624ABZI-S2D04 CY8C624ABZI-S2D14 CY8C624AAZI-S2D14 CY8C6248AZI-S2D14 CY8C6248BZI-S2D44 CY8C6248AZI-S2D44 CY8C6248FNI-S2D43 +CY_DEVICES_WITH_DIE_PSOC6A512K=CY8C6245AZI-S3D72 CY8C6245LQI-S3D72 CY8C6245FNI-S3D71 CY8C6245AZI-S3D62 CY8C6245LQI-S3D62 CY8C6245AZI-S3D42 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245FNI-S3D41 CY8C6245AZI-S3D12 CY8C6245LQI-S3D12 CY8C6245FNI-S3D11 CY8C6245AZI-S3D02 CY8C6245LQI-S3D02 CY8C6245W-S3D72 + +CY_DEVICES_WITH_FLASH_KB_512=CY8C6036BZI-F04 CY8C6016BZI-F04 CY8C6116BZI-F54 CY8C6136BZI-F14 CY8C6136BZI-F34 CY8C6246BZI-D04 CY8C6336BZI-BLF03 CY8C6316BZI-BLF03 CY8C6316BZI-BLF53 CY8C6336BZI-BLD13 CY8C6336BZI-BUD13 CY8C6136FDI-F42 CY8C6136FTI-F42 CY8C6336BZI-BLF04 CY8C6316BZI-BLF04 CY8C6316BZI-BLF54 CY8C6336BZI-BLD14 CY8C6336LQI-BLF02 CY8C6336LQI-BLF42 CY8C6245AZI-S3D72 CY8C6245LQI-S3D72 CY8C6245FNI-S3D71 CY8C6245AZI-S3D62 CY8C6245LQI-S3D62 CY8C6245AZI-S3D42 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245FNI-S3D41 CY8C6245AZI-S3D12 CY8C6245LQI-S3D12 CY8C6245FNI-S3D11 CY8C6245AZI-S3D02 CY8C6245LQI-S3D02 CY8C6245W-S3D72 +CY_DEVICES_WITH_FLASH_KB_1024=CY8C6137BZI-F14 CY8C6137BZI-F34 CY8C6137BZI-F54 CY8C6117BZI-F34 CY8C6247BZI-D44 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C6347BZI-BLD43 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C6347FMI-BLD13 CY8C6347FMI-BLD43 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637BZI-MD76 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C68237BZ-BLE CY8C68237FM-BLE CY8C6137FDI-F02 CY8C6117FDI-F02 CY8C6247FDI-D02 CY8C6247FDI-D32 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6337BZI-BLF13 CY8C6247FDI-D52 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 CY8C6137WI-F54 CY8C6117WI-F34 CY8C6247WI-D54 CY8C6347LQI-BLD52 CY8C6248BZI-D44 CY8C6248AZI-D44 CY8C6248FNI-D43 CY8C6248BZI-S2D44 CY8C6248AZI-S2D44 CY8C6248FNI-S2D43 +CY_DEVICES_WITH_FLASH_KB_832=CYB06447BZI-BLD54 CYB06447BZI-BLD53 CYB06447BZI-D54 +CY_DEVICES_WITH_FLASH_KB_2048=CY8C624ABZI-D44 CY8C624AAZI-D44 CY8C624AFNI-D43 CY8C624ABZI-D04 CY8C624ABZI-D14 CY8C624AAZI-D14 CY8C6248AZI-D14 CY8C624ALQI-D42 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624AAZI-S2D44 CY8C624AFNI-S2D43 CY8C624ABZI-S2D04 CY8C624ABZI-S2D14 CY8C624AAZI-S2D14 CY8C6248AZI-S2D14 +CY_DEVICES_WITH_FLASH_KB_1856=CYB0644ABZI-S2D44 + +CY_DEVICES_WITH_SRAM_KB_128=CY8C6036BZI-F04 CY8C6016BZI-F04 CY8C6116BZI-F54 CY8C6136BZI-F14 CY8C6136BZI-F34 CY8C6246BZI-D04 CY8C6336BZI-BLF03 CY8C6316BZI-BLF03 CY8C6316BZI-BLF53 CY8C6336BZI-BLD13 CY8C6336BZI-BUD13 CY8C6136FDI-F42 CY8C6136FTI-F42 CY8C6336BZI-BLF04 CY8C6316BZI-BLF04 CY8C6316BZI-BLF54 CY8C6336BZI-BLD14 CY8C6336LQI-BLF02 CY8C6336LQI-BLF42 +CY_DEVICES_WITH_SRAM_KB_288=CY8C6137BZI-F14 CY8C6137BZI-F34 CY8C6137BZI-F54 CY8C6117BZI-F34 CY8C6247BZI-D44 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C6347BZI-BLD43 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C6347FMI-BLD13 CY8C6347FMI-BLD43 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637BZI-MD76 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C68237BZ-BLE CY8C68237FM-BLE CY8C6137FDI-F02 CY8C6117FDI-F02 CY8C6247FDI-D02 CY8C6247FDI-D32 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6337BZI-BLF13 CY8C6247FDI-D52 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 CY8C6137WI-F54 CY8C6117WI-F34 CY8C6247WI-D54 CYB06447BZI-BLD54 CYB06447BZI-BLD53 CYB06447BZI-D54 CY8C6347LQI-BLD52 +CY_DEVICES_WITH_SRAM_KB_1024=CY8C624ABZI-D44 CY8C624AAZI-D44 CY8C624AFNI-D43 CY8C624ABZI-D04 CY8C624ABZI-D14 CY8C624AAZI-D14 CY8C6248AZI-D14 CY8C624ALQI-D42 CYB0644ABZI-S2D44 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624AAZI-S2D44 CY8C624AFNI-S2D43 CY8C624ABZI-S2D04 CY8C624ABZI-S2D14 CY8C624AAZI-S2D14 CY8C6248AZI-S2D14 +CY_DEVICES_WITH_SRAM_KB_512=CY8C6248BZI-D44 CY8C6248AZI-D44 CY8C6248FNI-D43 CY8C6248BZI-S2D44 CY8C6248AZI-S2D44 CY8C6248FNI-S2D43 +CY_DEVICES_WITH_SRAM_KB_256=CY8C6245AZI-S3D72 CY8C6245LQI-S3D72 CY8C6245FNI-S3D71 CY8C6245AZI-S3D62 CY8C6245LQI-S3D62 CY8C6245AZI-S3D42 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245FNI-S3D41 CY8C6245AZI-S3D12 CY8C6245LQI-S3D12 CY8C6245FNI-S3D11 CY8C6245AZI-S3D02 CY8C6245LQI-S3D02 CY8C6245W-S3D72 + +CY_DEVICES_WITH_MAX_SPEED_MHZ_150=CY8C6036BZI-F04 CY8C6136BZI-F14 CY8C6136BZI-F34 CY8C6137BZI-F14 CY8C6137BZI-F34 CY8C6137BZI-F54 CY8C6246BZI-D04 CY8C6247BZI-D44 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C6336BZI-BLF03 CY8C6336BZI-BLD13 CY8C6347BZI-BLD43 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C6347FMI-BLD13 CY8C6347FMI-BLD43 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637BZI-MD76 CY8C637BZI-BLD74 CY8C637FMI-BLD73 CY8C68237BZ-BLE CY8C68237FM-BLE CY8C6137FDI-F02 CY8C6247FDI-D02 CY8C6247FDI-D32 CY8C6336BZI-BUD13 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 CY8C6337BZI-BLF13 CY8C6136FDI-F42 CY8C6247FDI-D52 CY8C6136FTI-F42 CY8C6247FTI-D52 CY8C6247BZI-AUD54 CY8C6336BZI-BLF04 CY8C6336BZI-BLD14 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CY8C6247BFI-D54 CYBLE-416045-02 CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 CY8C6137WI-F54 CY8C6247WI-D54 CYB06447BZI-BLD54 CYB06447BZI-BLD53 CYB06447BZI-D54 CY8C6336LQI-BLF02 CY8C6336LQI-BLF42 CY8C6347LQI-BLD52 CY8C624ABZI-D44 CY8C624AAZI-D44 CY8C624AFNI-D43 CY8C624ABZI-D04 CY8C624ABZI-D14 CY8C624AAZI-D14 CY8C6248AZI-D14 CY8C6248BZI-D44 CY8C6248AZI-D44 CY8C6248FNI-D43 CY8C624ALQI-D42 CYB0644ABZI-S2D44 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624AAZI-S2D44 CY8C624AFNI-S2D43 CY8C624ABZI-S2D04 CY8C624ABZI-S2D14 CY8C624AAZI-S2D14 CY8C6248AZI-S2D14 CY8C6248BZI-S2D44 CY8C6248AZI-S2D44 CY8C6248FNI-S2D43 CY8C6245AZI-S3D72 CY8C6245LQI-S3D72 CY8C6245FNI-S3D71 CY8C6245AZI-S3D62 CY8C6245LQI-S3D62 CY8C6245AZI-S3D42 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245FNI-S3D41 CY8C6245AZI-S3D12 CY8C6245LQI-S3D12 CY8C6245FNI-S3D11 CY8C6245AZI-S3D02 CY8C6245LQI-S3D02 CY8C6245W-S3D72 +CY_DEVICES_WITH_MAX_SPEED_MHZ_50=CY8C6016BZI-F04 CY8C6116BZI-F54 CY8C6117BZI-F34 CY8C6316BZI-BLF03 CY8C6316BZI-BLF53 CY8C6117FDI-F02 CY8C6316BZI-BLF04 CY8C6316BZI-BLF54 CY8C6117WI-F34 + +CY_DEVICES_WITH_PACKAGE_124-BGA=CY8C6036BZI-F04 CY8C6016BZI-F04 CY8C6116BZI-F54 CY8C6136BZI-F14 CY8C6136BZI-F34 CY8C6137BZI-F14 CY8C6137BZI-F34 CY8C6137BZI-F54 CY8C6117BZI-F34 CY8C6246BZI-D04 CY8C6247BZI-D44 CY8C6247BZI-D34 CY8C6247BZI-D54 CY8C637BZI-MD76 CY8C6247BZI-AUD54 CY8C6247BFI-D54 CY8C6137WI-F54 CY8C6117WI-F34 CY8C6247WI-D54 CYB06447BZI-D54 CY8C624ABZI-D44 CY8C624ABZI-D04 CY8C624ABZI-D14 CY8C6248BZI-D44 CYB0644ABZI-S2D44 CY8C624ABZI-S2D44A0 CY8C624ABZI-S2D44 CY8C624ABZI-S2D04 CY8C624ABZI-S2D14 CY8C6248BZI-S2D44 +CY_DEVICES_WITH_PACKAGE_116-BGA-BLE=CY8C6336BZI-BLF03 CY8C6316BZI-BLF03 CY8C6316BZI-BLF53 CY8C6336BZI-BLD13 CY8C6347BZI-BLD43 CY8C6347BZI-BLD33 CY8C6347BZI-BLD53 CY8C637BZI-BLD74 CY8C68237BZ-BLE CY8C6337BZI-BLF13 CYB06447BZI-BLD53 +CY_DEVICES_WITH_PACKAGE_104-M-CSP-BLE=CY8C6347FMI-BLD13 CY8C6347FMI-BLD43 CY8C6347FMI-BLD33 CY8C6347FMI-BLD53 CY8C637FMI-BLD73 CY8C68237FM-BLE +CY_DEVICES_WITH_PACKAGE_80-WLCSP=CY8C6137FDI-F02 CY8C6117FDI-F02 CY8C6247FDI-D02 CY8C6247FDI-D32 CY8C6136FDI-F42 CY8C6247FDI-D52 CY8C6136FTI-F42 CY8C6247FTI-D52 +CY_DEVICES_WITH_PACKAGE_116-BGA-USB=CY8C6336BZI-BUD13 CY8C6347BZI-BUD43 CY8C6347BZI-BUD33 CY8C6347BZI-BUD53 +CY_DEVICES_WITH_PACKAGE_124-BGA-SIP=CY8C6336BZI-BLF04 CY8C6316BZI-BLF04 CY8C6316BZI-BLF54 CY8C6336BZI-BLD14 CY8C6347BZI-BLD44 CY8C6347BZI-BLD34 CY8C6347BZI-BLD54 CYB06447BZI-BLD54 +CY_DEVICES_WITH_PACKAGE_43-SMT=CYBLE-416045-02 +CY_DEVICES_WITH_PACKAGE_104-M-CSP-BLE-USB=CY8C6347FMI-BUD53 CY8C6347FMI-BUD13 CY8C6347FMI-BUD43 CY8C6347FMI-BUD33 +CY_DEVICES_WITH_PACKAGE_68-QFN-BLE=CY8C6336LQI-BLF02 CY8C6336LQI-BLF42 CY8C6347LQI-BLD52 +CY_DEVICES_WITH_PACKAGE_128-TQFP=CY8C624AAZI-D44 CY8C624AAZI-D14 CY8C6248AZI-D14 CY8C6248AZI-D44 CY8C624AAZI-S2D44 CY8C624AAZI-S2D14 CY8C6248AZI-S2D14 CY8C6248AZI-S2D44 +CY_DEVICES_WITH_PACKAGE_100-WLCSP=CY8C624AFNI-D43 CY8C6248FNI-D43 CY8C624AFNI-S2D43 CY8C6248FNI-S2D43 +CY_DEVICES_WITH_PACKAGE_68-QFN=CY8C624ALQI-D42 CY8C6245LQI-S3D72 CY8C6245LQI-S3D62 CY8C6245LQI-S3D42 CYB06445LQI-S3D42 CY8C6245LQI-S3D12 CY8C6245LQI-S3D02 +CY_DEVICES_WITH_PACKAGE_100-TQFP=CY8C6245AZI-S3D72 CY8C6245AZI-S3D62 CY8C6245AZI-S3D42 CY8C6245AZI-S3D12 CY8C6245AZI-S3D02 CY8C6245W-S3D72 +CY_DEVICES_WITH_PACKAGE_49-WLCSP=CY8C6245FNI-S3D71 CY8C6245FNI-S3D41 CY8C6245FNI-S3D11 diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/version.xml b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/version.xml new file mode 100644 index 0000000000..0c4180cb3d --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/psoc6make/version.xml @@ -0,0 +1 @@ +1.0.1.8025 diff --git a/bsp/cypress/psoc6-pioneerkit_modus/makefile.init b/bsp/cypress/psoc6-pioneerkit_modus/makefile.init new file mode 100644 index 0000000000..6721bdc2e2 --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/makefile.init @@ -0,0 +1,2 @@ +export MAKE=make +export PATH:=/usr/bin:$(PATH) diff --git a/bsp/cypress/psoc6-pioneerkit_modus/rtconfig.h b/bsp/cypress/psoc6-pioneerkit_modus/rtconfig.h new file mode 100644 index 0000000000..def5a08aff --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/rtconfig.h @@ -0,0 +1,156 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDEL_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 1024 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_DEBUG + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE +#define RT_USING_SIGNALS + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP +#define RT_USING_SMALL_MEM +#define RT_USING_MEMTRACE +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart0" +#define RT_VER_NUM 0x40000 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + + +/* Command shell */ + +#define RT_USING_FINSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SERIAL +#define RT_SERIAL_USING_DMA +#define RT_USING_PIN + +/* Using WiFi */ + + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC + +/* Network */ + +/* Socket abstraction layer */ + + +/* light weight TCP/IP stack */ + + +/* Modbus master and slave stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + +#define RT_USING_UART0 + +#endif -- Gitee From 88667374d5c027e9cae57b93ea59c00a68150a17 Mon Sep 17 00:00:00 2001 From: amy qian Date: Fri, 3 Jan 2020 17:20:12 +0800 Subject: [PATCH 034/110] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/cypress/psoc6-pioneerkit_modus/README.md | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/bsp/cypress/psoc6-pioneerkit_modus/README.md b/bsp/cypress/psoc6-pioneerkit_modus/README.md index bc3ba2803e..efca91f4b0 100644 --- a/bsp/cypress/psoc6-pioneerkit_modus/README.md +++ b/bsp/cypress/psoc6-pioneerkit_modus/README.md @@ -83,20 +83,20 @@ CY8CKIT-062-BLE PSoC6 BLE Pioneer Kit 是赛普拉斯推出的一款32位双核C 注:推荐使用串口调试助手如:sscom - msh > - \ | / - - RT - Thread Operating System - / | \ 4.0.3 build Jan 3 2020 - 2006 - 2019 Copyright by rt-thread team - thread1 created ok - thread1 count: 0 - thread2 created ok - thread2 count: 0 - thread2 count: 1 - thread2 count: 2 - thread2 count: 3 - thread1 count: 1 - thread2 count: 4 +msh > +\ | / +- RT - Thread Operating System +/ | \ 4.0.3 build Jan 3 2020 +2006 - 2019 Copyright by rt-thread team +thread1 created ok +thread1 count: 0 +thread2 created ok +thread2 count: 0 +thread2 count: 1 +thread2 count: 2 +thread2 count: 3 +thread1 count: 1 +thread2 count: 4 ## 联系人信息 -- Gitee From f76b3f9aa0ff1b7ea2968d3e66e9652d850f61ea Mon Sep 17 00:00:00 2001 From: amy qian Date: Fri, 3 Jan 2020 17:30:28 +0800 Subject: [PATCH 035/110] =?UTF-8?q?readme=E4=BF=AE=E6=94=B9=E4=BA=86?= =?UTF-8?q?=E4=B8=8B=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/cypress/psoc6-pioneerkit_modus/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/bsp/cypress/psoc6-pioneerkit_modus/README.md b/bsp/cypress/psoc6-pioneerkit_modus/README.md index efca91f4b0..ca8a7cd55c 100644 --- a/bsp/cypress/psoc6-pioneerkit_modus/README.md +++ b/bsp/cypress/psoc6-pioneerkit_modus/README.md @@ -82,12 +82,12 @@ CY8CKIT-062-BLE PSoC6 BLE Pioneer Kit 是赛普拉斯推出的一款32位双核C 下载程序成功之后,系统会自动运行。打开终端工具串口小助手,复位设备后,可以看到 RT-Thread 的输出信息: 注:推荐使用串口调试助手如:sscom - -msh > -\ | / + +``` + \ | / - RT - Thread Operating System -/ | \ 4.0.3 build Jan 3 2020 -2006 - 2019 Copyright by rt-thread team + / | \ 4.0.3 build Jan 3 2020 + 2006 - 2019 Copyright by rt-thread team thread1 created ok thread1 count: 0 thread2 created ok @@ -97,7 +97,8 @@ thread2 count: 2 thread2 count: 3 thread1 count: 1 thread2 count: 4 - +thread2 count: 5 +``` ## 联系人信息 -- Gitee From 220343ab7e718977fc1d5377a32d41c699704c56 Mon Sep 17 00:00:00 2001 From: amy qian Date: Fri, 3 Jan 2020 17:44:00 +0800 Subject: [PATCH 036/110] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86readme?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/cypress/psoc6-pioneerkit_modus/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bsp/cypress/psoc6-pioneerkit_modus/README.md b/bsp/cypress/psoc6-pioneerkit_modus/README.md index ca8a7cd55c..27b113c1c2 100644 --- a/bsp/cypress/psoc6-pioneerkit_modus/README.md +++ b/bsp/cypress/psoc6-pioneerkit_modus/README.md @@ -34,9 +34,7 @@ CY8CKIT-062-BLE PSoC6 BLE Pioneer Kit 是赛普拉斯推出的一款32位双核C ## 外设支持 -本 BSP 目前对外设的支持情况如下: - -开发板更多详细信息请参考文档 https://www.cypress.com/file/390496/download +本 BSP 目前对外设的支持情况详细信息请参考文档 https://www.cypress.com/file/390496/download ## 使用说明 -- Gitee From ead5f07c5f747e970b9ee5320d5086a4ed6e1bfd Mon Sep 17 00:00:00 2001 From: liuxinaliang Date: Fri, 3 Jan 2020 17:59:10 +0800 Subject: [PATCH 037/110] [bsp][stm32] change tab into whitespace Signed-off-by: liuxinaliang --- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s | 2 +- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s | 2 +- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s | 2 +- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s | 2 +- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s | 2 +- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s | 2 +- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s | 2 +- .../ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s index 816b49db7c..895acc38c7 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g431xx.s @@ -99,7 +99,7 @@ LoopFillZerobss: /* Call static constructors */ /* bl __libc_init_array */ /* Call the application's entry point.*/ - bl entry + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s index 32e51a7493..cc8cb00ce9 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g441xx.s @@ -99,7 +99,7 @@ LoopFillZerobss: /* Call static constructors */ /* bl __libc_init_array */ /* Call the application's entry point.*/ - bl entry + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s index 95a9bfecbc..3924adbc0a 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g471xx.s @@ -99,7 +99,7 @@ LoopFillZerobss: /* Call static constructors */ /* bl __libc_init_array */ /* Call the application's entry point.*/ - bl entry + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s index a6a3cfa206..86e0db30ec 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g473xx.s @@ -99,7 +99,7 @@ LoopFillZerobss: /* Call static constructors */ /* bl __libc_init_array */ /* Call the application's entry point.*/ - bl entry + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s index 3ad8ccee4d..8a418820c3 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g474xx.s @@ -99,7 +99,7 @@ LoopFillZerobss: /* Call static constructors */ /* bl __libc_init_array */ /* Call the application's entry point.*/ - bl entry + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s index 0eeb0b1850..c6c52988de 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g483xx.s @@ -99,7 +99,7 @@ LoopFillZerobss: /* Call static constructors */ /* bl __libc_init_array */ /* Call the application's entry point.*/ - bl entry + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s index dd8d6207d0..42d8b4c3a0 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32g484xx.s @@ -98,7 +98,7 @@ LoopFillZerobss: /* Call static constructors */ /* bl __libc_init_array */ /* Call the application's entry point.*/ - bl entry + bl entry LoopForever: b LoopForever diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s index 4e9a9963af..ae2df5a669 100644 --- a/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s +++ b/bsp/stm32/libraries/STM32G4xx_HAL/CMSIS/Device/ST/STM32G4xx/Source/Templates/gcc/startup_stm32gbk1cb.s @@ -95,7 +95,7 @@ LoopFillZerobss: /* Call static constructors */ /* bl __libc_init_array */ /* Call the application's entry point.*/ - bl entry + bl entry LoopForever: b LoopForever -- Gitee From 75e832c65e3c9d4c9f7805f74e1d156e0cf02e2f Mon Sep 17 00:00:00 2001 From: linyiyang <393676163@qq.com> Date: Mon, 6 Jan 2020 09:12:45 +0800 Subject: [PATCH 038/110] [bsp][stm32]add stm32f103-atk-warshipv3 sram driver --- bsp/stm32/libraries/STM32F1xx_HAL/SConscript | 5 +- .../board/CubeMX_Config/.mxproject | 4 +- .../board/CubeMX_Config/CubeMX_Config.ioc | 201 ++++++++++++++++-- .../CubeMX_Config/Inc/stm32f1xx_hal_conf.h | 2 +- .../board/CubeMX_Config/Src/main.c | 65 ++++++ .../CubeMX_Config/Src/stm32f1xx_hal_msp.c | 184 ++++++++++++++++ .../stm32f103-atk-warshipv3/board/Kconfig | 4 + .../stm32f103-atk-warshipv3/board/SConscript | 4 + .../board/ports/drv_sram.c | 168 +++++++++++++++ .../board/ports/include/sram_port.h | 22 ++ 10 files changed, 638 insertions(+), 21 deletions(-) create mode 100644 bsp/stm32/stm32f103-atk-warshipv3/board/ports/drv_sram.c create mode 100644 bsp/stm32/stm32f103-atk-warshipv3/board/ports/include/sram_port.h diff --git a/bsp/stm32/libraries/STM32F1xx_HAL/SConscript b/bsp/stm32/libraries/STM32F1xx_HAL/SConscript index af0704c81e..01242a9817 100644 --- a/bsp/stm32/libraries/STM32F1xx_HAL/SConscript +++ b/bsp/stm32/libraries/STM32F1xx_HAL/SConscript @@ -16,7 +16,6 @@ STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cec.c -STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c """) @@ -75,6 +74,10 @@ if GetDepend(['RT_USING_MTD_NOR']): if GetDepend(['RT_USING_MTD_NAND']): src += ['STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nand.c'] +if GetDepend(['BSP_USING_SRAM']): + src += ['STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c'] + src += ['STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c'] + if GetDepend(['BSP_USING_ON_CHIP_FLASH']): src += ['STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c'] src += ['STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c'] diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/.mxproject index b231b540b3..06ad37afbd 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/.mxproject +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/.mxproject @@ -5,10 +5,10 @@ SourcePath=F:/rt-thread/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Sr SourceFiles=stm32f1xx_it.c;stm32f1xx_hal_msp.c;main.c; [PreviousLibFiles] -LibFiles=Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; +LibFiles=Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_fsmc.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_sram.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; [PreviousUsedKeilFiles] -SourceFiles=..\Src\main.c;..\Src\stm32f1xx_it.c;..\Src\stm32f1xx_hal_msp.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;..\\Src/system_stm32f1xx.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;..\\Src/system_stm32f1xx.c;..\Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;; +SourceFiles=..\Src\main.c;..\Src\stm32f1xx_it.c;..\Src\stm32f1xx_hal_msp.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;..\\Src/system_stm32f1xx.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;..\Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;..\\Src/system_stm32f1xx.c;..\Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;; HeaderPath=..\Drivers\STM32F1xx_HAL_Driver\Inc;..\Drivers\STM32F1xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F1xx\Include;..\Drivers\CMSIS\Include;..\Inc; CDefines=USE_HAL_DRIVER;STM32F103xE;USE_HAL_DRIVER;USE_HAL_DRIVER; diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/CubeMX_Config.ioc index bee20f0926..3ad31b6277 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/CubeMX_Config.ioc +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/CubeMX_Config.ioc @@ -1,27 +1,73 @@ #MicroXplorer Configuration settings - do not modify +FSMC.AddressSetupTime1=0 +FSMC.BusTurnAroundDuration1=0 +FSMC.DataSetupTime1=3 +FSMC.IPParameters=AddressSetupTime1,DataSetupTime1,BusTurnAroundDuration1,WriteOperation1 +FSMC.WriteOperation1=FSMC_WRITE_OPERATION_ENABLE File.Version=6 KeepUserPlacement=false Mcu.Family=STM32F1 -Mcu.IP0=NVIC -Mcu.IP1=RCC -Mcu.IP2=SYS -Mcu.IP3=TIM3 -Mcu.IP4=USART1 -Mcu.IPNb=5 +Mcu.IP0=FSMC +Mcu.IP1=NVIC +Mcu.IP2=RCC +Mcu.IP3=SYS +Mcu.IP4=TIM3 +Mcu.IP5=USART1 +Mcu.IPNb=6 Mcu.Name=STM32F103Z(C-D-E)Tx Mcu.Package=LQFP144 Mcu.Pin0=PC14-OSC32_IN Mcu.Pin1=PC15-OSC32_OUT -Mcu.Pin10=VP_SYS_VS_Systick -Mcu.Pin2=OSC_IN -Mcu.Pin3=OSC_OUT -Mcu.Pin4=PC6 -Mcu.Pin5=PC7 -Mcu.Pin6=PA9 -Mcu.Pin7=PA10 -Mcu.Pin8=PA13 -Mcu.Pin9=PA14 -Mcu.PinsNb=11 +Mcu.Pin10=PF12 +Mcu.Pin11=PF13 +Mcu.Pin12=PF14 +Mcu.Pin13=PF15 +Mcu.Pin14=PG0 +Mcu.Pin15=PG1 +Mcu.Pin16=PE7 +Mcu.Pin17=PE8 +Mcu.Pin18=PE9 +Mcu.Pin19=PE10 +Mcu.Pin2=PF0 +Mcu.Pin20=PE11 +Mcu.Pin21=PE12 +Mcu.Pin22=PE13 +Mcu.Pin23=PE14 +Mcu.Pin24=PE15 +Mcu.Pin25=PD8 +Mcu.Pin26=PD9 +Mcu.Pin27=PD10 +Mcu.Pin28=PD11 +Mcu.Pin29=PD12 +Mcu.Pin3=PF1 +Mcu.Pin30=PD13 +Mcu.Pin31=PD14 +Mcu.Pin32=PD15 +Mcu.Pin33=PG2 +Mcu.Pin34=PG3 +Mcu.Pin35=PG4 +Mcu.Pin36=PG5 +Mcu.Pin37=PC6 +Mcu.Pin38=PC7 +Mcu.Pin39=PA9 +Mcu.Pin4=PF2 +Mcu.Pin40=PA10 +Mcu.Pin41=PA13 +Mcu.Pin42=PA14 +Mcu.Pin43=PD0 +Mcu.Pin44=PD1 +Mcu.Pin45=PD4 +Mcu.Pin46=PD5 +Mcu.Pin47=PG10 +Mcu.Pin48=PE0 +Mcu.Pin49=PE1 +Mcu.Pin5=PF3 +Mcu.Pin50=VP_SYS_VS_Systick +Mcu.Pin6=PF4 +Mcu.Pin7=PF5 +Mcu.Pin8=OSC_IN +Mcu.Pin9=OSC_OUT +Mcu.PinsNb=51 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F103ZETx @@ -66,6 +112,49 @@ PCC.Seq0=0 PCC.Series=STM32F1 PCC.Temperature=25 PCC.Vdd=3.3 +PD0.Signal=FSMC_D2_DA2 +PD1.Signal=FSMC_D3_DA3 +PD10.Signal=FSMC_D15_DA15 +PD11.Signal=FSMC_A16_CLE +PD12.Signal=FSMC_A17_ALE +PD13.Signal=FSMC_A18 +PD14.Signal=FSMC_D0_DA0 +PD15.Signal=FSMC_D1_DA1 +PD4.Signal=FSMC_NOE +PD5.Signal=FSMC_NWE +PD8.Signal=FSMC_D13_DA13 +PD9.Signal=FSMC_D14_DA14 +PE0.Locked=true +PE0.Signal=FSMC_NBL0 +PE1.Locked=true +PE1.Signal=FSMC_NBL1 +PE10.Signal=FSMC_D7_DA7 +PE11.Signal=FSMC_D8_DA8 +PE12.Signal=FSMC_D9_DA9 +PE13.Signal=FSMC_D10_DA10 +PE14.Signal=FSMC_D11_DA11 +PE15.Signal=FSMC_D12_DA12 +PE7.Signal=FSMC_D4_DA4 +PE8.Signal=FSMC_D5_DA5 +PE9.Signal=FSMC_D6_DA6 +PF0.Signal=FSMC_A0 +PF1.Signal=FSMC_A1 +PF12.Signal=FSMC_A6 +PF13.Signal=FSMC_A7 +PF14.Signal=FSMC_A8 +PF15.Signal=FSMC_A9 +PF2.Signal=FSMC_A2 +PF3.Signal=FSMC_A3 +PF4.Signal=FSMC_A4 +PF5.Signal=FSMC_A5 +PG0.Signal=FSMC_A10 +PG1.Signal=FSMC_A11 +PG10.Mode=NorPsramChipSelect3_1 +PG10.Signal=FSMC_NE3 +PG2.Signal=FSMC_A12 +PG3.Signal=FSMC_A13 +PG4.Signal=FSMC_A14 +PG5.Signal=FSMC_A15 PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false @@ -93,7 +182,7 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=MDK-ARM V5 ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_TIM8_Init-TIM8-false-HAL-true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_FSMC_Init-FSMC-false-HAL-true,5-MX_TIM3_Init-TIM3-false-HAL-true RCC.ADCFreqValue=36000000 RCC.AHBFreq_Value=72000000 RCC.APB1CLKDivider=RCC_HCLK_DIV2 @@ -120,6 +209,84 @@ RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK RCC.TimSysFreq_Value=72000000 RCC.USBFreq_Value=72000000 RCC.VCOOutput2Freq_Value=8000000 +SH.FSMC_A0.0=FSMC_A0,19b-a1 +SH.FSMC_A0.ConfNb=1 +SH.FSMC_A1.0=FSMC_A1,19b-a1 +SH.FSMC_A1.ConfNb=1 +SH.FSMC_A10.0=FSMC_A10,19b-a1 +SH.FSMC_A10.ConfNb=1 +SH.FSMC_A11.0=FSMC_A11,19b-a1 +SH.FSMC_A11.ConfNb=1 +SH.FSMC_A12.0=FSMC_A12,19b-a1 +SH.FSMC_A12.ConfNb=1 +SH.FSMC_A13.0=FSMC_A13,19b-a1 +SH.FSMC_A13.ConfNb=1 +SH.FSMC_A14.0=FSMC_A14,19b-a1 +SH.FSMC_A14.ConfNb=1 +SH.FSMC_A15.0=FSMC_A15,19b-a1 +SH.FSMC_A15.ConfNb=1 +SH.FSMC_A16_CLE.0=FSMC_A16,19b-a1 +SH.FSMC_A16_CLE.ConfNb=1 +SH.FSMC_A17_ALE.0=FSMC_A17,19b-a1 +SH.FSMC_A17_ALE.ConfNb=1 +SH.FSMC_A18.0=FSMC_A18,19b-a1 +SH.FSMC_A18.ConfNb=1 +SH.FSMC_A2.0=FSMC_A2,19b-a1 +SH.FSMC_A2.ConfNb=1 +SH.FSMC_A3.0=FSMC_A3,19b-a1 +SH.FSMC_A3.ConfNb=1 +SH.FSMC_A4.0=FSMC_A4,19b-a1 +SH.FSMC_A4.ConfNb=1 +SH.FSMC_A5.0=FSMC_A5,19b-a1 +SH.FSMC_A5.ConfNb=1 +SH.FSMC_A6.0=FSMC_A6,19b-a1 +SH.FSMC_A6.ConfNb=1 +SH.FSMC_A7.0=FSMC_A7,19b-a1 +SH.FSMC_A7.ConfNb=1 +SH.FSMC_A8.0=FSMC_A8,19b-a1 +SH.FSMC_A8.ConfNb=1 +SH.FSMC_A9.0=FSMC_A9,19b-a1 +SH.FSMC_A9.ConfNb=1 +SH.FSMC_D0_DA0.0=FSMC_D0,16b-d1 +SH.FSMC_D0_DA0.ConfNb=1 +SH.FSMC_D10_DA10.0=FSMC_D10,16b-d1 +SH.FSMC_D10_DA10.ConfNb=1 +SH.FSMC_D11_DA11.0=FSMC_D11,16b-d1 +SH.FSMC_D11_DA11.ConfNb=1 +SH.FSMC_D12_DA12.0=FSMC_D12,16b-d1 +SH.FSMC_D12_DA12.ConfNb=1 +SH.FSMC_D13_DA13.0=FSMC_D13,16b-d1 +SH.FSMC_D13_DA13.ConfNb=1 +SH.FSMC_D14_DA14.0=FSMC_D14,16b-d1 +SH.FSMC_D14_DA14.ConfNb=1 +SH.FSMC_D15_DA15.0=FSMC_D15,16b-d1 +SH.FSMC_D15_DA15.ConfNb=1 +SH.FSMC_D1_DA1.0=FSMC_D1,16b-d1 +SH.FSMC_D1_DA1.ConfNb=1 +SH.FSMC_D2_DA2.0=FSMC_D2,16b-d1 +SH.FSMC_D2_DA2.ConfNb=1 +SH.FSMC_D3_DA3.0=FSMC_D3,16b-d1 +SH.FSMC_D3_DA3.ConfNb=1 +SH.FSMC_D4_DA4.0=FSMC_D4,16b-d1 +SH.FSMC_D4_DA4.ConfNb=1 +SH.FSMC_D5_DA5.0=FSMC_D5,16b-d1 +SH.FSMC_D5_DA5.ConfNb=1 +SH.FSMC_D6_DA6.0=FSMC_D6,16b-d1 +SH.FSMC_D6_DA6.ConfNb=1 +SH.FSMC_D7_DA7.0=FSMC_D7,16b-d1 +SH.FSMC_D7_DA7.ConfNb=1 +SH.FSMC_D8_DA8.0=FSMC_D8,16b-d1 +SH.FSMC_D8_DA8.ConfNb=1 +SH.FSMC_D9_DA9.0=FSMC_D9,16b-d1 +SH.FSMC_D9_DA9.ConfNb=1 +SH.FSMC_NBL0.0=FSMC_NBL0 +SH.FSMC_NBL0.ConfNb=1 +SH.FSMC_NBL1.0=FSMC_NBL1 +SH.FSMC_NBL1.ConfNb=1 +SH.FSMC_NOE.0=FSMC_NOE,Sram1 +SH.FSMC_NOE.ConfNb=1 +SH.FSMC_NWE.0=FSMC_NWE,Sram1 +SH.FSMC_NWE.ConfNb=1 SH.S_TIM3_CH1.0=TIM3_CH1,Encoder_Interface SH.S_TIM3_CH1.ConfNb=1 SH.S_TIM3_CH2.0=TIM3_CH2,Encoder_Interface diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Inc/stm32f1xx_hal_conf.h b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Inc/stm32f1xx_hal_conf.h index 259acb159b..6ab2796506 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Inc/stm32f1xx_hal_conf.h +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Inc/stm32f1xx_hal_conf.h @@ -62,7 +62,7 @@ /*#define HAL_SDRAM_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */ /*#define HAL_SPI_MODULE_ENABLED */ -/*#define HAL_SRAM_MODULE_ENABLED */ +#define HAL_SRAM_MODULE_ENABLED #define HAL_TIM_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Src/main.c index 85ab28b8c9..09d3a86dbf 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Src/main.c @@ -46,6 +46,8 @@ TIM_HandleTypeDef htim3; UART_HandleTypeDef huart1; +SRAM_HandleTypeDef hsram1; + /* USER CODE BEGIN PV */ /* USER CODE END PV */ @@ -54,6 +56,7 @@ UART_HandleTypeDef huart1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); +static void MX_FSMC_Init(void); static void MX_TIM3_Init(void); /* USER CODE BEGIN PFP */ @@ -94,6 +97,7 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); + MX_FSMC_Init(); MX_TIM3_Init(); /* USER CODE BEGIN 2 */ @@ -239,10 +243,71 @@ static void MX_GPIO_Init(void) /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); } +/* FSMC initialization function */ +static void MX_FSMC_Init(void) +{ + + /* USER CODE BEGIN FSMC_Init 0 */ + + /* USER CODE END FSMC_Init 0 */ + + FSMC_NORSRAM_TimingTypeDef Timing = {0}; + + /* USER CODE BEGIN FSMC_Init 1 */ + + /* USER CODE END FSMC_Init 1 */ + + /** Perform the SRAM1 memory initialization sequence + */ + hsram1.Instance = FSMC_NORSRAM_DEVICE; + hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE; + /* hsram1.Init */ + hsram1.Init.NSBank = FSMC_NORSRAM_BANK3; + hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; + hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; + hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; + hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; + hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; + hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE; + hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; + hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; + hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; + hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE; + hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; + hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; + /* Timing */ + Timing.AddressSetupTime = 0; + Timing.AddressHoldTime = 15; + Timing.DataSetupTime = 3; + Timing.BusTurnAroundDuration = 0; + Timing.CLKDivision = 16; + Timing.DataLatency = 17; + Timing.AccessMode = FSMC_ACCESS_MODE_A; + /* ExtTiming */ + + if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK) + { + Error_Handler( ); + } + + /** Disconnect NADV + */ + + __HAL_AFIO_FSMCNADV_DISCONNECTED(); + + /* USER CODE BEGIN FSMC_Init 2 */ + + /* USER CODE END FSMC_Init 2 */ +} + /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Src/stm32f1xx_hal_msp.c b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Src/stm32f1xx_hal_msp.c index ac85b3192f..b481c16620 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Src/stm32f1xx_hal_msp.c +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/CubeMX_Config/Src/stm32f1xx_hal_msp.c @@ -214,6 +214,190 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) } +static uint32_t FSMC_Initialized = 0; + +static void HAL_FSMC_MspInit(void){ + /* USER CODE BEGIN FSMC_MspInit 0 */ + + /* USER CODE END FSMC_MspInit 0 */ + GPIO_InitTypeDef GPIO_InitStruct ={0}; + if (FSMC_Initialized) { + return; + } + FSMC_Initialized = 1; + + /* Peripheral clock enable */ + __HAL_RCC_FSMC_CLK_ENABLE(); + + /** FSMC GPIO Configuration + PF0 ------> FSMC_A0 + PF1 ------> FSMC_A1 + PF2 ------> FSMC_A2 + PF3 ------> FSMC_A3 + PF4 ------> FSMC_A4 + PF5 ------> FSMC_A5 + PF12 ------> FSMC_A6 + PF13 ------> FSMC_A7 + PF14 ------> FSMC_A8 + PF15 ------> FSMC_A9 + PG0 ------> FSMC_A10 + PG1 ------> FSMC_A11 + PE7 ------> FSMC_D4 + PE8 ------> FSMC_D5 + PE9 ------> FSMC_D6 + PE10 ------> FSMC_D7 + PE11 ------> FSMC_D8 + PE12 ------> FSMC_D9 + PE13 ------> FSMC_D10 + PE14 ------> FSMC_D11 + PE15 ------> FSMC_D12 + PD8 ------> FSMC_D13 + PD9 ------> FSMC_D14 + PD10 ------> FSMC_D15 + PD11 ------> FSMC_A16 + PD12 ------> FSMC_A17 + PD13 ------> FSMC_A18 + PD14 ------> FSMC_D0 + PD15 ------> FSMC_D1 + PG2 ------> FSMC_A12 + PG3 ------> FSMC_A13 + PG4 ------> FSMC_A14 + PG5 ------> FSMC_A15 + PD0 ------> FSMC_D2 + PD1 ------> FSMC_D3 + PD4 ------> FSMC_NOE + PD5 ------> FSMC_NWE + PG10 ------> FSMC_NE3 + PE0 ------> FSMC_NBL0 + PE1 ------> FSMC_NBL1 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13 + |GPIO_PIN_14|GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 + |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 + |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 + |GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /* USER CODE BEGIN FSMC_MspInit 1 */ + + /* USER CODE END FSMC_MspInit 1 */ +} + +void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram){ + /* USER CODE BEGIN SRAM_MspInit 0 */ + + /* USER CODE END SRAM_MspInit 0 */ + HAL_FSMC_MspInit(); + /* USER CODE BEGIN SRAM_MspInit 1 */ + + /* USER CODE END SRAM_MspInit 1 */ +} + +static uint32_t FSMC_DeInitialized = 0; + +static void HAL_FSMC_MspDeInit(void){ + /* USER CODE BEGIN FSMC_MspDeInit 0 */ + + /* USER CODE END FSMC_MspDeInit 0 */ + if (FSMC_DeInitialized) { + return; + } + FSMC_DeInitialized = 1; + /* Peripheral clock enable */ + __HAL_RCC_FSMC_CLK_DISABLE(); + + /** FSMC GPIO Configuration + PF0 ------> FSMC_A0 + PF1 ------> FSMC_A1 + PF2 ------> FSMC_A2 + PF3 ------> FSMC_A3 + PF4 ------> FSMC_A4 + PF5 ------> FSMC_A5 + PF12 ------> FSMC_A6 + PF13 ------> FSMC_A7 + PF14 ------> FSMC_A8 + PF15 ------> FSMC_A9 + PG0 ------> FSMC_A10 + PG1 ------> FSMC_A11 + PE7 ------> FSMC_D4 + PE8 ------> FSMC_D5 + PE9 ------> FSMC_D6 + PE10 ------> FSMC_D7 + PE11 ------> FSMC_D8 + PE12 ------> FSMC_D9 + PE13 ------> FSMC_D10 + PE14 ------> FSMC_D11 + PE15 ------> FSMC_D12 + PD8 ------> FSMC_D13 + PD9 ------> FSMC_D14 + PD10 ------> FSMC_D15 + PD11 ------> FSMC_A16 + PD12 ------> FSMC_A17 + PD13 ------> FSMC_A18 + PD14 ------> FSMC_D0 + PD15 ------> FSMC_D1 + PG2 ------> FSMC_A12 + PG3 ------> FSMC_A13 + PG4 ------> FSMC_A14 + PG5 ------> FSMC_A15 + PD0 ------> FSMC_D2 + PD1 ------> FSMC_D3 + PD4 ------> FSMC_NOE + PD5 ------> FSMC_NWE + PG10 ------> FSMC_NE3 + PE0 ------> FSMC_NBL0 + PE1 ------> FSMC_NBL1 + */ + HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13 + |GPIO_PIN_14|GPIO_PIN_15); + + HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 + |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10); + + HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 + |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 + |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1); + + HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 + |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 + |GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5); + + /* USER CODE BEGIN FSMC_MspDeInit 1 */ + + /* USER CODE END FSMC_MspDeInit 1 */ +} + +void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram){ + /* USER CODE BEGIN SRAM_MspDeInit 0 */ + + /* USER CODE END SRAM_MspDeInit 0 */ + HAL_FSMC_MspDeInit(); + /* USER CODE BEGIN SRAM_MspDeInit 1 */ + + /* USER CODE END SRAM_MspDeInit 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig b/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig index aca91d47fc..c30f9ba572 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig @@ -34,6 +34,10 @@ menu "Onboard Peripheral Drivers" select BSP_USING_ADC1 default n + config BSP_USING_SRAM + bool "Enable SRAM" + default n + endmenu menu "On-chip Peripheral Drivers" diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/SConscript b/bsp/stm32/stm32f103-atk-warshipv3/board/SConscript index 0f7ccb024c..5df1bbcc7d 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/SConscript +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/SConscript @@ -12,8 +12,12 @@ board.c CubeMX_Config/Src/stm32f1xx_hal_msp.c ''') +if GetDepend(['BSP_USING_SRAM']): + src += Glob('ports/drv_sram.c') + path = [cwd] path += [cwd + '/CubeMX_Config/Inc'] +path += [cwd + '/ports/include'] startup_path_prefix = SDK_LIB diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/ports/drv_sram.c b/bsp/stm32/stm32f103-atk-warshipv3/board/ports/drv_sram.c new file mode 100644 index 0000000000..224383d3c1 --- /dev/null +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/ports/drv_sram.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-05 linyiyang first version + */ + +#include +#include +#include + +#ifdef BSP_USING_SRAM +#include + +#define DRV_DEBUG +#define LOG_TAG "drv.sram" +#include + +static SRAM_HandleTypeDef hsram1; +#ifdef RT_USING_MEMHEAP_AS_HEAP +static struct rt_memheap system_heap; +#endif + +static int sram_init(void) +{ + int result = RT_EOK; + + FSMC_NORSRAM_TimingTypeDef Timing = {0}; + + /** Perform the SRAM1 memory initialization sequence + */ + hsram1.Instance = FSMC_NORSRAM_DEVICE; + hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE; + + /* hsram1.Init */ + hsram1.Init.NSBank = FSMC_NORSRAM_BANK3; + hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; + hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; +#if SRAM_DATA_WIDTH == 8 + hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_8; +#elif SRAM_DATA_WIDTH == 16 + hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; +#else + hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_32; +#endif + hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; + hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; + hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE; + hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; + hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; + hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; + hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE; + hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; + hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; + + /* Timing */ + Timing.AddressSetupTime = 0; + Timing.AddressHoldTime = 15; + Timing.DataSetupTime = 3; + Timing.BusTurnAroundDuration = 0; + Timing.CLKDivision = 16; + Timing.DataLatency = 17; + Timing.AccessMode = FSMC_ACCESS_MODE_A; + /* ExtTiming */ + + /* Initialize the SRAM controller */ + if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK) + { + LOG_E("SRAM init failed!"); + result = -RT_ERROR; + } + else + { + LOG_D("sram init success, mapped at 0x%X, size is %d bytes, data width is %d", SRAM_BANK_ADDR, SRAM_SIZE, SRAM_DATA_WIDTH); +#ifdef RT_USING_MEMHEAP_AS_HEAP + /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SRAM is initialized to the heap */ + rt_memheap_init(&system_heap, "sram", (void *)SRAM_BANK_ADDR, SRAM_SIZE); +#endif + } + + /** Disconnect NADV + */ + + __HAL_AFIO_FSMCNADV_DISCONNECTED(); + + return result; +} +INIT_BOARD_EXPORT(sram_init); + +#ifdef DRV_DEBUG +#ifdef FINSH_USING_MSH +int sram_test(void) +{ + int i = 0; + uint32_t start_time = 0, time_cast = 0; +#if SRAM_DATA_WIDTH == 8 + char data_width = 1; + uint8_t data = 0; + uint8_t *ptr = (uint8_t *)SRAM_BANK_ADDR; +#elif SRAM_DATA_WIDTH == 16 + char data_width = 2; + uint16_t data = 0; + uint16_t *ptr = (uint16_t *)SRAM_BANK_ADDR; +#else + char data_width = 4; + uint32_t data = 0; + uint32_t *ptr = (uint32_t *)SRAM_BANK_ADDR; +#endif + + /* write data */ + LOG_D("Writing the %ld bytes data, waiting....", SRAM_SIZE); + start_time = rt_tick_get(); + for (i = 0; i < SRAM_SIZE / data_width; i++) + { +#if SRAM_DATA_WIDTH == 8 + ((__IO uint8_t *)ptr)[i] = (uint8_t)0x55; +#elif SRAM_DATA_WIDTH == 16 + ((__IO uint16_t *)ptr)[i] = (uint16_t)0x5555; +#else + ((__IO uint32_t *)ptr)[i] = (uint32_t)0x55555555; +#endif + } + time_cast = rt_tick_get() - start_time; + LOG_D("Write data success, total time: %d.%03dS.", time_cast / RT_TICK_PER_SECOND, + time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000)); + + /* read data */ + LOG_D("start Reading and verifying data, waiting...."); + for (i = 0; i < SRAM_SIZE / data_width; i++) + { +#if SRAM_DATA_WIDTH == 8 + data = ((__IO uint8_t *)ptr)[i]; + if (data != 0x55) + { + LOG_E("SRAM test failed!"); + break; + } +#elif SRAM_DATA_WIDTH == 16 + data = ((__IO uint16_t *)ptr)[i]; + if (data != 0x5555) + { + LOG_E("SRAM test failed!"); + break; + } +#else + data = ((__IO uint32_t *)ptr)[i]; + if (data != 0x55555555) + { + LOG_E("SRAM test failed!"); + break; + } +#endif + } + + if (i >= SRAM_SIZE / data_width) + { + LOG_D("SRAM test success!"); + } + + return RT_EOK; +} +MSH_CMD_EXPORT(sram_test, sram test); +#endif /* FINSH_USING_MSH */ +#endif /* DRV_DEBUG */ +#endif /* BSP_USING_SRAM */ diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/ports/include/sram_port.h b/bsp/stm32/stm32f103-atk-warshipv3/board/ports/include/sram_port.h new file mode 100644 index 0000000000..be8cedc990 --- /dev/null +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/ports/include/sram_port.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-05 linyiyang first version + */ + +#ifndef __SDRAM_PORT_H__ +#define __SDRAM_PORT_H__ + +/* parameters for sdram peripheral */ +/* stm32f1 Bank1:0x68000000 */ +#define SRAM_BANK_ADDR ((uint32_t)0x68000000) +/* data width: 8, 16, 32 */ +#define SRAM_DATA_WIDTH 16 +/* sram size */ +#define SRAM_SIZE ((uint32_t)0x100000) + +#endif -- Gitee From 0ef62c7b105dcdc035d4ec67a77e16495a163348 Mon Sep 17 00:00:00 2001 From: amy qian Date: Mon, 6 Jan 2020 10:27:04 +0800 Subject: [PATCH 039/110] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=86demo.c?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=BF=AE=E6=94=B9=E4=BA=86main.c=EF=BC=8C?= =?UTF-8?q?=E7=9B=B8=E5=BA=94=E4=BF=AE=E6=94=B9=E4=BA=86readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/cypress/psoc6-pioneerkit_modus/README.md | 15 ++--- .../applications/demo.c | 60 ------------------- .../applications/main.c | 13 +++- 3 files changed, 15 insertions(+), 73 deletions(-) delete mode 100644 bsp/cypress/psoc6-pioneerkit_modus/applications/demo.c diff --git a/bsp/cypress/psoc6-pioneerkit_modus/README.md b/bsp/cypress/psoc6-pioneerkit_modus/README.md index 27b113c1c2..bf886a7073 100644 --- a/bsp/cypress/psoc6-pioneerkit_modus/README.md +++ b/bsp/cypress/psoc6-pioneerkit_modus/README.md @@ -84,18 +84,11 @@ CY8CKIT-062-BLE PSoC6 BLE Pioneer Kit 是赛普拉斯推出的一款32位双核C ``` \ | / - RT - Thread Operating System - / | \ 4.0.3 build Jan 3 2020 + / | \ 4.0.3 build Jan 6 2020 2006 - 2019 Copyright by rt-thread team -thread1 created ok -thread1 count: 0 -thread2 created ok -thread2 count: 0 -thread2 count: 1 -thread2 count: 2 -thread2 count: 3 -thread1 count: 1 -thread2 count: 4 -thread2 count: 5 +hello rt-thread +msh >hello rt-thread +hello rt-thread ``` ## 联系人信息 diff --git a/bsp/cypress/psoc6-pioneerkit_modus/applications/demo.c b/bsp/cypress/psoc6-pioneerkit_modus/applications/demo.c deleted file mode 100644 index 84e37aedd7..0000000000 --- a/bsp/cypress/psoc6-pioneerkit_modus/applications/demo.c +++ /dev/null @@ -1,60 +0,0 @@ - -#include -#include "board.h" -#include "cybsp.h" -#include "cy_device_headers.h" -#ifdef RT_USING_FINSH -#include -#include -#endif - - -static rt_thread_t tid1 = RT_NULL; -static rt_thread_t tid2 = RT_NULL; - - -static void thread1_entry(void* parameter) -{ - rt_uint32_t count = 0; - parameter = parameter; - - rt_kprintf("thread1 created ok\n"); - while (1) - { - rt_kprintf("thread1 count: %d\n",count++); - rt_thread_delay(RT_TICK_PER_SECOND); - - } -} - -static void thread2_entry(void* parameter) -{ - rt_uint32_t count = 0; - parameter = parameter; - - rt_kprintf("thread2 created ok\n"); - while(1) - { - rt_kprintf("thread2 count: %d\n",count++); - rt_thread_delay(RT_TICK_PER_SECOND/4); - - } - - rt_thread_delay(RT_TICK_PER_SECOND * 4); - rt_thread_delete(tid1); - rt_kprintf("thread1 deleted ok\n"); -} - -int demo_init(void) -{ - tid1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 512, 6, 10); - if (tid1 != RT_NULL) - rt_thread_startup(tid1); - - tid2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 512, 6, 10); - if (tid2 != RT_NULL) - rt_thread_startup(tid2); - - return 0; -} - diff --git a/bsp/cypress/psoc6-pioneerkit_modus/applications/main.c b/bsp/cypress/psoc6-pioneerkit_modus/applications/main.c index 99008c8326..56fc49240b 100644 --- a/bsp/cypress/psoc6-pioneerkit_modus/applications/main.c +++ b/bsp/cypress/psoc6-pioneerkit_modus/applications/main.c @@ -43,14 +43,23 @@ #include "cycfg.h" #include "cy_device_headers.h" #include "cycfg_peripherals.h" +#include +#include "board.h" +#include "cybsp.h" + +#ifdef RT_USING_FINSH +#include +#include +#endif -extern int demo_init(void); int main(void) { - demo_init(); for(;;) { + rt_kprintf("hello rt-thread\n"); + rt_thread_mdelay(1000); + } } -- Gitee From 3f70d441161df22201b9a4aa9e5e43c8961d8b2e Mon Sep 17 00:00:00 2001 From: amy qian Date: Mon, 6 Jan 2020 10:30:10 +0800 Subject: [PATCH 040/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=81=97=E6=BC=8F?= =?UTF-8?q?=E7=9A=84.lib=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE.lib | 1 + 1 file changed, 1 insertion(+) create mode 100644 bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE.lib diff --git a/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE.lib b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE.lib new file mode 100644 index 0000000000..e144e75a2a --- /dev/null +++ b/bsp/cypress/psoc6-pioneerkit_modus/libs/TARGET_CY8CKIT-062-BLE.lib @@ -0,0 +1 @@ +https://github.com/cypresssemiconductorco/TARGET_CY8CKIT-062-BLE/#latest-v1.X -- Gitee From 8b11bfd3ac6b6623d19c89a52c9e624d31ca80be Mon Sep 17 00:00:00 2001 From: linyiyang <50727129+eYoung8475@users.noreply.github.com> Date: Mon, 6 Jan 2020 19:14:35 +0800 Subject: [PATCH 041/110] Provide more information about this SRAM --- bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig b/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig index c30f9ba572..548d5641bb 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig @@ -35,7 +35,7 @@ menu "Onboard Peripheral Drivers" default n config BSP_USING_SRAM - bool "Enable SRAM" + bool "Enable SRAM. Chip name is IS62WV51216, 1Mbytes static RAMs organized as 512K words by 16bits." default n endmenu -- Gitee From 516702d69ef0d4073ba0d66555cd05b036fd4b9f Mon Sep 17 00:00:00 2001 From: "ethan.du" Date: Mon, 6 Jan 2020 19:24:23 +0800 Subject: [PATCH 042/110] drv_flash_f7.c support single bank mode --- .../HAL_Drivers/drv_flash/drv_flash_f7.c | 319 +++++++----------- 1 file changed, 123 insertions(+), 196 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c index 3ecb0be5e9..bcefe04342 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c @@ -7,6 +7,7 @@ * Date Author Notes * 2018-12-5 SummerGift first version * 2019-3-2 jinsheng add Macro judgment + * 2020-1-6 duminmin support single bank mode */ #include "board.h" @@ -22,32 +23,6 @@ //#define DRV_DEBUG #define LOG_TAG "drv.flash" #include -#if defined (FLASH_OPTCR_nDBANK) -#define ADDR_FLASH_SECTOR_0 ((rt_uint32_t)0x08000000) /* Base address of Sector 0, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_1 ((rt_uint32_t)0x08004000) /* Base address of Sector 1, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_2 ((rt_uint32_t)0x08008000) /* Base address of Sector 2, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_3 ((rt_uint32_t)0x0800C000) /* Base address of Sector 3, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_4 ((rt_uint32_t)0x08010000) /* Base address of Sector 4, 64 Kbytes */ -#define ADDR_FLASH_SECTOR_5 ((rt_uint32_t)0x08020000) /* Base address of Sector 5, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_6 ((rt_uint32_t)0x08040000) /* Base address of Sector 6, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_7 ((rt_uint32_t)0x08060000) /* Base address of Sector 7, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_8 ((rt_uint32_t)0x08080000) /* Base address of Sector 8, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_9 ((rt_uint32_t)0x080A0000) /* Base address of Sector 9, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_10 ((rt_uint32_t)0x080C0000) /* Base address of Sector 10, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_11 ((rt_uint32_t)0x080E0000) /* Base address of Sector 11, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_12 ((rt_uint32_t)0x08100000) /* Base address of Sector 12, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_13 ((rt_uint32_t)0x08104000) /* Base address of Sector 13, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_14 ((rt_uint32_t)0x08108000) /* Base address of Sector 14, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_15 ((rt_uint32_t)0x0810C000) /* Base address of Sector 15, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_16 ((rt_uint32_t)0x08110000) /* Base address of Sector 16, 64 Kbytes */ -#define ADDR_FLASH_SECTOR_17 ((rt_uint32_t)0x08120000) /* Base address of Sector 17, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_18 ((rt_uint32_t)0x08140000) /* Base address of Sector 18, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_19 ((rt_uint32_t)0x08160000) /* Base address of Sector 19, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_20 ((rt_uint32_t)0x08180000) /* Base address of Sector 20, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_21 ((rt_uint32_t)0x081A0000) /* Base address of Sector 21, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_22 ((rt_uint32_t)0x081C0000) /* Base address of Sector 22, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_23 ((rt_uint32_t)0x081E0000) /* Base address of Sector 23, 128 Kbytes */ -#else #define ADDR_FLASH_SECTOR_0 ((rt_uint32_t)0x08000000) /* Base address of Sector 0, 32 Kbytes */ #define ADDR_FLASH_SECTOR_1 ((rt_uint32_t)0x08008000) /* Base address of Sector 1, 32 Kbytes */ #define ADDR_FLASH_SECTOR_2 ((rt_uint32_t)0x08010000) /* Base address of Sector 2, 32 Kbytes */ @@ -60,7 +35,6 @@ #define ADDR_FLASH_SECTOR_9 ((rt_uint32_t)0x08140000) /* Base address of Sector 9, 256 Kbytes */ #define ADDR_FLASH_SECTOR_10 ((rt_uint32_t)0x08180000) /* Base address of Sector 10, 256 Kbytes */ #define ADDR_FLASH_SECTOR_11 ((rt_uint32_t)0x081C0000) /* Base address of Sector 11, 256 Kbytes */ -#endif /** * @brief Gets the sector of a given address * @param None @@ -68,179 +42,125 @@ */ static rt_uint32_t GetSector(rt_uint32_t Address) { - rt_uint32_t sector = 0; + uint32_t sector = 0; + #if defined (FLASH_OPTCR_nDBANK) - if ((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) - { - sector = FLASH_SECTOR_0; - } - else if ((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) - { - sector = FLASH_SECTOR_1; - } -#if (FLASH_SECTOR_TOTAL >= 4) - else if ((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) - { - sector = FLASH_SECTOR_2; - } - else if ((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) - { - sector = FLASH_SECTOR_3; - } -#elif (FLASH_SECTOR_TOTAL >= 8) - else if ((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) - { - sector = FLASH_SECTOR_4; - } - else if ((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) - { - sector = FLASH_SECTOR_5; - } - else if ((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) - { - sector = FLASH_SECTOR_6; - } - else if ((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) - { - sector = FLASH_SECTOR_7; - } -#elif (FLASH_SECTOR_TOTAL >= 24) - else if ((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) - { - sector = FLASH_SECTOR_8; - } - else if ((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) - { - sector = FLASH_SECTOR_9; - } - else if ((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) - { - sector = FLASH_SECTOR_10; - } - else if ((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11)) - { - sector = FLASH_SECTOR_11; - } - else if ((Address < ADDR_FLASH_SECTOR_13) && (Address >= ADDR_FLASH_SECTOR_12)) - { - sector = FLASH_SECTOR_12; - } - else if ((Address < ADDR_FLASH_SECTOR_14) && (Address >= ADDR_FLASH_SECTOR_13)) - { - sector = FLASH_SECTOR_13; - } - else if ((Address < ADDR_FLASH_SECTOR_15) && (Address >= ADDR_FLASH_SECTOR_14)) - { - sector = FLASH_SECTOR_14; - } - else if ((Address < ADDR_FLASH_SECTOR_16) && (Address >= ADDR_FLASH_SECTOR_15)) - { - sector = FLASH_SECTOR_15; - } - else if ((Address < ADDR_FLASH_SECTOR_17) && (Address >= ADDR_FLASH_SECTOR_16)) - { - sector = FLASH_SECTOR_16; - } - else if ((Address < ADDR_FLASH_SECTOR_18) && (Address >= ADDR_FLASH_SECTOR_17)) - { - sector = FLASH_SECTOR_17; - } - else if ((Address < ADDR_FLASH_SECTOR_19) && (Address >= ADDR_FLASH_SECTOR_18)) - { - sector = FLASH_SECTOR_18; - } - else if ((Address < ADDR_FLASH_SECTOR_20) && (Address >= ADDR_FLASH_SECTOR_19)) - { - sector = FLASH_SECTOR_19; - } - else if ((Address < ADDR_FLASH_SECTOR_21) && (Address >= ADDR_FLASH_SECTOR_20)) - { - sector = FLASH_SECTOR_20; - } - else if ((Address < ADDR_FLASH_SECTOR_22) && (Address >= ADDR_FLASH_SECTOR_21)) - { - sector = FLASH_SECTOR_21; - } - else if ((Address < ADDR_FLASH_SECTOR_23) && (Address >= ADDR_FLASH_SECTOR_22)) - { - sector = FLASH_SECTOR_22; - } -#else - else - { -#if (FLASH_SECTOR_TOTAL == 4) - sector = FLASH_SECTOR_4; -#elif (FLASH_SECTOR_TOTAL == 8) - sector = FLASH_SECTOR_8; -#elif (FLASH_SECTOR_TOTAL == 24) - sector = FLASH_SECTOR_23; -#endif - } -#endif -#else - if ((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) - { - sector = FLASH_SECTOR_0; - } - else if ((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) - { - sector = FLASH_SECTOR_1; - } -#if (FLASH_SECTOR_TOTAL >= 4) - else if ((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) - { - sector = FLASH_SECTOR_2; - } - else if ((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) - { - sector = FLASH_SECTOR_3; - } -#elif (FLASH_SECTOR_TOTAL >= 8) - else if ((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) - { - sector = FLASH_SECTOR_4; - } - else if ((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) - { - sector = FLASH_SECTOR_5; - } - else if ((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) - { - sector = FLASH_SECTOR_6; - } - else if ((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) - { - sector = FLASH_SECTOR_7; - } -#elif (FLASH_SECTOR_TOTAL >= 24) - else if ((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) - { - sector = FLASH_SECTOR_8; - } - else if ((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) - { - sector = FLASH_SECTOR_9; - } - else if ((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) - { - sector = FLASH_SECTOR_10; - } -#else - else - { -#if (FLASH_SECTOR_TOTAL == 4) - sector = FLASH_SECTOR_4; -#elif (FLASH_SECTOR_TOTAL == 8) - sector = FLASH_SECTOR_8; -#elif (FLASH_SECTOR_TOTAL == 24) - sector = FLASH_SECTOR_11; -#endif - } -#endif + FLASH_OBProgramInitTypeDef OBInit; + uint32_t nbank = 0; + + //get duel bank ability:nDBANK(Bit29) + HAL_FLASHEx_OBGetConfig(&OBInit); + nbank = ((OBInit.USERConfig & 0x20000000U) >> 29); + //1:single bank mode + if(1 == nbank) + { + if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) + { + sector = FLASH_SECTOR_0; + } + else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) + { + sector = FLASH_SECTOR_1; + } + else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) + { + sector = FLASH_SECTOR_2; + } + else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) + { + sector = FLASH_SECTOR_3; + } + else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) + { + sector = FLASH_SECTOR_4; + } + else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) + { + sector = FLASH_SECTOR_5; + } + else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) + { + sector = FLASH_SECTOR_6; + } + else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) + { + sector = FLASH_SECTOR_7; + } + else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) + { + sector = FLASH_SECTOR_8; + } + else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) + { + sector = FLASH_SECTOR_9; + } + else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) + { + sector = FLASH_SECTOR_10; + } + else + { + sector = FLASH_SECTOR_11; + } + } + else //0:dual bank mode + { + RT_ASSERT("rtthread doesn't support duel bank mode yet!"); + } +#else //no dual bank ability + if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) + { + sector = FLASH_SECTOR_0; + } + else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) + { + sector = FLASH_SECTOR_1; + } + else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) + { + sector = FLASH_SECTOR_2; + } + else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) + { + sector = FLASH_SECTOR_3; + } + else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) + { + sector = FLASH_SECTOR_4; + } + else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) + { + sector = FLASH_SECTOR_5; + } + else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) + { + sector = FLASH_SECTOR_6; + } + else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) + { + sector = FLASH_SECTOR_7; + } + else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) + { + sector = FLASH_SECTOR_8; + } + else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) + { + sector = FLASH_SECTOR_9; + } + else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) + { + sector = FLASH_SECTOR_10; + } + else + { + sector = FLASH_SECTOR_11; + } #endif - return sector; + return sector; } + /** * Read data from flash. * @note This operation's units is word. @@ -386,6 +306,13 @@ __exit: } #if defined(PKG_USING_FAL) +#define FLASH_SIZE_GRANULARITY_32K 4 * 32 * 1024 +#define FLASH_SIZE_GRANULARITY_128K 128 * 1024 +#define FLASH_SIZE_GRANULARITY_256K 7 * 256 *1024 + +#define STM32_FLASH_START_ADRESS_32K STM32_FLASH_START_ADRESS +#define STM32_FLASH_START_ADRESS_128K STM32_FLASH_START_ADRESS_32K + FLASH_SIZE_GRANULARITY_32K +#define STM32_FLASH_START_ADRESS_256K STM32_FLASH_START_ADRESS_128K + FLASH_SIZE_GRANULARITY_128K static int fal_flash_read_32k(long offset, rt_uint8_t *buf, size_t size); static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size); -- Gitee From 3a11955b2110d74544f4691464e9bab00a386267 Mon Sep 17 00:00:00 2001 From: linyiyang <50727129+eYoung8475@users.noreply.github.com> Date: Mon, 6 Jan 2020 19:26:35 +0800 Subject: [PATCH 043/110] Add information about sram in help command. --- bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig b/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig index 548d5641bb..9b0caaddd6 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig @@ -35,8 +35,10 @@ menu "Onboard Peripheral Drivers" default n config BSP_USING_SRAM - bool "Enable SRAM. Chip name is IS62WV51216, 1Mbytes static RAMs organized as 512K words by 16bits." + bool "Enable SRAM." default n + help + Chip name is IS62WV51216, 1Mbytes static RAMs organized as 512K words by 16bits. endmenu -- Gitee From 6b614c05b81d3f733012cd664c6e4efac7de2f8e Mon Sep 17 00:00:00 2001 From: "ethan.du" Date: Mon, 6 Jan 2020 19:40:25 +0800 Subject: [PATCH 044/110] modify space --- .../HAL_Drivers/drv_flash/drv_flash_f7.c | 154 +++++++++--------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c index bcefe04342..c4bc75b820 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c @@ -42,122 +42,122 @@ */ static rt_uint32_t GetSector(rt_uint32_t Address) { - uint32_t sector = 0; + uint32_t sector = 0; #if defined (FLASH_OPTCR_nDBANK) - FLASH_OBProgramInitTypeDef OBInit; - uint32_t nbank = 0; - - //get duel bank ability:nDBANK(Bit29) - HAL_FLASHEx_OBGetConfig(&OBInit); - nbank = ((OBInit.USERConfig & 0x20000000U) >> 29); - //1:single bank mode - if(1 == nbank) - { + FLASH_OBProgramInitTypeDef OBInit; + uint32_t nbank = 0; + + //get duel bank ability:nDBANK(Bit29) + HAL_FLASHEx_OBGetConfig(&OBInit); + nbank = ((OBInit.USERConfig & 0x20000000U) >> 29); + //1:single bank mode + if(1 == nbank) + { + if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) + { + sector = FLASH_SECTOR_0; + } + else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) + { + sector = FLASH_SECTOR_1; + } + else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) + { + sector = FLASH_SECTOR_2; + } + else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) + { + sector = FLASH_SECTOR_3; + } + else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) + { + sector = FLASH_SECTOR_4; + } + else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) + { + sector = FLASH_SECTOR_5; + } + else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) + { + sector = FLASH_SECTOR_6; + } + else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) + { + sector = FLASH_SECTOR_7; + } + else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) + { + sector = FLASH_SECTOR_8; + } + else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) + { + sector = FLASH_SECTOR_9; + } + else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) + { + sector = FLASH_SECTOR_10; + } + else + { + sector = FLASH_SECTOR_11; + } + } + else //0:dual bank mode + { + RT_ASSERT("rtthread doesn't support duel bank mode yet!"); + } +#else //no dual bank ability if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) { - sector = FLASH_SECTOR_0; + sector = FLASH_SECTOR_0; } else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) { - sector = FLASH_SECTOR_1; + sector = FLASH_SECTOR_1; } else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) { - sector = FLASH_SECTOR_2; + sector = FLASH_SECTOR_2; } else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) { - sector = FLASH_SECTOR_3; + sector = FLASH_SECTOR_3; } else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) { - sector = FLASH_SECTOR_4; + sector = FLASH_SECTOR_4; } else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) { - sector = FLASH_SECTOR_5; + sector = FLASH_SECTOR_5; } else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) { - sector = FLASH_SECTOR_6; + sector = FLASH_SECTOR_6; } else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) { - sector = FLASH_SECTOR_7; + sector = FLASH_SECTOR_7; } else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) { - sector = FLASH_SECTOR_8; + sector = FLASH_SECTOR_8; } else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) { - sector = FLASH_SECTOR_9; + sector = FLASH_SECTOR_9; } else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) { - sector = FLASH_SECTOR_10; + sector = FLASH_SECTOR_10; } else { - sector = FLASH_SECTOR_11; + sector = FLASH_SECTOR_11; } - } - else //0:dual bank mode - { - RT_ASSERT("rtthread doesn't support duel bank mode yet!"); - } -#else //no dual bank ability - if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) - { - sector = FLASH_SECTOR_0; - } - else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) - { - sector = FLASH_SECTOR_1; - } - else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) - { - sector = FLASH_SECTOR_2; - } - else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) - { - sector = FLASH_SECTOR_3; - } - else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) - { - sector = FLASH_SECTOR_4; - } - else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) - { - sector = FLASH_SECTOR_5; - } - else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) - { - sector = FLASH_SECTOR_6; - } - else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) - { - sector = FLASH_SECTOR_7; - } - else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) - { - sector = FLASH_SECTOR_8; - } - else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) - { - sector = FLASH_SECTOR_9; - } - else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) - { - sector = FLASH_SECTOR_10; - } - else - { - sector = FLASH_SECTOR_11; - } #endif - return sector; + return sector; } -- Gitee From 8f5e1c57153dd4054dc08f6893ebbbc989e9f8dc Mon Sep 17 00:00:00 2001 From: "ethan.du" Date: Mon, 6 Jan 2020 19:43:45 +0800 Subject: [PATCH 045/110] add space --- .../HAL_Drivers/drv_flash/drv_flash_f7.c | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c index c4bc75b820..b89b6c39a7 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c @@ -52,49 +52,49 @@ static rt_uint32_t GetSector(rt_uint32_t Address) HAL_FLASHEx_OBGetConfig(&OBInit); nbank = ((OBInit.USERConfig & 0x20000000U) >> 29); //1:single bank mode - if(1 == nbank) + if (1 == nbank) { - if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) + if ((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) { sector = FLASH_SECTOR_0; } - else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) + else if ((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) { sector = FLASH_SECTOR_1; } - else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) + else if ((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) { sector = FLASH_SECTOR_2; } - else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) + else if ((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) { sector = FLASH_SECTOR_3; } - else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) + else if ((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) { sector = FLASH_SECTOR_4; } - else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) + else if ((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) { sector = FLASH_SECTOR_5; } - else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) + else if ((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) { sector = FLASH_SECTOR_6; } - else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) + else if ((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) { sector = FLASH_SECTOR_7; } - else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) + else if ((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) { sector = FLASH_SECTOR_8; } - else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) + else if ((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) { sector = FLASH_SECTOR_9; } - else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) + else if ((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) { sector = FLASH_SECTOR_10; } @@ -108,47 +108,47 @@ static rt_uint32_t GetSector(rt_uint32_t Address) RT_ASSERT("rtthread doesn't support duel bank mode yet!"); } #else //no dual bank ability - if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) + if ((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) { sector = FLASH_SECTOR_0; } - else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) + else if ((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) { sector = FLASH_SECTOR_1; } - else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) + else if ((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) { sector = FLASH_SECTOR_2; } - else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) + else if ((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) { sector = FLASH_SECTOR_3; } - else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) + else if ((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) { sector = FLASH_SECTOR_4; } - else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) + else if ((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) { sector = FLASH_SECTOR_5; } - else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) + else if ((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) { sector = FLASH_SECTOR_6; } - else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) + else if ((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) { sector = FLASH_SECTOR_7; } - else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) + else if ((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) { sector = FLASH_SECTOR_8; } - else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) + else if ((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) { sector = FLASH_SECTOR_9; } - else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) + else if ((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) { sector = FLASH_SECTOR_10; } -- Gitee From 73cae9564b0edfeea05d277e7a673ad15acc5a1f Mon Sep 17 00:00:00 2001 From: a1012112796 <1012112796@qq.com> Date: Tue, 7 Jan 2020 11:22:26 +0800 Subject: [PATCH 046/110] [ULOG] fix raw size bug for backend which don't suport color --- components/utilities/ulog/ulog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/utilities/ulog/ulog.c b/components/utilities/ulog/ulog.c index ca356f92f2..7610089298 100644 --- a/components/utilities/ulog/ulog.c +++ b/components/utilities/ulog/ulog.c @@ -396,7 +396,7 @@ void ulog_output_to_all_backend(rt_uint32_t level, const char *tag, rt_bool_t is #if !defined(ULOG_USING_COLOR) || defined(ULOG_USING_SYSLOG) backend->output(backend, level, tag, is_raw, log, size); #else - if (backend->support_color) + if (backend->support_color || is_raw) { backend->output(backend, level, tag, is_raw, log, size); } -- Gitee From 8e4d05d7ae2222e9da6bc365c9f24877081b2d90 Mon Sep 17 00:00:00 2001 From: "ethan.du" Date: Tue, 7 Jan 2020 14:29:33 +0800 Subject: [PATCH 047/110] modify assert and code style --- .../HAL_Drivers/drv_flash/drv_flash_f7.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c index b89b6c39a7..276c9ba0b9 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_f7.c @@ -105,7 +105,8 @@ static rt_uint32_t GetSector(rt_uint32_t Address) } else //0:dual bank mode { - RT_ASSERT("rtthread doesn't support duel bank mode yet!"); + LOG_E("rtthread doesn't support duel bank mode yet!"); + RT_ASSERT(0); } #else //no dual bank ability if ((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) @@ -306,13 +307,13 @@ __exit: } #if defined(PKG_USING_FAL) -#define FLASH_SIZE_GRANULARITY_32K 4 * 32 * 1024 -#define FLASH_SIZE_GRANULARITY_128K 128 * 1024 -#define FLASH_SIZE_GRANULARITY_256K 7 * 256 *1024 +#define FLASH_SIZE_GRANULARITY_32K (4 * 32 * 1024) +#define FLASH_SIZE_GRANULARITY_128K (128 * 1024) +#define FLASH_SIZE_GRANULARITY_256K (7 * 256 *1024) -#define STM32_FLASH_START_ADRESS_32K STM32_FLASH_START_ADRESS -#define STM32_FLASH_START_ADRESS_128K STM32_FLASH_START_ADRESS_32K + FLASH_SIZE_GRANULARITY_32K -#define STM32_FLASH_START_ADRESS_256K STM32_FLASH_START_ADRESS_128K + FLASH_SIZE_GRANULARITY_128K +#define STM32_FLASH_START_ADRESS_32K (STM32_FLASH_START_ADRESS) +#define STM32_FLASH_START_ADRESS_128K (STM32_FLASH_START_ADRESS_32K + FLASH_SIZE_GRANULARITY_32K) +#define STM32_FLASH_START_ADRESS_256K (STM32_FLASH_START_ADRESS_128K + FLASH_SIZE_GRANULARITY_128K) static int fal_flash_read_32k(long offset, rt_uint8_t *buf, size_t size); static int fal_flash_read_128k(long offset, rt_uint8_t *buf, size_t size); -- Gitee From 7e003b2214c1e1581144dc1380dcced9733dc923 Mon Sep 17 00:00:00 2001 From: linyiyang <393676163@qq.com> Date: Wed, 8 Jan 2020 22:04:49 +0800 Subject: [PATCH 048/110] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=9B=B8=E5=85=B3sra?= =?UTF-8?q?m=E5=90=8D=E7=A7=B0=E4=B8=BAexternal=20sram=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/stm32/libraries/STM32F1xx_HAL/SConscript | 2 +- .../stm32f103-atk-warshipv3/board/Kconfig | 6 +- .../stm32f103-atk-warshipv3/board/SConscript | 2 +- .../board/ports/drv_sram.c | 58 +++++++++---------- .../board/ports/include/sram_port.h | 6 +- 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/bsp/stm32/libraries/STM32F1xx_HAL/SConscript b/bsp/stm32/libraries/STM32F1xx_HAL/SConscript index 01242a9817..ff87a4aa25 100644 --- a/bsp/stm32/libraries/STM32F1xx_HAL/SConscript +++ b/bsp/stm32/libraries/STM32F1xx_HAL/SConscript @@ -74,7 +74,7 @@ if GetDepend(['RT_USING_MTD_NOR']): if GetDepend(['RT_USING_MTD_NAND']): src += ['STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_nand.c'] -if GetDepend(['BSP_USING_SRAM']): +if GetDepend(['BSP_USING_EXT_SRAM']): src += ['STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_fsmc.c'] src += ['STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_sram.c'] diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig b/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig index 548d5641bb..588abe47a2 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/Kconfig @@ -34,9 +34,11 @@ menu "Onboard Peripheral Drivers" select BSP_USING_ADC1 default n - config BSP_USING_SRAM - bool "Enable SRAM. Chip name is IS62WV51216, 1Mbytes static RAMs organized as 512K words by 16bits." + config BSP_USING_EXT_SRAM + bool "Enable external sram" default n + help + Chip name is IS62WV51216, 1Mbytes static RAMs organized as 512K words by 16bits. endmenu diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/SConscript b/bsp/stm32/stm32f103-atk-warshipv3/board/SConscript index 5df1bbcc7d..545cc5c842 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/SConscript +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/SConscript @@ -12,7 +12,7 @@ board.c CubeMX_Config/Src/stm32f1xx_hal_msp.c ''') -if GetDepend(['BSP_USING_SRAM']): +if GetDepend(['BSP_USING_EXT_SRAM']): src += Glob('ports/drv_sram.c') path = [cwd] diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/ports/drv_sram.c b/bsp/stm32/stm32f103-atk-warshipv3/board/ports/drv_sram.c index 224383d3c1..c0b077e600 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/ports/drv_sram.c +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/ports/drv_sram.c @@ -12,11 +12,11 @@ #include #include -#ifdef BSP_USING_SRAM +#ifdef BSP_USING_EXT_SRAM #include #define DRV_DEBUG -#define LOG_TAG "drv.sram" +#define LOG_TAG "drv.ext_sram" #include static SRAM_HandleTypeDef hsram1; @@ -24,7 +24,7 @@ static SRAM_HandleTypeDef hsram1; static struct rt_memheap system_heap; #endif -static int sram_init(void) +static int external_sram_init(void) { int result = RT_EOK; @@ -39,9 +39,9 @@ static int sram_init(void) hsram1.Init.NSBank = FSMC_NORSRAM_BANK3; hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; -#if SRAM_DATA_WIDTH == 8 +#if EXTERNAL_SRAM_DATA_WIDTH == 8 hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_8; -#elif SRAM_DATA_WIDTH == 16 +#elif EXTERNAL_SRAM_DATA_WIDTH == 16 hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16; #else hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_32; @@ -69,15 +69,15 @@ static int sram_init(void) /* Initialize the SRAM controller */ if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK) { - LOG_E("SRAM init failed!"); + LOG_E("External SRAM init failed!"); result = -RT_ERROR; } else { - LOG_D("sram init success, mapped at 0x%X, size is %d bytes, data width is %d", SRAM_BANK_ADDR, SRAM_SIZE, SRAM_DATA_WIDTH); + LOG_D("External sram init success, mapped at 0x%X, size is %d bytes, data width is %d", EXTERNAL_SRAM_BANK_ADDR, EXTERNAL_SRAM_SIZE, EXTERNAL_SRAM_DATA_WIDTH); #ifdef RT_USING_MEMHEAP_AS_HEAP /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SRAM is initialized to the heap */ - rt_memheap_init(&system_heap, "sram", (void *)SRAM_BANK_ADDR, SRAM_SIZE); + rt_memheap_init(&system_heap, "ext_sram", (void *)EXTERNAL_SRAM_BANK_ADDR, EXTERNAL_SRAM_SIZE); #endif } @@ -88,36 +88,36 @@ static int sram_init(void) return result; } -INIT_BOARD_EXPORT(sram_init); +INIT_BOARD_EXPORT(external_sram_init); #ifdef DRV_DEBUG #ifdef FINSH_USING_MSH -int sram_test(void) +int external_sram_test(void) { int i = 0; uint32_t start_time = 0, time_cast = 0; -#if SRAM_DATA_WIDTH == 8 +#if EXTERNAL_SRAM_DATA_WIDTH == 8 char data_width = 1; uint8_t data = 0; - uint8_t *ptr = (uint8_t *)SRAM_BANK_ADDR; -#elif SRAM_DATA_WIDTH == 16 + uint8_t *ptr = (uint8_t *)EXTERNAL_SRAM_BANK_ADDR; +#elif EXTERNAL_SRAM_DATA_WIDTH == 16 char data_width = 2; uint16_t data = 0; - uint16_t *ptr = (uint16_t *)SRAM_BANK_ADDR; + uint16_t *ptr = (uint16_t *)EXTERNAL_SRAM_BANK_ADDR; #else char data_width = 4; uint32_t data = 0; - uint32_t *ptr = (uint32_t *)SRAM_BANK_ADDR; + uint32_t *ptr = (uint32_t *)EXTERNAL_SRAM_BANK_ADDR; #endif /* write data */ - LOG_D("Writing the %ld bytes data, waiting....", SRAM_SIZE); + LOG_D("Writing the %ld bytes data, waiting....", EXTERNAL_SRAM_SIZE); start_time = rt_tick_get(); - for (i = 0; i < SRAM_SIZE / data_width; i++) + for (i = 0; i < EXTERNAL_SRAM_SIZE / data_width; i++) { -#if SRAM_DATA_WIDTH == 8 +#if EXTERNAL_SRAM_DATA_WIDTH == 8 ((__IO uint8_t *)ptr)[i] = (uint8_t)0x55; -#elif SRAM_DATA_WIDTH == 16 +#elif EXTERNAL_SRAM_DATA_WIDTH == 16 ((__IO uint16_t *)ptr)[i] = (uint16_t)0x5555; #else ((__IO uint32_t *)ptr)[i] = (uint32_t)0x55555555; @@ -129,40 +129,40 @@ int sram_test(void) /* read data */ LOG_D("start Reading and verifying data, waiting...."); - for (i = 0; i < SRAM_SIZE / data_width; i++) + for (i = 0; i < EXTERNAL_SRAM_SIZE / data_width; i++) { -#if SRAM_DATA_WIDTH == 8 +#if EXTERNAL_SRAM_DATA_WIDTH == 8 data = ((__IO uint8_t *)ptr)[i]; if (data != 0x55) { - LOG_E("SRAM test failed!"); + LOG_E("External SRAM test failed!"); break; } -#elif SRAM_DATA_WIDTH == 16 +#elif EXTERNAL_SRAM_DATA_WIDTH == 16 data = ((__IO uint16_t *)ptr)[i]; if (data != 0x5555) { - LOG_E("SRAM test failed!"); + LOG_E("External SRAM test failed!"); break; } #else data = ((__IO uint32_t *)ptr)[i]; if (data != 0x55555555) { - LOG_E("SRAM test failed!"); + LOG_E("External SRAM test failed!"); break; } #endif } - if (i >= SRAM_SIZE / data_width) + if (i >= EXTERNAL_SRAM_SIZE / data_width) { - LOG_D("SRAM test success!"); + LOG_D("External SRAM test success!"); } return RT_EOK; } -MSH_CMD_EXPORT(sram_test, sram test); +MSH_CMD_EXPORT(external_sram_test, sram test); #endif /* FINSH_USING_MSH */ #endif /* DRV_DEBUG */ -#endif /* BSP_USING_SRAM */ +#endif /* BSP_USING_EXT_SRAM */ diff --git a/bsp/stm32/stm32f103-atk-warshipv3/board/ports/include/sram_port.h b/bsp/stm32/stm32f103-atk-warshipv3/board/ports/include/sram_port.h index be8cedc990..06ee47cca2 100644 --- a/bsp/stm32/stm32f103-atk-warshipv3/board/ports/include/sram_port.h +++ b/bsp/stm32/stm32f103-atk-warshipv3/board/ports/include/sram_port.h @@ -13,10 +13,10 @@ /* parameters for sdram peripheral */ /* stm32f1 Bank1:0x68000000 */ -#define SRAM_BANK_ADDR ((uint32_t)0x68000000) +#define EXTERNAL_SRAM_BANK_ADDR ((uint32_t)0x68000000) /* data width: 8, 16, 32 */ -#define SRAM_DATA_WIDTH 16 +#define EXTERNAL_SRAM_DATA_WIDTH 16 /* sram size */ -#define SRAM_SIZE ((uint32_t)0x100000) +#define EXTERNAL_SRAM_SIZE ((uint32_t)0x100000) #endif -- Gitee From dddc8ab896fcec1d79b6e77de573d53d2e133dd3 Mon Sep 17 00:00:00 2001 From: armink Date: Thu, 9 Jan 2020 10:45:21 +0800 Subject: [PATCH 049/110] Update the RT_VER_NUM to 4.0.3. --- src/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Kconfig b/src/Kconfig index 22942a017e..63a7a67887 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -331,7 +331,7 @@ endmenu config RT_VER_NUM hex - default 0x40002 + default 0x40003 help RT-Thread version number -- Gitee From 438397b586a62ea65917bc961e95ffa8e376098f Mon Sep 17 00:00:00 2001 From: chenxuuu Date: Thu, 9 Jan 2020 17:05:05 +0800 Subject: [PATCH 050/110] fix makeimg.py wrong on linux --- bsp/w60x/makeimg.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/bsp/w60x/makeimg.py b/bsp/w60x/makeimg.py index 277ad872d5..f3f194cd90 100644 --- a/bsp/w60x/makeimg.py +++ b/bsp/w60x/makeimg.py @@ -103,6 +103,11 @@ if __name__=='__main__': # Setting the makeimg_all.exe file path makeimg_all_file=wmlib_path_full + '/Tools/makeimg_all.exe' + if (platform.system() == "Linux"): + wm_gzip_file=wmlib_path_full + '/Tools/wm_gzip.py' + makeimg_file=wmlib_path_full + '/Tools/makeimg' + makeimg_all_file=wmlib_path_full + '/Tools/makeimg_all' + # Get absolute path out_path = os.path.abspath(out_path).replace('\\', '/'); bin_file = os.path.abspath(bin_file).replace('\\', '/'); @@ -149,7 +154,10 @@ if __name__=='__main__': print('make_SEC_param' + make_SEC_param) print('make_FLS_param' + make_FLS_param) - do_makeimg(wm_gzip_file, gzip_param) + if (platform.system() == "Linux"): + do_makeimg("python",wm_gzip_file + " " + gzip_param) + else: + do_makeimg(wm_gzip_file, gzip_param) do_makeimg(makeimg_file, make_img_param) do_makeimg(makeimg_file, make_GZ_param) do_makeimg(makeimg_file, make_SEC_param) @@ -177,7 +185,10 @@ if __name__=='__main__': print('make_SEC_param' + make_SEC_param) print('make_FLS_param' + make_FLS_param) - do_makeimg(wm_gzip_file, gzip_param) + if (platform.system() == "Linux"): + do_makeimg("python",wm_gzip_file + " " + gzip_param) + else: + do_makeimg(wm_gzip_file, gzip_param) do_makeimg(makeimg_file, make_img_param) do_makeimg(makeimg_file, make_GZ_param) do_makeimg(makeimg_file, make_SEC_param) @@ -211,4 +222,4 @@ if __name__=='__main__': if os.path.exists(rm_file): os.remove(rm_file) - print('end') \ No newline at end of file + print('end') -- Gitee From fdde8ab1982adabc71ab651e55160993dbdd9365 Mon Sep 17 00:00:00 2001 From: bigmagic Date: Fri, 10 Jan 2020 10:38:21 +0800 Subject: [PATCH 051/110] add raspi2 and raspi3 BSP --- bsp/{ => raspberry-pi}/raspi2/.config | 0 bsp/raspberry-pi/raspi2/Kconfig | 28 + bsp/{ => raspberry-pi}/raspi2/README.md | 0 bsp/{ => raspberry-pi}/raspi2/SConscript | 0 bsp/{ => raspberry-pi}/raspi2/SConstruct | 2 +- .../raspi2/applications/SConscript | 0 .../raspi2/applications/main.c | 0 .../raspi2/applications/mnt.c | 0 bsp/{ => raspberry-pi}/raspi2/driver/Kconfig | 0 .../raspi2/driver/SConscript | 0 .../raspi2/driver/bcm283x.h | 0 bsp/{ => raspberry-pi}/raspi2/driver/board.c | 0 bsp/{ => raspberry-pi}/raspi2/driver/board.h | 0 .../raspi2/driver/drv_uart.c | 0 .../raspi2/driver/drv_uart.h | 0 .../raspi2/figures/raspi2.png | Bin .../raspi2/figures/raspi_uart.png | Bin bsp/raspberry-pi/raspi2/kernel7.img | Bin 0 -> 91456 bytes bsp/{ => raspberry-pi}/raspi2/link.lds | 0 bsp/{ => raspberry-pi}/raspi2/rtconfig.h | 0 bsp/{ => raspberry-pi}/raspi2/rtconfig.py | 4 +- bsp/raspberry-pi/raspi3-32/.config | 427 ++++++++++++ .../raspi3-32}/Kconfig | 0 bsp/raspberry-pi/raspi3-32/README.md | 153 +++++ bsp/raspberry-pi/raspi3-32/SConscript | 14 + bsp/raspberry-pi/raspi3-32/SConstruct | 28 + .../raspi3-32/applications/SConscript | 9 + .../raspi3-32/applications/main.c | 18 + bsp/raspberry-pi/raspi3-32/applications/mnt.c | 29 + .../raspi3-32/applications/test_device.c | 462 +++++++++++++ .../raspi3-32}/cpu/SConscript | 0 bsp/raspberry-pi/raspi3-32/cpu/armv7.h | 74 ++ bsp/raspberry-pi/raspi3-32/cpu/context_gcc.S | 183 +++++ bsp/raspberry-pi/raspi3-32/cpu/cp15.h | 168 +++++ bsp/raspberry-pi/raspi3-32/cpu/cp15_gcc.S | 147 ++++ bsp/raspberry-pi/raspi3-32/cpu/cpu.c | 91 +++ bsp/raspberry-pi/raspi3-32/cpu/interrupt.c | 186 +++++ bsp/raspberry-pi/raspi3-32/cpu/interrupt.h | 18 + bsp/raspberry-pi/raspi3-32/cpu/mmu.c | 188 +++++ bsp/raspberry-pi/raspi3-32/cpu/mmu.h | 51 ++ bsp/raspberry-pi/raspi3-32/cpu/stack.c | 72 ++ bsp/raspberry-pi/raspi3-32/cpu/start_gcc.S | 459 +++++++++++++ bsp/raspberry-pi/raspi3-32/cpu/trap.c | 219 ++++++ bsp/raspberry-pi/raspi3-32/cpu/vector_gcc.S | 51 ++ bsp/raspberry-pi/raspi3-32/driver/Kconfig | 103 +++ bsp/raspberry-pi/raspi3-32/driver/SConscript | 31 + bsp/raspberry-pi/raspi3-32/driver/board.c | 182 +++++ bsp/raspberry-pi/raspi3-32/driver/board.h | 29 + bsp/raspberry-pi/raspi3-32/driver/drv_fb.c | 508 ++++++++++++++ bsp/raspberry-pi/raspi3-32/driver/drv_fb.h | 60 ++ bsp/raspberry-pi/raspi3-32/driver/drv_gpio.c | 318 +++++++++ bsp/raspberry-pi/raspi3-32/driver/drv_gpio.h | 42 ++ bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c | 238 +++++++ bsp/raspberry-pi/raspi3-32/driver/drv_i2c.h | 43 ++ bsp/raspberry-pi/raspi3-32/driver/drv_rtc.c | 301 ++++++++ bsp/raspberry-pi/raspi3-32/driver/drv_rtc.h | 21 + bsp/raspberry-pi/raspi3-32/driver/drv_sdio.c | 580 ++++++++++++++++ bsp/raspberry-pi/raspi3-32/driver/drv_sdio.h | 253 +++++++ bsp/raspberry-pi/raspi3-32/driver/drv_spi.c | 287 ++++++++ bsp/raspberry-pi/raspi3-32/driver/drv_spi.h | 102 +++ bsp/raspberry-pi/raspi3-32/driver/drv_timer.c | 154 +++++ bsp/raspberry-pi/raspi3-32/driver/drv_timer.h | 27 + bsp/raspberry-pi/raspi3-32/driver/drv_uart.c | 183 +++++ bsp/raspberry-pi/raspi3-32/driver/drv_uart.h | 41 ++ bsp/raspberry-pi/raspi3-32/driver/drv_wdt.c | 117 ++++ bsp/raspberry-pi/raspi3-32/driver/drv_wdt.h | 26 + bsp/raspberry-pi/raspi3-32/driver/mbox.c | 54 ++ bsp/raspberry-pi/raspi3-32/driver/mbox.h | 63 ++ bsp/raspberry-pi/raspi3-32/driver/raspi.h | 432 ++++++++++++ .../figures/GPIO-Pinout-Diagram-2.png | Bin 0 -> 206936 bytes .../raspi3-32/figures/raspberrypi-console.png | Bin 0 -> 1356117 bytes .../raspi3-32/figures/raspi3_b.jpg | Bin 0 -> 184309 bytes .../raspi3-32/figures/raspi3_f.jpg | Bin 0 -> 225139 bytes bsp/raspberry-pi/raspi3-32/link.lds | 149 ++++ bsp/raspberry-pi/raspi3-32/rtconfig.h | 391 +++++++++++ bsp/raspberry-pi/raspi3-32/rtconfig.py | 52 ++ bsp/raspberry-pi/raspi3-64/.config | 418 ++++++++++++ bsp/raspberry-pi/raspi3-64/.cproject | 150 ++++ bsp/raspberry-pi/raspi3-64/.project | 54 ++ bsp/raspberry-pi/raspi3-64/Kconfig | 29 + bsp/raspberry-pi/raspi3-64/README.md | 100 +++ bsp/raspberry-pi/raspi3-64/SConscript | 14 + bsp/raspberry-pi/raspi3-64/SConstruct | 30 + .../raspi3-64/applications/SConscript | 9 + .../raspi3-64/applications/main.c | 19 + bsp/raspberry-pi/raspi3-64/applications/mnt.c | 16 + .../raspi3-64/applications/test/gpio.h | 45 ++ .../raspi3-64/applications/test/uart.c | 103 +++ .../raspi3-64/applications/test/uart.h | 29 + bsp/raspberry-pi/raspi3-64/driver/Kconfig | 112 +++ bsp/raspberry-pi/raspi3-64/driver/SConscript | 32 + bsp/raspberry-pi/raspi3-64/driver/bcm283x.c | 575 ++++++++++++++++ bsp/raspberry-pi/raspi3-64/driver/bcm283x.h | 641 ++++++++++++++++++ bsp/raspberry-pi/raspi3-64/driver/board.c | 298 ++++++++ bsp/raspberry-pi/raspi3-64/driver/board.h | 29 + bsp/raspberry-pi/raspi3-64/driver/drv_fb.c | 523 ++++++++++++++ bsp/raspberry-pi/raspi3-64/driver/drv_fb.h | 60 ++ bsp/raspberry-pi/raspi3-64/driver/drv_gpio.c | 473 +++++++++++++ bsp/raspberry-pi/raspi3-64/driver/drv_gpio.h | 42 ++ bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c | 177 +++++ bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h | 43 ++ bsp/raspberry-pi/raspi3-64/driver/drv_rtc.c | 135 ++++ bsp/raspberry-pi/raspi3-64/driver/drv_rtc.h | 26 + bsp/raspberry-pi/raspi3-64/driver/drv_sdio.c | 532 +++++++++++++++ bsp/raspberry-pi/raspi3-64/driver/drv_sdio.h | 345 ++++++++++ bsp/raspberry-pi/raspi3-64/driver/drv_spi.c | 396 +++++++++++ bsp/raspberry-pi/raspi3-64/driver/drv_spi.h | 68 ++ bsp/raspberry-pi/raspi3-64/driver/drv_timer.c | 141 ++++ bsp/raspberry-pi/raspi3-64/driver/drv_timer.h | 24 + bsp/raspberry-pi/raspi3-64/driver/drv_uart.c | 184 +++++ bsp/raspberry-pi/raspi3-64/driver/drv_uart.h | 42 ++ bsp/raspberry-pi/raspi3-64/driver/drv_wdt.c | 140 ++++ bsp/raspberry-pi/raspi3-64/driver/drv_wdt.h | 29 + bsp/raspberry-pi/raspi3-64/driver/mbox.c | 53 ++ bsp/raspberry-pi/raspi3-64/driver/mbox.h | 62 ++ bsp/raspberry-pi/raspi3-64/driver/raspi.h | 70 ++ .../raspi3-64/figures/raspi_uart.png | Bin 0 -> 1067143 bytes bsp/raspberry-pi/raspi3-64/kernel8.img | Bin 0 -> 163872 bytes bsp/raspberry-pi/raspi3-64/link.lds | 151 +++++ bsp/raspberry-pi/raspi3-64/qemu-64.bat | 1 + bsp/raspberry-pi/raspi3-64/rtconfig.h | 382 +++++++++++ bsp/raspberry-pi/raspi3-64/rtconfig.py | 54 ++ libcpu/aarch64/SConscript | 16 + libcpu/aarch64/cortex-a53/SConscript | 15 + libcpu/aarch64/cortex-a53/armv8.h | 63 ++ libcpu/aarch64/cortex-a53/context_gcc.S | 307 +++++++++ libcpu/aarch64/cortex-a53/cp15.h | 167 +++++ libcpu/aarch64/cortex-a53/cpu.c | 91 +++ libcpu/aarch64/cortex-a53/cpu_gcc.S | 78 +++ libcpu/aarch64/cortex-a53/entry_point.S | 102 +++ libcpu/aarch64/cortex-a53/interrupt.c | 183 +++++ libcpu/aarch64/cortex-a53/interrupt.h | 20 + libcpu/aarch64/cortex-a53/mmu.c | 186 +++++ libcpu/aarch64/cortex-a53/mmu.h | 51 ++ libcpu/aarch64/cortex-a53/stack.c | 90 +++ libcpu/aarch64/cortex-a53/startup_gcc.S | 13 + libcpu/aarch64/cortex-a53/trap.c | 221 ++++++ libcpu/aarch64/cortex-a53/vector_gcc.S | 57 ++ libcpu/arm/cortex-a53/SConscript | 9 + libcpu/arm/cortex-a53/armv7.h | 74 ++ libcpu/arm/cortex-a53/context_gcc.S | 183 +++++ libcpu/arm/cortex-a53/cp15.h | 168 +++++ libcpu/arm/cortex-a53/cp15_gcc.S | 147 ++++ libcpu/arm/cortex-a53/cpu.c | 91 +++ libcpu/arm/cortex-a53/interrupt.c | 186 +++++ libcpu/arm/cortex-a53/interrupt.h | 18 + libcpu/arm/cortex-a53/mmu.c | 188 +++++ libcpu/arm/cortex-a53/mmu.h | 51 ++ libcpu/arm/cortex-a53/stack.c | 72 ++ libcpu/arm/cortex-a53/start_gcc.S | 459 +++++++++++++ libcpu/arm/cortex-a53/trap.c | 219 ++++++ libcpu/arm/cortex-a53/vector_gcc.S | 51 ++ libcpu/arm/cortex-a7/SConscript | 9 + .../cpu => libcpu/arm/cortex-a7}/armv7.h | 0 .../arm/cortex-a7}/context_gcc.S | 0 .../cpu => libcpu/arm/cortex-a7}/cp15.h | 0 .../cpu => libcpu/arm/cortex-a7}/cp15_gcc.S | 0 .../raspi2/cpu => libcpu/arm/cortex-a7}/cpu.c | 0 .../cpu => libcpu/arm/cortex-a7}/interrupt.c | 0 .../raspi2/cpu => libcpu/arm/cortex-a7}/mmu.c | 0 .../cpu => libcpu/arm/cortex-a7}/stack.c | 0 .../cpu => libcpu/arm/cortex-a7}/start_gcc.S | 0 .../cpu => libcpu/arm/cortex-a7}/trap.c | 0 .../cpu => libcpu/arm/cortex-a7}/vector_gcc.S | 0 164 files changed, 18306 insertions(+), 3 deletions(-) rename bsp/{ => raspberry-pi}/raspi2/.config (100%) create mode 100644 bsp/raspberry-pi/raspi2/Kconfig rename bsp/{ => raspberry-pi}/raspi2/README.md (100%) rename bsp/{ => raspberry-pi}/raspi2/SConscript (100%) rename bsp/{ => raspberry-pi}/raspi2/SConstruct (92%) rename bsp/{ => raspberry-pi}/raspi2/applications/SConscript (100%) rename bsp/{ => raspberry-pi}/raspi2/applications/main.c (100%) rename bsp/{ => raspberry-pi}/raspi2/applications/mnt.c (100%) rename bsp/{ => raspberry-pi}/raspi2/driver/Kconfig (100%) rename bsp/{ => raspberry-pi}/raspi2/driver/SConscript (100%) rename bsp/{ => raspberry-pi}/raspi2/driver/bcm283x.h (100%) rename bsp/{ => raspberry-pi}/raspi2/driver/board.c (100%) rename bsp/{ => raspberry-pi}/raspi2/driver/board.h (100%) rename bsp/{ => raspberry-pi}/raspi2/driver/drv_uart.c (100%) rename bsp/{ => raspberry-pi}/raspi2/driver/drv_uart.h (100%) rename bsp/{ => raspberry-pi}/raspi2/figures/raspi2.png (100%) rename bsp/{ => raspberry-pi}/raspi2/figures/raspi_uart.png (100%) create mode 100755 bsp/raspberry-pi/raspi2/kernel7.img rename bsp/{ => raspberry-pi}/raspi2/link.lds (100%) rename bsp/{ => raspberry-pi}/raspi2/rtconfig.h (100%) rename bsp/{ => raspberry-pi}/raspi2/rtconfig.py (94%) create mode 100644 bsp/raspberry-pi/raspi3-32/.config rename bsp/{raspi2 => raspberry-pi/raspi3-32}/Kconfig (100%) create mode 100644 bsp/raspberry-pi/raspi3-32/README.md create mode 100644 bsp/raspberry-pi/raspi3-32/SConscript create mode 100644 bsp/raspberry-pi/raspi3-32/SConstruct create mode 100644 bsp/raspberry-pi/raspi3-32/applications/SConscript create mode 100644 bsp/raspberry-pi/raspi3-32/applications/main.c create mode 100644 bsp/raspberry-pi/raspi3-32/applications/mnt.c create mode 100644 bsp/raspberry-pi/raspi3-32/applications/test_device.c rename bsp/{raspi2 => raspberry-pi/raspi3-32}/cpu/SConscript (100%) create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/armv7.h create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/context_gcc.S create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/cp15.h create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/cp15_gcc.S create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/cpu.c create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/interrupt.c create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/interrupt.h create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/mmu.c create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/mmu.h create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/stack.c create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/start_gcc.S create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/trap.c create mode 100644 bsp/raspberry-pi/raspi3-32/cpu/vector_gcc.S create mode 100644 bsp/raspberry-pi/raspi3-32/driver/Kconfig create mode 100644 bsp/raspberry-pi/raspi3-32/driver/SConscript create mode 100644 bsp/raspberry-pi/raspi3-32/driver/board.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/board.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_fb.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_fb.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_gpio.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_gpio.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_i2c.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_rtc.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_rtc.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_sdio.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_sdio.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_spi.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_spi.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_timer.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_timer.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_uart.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_uart.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_wdt.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/drv_wdt.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/mbox.c create mode 100644 bsp/raspberry-pi/raspi3-32/driver/mbox.h create mode 100644 bsp/raspberry-pi/raspi3-32/driver/raspi.h create mode 100644 bsp/raspberry-pi/raspi3-32/figures/GPIO-Pinout-Diagram-2.png create mode 100644 bsp/raspberry-pi/raspi3-32/figures/raspberrypi-console.png create mode 100644 bsp/raspberry-pi/raspi3-32/figures/raspi3_b.jpg create mode 100644 bsp/raspberry-pi/raspi3-32/figures/raspi3_f.jpg create mode 100644 bsp/raspberry-pi/raspi3-32/link.lds create mode 100644 bsp/raspberry-pi/raspi3-32/rtconfig.h create mode 100644 bsp/raspberry-pi/raspi3-32/rtconfig.py create mode 100644 bsp/raspberry-pi/raspi3-64/.config create mode 100644 bsp/raspberry-pi/raspi3-64/.cproject create mode 100644 bsp/raspberry-pi/raspi3-64/.project create mode 100644 bsp/raspberry-pi/raspi3-64/Kconfig create mode 100644 bsp/raspberry-pi/raspi3-64/README.md create mode 100644 bsp/raspberry-pi/raspi3-64/SConscript create mode 100644 bsp/raspberry-pi/raspi3-64/SConstruct create mode 100644 bsp/raspberry-pi/raspi3-64/applications/SConscript create mode 100644 bsp/raspberry-pi/raspi3-64/applications/main.c create mode 100644 bsp/raspberry-pi/raspi3-64/applications/mnt.c create mode 100644 bsp/raspberry-pi/raspi3-64/applications/test/gpio.h create mode 100644 bsp/raspberry-pi/raspi3-64/applications/test/uart.c create mode 100644 bsp/raspberry-pi/raspi3-64/applications/test/uart.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/Kconfig create mode 100644 bsp/raspberry-pi/raspi3-64/driver/SConscript create mode 100644 bsp/raspberry-pi/raspi3-64/driver/bcm283x.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/bcm283x.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/board.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/board.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_fb.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_fb.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_gpio.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_gpio.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_rtc.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_rtc.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_sdio.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_sdio.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_spi.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_spi.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_timer.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_timer.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_uart.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_uart.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_wdt.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/drv_wdt.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/mbox.c create mode 100644 bsp/raspberry-pi/raspi3-64/driver/mbox.h create mode 100644 bsp/raspberry-pi/raspi3-64/driver/raspi.h create mode 100644 bsp/raspberry-pi/raspi3-64/figures/raspi_uart.png create mode 100755 bsp/raspberry-pi/raspi3-64/kernel8.img create mode 100644 bsp/raspberry-pi/raspi3-64/link.lds create mode 100644 bsp/raspberry-pi/raspi3-64/qemu-64.bat create mode 100644 bsp/raspberry-pi/raspi3-64/rtconfig.h create mode 100644 bsp/raspberry-pi/raspi3-64/rtconfig.py create mode 100644 libcpu/aarch64/SConscript create mode 100644 libcpu/aarch64/cortex-a53/SConscript create mode 100644 libcpu/aarch64/cortex-a53/armv8.h create mode 100644 libcpu/aarch64/cortex-a53/context_gcc.S create mode 100644 libcpu/aarch64/cortex-a53/cp15.h create mode 100644 libcpu/aarch64/cortex-a53/cpu.c create mode 100644 libcpu/aarch64/cortex-a53/cpu_gcc.S create mode 100644 libcpu/aarch64/cortex-a53/entry_point.S create mode 100644 libcpu/aarch64/cortex-a53/interrupt.c create mode 100644 libcpu/aarch64/cortex-a53/interrupt.h create mode 100644 libcpu/aarch64/cortex-a53/mmu.c create mode 100644 libcpu/aarch64/cortex-a53/mmu.h create mode 100644 libcpu/aarch64/cortex-a53/stack.c create mode 100644 libcpu/aarch64/cortex-a53/startup_gcc.S create mode 100644 libcpu/aarch64/cortex-a53/trap.c create mode 100644 libcpu/aarch64/cortex-a53/vector_gcc.S create mode 100644 libcpu/arm/cortex-a53/SConscript create mode 100644 libcpu/arm/cortex-a53/armv7.h create mode 100644 libcpu/arm/cortex-a53/context_gcc.S create mode 100644 libcpu/arm/cortex-a53/cp15.h create mode 100644 libcpu/arm/cortex-a53/cp15_gcc.S create mode 100644 libcpu/arm/cortex-a53/cpu.c create mode 100644 libcpu/arm/cortex-a53/interrupt.c create mode 100644 libcpu/arm/cortex-a53/interrupt.h create mode 100644 libcpu/arm/cortex-a53/mmu.c create mode 100644 libcpu/arm/cortex-a53/mmu.h create mode 100644 libcpu/arm/cortex-a53/stack.c create mode 100644 libcpu/arm/cortex-a53/start_gcc.S create mode 100644 libcpu/arm/cortex-a53/trap.c create mode 100644 libcpu/arm/cortex-a53/vector_gcc.S create mode 100644 libcpu/arm/cortex-a7/SConscript rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/armv7.h (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/context_gcc.S (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/cp15.h (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/cp15_gcc.S (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/cpu.c (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/interrupt.c (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/mmu.c (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/stack.c (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/start_gcc.S (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/trap.c (100%) rename {bsp/raspi2/cpu => libcpu/arm/cortex-a7}/vector_gcc.S (100%) diff --git a/bsp/raspi2/.config b/bsp/raspberry-pi/raspi2/.config similarity index 100% rename from bsp/raspi2/.config rename to bsp/raspberry-pi/raspi2/.config diff --git a/bsp/raspberry-pi/raspi2/Kconfig b/bsp/raspberry-pi/raspi2/Kconfig new file mode 100644 index 0000000000..f7693c8378 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/Kconfig @@ -0,0 +1,28 @@ +mainmenu "RT-Thread Project Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" + +config BCM2836_SOC + bool + select ARCH_ARM_CORTEX_A7 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +source "driver/Kconfig" diff --git a/bsp/raspi2/README.md b/bsp/raspberry-pi/raspi2/README.md similarity index 100% rename from bsp/raspi2/README.md rename to bsp/raspberry-pi/raspi2/README.md diff --git a/bsp/raspi2/SConscript b/bsp/raspberry-pi/raspi2/SConscript similarity index 100% rename from bsp/raspi2/SConscript rename to bsp/raspberry-pi/raspi2/SConscript diff --git a/bsp/raspi2/SConstruct b/bsp/raspberry-pi/raspi2/SConstruct similarity index 92% rename from bsp/raspi2/SConstruct rename to bsp/raspberry-pi/raspi2/SConstruct index e5acdb2554..e94a364d9d 100644 --- a/bsp/raspi2/SConstruct +++ b/bsp/raspberry-pi/raspi2/SConstruct @@ -22,7 +22,7 @@ Export('RTT_ROOT') Export('rtconfig') # prepare building environment -objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True) +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False) # make a building DoBuilding(TARGET, objs) diff --git a/bsp/raspi2/applications/SConscript b/bsp/raspberry-pi/raspi2/applications/SConscript similarity index 100% rename from bsp/raspi2/applications/SConscript rename to bsp/raspberry-pi/raspi2/applications/SConscript diff --git a/bsp/raspi2/applications/main.c b/bsp/raspberry-pi/raspi2/applications/main.c similarity index 100% rename from bsp/raspi2/applications/main.c rename to bsp/raspberry-pi/raspi2/applications/main.c diff --git a/bsp/raspi2/applications/mnt.c b/bsp/raspberry-pi/raspi2/applications/mnt.c similarity index 100% rename from bsp/raspi2/applications/mnt.c rename to bsp/raspberry-pi/raspi2/applications/mnt.c diff --git a/bsp/raspi2/driver/Kconfig b/bsp/raspberry-pi/raspi2/driver/Kconfig similarity index 100% rename from bsp/raspi2/driver/Kconfig rename to bsp/raspberry-pi/raspi2/driver/Kconfig diff --git a/bsp/raspi2/driver/SConscript b/bsp/raspberry-pi/raspi2/driver/SConscript similarity index 100% rename from bsp/raspi2/driver/SConscript rename to bsp/raspberry-pi/raspi2/driver/SConscript diff --git a/bsp/raspi2/driver/bcm283x.h b/bsp/raspberry-pi/raspi2/driver/bcm283x.h similarity index 100% rename from bsp/raspi2/driver/bcm283x.h rename to bsp/raspberry-pi/raspi2/driver/bcm283x.h diff --git a/bsp/raspi2/driver/board.c b/bsp/raspberry-pi/raspi2/driver/board.c similarity index 100% rename from bsp/raspi2/driver/board.c rename to bsp/raspberry-pi/raspi2/driver/board.c diff --git a/bsp/raspi2/driver/board.h b/bsp/raspberry-pi/raspi2/driver/board.h similarity index 100% rename from bsp/raspi2/driver/board.h rename to bsp/raspberry-pi/raspi2/driver/board.h diff --git a/bsp/raspi2/driver/drv_uart.c b/bsp/raspberry-pi/raspi2/driver/drv_uart.c similarity index 100% rename from bsp/raspi2/driver/drv_uart.c rename to bsp/raspberry-pi/raspi2/driver/drv_uart.c diff --git a/bsp/raspi2/driver/drv_uart.h b/bsp/raspberry-pi/raspi2/driver/drv_uart.h similarity index 100% rename from bsp/raspi2/driver/drv_uart.h rename to bsp/raspberry-pi/raspi2/driver/drv_uart.h diff --git a/bsp/raspi2/figures/raspi2.png b/bsp/raspberry-pi/raspi2/figures/raspi2.png similarity index 100% rename from bsp/raspi2/figures/raspi2.png rename to bsp/raspberry-pi/raspi2/figures/raspi2.png diff --git a/bsp/raspi2/figures/raspi_uart.png b/bsp/raspberry-pi/raspi2/figures/raspi_uart.png similarity index 100% rename from bsp/raspi2/figures/raspi_uart.png rename to bsp/raspberry-pi/raspi2/figures/raspi_uart.png diff --git a/bsp/raspberry-pi/raspi2/kernel7.img b/bsp/raspberry-pi/raspi2/kernel7.img new file mode 100755 index 0000000000000000000000000000000000000000..82e849b25d9544e80bce3664bea3cd509f1df0b8 GIT binary patch literal 91456 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 Existing Peojects into Workspace 然后 Browse.. 你的raspi3目录,点击Finish + +btw:编译依旧使用scons,目前不支持qemu debug,后期如果有大佬实现ARM JTAG调试 + +## 3. 执行 + +### 3.1 下载[raspbian镜像][3],生成可以运行的raspbian SD卡 + +Windows下,去[etcher.io][4]下载etcher,这是个可以烧写img的工具 + +解开下载的镜像文件, linux下使用如下的命令 + +``` +unzip 2018-06-27-raspbian-stretch-lite.zip +``` + +准备一张空SD卡,linux环境下,插入电脑并执行 + +``` +sudo dd if=2018-06-27-raspbian-stretch-lite.img of=/dev/xxx bs=32M conv=fsync +``` + +**注意: /dev/xxx 要换成真实环境中的SD卡所在设置,千万不要弄错。** + +Windows环境下,执行etcher选择解压后的2018-06-27-raspbian-stretch-lite.img文件和SD卡就可以开始烧写了。 + +最后把kernel7.img放入SD boot分区,覆盖原来的文件。 + +### 3.2 准备好串口线 + +目前版本是使用raspi3的 GPIO 14, GPIO 15来作路口输出,连线情况如下图所示: + + + +![raspberrypi-console](figures/raspberrypi-console.png) + +串口参数: 115200 8N1 ,硬件和软件流控为关。 + +按上面的方法做好SD卡后,插入树莓派3B,通电可以在串口上看到如下所示的输出信息: + +```text +heap: 0x0005d784 - 0x0045d784 + + \ | / +- RT - Thread Operating System + / | \ 4.0.2 build Jan 9 2020 + 2006 - 2019 Copyright by rt-thread team +[I/I2C] I2C bus [i2c0] registered +[I/I2C] I2C bus [i2c1] registered +[I/SDIO] SD card capacity 15558144 KB. +found part[0], begin: 1048576, size: 63.0MB +found part[1], begin: 67108864, size: 14.793GB +file system initialization done! +boot cpu:3 +msh />cpu = 0x00000003 +cpu 3 startup. +start OK: CPU 3 +boot cpu:2 +cpu = 0x00000002 +cpu 2 startup. +start OK: CPU 2 +boot cpu:1 +cpu = 0x00000001 +cpu 1 startup. +start OK: CPU 1 +Hello RT-Thread! + +msh /> +``` + +## 4. 支持情况 + +| 驱动 | 支持情况 | 备注 | +| ------ | ---- | :------: | +| UART | 支持 | UART0| +| GPIO | 支持 | | +| IIC | 支持 | | +| SPI | 支持 | | +| CPU Timer | 支持 | | +| SD卡驱动 | 支持 | | + +## 5. 联系人信息 + +维护人:[bernard][5] + +[1]: https://www.rt-thread.org/page/download.html +[2]: https://launchpad.net/gcc-arm-embedded/4.8/4.8-2014-q1-update/+download/gcc-arm-none-eabi-4_8-2014q1-20140314-linux.tar.bz2 +[3]: https://downloads.raspberrypi.org/raspbian_lite_latest +[4]: https://etcher.io +[5]: https://github.com/BernardXiong diff --git a/bsp/raspberry-pi/raspi3-32/SConscript b/bsp/raspberry-pi/raspi3-32/SConscript new file mode 100644 index 0000000000..c7ef7659ec --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/raspberry-pi/raspi3-32/SConstruct b/bsp/raspberry-pi/raspi3-32/SConstruct new file mode 100644 index 0000000000..e94a364d9d --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/SConstruct @@ -0,0 +1,28 @@ +import os +import sys +import rtconfig + +from rtconfig import RTT_ROOT + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/raspberry-pi/raspi3-32/applications/SConscript b/bsp/raspberry-pi/raspi3-32/applications/SConscript new file mode 100644 index 0000000000..533df8ac31 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/applications/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/raspberry-pi/raspi3-32/applications/main.c b/bsp/raspberry-pi/raspi3-32/applications/main.c new file mode 100644 index 0000000000..cda0e0d711 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/applications/main.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 bernard the first version + */ + +#include + +int main(int argc, char** argv) +{ + rt_kprintf("Hello RT-Thread!\n"); + + return 0; +} diff --git a/bsp/raspberry-pi/raspi3-32/applications/mnt.c b/bsp/raspberry-pi/raspi3-32/applications/mnt.c new file mode 100644 index 0000000000..88b714022c --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/applications/mnt.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 bernard the first version + */ + +#include + +#ifdef BSP_USING_SDIO0 +#include + +int mnt_init(void) +{ + rt_thread_delay(RT_TICK_PER_SECOND); + + if (dfs_mount("sd0", "/", "elm", 0, 0) == 0) + { + rt_kprintf("file system initialization done!\n"); + } + + return 0; +} +INIT_ENV_EXPORT(mnt_init); +#endif + diff --git a/bsp/raspberry-pi/raspi3-32/applications/test_device.c b/bsp/raspberry-pi/raspi3-32/applications/test_device.c new file mode 100644 index 0000000000..222bb2e822 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/applications/test_device.c @@ -0,0 +1,462 @@ +/* + * File : test_driver.h + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include +#include +#include +#include +#include +#include "raspi.h" + +#ifdef BSP_USING_HDMI +#include "drv_fb.h" +#endif + +void test_hdmi() +{ + rt_kprintf("Hello Test hdmi!\n"); +#ifdef BSP_USING_HDMI + print_fb_info(); +#ifdef BSP_USING_HDMI_DISPLAY + rt_kprintf("hdmi is tested!\n"); +#else + rt_console_set_device("hdmi"); + rt_kprintf("hdmi is testing!\n"); +#endif + rt_kprintf("search hdmi device"); + rt_device_t hdmi = rt_device_find("hdmi"); + if (hdmi == RT_NULL) + { + rt_kprintf("cannot find hdmi device"); + } + int color = COLOR_YELLOW; + rt_kprintf("begin test hdmi deivice"); + rt_graphix_ops(hdmi) -> set_pixel((char *)&color, 5, 5); + + rt_graphix_ops(hdmi) -> get_pixel((char *)&color, 5, 5); + rt_kprintf("color is %x\n",color); + rt_graphix_ops(hdmi) -> draw_hline((char *)&color, 10, 100, 10); + color = COLOR_GREEN; + rt_graphix_ops(hdmi) -> draw_vline((char *)&color, 10, 10, 100); + int colors[100]; + int i=0; + for (; i < 20; i++) colors[i] = COLOR_RED; + rt_graphix_ops(hdmi) -> blit_line((char *)colors, 20, 20, 20); + +#endif +} + +#ifdef RT_USING_SMP +#define _CPUS_NR RT_CPUS_NR +#else +#define _CPUS_NR 1 +#endif + +#ifdef RT_USING_SMP +static rt_uint8_t rt_thread_stack[_CPUS_NR][128]; +static struct rt_thread smp[_CPUS_NR]; +void smp_test_entry() +{ + rt_kprintf("cpu %d is running.\n",rt_hw_cpu_id()); +} +#endif + +void test_cpusmp(void) +{ + rt_kprintf("Hello Test SMP!\n"); +#ifdef RT_USING_SMP + int i; + char test_name[RT_NAME_MAX]; + for (i = 0; i < _CPUS_NR; i++) + { + rt_sprintf(test_name, "smp%d", i); + rt_thread_init(&smp[i], + test_name, + smp_test_entry, + RT_NULL, + &rt_thread_stack[i][0], + sizeof(rt_thread_stack[i]), + RT_THREAD_PRIORITY_MAX - 2, + 32); + rt_thread_control(&smp[i], RT_THREAD_CTRL_BIND_CPU, (void*)i); + /* startup */ + rt_thread_startup(&smp[i]); + rt_thread_delay(RT_TICK_PER_SECOND); + } +#endif +} + +#ifdef BSP_USING_PIN +#define TEST_PIN_OUT 33 +#define TEST_PIN_IN 37 + +void gpio_rising_test() +{ + rt_kprintf("gpio rising irq function ok!\n"); +} +#endif + +void test_gpio(void) +{ +#ifdef BSP_USING_PIN + rt_uint32_t ret; + rt_kprintf("Hello Test GPIO!\n"); + + rt_pin_mode(TEST_PIN_OUT, PIN_MODE_OUTPUT); + rt_pin_write(TEST_PIN_OUT, PIN_HIGH); + rt_pin_mode(TEST_PIN_IN, PIN_MODE_INPUT); + + ret = rt_pin_read(TEST_PIN_IN); + rt_kprintf("common high input test read result: %d\n",ret); + + rt_pin_write(TEST_PIN_OUT, PIN_LOW); + ret = rt_pin_read(TEST_PIN_IN); + rt_kprintf("common low input test read result: %d\n",ret); + + rt_pin_mode(TEST_PIN_IN, PIN_MODE_INPUT_PULLDOWN); + rt_pin_attach_irq(TEST_PIN_IN, PIN_IRQ_MODE_RISING, gpio_rising_test, RT_NULL); + rt_pin_irq_enable(TEST_PIN_IN, PIN_IRQ_ENABLE); + rt_pin_write(TEST_PIN_OUT, PIN_HIGH); + + rt_pin_irq_enable(TEST_PIN_IN, PIN_IRQ_DISABLE); +#endif +} + +#ifdef BSP_USING_I2C1 +#define DS3231_I2C_BUS_NAME "i2c1" +#define DS3231_ADDR 0x68 +struct rt_i2c_bus_device *i2c_bus = RT_NULL; +static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf) +{ + struct rt_i2c_msg msgs; + msgs.addr = DS3231_ADDR; + msgs.flags = RT_I2C_RD; + msgs.buf = buf; + msgs.len = len; + + if (rt_i2c_transfer(bus, &msgs, 1) == 1) + return RT_EOK; + else + return -RT_ERROR; +} +#endif + +void test_i2c(void) +{ +#ifdef BSP_USING_I2C1 + rt_kprintf("Hello Test I2C!\n"); + char name[RT_NAME_MAX]; + rt_uint8_t buf[]={0x00,0x00,0x43,0x15,0x05,0x01,0x03,0x19}; + + rt_strncpy(name, DS3231_I2C_BUS_NAME, RT_NAME_MAX); + i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name); + if (i2c_bus == RT_NULL) + rt_kprintf("can't find %s device!\n", name); + else + { + read_regs(i2c_bus, 7, buf); + buf[0] = buf[0]&0x7F; //sec + buf[1] = buf[1]&0x7F; //min + buf[2] = buf[2]&0x3F; //hour + buf[3] = buf[3]&0x07; //week + buf[4] = buf[4]&0x3F; //day + buf[5] = buf[5]&0x1F; //mouth + //year/month/day + rt_kprintf("20%02x-%02x-%02x ",buf[6],buf[5],buf[4]); + //hour:minute/second + rt_kprintf("%02x:%02x:%02x \n",buf[2],buf[1],buf[0]); + } +#endif +} + +#define W25Q_SPI_DEVICE_NAME "spi0.0" +void test_spi(void) +{ +#ifdef BSP_USING_SPI + rt_kprintf("Hello Test SPI!\n"); + struct rt_spi_device *spi0_dev0; + struct rt_spi_device *spi0_dev1; + + char name0[RT_NAME_MAX]; + char name1[RT_NAME_MAX]; + + rt_uint8_t w25x_read_id = 0x90; + rt_uint8_t id[5] = {0}; + + rt_strncpy(name0, "spi0.0", RT_NAME_MAX); + rt_strncpy(name1, "spi0.1", RT_NAME_MAX); + + spi0_dev0 = (struct rt_spi_device *)rt_device_find(name0); + spi0_dev1 = (struct rt_spi_device *)rt_device_find(name1); + + + if (!spi0_dev0 || !spi0_dev1) + { + rt_kprintf("spi sample run failed! can't find %s device!\n", name0); + } + else + { + struct rt_spi_message msg1, msg2; + + msg1.send_buf = &w25x_read_id; + msg1.recv_buf = RT_NULL; + msg1.length = 1; + msg1.cs_take = 1; + msg1.cs_release = 0; + msg1.next = &msg2; + + msg2.send_buf = RT_NULL; + msg2.recv_buf = id; + msg2.length = 5; + msg2.cs_take = 0; + msg2.cs_release = 1; + msg2.next = RT_NULL; + + rt_spi_transfer_message(spi0_dev0, &msg1); + rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id[3], id[4]); + + } +#endif +} + +#ifdef BSP_USING_SYSTIMER +#define TIMER "timer1" + +static rt_err_t timer_timeout_cb(rt_device_t dev, rt_size_t size) +{ + rt_kprintf("enter hardware timer isr\n"); + return 0; +} +#endif +rt_err_t test_hwtimer(void) +{ +#ifdef BSP_USING_SYSTIMER + rt_kprintf("Hello Test HW Timer!\n"); + rt_err_t err; + rt_hwtimerval_t val; + rt_device_t dev = RT_NULL; + rt_tick_t tick; + rt_hwtimer_mode_t mode; + int t = 5; + + if ((dev = rt_device_find(TIMER)) == RT_NULL) + { + rt_kprintf("No Device: %s\n", TIMER); + return -1; + } + + if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK) + { + rt_kprintf("Open %s Fail\n", TIMER); + return -1; + } + + mode = HWTIMER_MODE_PERIOD; + err = rt_device_control(dev, HWTIMER_CTRL_MODE_SET, &mode); + + tick = rt_tick_get(); + rt_kprintf("Start Timer> Tick: %d\n", tick); + + val.sec = t; + val.usec = 0; + rt_kprintf("SetTime: Sec %d, Usec %d\n", val.sec, val.usec); + if (rt_device_write(dev, 0, &val, sizeof(val)) != sizeof(val)) + { + rt_kprintf("SetTime Fail\n"); + goto EXIT; + } + rt_kprintf("Sleep %d sec\n", t); + rt_thread_delay(t*RT_TICK_PER_SECOND); + + err = rt_device_control(dev, HWTIMER_CTRL_STOP, RT_NULL); + rt_kprintf("Timer Stoped\n"); + + rt_device_read(dev, 0, &val, sizeof(val)); + rt_kprintf("Read: Sec = %d, Usec = %d\n", val.sec, val.usec); + + rt_device_set_rx_indicate(dev, timer_timeout_cb); + + mode = HWTIMER_MODE_PERIOD; + err = rt_device_control(dev, HWTIMER_CTRL_MODE_SET, &mode); + + val.sec = t; + val.usec = 0; + rt_kprintf("SetTime: Sec %d, Usec %d\n", val.sec, val.usec); + if (rt_device_write(dev, 0, &val, sizeof(val)) != sizeof(val)) + { + rt_kprintf("SetTime Fail\n"); + goto EXIT; + } + + rt_thread_delay((t *5 + 1)*RT_TICK_PER_SECOND); + +EXIT: + err = rt_device_close(dev); + rt_kprintf("Close %s\n", TIMER); + + return err; +#endif +} + +#ifdef RT_USING_WDT +#define WDT_DEVICE_NAME "wdg" /* 鐪嬮棬鐙楄澶囧悕绉� */ +static rt_device_t wdg_dev; /* 鐪嬮棬鐙楄澶囧彞鏌� */ +static void idle_hook(void) +{ + /* 鍦ㄧ┖闂茬嚎绋嬬殑鍥炶皟鍑芥暟閲屽杺鐙� */ + rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL); + //rt_kprintf("feed the dog!\n "); +} + +rt_err_t test_wdt(void) +{ + rt_kprintf("Hello Test WDT!\n"); + rt_err_t ret = RT_EOK; + rt_uint32_t timeout = 1; /* 婧㈠嚭鏃堕棿锛屽崟浣嶏細绉� */ + char device_name[RT_NAME_MAX]; + rt_strncpy(device_name, WDT_DEVICE_NAME, RT_NAME_MAX); + /* 鏍规嵁璁惧鍚嶇О鏌ユ壘鐪嬮棬鐙楄澶囷紝鑾峰彇璁惧鍙ユ焺 */ + wdg_dev = rt_device_find(device_name); + if (!wdg_dev) + { + rt_kprintf("find %s failed!\n", device_name); + return RT_ERROR; + } + /* 鍒濆鍖栬澶� */ + ret = rt_device_init(wdg_dev); + if (ret != RT_EOK) + { + rt_kprintf("initialize %s failed!\n", device_name); + return RT_ERROR; + } + /* 璁剧疆鐪嬮棬鐙楁孩鍑烘椂闂� */ + ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout); + if (ret != RT_EOK) + { + rt_kprintf("set %s timeout failed!\n", device_name); + return RT_ERROR; + } + /* 鍚姩鐪嬮棬鐙� */ + ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL); + if (ret != RT_EOK) + { + rt_kprintf("start %s failed!\n", device_name); + return -RT_ERROR; + } + /* 璁剧疆绌洪棽绾跨▼鍥炶皟鍑芥暟 */ + rt_thread_idle_sethook(idle_hook); + + return ret; + +} +#else +rt_err_t test_wdt(void) +{ + return RT_EOK; +} +#endif + +int test_rtc(void) +{ +#ifdef BSP_USING_RTD + rt_kprintf("Hello Test RTC!\n"); + uint8_t i; + time_t now; + + rt_err_t ret = RT_EOK; + + rt_kprintf("[RTC Test]RTC Test Start...\n"); + rt_thread_delay(RT_TICK_PER_SECOND); + rt_kprintf("[RTC Test]Set RTC 2017-04-01 12:30:46\n\n"); + rt_thread_delay(RT_TICK_PER_SECOND); + + ret = set_date(2017, 4, 1); + if (ret != RT_EOK) + { + rt_kprintf("[RTC Test]Set RTC Date failed\n"); + return RT_ERROR; + } + + rt_thread_delay(RT_TICK_PER_SECOND); + + ret = set_time(12, 30, 46); + if (ret != RT_EOK) + { + rt_kprintf("[RTC Test]Set RTC Time failed\n"); + return RT_ERROR; + } + + rt_thread_delay(RT_TICK_PER_SECOND); + + for (i = 0; i < 10; i++) + { + rt_kprintf("[RTC Test]Read RTC Date and Time: "); + now = time(RT_NULL); + rt_kprintf("%s", ctime(&now)); + + rt_thread_delay(RT_TICK_PER_SECOND); + } + + rt_kprintf("\n"); +#endif + return RT_EOK; +} + +void test_device(int argc, char**argv) +{ + if (0 == strcmp(argv[1],"smp")) + { + test_cpusmp(); + return; + } + if (0 == strcmp(argv[1],"gpio")) + { + test_gpio(); + return; + } + + if (0 == strcmp(argv[1],"i2c")) + { + test_i2c(); + return; + } + + if (0 == strcmp(argv[1],"spi")) + { + test_spi(); + return; + } + + if (0 == strcmp(argv[1],"hwtimer")) + { + test_hwtimer(); + return; + } + + if (0 == strcmp(argv[1],"wdt")) + { + test_wdt(); + return; + } + + if (0 == strcmp(argv[1],"rtc")) + { + test_rtc(); + return; + } + if (0 == strcmp(argv[1],"hdmi")) + { + test_hdmi(); + return; + } + rt_kprintf("param err, please entry test_device \n"); +} +MSH_CMD_EXPORT(test_device, sample: test_device ); diff --git a/bsp/raspi2/cpu/SConscript b/bsp/raspberry-pi/raspi3-32/cpu/SConscript similarity index 100% rename from bsp/raspi2/cpu/SConscript rename to bsp/raspberry-pi/raspi3-32/cpu/SConscript diff --git a/bsp/raspberry-pi/raspi3-32/cpu/armv7.h b/bsp/raspberry-pi/raspi3-32/cpu/armv7.h new file mode 100644 index 0000000000..859b0371b7 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/armv7.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ + +#ifndef __ARMV7_H__ +#define __ARMV7_H__ + +/* the exception stack without VFP registers */ +struct rt_hw_exp_stack +{ + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long sp; + unsigned long lr; + unsigned long pc; + unsigned long cpsr; +}; + +struct rt_hw_stack +{ + unsigned long cpsr; + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long lr; + unsigned long pc; +}; + +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define MONITORMODE 0x16 +#define ABORTMODE 0x17 +#define HYPMODE 0x1b +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 + +#define T_Bit (1<<5) +#define F_Bit (1<<6) +#define I_Bit (1<<7) +#define A_Bit (1<<8) +#define E_Bit (1<<9) +#define J_Bit (1<<24) + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/cpu/context_gcc.S b/bsp/raspberry-pi/raspi3-32/cpu/context_gcc.S new file mode 100644 index 0000000000..cb95558f7a --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/context_gcc.S @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + * 2019-07-28 zdzn add smp support + */ + +#include "../rtconfig.h" +.section .text, "ax" + +#ifdef RT_USING_SMP +#define rt_hw_interrupt_disable rt_hw_local_irq_disable +#define rt_hw_interrupt_enable rt_hw_local_irq_enable +#endif + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mrs r0, cpsr + cpsid i + bx lr + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + msr cpsr, r0 + bx lr + +/* + * void rt_hw_context_switch_to(rt_uint32 to, struct rt_thread *to_thread); + * r0 --> to (thread stack) + * r1 --> to_thread + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + ldr sp, [r0] @ get new task stack pointer + +#ifdef RT_USING_SMP + mov r0, r1 + bl rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + b rt_hw_context_switch_exit + +.section .bss.share.isr +_guest_switch_lvl: + .word 0 + +.globl vmm_virq_update + +.section .text.isr, "ax" +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to, struct rt_thread *to_thread); + * r0 --> from (from_thread stack) + * r1 --> to (to_thread stack) + * r2 --> to_thread + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) + stmfd sp!, {r0-r12, lr} @ push lr & register file + + mrs r4, cpsr + tst lr, #0x01 + orrne r4, r4, #0x20 @ it's thumb code + + stmfd sp!, {r4} @ push cpsr + +#ifdef RT_USING_LWP + stmfd sp, {r13, r14}^ @ push usr_sp usr_lr + sub sp, #8 +#endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb sp!, {d0-d15} + vstmdb sp!, {d16-d31} + vmrs r5, fpscr + stmfd sp!, {r5} +1: + stmfd sp!, {r6} +#endif + + str sp, [r0] @ store sp in preempted tasks TCB + ldr sp, [r1] @ get new task stack pointer + +#ifdef RT_USING_SMP + mov r0, r2 + bl rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + b rt_hw_context_switch_exit + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: +#ifdef RT_USING_SMP + /* r0 :svc_mod context + * r1 :addr of from_thread's sp + * r2 :addr of to_thread's sp + * r3 :to_thread's tcb + */ + + str r0, [r1] + + ldr sp, [r2] + mov r0, r3 + bl rt_cpus_lock_status_restore + + b rt_hw_context_switch_exit + +#else /*RT_USING_SMP*/ + ldr r2, =rt_thread_switch_interrupt_flag + ldr r3, [r2] + cmp r3, #1 + beq _reswitch + ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 + str r0, [ip] + str r3, [r2] +_reswitch: + ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread + str r1, [r2] + bx lr +#endif /*RT_USING_SMP*/ + +.global rt_hw_context_switch_exit +rt_hw_context_switch_exit: + +#ifdef RT_USING_SMP +#ifdef RT_USING_SIGNALS + mov r0, sp + cps #Mode_IRQ + bl rt_signal_check + cps #Mode_SVC + mov sp, r0 +#endif +#endif +#ifdef RT_USING_FPU +/* fpu context */ + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq 1f + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d16-d31} + vldmia sp!, {d0-d15} + +#endif + +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ /* usr_sp, usr_lr */ + add sp, #8 +#endif + ldmfd sp!, {r4} + msr spsr_cxsf, r4 /* original mode */ + ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ + diff --git a/bsp/raspberry-pi/raspi3-32/cpu/cp15.h b/bsp/raspberry-pi/raspi3-32/cpu/cp15.h new file mode 100644 index 0000000000..14b85b7e64 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/cp15.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ +#include "raspi.h" +#ifndef __CP15_H__ +#define __CP15_H__ + +#ifndef __STATIC_FORCEINLINE +#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif + +#define __WFI() __asm__ volatile ("wfi":::"memory") + +#define __WFE() __asm__ volatile ("wfe":::"memory") + +#define __SEV() __asm__ volatile ("sev") + +__STATIC_FORCEINLINE void __ISB(void) +{ + __asm__ volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __asm__ volatile ("dsb 0xF":::"memory"); +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ + +__STATIC_FORCEINLINE void __DMB(void) +{ + __asm__ volatile ("dmb 0xF":::"memory"); +} + + +#ifdef RT_USING_SMP +static inline void send_ipi_msg(int cpu, int ipi_vector) +{ + IPI_MAILBOX_SET(cpu) = 1 << ipi_vector; +} + +static inline void setup_bootstrap_addr(int cpu, int addr) +{ + CORE_MAILBOX3_SET(cpu) = addr; +} + +static inline void enable_cpu_ipi_intr(int cpu) +{ + COREMB_INTCTL(cpu) = IPI_MAILBOX_INT_MASK; +} + +static inline void enable_cpu_timer_intr(int cpu) +{ + CORETIMER_INTCTL(cpu) = 0x8; +} + +static inline void enable_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 1; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL +} + +static inline void disable_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 0; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL +} + +static inline void mask_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 2; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL +} + +static inline void unmask_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 1; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL +} + +static inline rt_uint64_t read_cntvct(void) +{ + rt_uint32_t val,val1; + asm volatile ("mrrc p15, 1, %0, %1, c14" : "=r" (val),"=r" (val1)); + return (val); +} + +static inline rt_uint64_t read_cntvoff(void) +{ + + rt_uint64_t val; + asm volatile ("mrrc p15, 4, %Q0, %R0, c14" : "=r" (val)); + return (val); +} + +static inline rt_uint32_t read_cntv_tval(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c3, 0" : "=r"(val)); + return val; +} + + +static inline void write_cntv_tval(rt_uint32_t val) +{ + asm volatile ("mcr p15, 0, %0, c14, c3, 0" :: "r"(val)); + return; +} + +static inline rt_uint32_t read_cntfrq(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val)); + return val; +} + + +static inline rt_uint32_t read_cntctrl(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c1, 0" : "=r"(val)); + return val; +} + +static inline uint32_t write_cntctrl(uint32_t val) +{ + + asm volatile ("mcr p15, 0, %0, c14, c1, 0" : :"r"(val)); + return val; +} +#endif + +unsigned long rt_cpu_get_smp_id(void); + +void rt_cpu_mmu_disable(void); +void rt_cpu_mmu_enable(void); +void rt_cpu_tlb_set(volatile unsigned long*); + +void rt_cpu_dcache_clean_flush(void); +void rt_cpu_icache_flush(void); + +void rt_cpu_vector_set_base(unsigned int addr); +void rt_hw_mmu_init(void); +void rt_hw_vector_init(void); + +void set_timer_counter(unsigned int counter); +void set_timer_control(unsigned int control); +#endif diff --git a/bsp/raspberry-pi/raspi3-32/cpu/cp15_gcc.S b/bsp/raspberry-pi/raspi3-32/cpu/cp15_gcc.S new file mode 100644 index 0000000000..db2e6143ae --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/cp15_gcc.S @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.globl rt_cpu_get_smp_id +rt_cpu_get_smp_id: + mrc p15, #0, r0, c0, c0, #5 + bx lr + +.globl rt_cpu_vector_set_base +rt_cpu_vector_set_base: + /* clear SCTRL.V to customize the vector address */ + mrc p15, #0, r1, c1, c0, #0 + bic r1, #(1 << 13) + mcr p15, #0, r1, c1, c0, #0 + /* set up the vector address */ + mcr p15, #0, r0, c12, c0, #0 + dsb + bx lr + +.globl rt_hw_cpu_dcache_enable +rt_hw_cpu_dcache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_hw_cpu_icache_enable +rt_hw_cpu_icache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +_FLD_MAX_WAY: + .word 0x3ff +_FLD_MAX_IDX: + .word 0x7ff + +.globl set_timer_counter +set_timer_counter: + mcr p15, #0, r0, c14, c3, #0 @ write virtual timer timerval register + bx lr +.globl set_timer_control +set_timer_control: + mcr p15, #0, r0, c14, c3, #1 @ write virtual timer control register + bx lr + +.globl rt_cpu_dcache_clean_flush +rt_cpu_dcache_clean_flush: + push {r4-r11} + dmb + mrc p15, #1, r0, c0, c0, #1 @ read clid register + ands r3, r0, #0x7000000 @ get level of coherency + mov r3, r3, lsr #23 + beq finished + mov r10, #0 +loop1: + add r2, r10, r10, lsr #1 + mov r1, r0, lsr r2 + and r1, r1, #7 + cmp r1, #2 + blt skip + mcr p15, #2, r10, c0, c0, #0 + isb + mrc p15, #1, r1, c0, c0, #0 + and r2, r1, #7 + add r2, r2, #4 + ldr r4, _FLD_MAX_WAY + ands r4, r4, r1, lsr #3 + clz r5, r4 + ldr r7, _FLD_MAX_IDX + ands r7, r7, r1, lsr #13 +loop2: + mov r9, r4 +loop3: + orr r11, r10, r9, lsl r5 + orr r11, r11, r7, lsl r2 + mcr p15, #0, r11, c7, c14, #2 + subs r9, r9, #1 + bge loop3 + subs r7, r7, #1 + bge loop2 +skip: + add r10, r10, #2 + cmp r3, r10 + bgt loop1 + +finished: + dsb + isb + pop {r4-r11} + bx lr + +.globl rt_cpu_icache_flush +rt_cpu_icache_flush: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate + dsb + isb + bx lr + +.globl rt_hw_cpu_dcache_disable +rt_hw_cpu_dcache_disable: + push {r4-r11, lr} + bl rt_cpu_dcache_clean_flush + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + pop {r4-r11, lr} + bx lr + +.globl rt_hw_cpu_icache_disable +rt_hw_cpu_icache_disable: + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_cpu_mmu_disable +rt_cpu_mmu_disable: + mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #1 + mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit + dsb + bx lr + +.globl rt_cpu_mmu_enable +rt_cpu_mmu_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x001 + mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit + dsb + bx lr + +.globl rt_cpu_tlb_set +rt_cpu_tlb_set: + mcr p15, #0, r0, c2, c0, #0 + dmb + bx lr diff --git a/bsp/raspberry-pi/raspi3-32/cpu/cpu.c b/bsp/raspberry-pi/raspi3-32/cpu/cpu.c new file mode 100644 index 0000000000..4d02ca35e1 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/cpu.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + * 2019-07-28 zdzn add smp support + */ + +#include +#include +#include +#include "cp15.h" + +int rt_hw_cpu_id(void) +{ + int cpu_id; + __asm__ volatile ( + "mrc p15, 0, %0, c0, c0, 5" + :"=r"(cpu_id) + ); + cpu_id &= 0xf; + return cpu_id; +}; + + +#ifdef RT_USING_SMP +void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock) +{ + lock->slock = 0; +} + +void rt_hw_spin_lock(rt_hw_spinlock_t *lock) +{ + unsigned long tmp; + unsigned long newval; + rt_hw_spinlock_t lockval; + __asm__ __volatile__( + "pld [%0]" + ::"r"(&lock->slock) + ); + + __asm__ __volatile__( + "1: ldrex %0, [%3]\n" + " add %1, %0, %4\n" + " strex %2, %1, [%3]\n" + " teq %2, #0\n" + " bne 1b" + : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) + : "r" (&lock->slock), "I" (1 << 16) + : "cc"); + + while (lockval.tickets.next != lockval.tickets.owner) + { + __WFE(); + lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner); + } + + __DMB(); +} + +void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) +{ + __DMB(); + lock->tickets.owner++; + __DSB(); + __SEV(); +} +#endif /*RT_USING_SMP*/ + +/** + * @addtogroup ARM CPU + */ +/*@{*/ + +/** shutdown CPU */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} + +/*@}*/ diff --git a/bsp/raspberry-pi/raspi3-32/cpu/interrupt.c b/bsp/raspberry-pi/raspi3-32/cpu/interrupt.c new file mode 100644 index 0000000000..c9e7c17f8f --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/interrupt.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/5/3 Bernard first version + * 2019-07-28 zdzn add smp support + * 2019-08-09 zhangjun fixup the problem of smp startup and scheduling issues, + * write addr to mailbox3 to startup smp, and we use mailbox0 for ipi + */ + +#include +#include + +#include "cp15.h" +#include + +#define MAX_HANDLERS 72 + +#ifdef RT_USING_SMP +#define rt_interrupt_nest rt_cpu_self()->irq_nest +#else +extern volatile rt_uint8_t rt_interrupt_nest; +#endif + +const unsigned int VECTOR_BASE = 0x00; +extern void rt_cpu_vector_set_base(unsigned int addr); +extern int system_vectors; + +void rt_hw_vector_init(void) +{ + rt_cpu_vector_set_base((unsigned int)&system_vectors); +} + +/* exception and interrupt handler table */ +struct rt_irq_desc isr_table[MAX_HANDLERS]; + +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +extern int system_vectors; + +static void default_isr_handler(int vector, void *param) +{ +#ifdef RT_USING_SMP + rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(),vector); +#else + rt_kprintf("unhandled irq: %d\n",vector); +#endif +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + rt_uint32_t index; + + /* mask all of interrupts */ + IRQ_DISABLE_BASIC = 0x000000ff; + IRQ_DISABLE1 = 0xffffffff; + IRQ_DISABLE2 = 0xffffffff; + for (index = 0; index < MAX_HANDLERS; index ++) + { + isr_table[index].handler = default_isr_handler; + isr_table[index].param = NULL; +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX); + isr_table[index].counter = 0; +#endif + } + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + + if (vector < 32) + { + IRQ_DISABLE1 = (1 << vector); + } + else if (vector < 64) + { + vector = vector % 32; + IRQ_DISABLE2 = (1 << vector); + } + else + { + vector = vector - 64; + IRQ_DISABLE_BASIC = (1 << vector); + } +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + if (vector < 32) + { + IRQ_ENABLE1 = (1 << vector); + } + else if (vector < 64) + { + vector = vector % 32; + IRQ_ENABLE2 = (1 << vector); + } + else + { + vector = vector - 64; + IRQ_ENABLE_BASIC = (1 << vector); + } +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} + +#ifdef RT_USING_SMP +void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) +{ + __DSB(); + if (cpu_mask & 0x1) + { + send_ipi_msg(0, ipi_vector); + } + if (cpu_mask & 0x2) + { + send_ipi_msg(1, ipi_vector); + } + if (cpu_mask & 0x4) + { + send_ipi_msg(2, ipi_vector); + } + if (cpu_mask & 0x8) + { + send_ipi_msg(3, ipi_vector); + } + __DSB(); +} +#endif + +#ifdef RT_USING_SMP +void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) +{ + /* note: ipi_vector maybe different with irq_vector */ + rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER"); +} +#endif diff --git a/bsp/raspberry-pi/raspi3-32/cpu/interrupt.h b/bsp/raspberry-pi/raspi3-32/cpu/interrupt.h new file mode 100644 index 0000000000..9aae0f556a --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/interrupt.h @@ -0,0 +1,18 @@ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include +#include + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(int vector); + +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/cpu/mmu.c b/bsp/raspberry-pi/raspi3-32/cpu/mmu.c new file mode 100644 index 0000000000..b3541d2ad4 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/mmu.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2012-01-10 bernard porting to AM1808 + * 2019-07-28 zdzn add smp support + */ + +#include "mmu.h" + +/* dump 2nd level page table */ +void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + for (i = 0; i < 256; i++) + { + rt_uint32_t pte2 = ptb[i]; + if ((pte2 & 0x3) == 0) + { + if (fcnt == 0) + rt_kprintf(" "); + rt_kprintf("%04x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf(" %04x: %x: ", i, pte2); + if ((pte2 & 0x3) == 0x1) + { + rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, + (pte2 >> 15) & 0x1, + ((pte2 >> 10) | (pte2 >> 2)) & 0x1f); + } + else + { + rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1, + ((pte2 >> 4) | (pte2 >> 2)) & 0x1f); + } + } +} + +void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + rt_kprintf("page table@%p\n", ptb); + for (i = 0; i < 1024*4; i++) + { + rt_uint32_t pte1 = ptb[i]; + if ((pte1 & 0x3) == 0) + { + rt_kprintf("%03x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf("%03x: %08x: ", i, pte1); + if ((pte1 & 0x3) == 0x3) + { + rt_kprintf("LPAE\n"); + } + else if ((pte1 & 0x3) == 0x1) + { + rt_kprintf("pte,ns:%d,domain:%d\n", + (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf); + /* + *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000) + * - 0x80000000 + 0xC0000000)); + */ + } + else if (pte1 & (1 << 18)) + { + rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + ((pte1 >> 10) | (pte1 >> 2)) & 0x1f); + } + else + { + rt_kprintf("section,ns:%d,ap:%x," + "xn:%d,texcb:%02x,domain:%d\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + (((pte1 & (0x7 << 12)) >> 10) | + ((pte1 & 0x0c) >> 2)) & 0x1f, + (pte1 >> 5) & 0xf); + } + } +} + +/* level1 page table, each entry for 1MB memory. */ +volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024))); +void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, + rt_uint32_t vaddrEnd, + rt_uint32_t paddrStart, + rt_uint32_t attr) +{ + volatile rt_uint32_t *pTT; + volatile int i, nSec; + pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20); + nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); + for (i = 0; i <= nSec; i++) + { + *pTT = attr | (((paddrStart >> 20) + i) << 20); + pTT++; + } +} + +unsigned long rt_hw_set_domain_register(unsigned long domain_val) +{ + unsigned long old_domain; + + asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain)); + asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory"); + + return old_domain; +} + +void rt_hw_init_mmu_table() +{ + /* set page table */ + /* 4G 1:1 memory */ + rt_hw_mmu_setmtt(0x00000000, 0x3effffff, 0x00000000, NORMAL_MEM); + /* IO memory region */ + rt_hw_mmu_setmtt(0x3f000000, 0x40010000, 0x3f000000, DEVICE_MEM); +} + +void rt_hw_change_mmu_table(rt_uint32_t vaddrStart, + rt_uint32_t size, + rt_uint32_t paddrStart, rt_uint32_t attr) +{ + rt_hw_mmu_setmtt(vaddrStart, vaddrStart+size-1, paddrStart, attr); +#ifndef RT_USING_SMP + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); +#endif +} + + +void rt_hw_mmu_init(void) +{ + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); + rt_hw_cpu_dcache_disable(); + rt_hw_cpu_icache_disable(); + rt_cpu_mmu_disable(); + + /*rt_hw_cpu_dump_page_table(MMUTable);*/ + rt_hw_set_domain_register(0x55555555); + + rt_cpu_tlb_set(MMUTable); + + rt_cpu_mmu_enable(); + + rt_hw_cpu_icache_enable(); + rt_hw_cpu_dcache_enable(); +} + diff --git a/bsp/raspberry-pi/raspi3-32/cpu/mmu.h b/bsp/raspberry-pi/raspi3-32/cpu/mmu.h new file mode 100644 index 0000000000..6b0c25e990 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/mmu.h @@ -0,0 +1,51 @@ +#ifndef MMU_H__ +#define MMU_H__ +#include +#include +#include +#include "cp15.h" + +#define DESC_SEC (0x2) +#define CB (3 << 2) //cache_on, write_back +#define CNB (2 << 2) //cache_on, write_through +#define NCB (1 << 2) //cache_off,WR_BUF on +#define NCNB (0 << 2) //cache_off,WR_BUF off +#define AP_RW (3 << 10) //supervisor=RW, user=RW +#define AP_RO (2 << 10) //supervisor=RW, user=RO +#define XN (1 << 4) // eXecute Never +#define SHARED (1 << 16) /* shareable */ +#define SHAREDEVICE (1 << 2) /* shared device */ +#define STRONGORDER (0 << 2) /* strong ordered */ +#define MEMWBWA ((1 << 12) | (3 << 2)) /* write back, write allocate */ + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0 << 5) +#define DOMAIN1 (0x1 << 5) + +#define DOMAIN0_ATTR (DOMAIN_CHK << 0) +#define DOMAIN1_ATTR (DOMAIN_FAULT << 2) + +/* Read/Write, cache, write back */ +#define RW_CB (AP_RW | DOMAIN0 | CB | DESC_SEC) +/* Read/Write, cache, write through */ +#define RW_CNB (AP_RW | DOMAIN0 | CNB | DESC_SEC) +/* Read/Write without cache and write buffer */ +#define RW_NCNB (AP_RW | DOMAIN0 | NCNB | DESC_SEC) +/* Read/Write without cache and write buffer, no execute */ +#define RW_NCNBXN (AP_RW | DOMAIN0 | NCNB | DESC_SEC | XN) +/* Read/Write without cache and write buffer */ +#define RW_FAULT (AP_RW | DOMAIN1 | NCNB | DESC_SEC) + +/* device mapping type */ +#define DEVICE_MEM (SHARED | SHAREDEVICE | RW_NCNBXN) +/* normal memory mapping type */ +#define NORMAL_MEM (SHARED | AP_RW | DOMAIN0 | MEMWBWA | DESC_SEC) +#define STRONG_ORDER_MEM (SHARED | AP_RO | XN | DESC_SEC) +#define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000) + +void rt_hw_change_mmu_table(rt_uint32_t vaddrStart, + rt_uint32_t size, + rt_uint32_t paddrStart, rt_uint32_t attr); +#endif diff --git a/bsp/raspberry-pi/raspi3-32/cpu/stack.c b/bsp/raspberry-pi/raspi3-32/cpu/stack.c new file mode 100644 index 0000000000..c2c60fbf49 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/stack.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-23 Bernard the first version + * 2011-10-05 Bernard add thumb mode + */ +#include +#include +#include + +/** + * @addtogroup AM33xx + */ +/*@{*/ + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_uint32_t *stk; + + stack_addr += sizeof(rt_uint32_t); + stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); + stk = (rt_uint32_t *)stack_addr; + *(--stk) = (rt_uint32_t)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0xdeadbeef; /* r12 */ + *(--stk) = 0xdeadbeef; /* r11 */ + *(--stk) = 0xdeadbeef; /* r10 */ + *(--stk) = 0xdeadbeef; /* r9 */ + *(--stk) = 0xdeadbeef; /* r8 */ + *(--stk) = 0xdeadbeef; /* r7 */ + *(--stk) = 0xdeadbeef; /* r6 */ + *(--stk) = 0xdeadbeef; /* r5 */ + *(--stk) = 0xdeadbeef; /* r4 */ + *(--stk) = 0xdeadbeef; /* r3 */ + *(--stk) = 0xdeadbeef; /* r2 */ + *(--stk) = 0xdeadbeef; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + + /* cpsr */ + if ((rt_uint32_t)tentry & 0x01) + *(--stk) = SVCMODE | 0x20; /* thumb mode */ + else + *(--stk) = SVCMODE; /* arm mode */ + +#ifdef RT_USING_LWP + *(--stk) = 0; /* user lr */ + *(--stk) = 0; /* user sp*/ +#endif +#ifdef RT_USING_FPU + *(--stk) = 0; /* not use fpu*/ +#endif + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} + +/*@}*/ diff --git a/bsp/raspberry-pi/raspi3-32/cpu/start_gcc.S b/bsp/raspberry-pi/raspi3-32/cpu/start_gcc.S new file mode 100644 index 0000000000..ec74213f07 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/start_gcc.S @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + * 2019-07-28 zdzn add smp support + */ + +#include "../rtconfig.h" +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + +#ifdef RT_USING_FPU +.equ UND_Stack_Size, 0x00000400 +#else +.equ UND_Stack_Size, 0x00000000 +#endif +.equ SVC_Stack_Size, 0x00000400 +.equ ABT_Stack_Size, 0x00000000 +.equ RT_FIQ_STACK_PGSZ, 0x00000000 +.equ RT_IRQ_STACK_PGSZ, 0x00000800 +.equ USR_Stack_Size, 0x00000400 + +#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ + RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) + +.section .data.share.isr +/* stack */ + +#ifdef RT_USING_SMP +.globl stack_start0 +.globl stack_top0 +.globl stack_start1 +.globl stack_top1 +.globl stack_start2 +.globl stack_top2 +.globl stack_start3 +.globl stack_top3 +stack_start0: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top0: + +stack_start1: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top1: + +stack_start2: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top2: + +stack_start3: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top3: + +.globl boot_indicate +boot_indicate: +.rept 16 +.byte 0 +.endr + +#else +.globl stack_start +.globl stack_top +stack_start: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top: +#endif + + +.text +/* reset entry */ +.globl _reset +_reset: + + /* Disable IRQ & FIQ */ + cpsid if + + /* Check for HYP mode */ + mrs r0, cpsr_all + and r0, r0, #0x1F + mov r8, #0x1A + cmp r0, r8 + beq overHyped + b continue + +overHyped: /* Get out of HYP mode */ + ldr r1, =continue + msr ELR_hyp, r1 + mrs r1, cpsr_all + and r1, r1, #0x1f ;@ CPSR_MODE_MASK + orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR + msr SPSR_hyp, r1 + eret + +continue: + + /* disable mmu */ + bl rt_cpu_mmu_disable + /* set the cpu to SVC32 mode and disable interrupt */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0x13 + msr cpsr_c, r0 +#ifdef RT_USING_SMP + mrc p15, 0, r0, c0, c0, 5 + ubfx r0, r0, #0, #2 + cmp r0, #0 + beq 1f + /* write boot indicate */ + ldr r5, = boot_indicate + str r0, [r5, r0, lsl #2] + bl secondary_cpu_start + b . +1: +#endif + /* setup stack */ +#ifdef RT_USING_SMP + ldr r0, =stack_top0 +#else + ldr r0, =stack_top +#endif + bl stack_setup + + /* clear .bss */ + mov r0,#0 /* get a zero */ + ldr r1,=__bss_start /* bss start */ + ldr r2,=__bss_end /* bss end */ + +bss_loop: + cmp r1,r2 /* check if data to clear */ + strlo r0,[r1],#4 /* clear 4 bytes */ + blo bss_loop /* loop until done */ + bl rt_hw_init_mmu_table + bl init_mbox_mmu_map + bl rt_hw_mmu_init + + /* start RT-Thread Kernel */ + ldr pc, _rtthread_startup +_rtthread_startup: + .word rtthread_startup + +stack_setup: + + @ Set the startup stack for svc + mov sp, r0 + + @ Enter Undefined Instruction Mode and set its Stack Pointer + msr cpsr_c, #Mode_UND|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #UND_Stack_Size + + @ Enter Abort Mode and set its Stack Pointer + msr cpsr_c, #Mode_ABT|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #ABT_Stack_Size + + @ Enter FIQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #RT_FIQ_STACK_PGSZ + + @ Enter IRQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #RT_IRQ_STACK_PGSZ + + /* come back to SVC mode */ + msr cpsr_c, #Mode_SVC|I_Bit|F_Bit + bx lr + +.text + +/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ +.section .text.isr, "ax" + .align 5 +.globl vector_fiq +vector_fiq: + stmfd sp!,{r0-r7,lr} + bl rt_hw_trap_fiq + ldmfd sp!,{r0-r7,lr} + subs pc, lr, #4 + +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread + +.globl rt_current_thread +.globl vmm_thread +.globl vmm_virq_check + + .align 5 +.globl vector_irq +vector_irq: +#ifdef RT_USING_SMP + clrex + + stmfd sp!, {r0, r1} + cps #Mode_SVC + mov r0, sp /* svc_sp */ + mov r1, lr /* svc_lr */ + + cps #Mode_IRQ + sub lr, lr, #4 + stmfd r0!, {r1, lr} /* svc_lr, svc_pc */ + stmfd r0!, {r2 - r12} + ldmfd sp!, {r1, r2} /* original r0, r1 */ + stmfd r0!, {r1 - r2} + mrs r1, spsr /* original mode */ + stmfd r0!, {r1} + +#ifdef RT_USING_LWP + stmfd r0, {r13, r14}^ /* usr_sp, usr_lr */ + sub r0, #8 +#endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb r0!, {d0-d15} + vstmdb r0!, {d16-d31} + vmrs r5, fpscr + stmfd r0!, {r5} +1: + stmfd r0!, {r6} +#endif + mov r8, r0 + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + cps #Mode_SVC + mov sp, r8 + mov r0, r8 + + bl rt_scheduler_do_irq_switch + + b rt_hw_context_switch_exit + +#else + stmfd sp!, {r0-r12,lr} + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + @ if rt_thread_switch_interrupt_flag set, jump to + @ rt_hw_context_switch_interrupt_do and don't return + ldr r0, =rt_thread_switch_interrupt_flag + ldr r1, [r0] + cmp r1, #1 + beq rt_hw_context_switch_interrupt_do + + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + +rt_hw_context_switch_interrupt_do: + mov r1, #0 @ clear flag + str r1, [r0] + + mov r1, sp @ r1 point to {r0-r3} in stack + add sp, sp, #4*4 + ldmfd sp!, {r4-r12,lr}@ reload saved registers + mrs r0, spsr @ get cpsr of interrupt thread + sub r2, lr, #4 @ save old task's pc to r2 + + @ Switch to SVC mode with no interrupt. If the usr mode guest is + @ interrupted, this will just switch to the stack of kernel space. + @ save the registers in kernel space won't trigger data abort. + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + + stmfd sp!, {r2} @ push old task's pc + stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 + ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread + stmfd sp!, {r1-r4} @ push old task's r0-r3 + stmfd sp!, {r0} @ push old task's cpsr + +#ifdef RT_USING_LWP + stmfd sp, {r13, r14}^ @push usr_sp, usr_lr + sub sp, #8 +#endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb sp!, {d0-d15} + vstmdb sp!, {d16-d31} + vmrs r5, fpscr + stmfd sp!, {r5} +1: + stmfd sp!, {r6} +#endif + + ldr r4, =rt_interrupt_from_thread + ldr r5, [r4] + str sp, [r5] @ store sp in preempted tasks's TCB + + ldr r6, =rt_interrupt_to_thread + ldr r6, [r6] + ldr sp, [r6] @ get new task's stack pointer + +#ifdef RT_USING_FPU +/* fpu context */ + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq 1f + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d16-d31} + vldmia sp!, {d0-d15} +1: +#endif + +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr + add sp, #8 +#endif + + ldmfd sp!, {r4} @ pop new task's cpsr to spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr + +#endif + +.macro push_svc_reg + sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + mov r0, sp + mrs r6, spsr @/* Save CPSR */ + str lr, [r0, #15*4] @/* Push PC */ + str r6, [r0, #16*4] @/* Push CPSR */ + cps #Mode_SVC + str sp, [r0, #13*4] @/* Save calling SP */ + str lr, [r0, #14*4] @/* Save calling PC */ +.endm + + .align 5 + .globl vector_swi +vector_swi: + push_svc_reg + bl rt_hw_trap_swi + b . + + .align 5 + .globl vector_undef +vector_undef: + push_svc_reg + cps #Mode_UND + bl rt_hw_trap_undef +#ifdef RT_USING_FPU + ldr lr, [sp, #15*4] + ldmia sp, {r0 - r12} + add sp, sp, #17 * 4 + movs pc, lr +#endif + b . + + .align 5 + .globl vector_pabt +vector_pabt: + push_svc_reg + bl rt_hw_trap_pabt + b . + + .align 5 + .globl vector_dabt +vector_dabt: + push_svc_reg + bl rt_hw_trap_dabt + b . + + .align 5 + .globl vector_resv +vector_resv: + push_svc_reg + bl rt_hw_trap_resv + b . + +#ifdef RT_USING_SMP + +.global secondary_cpu_start +secondary_cpu_start: + /* set vector base */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1<<13) + mcr p15, 0, r0, c1, c0, 0 + + /* setup stack */ + mrc p15, 0, r0, c0, c0, 5 + ubfx r0, r0, #0, #2 + ldr r1, =stack_top0 + ldr r2, =ISR_Stack_Size + mul r3, r2, r0 + add r0, r1, r3 + bl stack_setup + /* initialize the mmu table and enable mmu */ + bl rt_hw_mmu_init + b secondary_cpu_c_start + +#endif + +;@ void arm_smp_enable(void); +.globl arm_smp_enable +arm_smp_enable: + mrc p15, 0, r0, c1, c0, 1 ;@ set SMP bit in ACTLR + orr r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + bx lr +/* + mrrc p15, 1, r0, r1, c15 + orr r0, r0, #0x40 + mcrr p15, 1, r0, r1, c15 + dsb + isb + bx lr +*/ +.text +;@ void arm_smp_disable(void); +.globl arm_smp_disable + +arm_smp_disable: + mrc p15, 0, r0, c1, c0, 1 ;@ clear SMP bit in ACTLR + bic r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + bx lr +/* + mrrc p15, 1, r0, r1, c15 + bic r0, r0, #0x40 + mcrr p15, 1, r0, r1, c15 + bx lr +*/ + diff --git a/bsp/raspberry-pi/raspi3-32/cpu/trap.c b/bsp/raspberry-pi/raspi3-32/cpu/trap.c new file mode 100644 index 0000000000..f83f183695 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/trap.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2019-07-28 zdzn add smp support + * 2019-08-09 zhangjun fixup the problem of smp startup and scheduling issues, + * write addr to mailbox3 to startup smp, and we use mailbox0 for ipi + */ + +#include +#include +#include + +#include "armv7.h" + +extern struct rt_thread *rt_current_thread; +#ifdef RT_USING_FINSH +extern long list_thread(void); +#endif + + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ +void rt_hw_show_register(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); + rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); + rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); + rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); + rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); + rt_kprintf("cpsr:0x%08x\n", regs->cpsr); +} + + +/** + * When comes across an instruction which it cannot handle, + * it takes the undefined instruction trap. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("undefined instruction:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * The software interrupt instruction (SWI) is used for entering + * Supervisor mode, usually to request a particular supervisor + * function. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("software interrupt:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during an instruction prefetch. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("prefetch abort:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during a data access. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("data abort:"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * Normally, system will never reach here + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("reserved trap:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +void rt_hw_trap_irq(void) +{ + void *param; + uint32_t irq; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + uint32_t value = 0; + value = IRQ_PEND_BASIC & 0x3ff; +#ifdef RT_USING_SMP + uint32_t mailbox_data; + uint32_t cpu_id = rt_hw_cpu_id(); + uint32_t int_source = CORE_IRQSOURCE(cpu_id); + mailbox_data = IPI_MAILBOX_CLEAR(cpu_id); + if (int_source & 0x0f) + { + if (int_source & 0x08) + { + isr_func = isr_table[IRQ_ARM_TIMER].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[IRQ_ARM_TIMER].counter++; +#endif + if (isr_func) + { + param = isr_table[IRQ_ARM_TIMER].param; + isr_func(IRQ_ARM_TIMER, param); + } + } + } + if (int_source & 0xf0) + { + /*it's a ipi interrupt*/ + if (mailbox_data & 0x1) + { + /* clear mailbox */ + IPI_MAILBOX_CLEAR(cpu_id) = mailbox_data; + isr_func = isr_table[IRQ_ARM_MAILBOX].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[IRQ_ARM_MAILBOX].counter++; +#endif + if (isr_func) + { + param = isr_table[IRQ_ARM_MAILBOX].param; + isr_func(IRQ_ARM_MAILBOX, param); + } + } + else + CORE_MAILBOX3_CLEAR(cpu_id) = mailbox_data; + } +#endif + /* local interrupt*/ + if (value) + { + if (value & (1 << 8)) + { + value = IRQ_PEND1; + irq = __rt_ffs(value) - 1; + } + else if (value & (1 << 9)) + { + value = IRQ_PEND2; + irq = __rt_ffs(value) + 31; + } + else + { + value &= 0x0f; + irq = __rt_ffs(value) + 63; + } + + /* get interrupt service routine */ + isr_func = isr_table[irq].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[irq].counter++; +#endif + if (isr_func) + { + /* Interrupt for myself. */ + param = isr_table[irq].param; + /* turn to interrupt service routine */ + isr_func(irq, param); + } + } +} + +void rt_hw_trap_fiq(void) +{ + +} diff --git a/bsp/raspberry-pi/raspi3-32/cpu/vector_gcc.S b/bsp/raspberry-pi/raspi3-32/cpu/vector_gcc.S new file mode 100644 index 0000000000..eebfe9c13b --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/cpu/vector_gcc.S @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.section .vectors, "ax" +.code 32 + +.globl system_vectors +system_vectors: + ldr pc, _vector_reset + ldr pc, _vector_undef + ldr pc, _vector_swi + ldr pc, _vector_pabt + ldr pc, _vector_dabt + ldr pc, _vector_resv + ldr pc, _vector_irq + ldr pc, _vector_fiq + +.globl _reset +.globl vector_undef +.globl vector_swi +.globl vector_pabt +.globl vector_dabt +.globl vector_resv +.globl vector_irq +.globl vector_fiq + +_vector_reset: + .word _reset +_vector_undef: + .word vector_undef +_vector_swi: + .word vector_swi +_vector_pabt: + .word vector_pabt +_vector_dabt: + .word vector_dabt +_vector_resv: + .word vector_resv +_vector_irq: + .word vector_irq +_vector_fiq: + .word vector_fiq + +.balignl 16,0xdeadbeef diff --git a/bsp/raspberry-pi/raspi3-32/driver/Kconfig b/bsp/raspberry-pi/raspi3-32/driver/Kconfig new file mode 100644 index 0000000000..aaa7110f1d --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/Kconfig @@ -0,0 +1,103 @@ +menu "Hardware Drivers Config" + menu "BCM Peripheral Drivers" + menuconfig BSP_USING_UART + bool "Using UART" + select RT_USING_SERIAL + default y + + if BSP_USING_UART + config RT_USING_UART0 + bool "Enabel UART 0" + default y + + config RT_USING_UART1 + bool "Enabel UART 1" + default n + endif + + config BSP_USING_PIN + bool "Using PIN" + select RT_USING_PIN + default y + + menuconfig BSP_USING_SYSTIMER + bool "Enable SYSTIMER" + select RT_USING_HWTIMER + default n + + if BSP_USING_SYSTIMER + config RT_USING_SYSTIMER1 + bool "Enable sys timer1" + default n + config RT_USING_SYSTIMER3 + bool "Enable sys timer3" + default n + endif + + menuconfig BSP_USING_I2C + bool "Enable I2C" + select RT_USING_I2C + default n + + if BSP_USING_I2C + config BSP_USING_I2C0 + bool "Enable I2C0" + default n + config BSP_USING_I2C1 + bool "Enable I2C1" + default n + endif + + menuconfig BSP_USING_SPI + bool "Enable SPI" + select RT_USING_SPI + default n + + if BSP_USING_SPI + config BSP_USING_SPI0_BUS + bool "Enable SPI0 BUS" + default n + config BSP_USING_SPI0_DEVICE0 + bool "Enable SPI0 DEVICE0" + select BSP_USING_SPI0_BUS + default n + config BSP_USING_SPI0_DEVICE1 + bool "Enable SPI0 DEVICE1" + select BSP_USING_SPI0_BUS + default n + endif + + config BSP_USING_WDT + bool "Enable WDT" + select RT_USING_WDT + default n + + menuconfig BSP_USING_RTC + bool "Enable RTC" + select RT_USING_RTC + default n + + if BSP_USING_RTC + config BSP_USING_ALARM + bool "Enable Alarm" + select RT_USING_ALARM + default n + endif + + menuconfig BSP_USING_SDIO + bool "Enable SDIO" + select RT_USING_SDIO + default n + + if BSP_USING_SDIO + config BSP_USING_SDIO0 + bool "Enable SDIO0" + select RT_USING_SDIO + default n + endif + menuconfig BSP_USING_HDMI + bool "Enable HDMI" + select BSP_USING_SPI + default n + endmenu +endmenu diff --git a/bsp/raspberry-pi/raspi3-32/driver/SConscript b/bsp/raspberry-pi/raspi3-32/driver/SConscript new file mode 100644 index 0000000000..c51b2c42bf --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/SConscript @@ -0,0 +1,31 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Split(''' +board.c +drv_uart.c +mbox.c +''') +CPPPATH = [cwd] + +if GetDepend('BSP_USING_SYSTIMER'): + src += ['drv_timer.c'] +if GetDepend('BSP_USING_PIN'): + src += ['drv_gpio.c'] +if GetDepend('BSP_USING_I2C'): + src += ['drv_i2c.c'] +if GetDepend('BSP_USING_WDT'): + src += ['drv_wdt.c'] +if GetDepend('BSP_USING_SPI'): + src += ['drv_spi.c'] +if GetDepend('BSP_USING_SDIO'): + src += ['drv_sdio.c'] +if GetDepend('BSP_USING_RTC'): + src += ['drv_rtc.c'] +if GetDepend('BSP_USING_HDMI'): + src += ['drv_fb.c'] +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/raspberry-pi/raspi3-32/driver/board.c b/bsp/raspberry-pi/raspi3-32/driver/board.c new file mode 100644 index 0000000000..a1b3d603c8 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/board.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include +#include + +#include "board.h" +#include "drv_uart.h" +#include "drv_timer.h" + +#include "cp15.h" + +#ifdef RT_USING_SMP +unsigned int cntfrq; +#endif + +void rt_hw_timer_isr(int vector, void *parameter) +{ + rt_tick_increase(); +#ifndef RT_USING_SMP + ARM_TIMER_IRQCLR = 0; +#else + mask_cntv(); + __DSB(); + write_cntv_tval(cntfrq); + __DSB(); + unmask_cntv(); + __DSB(); +#endif +} + +int rt_hw_timer_init() +{ +#ifndef RT_USING_SMP + /* timer_clock = apb_clock/(pre_divider + 1) */ + ARM_TIMER_PREDIV = (250 - 1); + + ARM_TIMER_RELOAD = 0; + ARM_TIMER_LOAD = 0; + ARM_TIMER_IRQCLR = 0; + ARM_TIMER_CTRL = 0; + + ARM_TIMER_RELOAD = 10000; + ARM_TIMER_LOAD = 10000; + + /* 23-bit counter, enable interrupt, enable timer */ + ARM_TIMER_CTRL = (1 << 1) | (1 << 5) | (1 << 7); +#else + __DSB(); + cntfrq = 35000; + write_cntv_tval(cntfrq); + enable_cntv(); + __DSB(); + enable_cpu_timer_intr(rt_hw_cpu_id()); +#endif + + rt_hw_interrupt_install(IRQ_ARM_TIMER, rt_hw_timer_isr, RT_NULL, "tick"); + rt_hw_interrupt_umask(IRQ_ARM_TIMER); + return 0; +} +#ifdef RT_USING_SMP +extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler); + +void ipi_handler() +{ + rt_scheduler_ipi_handler(0,RT_NULL); +} +#endif +void vector_copy(void) +{ + rt_memcpy((void*)0x0, (void*)0x8000, 64); +} + +void idle_wfi(void) +{ + asm volatile ("wfi"); +} + +void rt_hw_board_init(void) +{ + /* initialize hardware interrupt */ + rt_hw_interrupt_init(); + vector_copy(); + rt_hw_vector_init(); + /* initialize uart */ + rt_hw_uart_init(); + /* initialize timer for os tick */ + rt_hw_timer_init(); + rt_thread_idle_sethook(idle_wfi); +#ifdef RT_USING_CONSOLE + /* set console device */ + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif /* RT_USING_CONSOLE */ +#ifdef RT_USING_HEAP + /* initialize memory system */ + rt_kprintf("heap: 0x%08x - 0x%08x\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); + rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); +#endif + +#ifdef RT_USING_SMP + /* install IPI handle */ + rt_hw_ipi_handler_install(IRQ_ARM_MAILBOX, ipi_handler); + rt_hw_interrupt_umask(IRQ_ARM_MAILBOX); + enable_cpu_ipi_intr(0); +#endif +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +} + + +void _reset(void); +void secondary_cpu_start(void); + +#ifdef RT_USING_SMP +void rt_hw_secondary_cpu_up(void) +{ + int i; + int retry,val; + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); + /*TODO maybe, there is some bug */ + for (i = RT_CPUS_NR - 1; i>0; i-- ) + { + rt_kprintf("boot cpu:%d\n", i); + setup_bootstrap_addr(i, (int)_reset); + __SEV(); + __DSB(); + __ISB(); + retry = 10; + rt_thread_delay(RT_TICK_PER_SECOND/1000); + do + { + val = CORE_MAILBOX3_CLEAR(i); + if (val == 0) + { + rt_kprintf("start OK: CPU %d \n",i); + break; + } + rt_thread_delay(RT_TICK_PER_SECOND); + + retry --; + if (retry <= 0) + { + rt_kprintf("can't start for CPU %d \n",i); + break; + } + } while (1); + } + __DSB(); + __SEV(); +} + +void secondary_cpu_c_start(void) +{ + uint32_t id; + id = rt_hw_cpu_id(); + rt_kprintf("cpu = 0x%08x\n",id); + rt_hw_timer_init(); + rt_kprintf("cpu %d startup.\n",id); + rt_hw_vector_init(); + enable_cpu_ipi_intr(id); + rt_hw_spin_lock(&_cpus_lock); + rt_system_scheduler_start(); +} + +void rt_hw_secondary_cpu_idle_exec(void) +{ + __WFE(); +} + +#endif + + diff --git a/bsp/raspberry-pi/raspi3-32/driver/board.h b/bsp/raspberry-pi/raspi3-32/driver/board.h new file mode 100644 index 0000000000..8736027c06 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/board.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 Bernard the first version + */ + +#ifndef BOARD_H__ +#define BOARD_H__ + +#include + +#include +#include "raspi.h" + +#define __REG32 HWREG32 +extern unsigned char __bss_start; +extern unsigned char __bss_end; + +#define RT_HW_HEAP_BEGIN (void*)&__bss_end +#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 4 * 1024 * 1024) + +void rt_hw_board_init(void); + +#endif + diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_fb.c b/bsp/raspberry-pi/raspi3-32/driver/drv_fb.c new file mode 100644 index 0000000000..a24ca63377 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_fb.c @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-29 zdzn first version + */ + +#include +#include +#include "mbox.h" +#include "drv_fb.h" +#include "mmu.h" + +#define CHAR_W 8 +#define CHAR_H 12 + +#define COLOR_DELTA 0.05 +static struct rt_hdmi_fb_device _hdmi; + +// https://github.com/xinu-os/xinu/blob/1789b7a50b5b73c2ea76ebd764c54a034097d04d/device/framebuffer_rpi/font.c +unsigned char FONT[] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'!'*/ +0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'"'*/ +0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14, 0x00, 0x00, 0x00, /*'#'*/ +0x00, 0x00, 0x08, 0x3c, 0x0a, 0x1c, 0x28, 0x1e, 0x08, 0x00, 0x00, 0x00, /*'$'*/ +0x00, 0x00, 0x06, 0x26, 0x10, 0x08, 0x04, 0x32, 0x30, 0x00, 0x00, 0x00, /*'%'*/ +0x00, 0x00, 0x1c, 0x02, 0x02, 0x04, 0x2a, 0x12, 0x2c, 0x00, 0x00, 0x00, /*'&'*/ +0x00, 0x18, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'''*/ +0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, /*'('*/ +0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x00, /*')'*/ +0x00, 0x00, 0x00, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x00, 0x00, /*'*'*/ +0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /*'+'*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*','*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'-'*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*'.'*/ +0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, /*'/'*/ +0x00, 0x1c, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'0'*/ +0x00, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'1'*/ +0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'2'*/ +0x00, 0x1c, 0x22, 0x20, 0x18, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'3'*/ +0x00, 0x10, 0x18, 0x18, 0x14, 0x14, 0x3e, 0x10, 0x38, 0x00, 0x00, 0x00, /*'4'*/ +0x00, 0x3e, 0x02, 0x02, 0x1e, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'5'*/ +0x00, 0x18, 0x04, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'6'*/ +0x00, 0x3e, 0x22, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00, /*'7'*/ +0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'8'*/ +0x00, 0x1c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00, /*'9'*/ +0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*':'*/ +0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*';'*/ +0x00, 0x00, 0x00, 0x30, 0x0c, 0x03, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, /*'<'*/ +0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, /*'='*/ +0x00, 0x00, 0x00, 0x03, 0x0c, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, /*'>'*/ +0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'?'*/ +0x00, 0x00, 0x1c, 0x22, 0x3a, 0x3a, 0x1a, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'@'*/ +0x00, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00, 0x00, 0x00, /*'A'*/ +0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'B'*/ +0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'C'*/ +0x00, 0x00, 0x0e, 0x12, 0x22, 0x22, 0x22, 0x12, 0x0e, 0x00, 0x00, 0x00, /*'D'*/ +0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'E'*/ +0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'F'*/ +0x00, 0x00, 0x1c, 0x22, 0x02, 0x32, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'G'*/ +0x00, 0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'H'*/ +0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, /*'I'*/ +0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'J'*/ +0x00, 0x00, 0x22, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'K'*/ +0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'L'*/ +0x00, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'M'*/ +0x00, 0x00, 0x22, 0x26, 0x26, 0x2a, 0x32, 0x32, 0x22, 0x00, 0x00, 0x00, /*'N'*/ +0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'O'*/ +0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'P'*/ +0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x30, 0x00, 0x00, /*'Q'*/ +0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'R'*/ +0x00, 0x00, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'S'*/ +0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'T'*/ +0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'U'*/ +0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'V'*/ +0x00, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00, 0x00, 0x00, /*'W'*/ +0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00, 0x00, /*'X'*/ +0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'Y'*/ +0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'Z'*/ +0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, /*'['*/ +0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, /*'\'*/ +0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, /*']'*/ +0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'^'*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, /*'_'*/ +0x00, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'`'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'a'*/ +0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'b'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x02, 0x02, 0x3c, 0x00, 0x00, 0x00, /*'c'*/ +0x00, 0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'d'*/ +0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'e'*/ +0x00, 0x38, 0x04, 0x04, 0x1e, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, /*'f'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'g'*/ +0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'h'*/ +0x00, 0x08, 0x08, 0x00, 0x0c, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'i'*/ +0x00, 0x10, 0x10, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, /*'j'*/ +0x00, 0x02, 0x02, 0x02, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x00, 0x00, 0x00, /*'k'*/ +0x00, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'l'*/ +0x00, 0x00, 0x00, 0x00, 0x16, 0x2a, 0x2a, 0x2a, 0x22, 0x00, 0x00, 0x00, /*'m'*/ +0x00, 0x00, 0x00, 0x00, 0x1a, 0x26, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'n'*/ +0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'o'*/ +0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, /*'p'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, /*'q'*/ +0x00, 0x00, 0x00, 0x00, 0x1a, 0x06, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'r'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x1c, 0x20, 0x1e, 0x00, 0x00, 0x00, /*'s'*/ +0x00, 0x08, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, /*'t'*/ +0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'u'*/ +0x00, 0x00, 0x00, 0x00, 0x36, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'v'*/ +0x00, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x2a, 0x14, 0x00, 0x00, 0x00, /*'w'*/ +0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, /*'x'*/ +0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'y'*/ +0x00, 0x00, 0x00, 0x00, 0x3e, 0x10, 0x08, 0x04, 0x3e, 0x00, 0x00, 0x00, /*'z'*/ +0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00, /*'{'*/ +0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, /*'|'*/ +0x02, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x00, /*'}'*/ +0x00, 0x04, 0x2a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'~'*/ +0x00, 0x00, 0x00, 0x08, 0x08, 0x14, 0x14, 0x22, 0x3e, 0x00, 0x00, 0x00, /*DEL*/ +}; + +void newline(fb_t* fb) +{ + uint8_t* to; + uint8_t* from; + int i; + fb->y++; + fb->x = 0; + + if (fb->y == (fb->height / CHAR_H)) + { + + to = (uint8_t*) fb->addr; + from = to + (CHAR_H * fb->pitch); + + for (i = 0; i < ((fb->height - CHAR_H) * fb->pitch); i++) + { + *to++ = *from++; + } + + uint32_t *addr = (uint32_t*) (fb->addr) + (fb->height - CHAR_H) * fb->width; + + for (i = 0; i < (CHAR_H * fb->width); i++) + { + *addr++ = fb->back; + } + + fb->y--; + } +} + +void clear_line(fb_t *fb, const int line) +{ + int i; + uint32_t* addr; + if (line > fb->height / CHAR_H) + { + fb->y = 0; + } + else + { + fb->y = line; + } + + fb->x = 0; + + addr = (uint32_t*) (fb->addr + (line * CHAR_H * fb->depth * fb->width)); + for (i = 0; i < (CHAR_H * fb->width); i++) + { + *addr++ = fb->back; + } + +} + +void clear(fb_t *fb, const uint32_t color) +{ + + uint32_t *addr = (uint32_t*) fb->addr; + uint32_t i; + for (i = 0; i < (fb->height * fb->width); i++) + { + *addr++ = color; + } + fb->x = 0; + fb->y = 0; + +} + +void fb_draw_char(fb_t *fb, char s) +{ + unsigned char* addr = (unsigned char*) fb->addr; + unsigned char *glyph = (unsigned char*) FONT + (s) * 12; + // calculate the offset on screen + int offs = (fb->y * CHAR_H * fb->pitch) + (fb->x * (CHAR_W + 1) * 4); + // variables + int i, j, line, mask, bytesperline = (CHAR_W + 7) / 8; + // display a character + for (j = 0; j < CHAR_H; j++) + { + // display one row + line = offs; + mask = 1; + for (i = 0; i < CHAR_W; i++) + { + // if bit set, we use white color, otherwise black + *((unsigned int*) (addr + line)) = ((int) *glyph) & mask ? fb->fore : fb->back; + mask <<= 1; + line += 4; + } + // adjust to next line + glyph += bytesperline; + offs += fb->pitch; + } +} + +void fb_print(fb_t *fb, char *s) +{ + + // draw next character if it's not zero + while (*s) + { + // handle carrige return + if (*s == '\r') + { + fb->x = 0; + } + else if (*s == '\n') + { + newline(fb); + } + else if (*s == '\t') + { + fb->x = ((fb->x + 4) >> 2) << 2; + } + else if (*s == '\b') + { + if (fb->x) + { + fb->x--; + fb_draw_char(fb, ' '); + } + } + else + { + fb_draw_char(fb, *s); + fb->x++; + } + // next character + if (fb->x == fb->width / CHAR_W) + { + newline(fb); + } + s++; + } +} + +rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +rt_err_t hdmi_fb_close(rt_device_t dev) +{ + return RT_EOK; +} + +rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size) +{ + return 0; +} + +rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + fb_print(&_hdmi.fb, (char *) buffer); +#ifdef BSP_USING_HDMI_DISPLAY + rt_device_t uart = rt_device_find("uart1"); + int old_flag = uart->open_flag; + uart->open_flag |= RT_DEVICE_FLAG_STREAM; + rt_device_write(uart, 0, buffer, size); + uart->open_flag = old_flag; +#endif + return size; +} + +rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args) +{ + return RT_EOK; +} + +const static struct rt_device_ops hdmi_fb_ops = +{ + RT_NULL, + hdmi_fb_open, + hdmi_fb_close, + hdmi_fb_read, + hdmi_fb_write, + hdmi_fb_control +}; + +static struct rt_device_graphic_info _hdmi_info; + +static void hdmi_draw_rect(const char* pixel, int x1, int y1, int x2, int y2) +{ + int i, j; + int line; + for (j = y1; j <= y2; j++) + { + line = (j * _hdmi.fb.pitch) + (x1 * 4); + for (i = x1; i <= x2; i++) + { + // if bit set, we use white color, otherwise black + *((unsigned int*) (_hdmi_info.framebuffer + line)) = *(unsigned int*) pixel; + line += 4; + } + } + +} + +static void hdmi_set_pixel(const char* pixel, int x, int y) +{ + *(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) = *(uint32_t *) pixel; +} + +static void hdmi_get_pixel(char* pixel, int x, int y) +{ + uint32_t ret = 0; + ret = (*(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) & 0x00FFFFFF); + *pixel = ret; +} + +static void hdmi_draw_hline(const char* pixel, int x1, int x2, int y) +{ + hdmi_draw_rect(pixel, x1, y, x2, y); +} + +static void hdmi_draw_vline(const char* pixel, int x, int y1, int y2) +{ + hdmi_draw_rect(pixel, x, y1, x, y2); +} + +static void hdmi_blit_line(const char* pixels, int x, int y, rt_size_t size) +{ + int i = 0; + uint32_t *pixel_base = (uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)); + uint32_t *colors = (uint32_t *) pixels; + for (i = 0; i < size; i++) + { + pixel_base[i] = colors[i]; + } +} + +static struct rt_device_graphic_ops hdmi_ops = +{ + hdmi_set_pixel, + hdmi_get_pixel, + hdmi_draw_hline, + hdmi_draw_vline, + hdmi_blit_line +}; + +rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name) +{ + struct rt_device *device; + RT_ASSERT(hdmi_fb != RT_NULL); + + device = &hdmi_fb->parent; + device->user_data = &hdmi_ops; + + /* set device type */ + device->type = RT_Device_Class_Graphic; + /* initialize device interface */ +#ifdef RT_USING_DEVICE_OPS + device->ops = &hdmi_fb_ops; +#else + device->init = RT_NULL; + device->open = hdmi_fb_open; + device->close = hdmi_fb_close; + device->read = hdmi_fb_read; + device->write = hdmi_fb_write; + device->control = hdmi_fb_control; +#endif + + /* register to device manager */ + rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); + + return RT_EOK; +} + +/** + * Show a picture + */ +void print_fb_info() +{ + rt_kprintf("FrameBuffer Info: \n \t width %x\t height %x\t depth %x\t addr %x\t size %x\t \n", fb_info.width, + fb_info.height, fb_info.depth, fb_info.addr, fb_info.size); + rt_kprintf("call mbox:%x,%x,%x,%x,%x\n", mbox[0], mbox[1], mbox[2], mbox[3], mbox[4]); +} + +void hdmi_fb_init() +{ + unsigned int *mbox = (unsigned int*) MBOX_ADDR; + mbox[0] = 35 * 4; + mbox[1] = MBOX_REQUEST; + + mbox[2] = 0x48003; //set phy wh + mbox[3] = 8; + mbox[4] = 8; + mbox[5] = 640; //FrameBufferInfo.width + mbox[6] = 480; //FrameBufferInfo.height + + mbox[7] = 0x48004; //set virt wh + mbox[8] = 8; + mbox[9] = 8; + mbox[10] = 640; //FrameBufferInfo.virtual_width + mbox[11] = 480; //FrameBufferInfo.virtual_height + + mbox[12] = 0x48009; //set virt offset + mbox[13] = 8; + mbox[14] = 8; + mbox[15] = 0; //FrameBufferInfo.x_offset + mbox[16] = 0; //FrameBufferInfo.y.offset + + mbox[17] = 0x48005; //set depth + mbox[18] = 4; + mbox[19] = 4; + mbox[20] = 32; //FrameBufferInfo.depth + + mbox[21] = 0x48006; //set pixel order + mbox[22] = 4; + mbox[23] = 4; + mbox[24] = 1; //RGB, not BGR preferably + + mbox[25] = 0x40001; //get framebuffer, gets alignment on request + mbox[26] = 8; + mbox[27] = 8; + mbox[28] = 4096; //FrameBufferInfo.pointer + mbox[29] = 0; //FrameBufferInfo.size + + mbox[30] = 0x40008; //get pitch + mbox[31] = 4; + mbox[32] = 4; + mbox[33] = 0; //FrameBufferInfo.pitch + + mbox[34] = MBOX_TAG_LAST; + if (mbox_call(MBOX_CH_PROP, MMU_DISABLE) && mbox[20] == 32 && mbox[28] != 0) + { + mbox[28] &= 0x3FFFFFFF; + _hdmi.fb.width = mbox[5]; + _hdmi.fb.height = mbox[6]; + _hdmi.fb.pitch = mbox[33]; + //_hdmi.fb.addr = (void*)((unsigned long)mbox[28]); + _hdmi.fb.addr = (rt_uint32_t) mbox[28]; + _hdmi.fb.size = mbox[29]; + _hdmi.fb.depth = 32; + _hdmi.fb.x = 0; + _hdmi.fb.y = 0; + _hdmi.fb.fore = CONSOLE_WHITE; + _hdmi.fb.back = CONSOLE_BLACK; + rt_hdmi_fb_device_init(&_hdmi, "hdmi"); + rt_hw_change_mmu_table(_hdmi.fb.addr, _hdmi.fb.size, _hdmi.fb.addr, DEVICE_MEM); + fb_info.width = _hdmi.fb.width; + fb_info.height = _hdmi.fb.height; + fb_info.addr = _hdmi.fb.addr; + fb_info.size = _hdmi.fb.size; + fb_info.pitch = _hdmi.fb.pitch; + fb_info.depth = _hdmi.fb.depth; + _hdmi_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888; + _hdmi_info.bits_per_pixel = _hdmi.fb.depth; + _hdmi_info.width = _hdmi.fb.width; + _hdmi_info.height = _hdmi.fb.height; + _hdmi_info.framebuffer = (rt_uint8_t *) _hdmi.fb.addr; + } +} + +INIT_DEVICE_EXPORT(hdmi_fb_init); diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_fb.h b/bsp/raspberry-pi/raspi3-32/driver/drv_fb.h new file mode 100644 index 0000000000..b11589e769 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_fb.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-29 zdzn first version + */ +#ifndef __DRV_FB_H__ +#define __DRV_FB_H__ + +#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b))) + +#define COLOR_BLACK RGB(0, 0, 0) + +#define COLOR_GREEN RGB(0, 255, 0) + +#define COLOR_CYAN RGB(0, 255, 255) + +#define COLOR_RED RGB(255, 0, 0) + +#define COLOR_YELLOW RGB(255, 255, 0) + +#define COLOR_WHITE RGB(255, 255, 255) + +#define CONSOLE_WHITE COLOR_WHITE +#define CONSOLE_BLACK COLOR_BLACK +#define CONSOLE_GREEN COLOR_GREEN +#define CONSOLE_CYAN COLOR_CYAN +#define CONSOLE_RED COLOR_RED +#define CONSOLE_YELLOW COLOR_YELLOW + +typedef struct +{ + rt_uint32_t width; + rt_uint32_t height; + rt_uint32_t vwidth; + rt_uint32_t vheight; + rt_uint32_t pitch; + rt_uint32_t depth; + rt_uint32_t fore; + rt_uint32_t back; + rt_uint32_t x; + rt_uint32_t y; + rt_uint32_t addr; + rt_uint32_t size; +} fb_t; + +struct rt_hdmi_fb_device +{ + struct rt_device parent; + fb_t fb; +}; + +fb_t fb_info; +void print_fb_info(); +void hdmi_fb_init(); + +#endif/* __DRV_FB_H__ */ diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_gpio.c b/bsp/raspberry-pi/raspi3-32/driver/drv_gpio.c new file mode 100644 index 0000000000..c239c56cf2 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_gpio.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include "drv_gpio.h" + +#ifdef BSP_USING_PIN +/* + * gpio_int[0] for BANK0 (pins 0-27) + * gpio_int[1] for BANK1 (pins 28-45) + * gpio_int[2] for BANK2 (pins 46-53) + */ +static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM]; + +void gpio_set_pud(rt_uint8_t pin, rt_uint8_t pud) +{ + rt_uint8_t num = pin / 32; + rt_uint8_t shift = pin % 32; + BCM283X_GPIO_GPPUD = pud; + DELAY_MICROS(10); + BCM283X_GPIO_GPPUDCLK(num) = 1 << shift; + DELAY_MICROS(10); + BCM283X_GPIO_GPPUD = BCM283X_GPIO_PUD_OFF; + BCM283X_GPIO_GPPUDCLK(num) = 0 << shift; +} + +static void gpio_ack_irq(int irq, bcm_gpio_pin pin) +{ + rt_uint32_t data; + data = IRQ_PEND2; + data &= (0x0 << (irq - 32)); + IRQ_PEND2 = data; + + data = IRQ_DISABLE2; + data |= (0x1 << (irq - 32)); + IRQ_DISABLE2 = data; +} + +void gpio_irq_disable(rt_uint8_t index, bcm_gpio_pin pin) +{ + int irq = 0; + rt_uint32_t reg_value; + rt_uint8_t irq_type; + irq = IRQ_GPIO0 + index; + + gpio_ack_irq(irq, pin); + + irq_type = _g_gpio_irq_tbl[index].irq_type[pin]; + rt_uint8_t shift = pin % 32; + rt_uint32_t mask = 1 << shift; + + switch (irq_type) + { + case PIN_IRQ_MODE_RISING: + reg_value = BCM283X_GPIO_GPREN(pin /32); + BCM283X_GPIO_GPREN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask); + break; + case PIN_IRQ_MODE_FALLING: + reg_value = BCM283X_GPIO_GPFEN(pin /32); + BCM283X_GPIO_GPFEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask); + break; + case PIN_IRQ_MODE_RISING_FALLING: + reg_value = BCM283X_GPIO_GPAREN(pin /32); + BCM283X_GPIO_GPAREN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask); + reg_value = BCM283X_GPIO_GPAFEN(pin /32); + BCM283X_GPIO_GPAFEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask); + break; + case PIN_IRQ_MODE_HIGH_LEVEL: + reg_value = BCM283X_GPIO_GPHEN(pin /32); + BCM283X_GPIO_GPHEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask); + break; + case PIN_IRQ_MODE_LOW_LEVEL: + reg_value = BCM283X_GPIO_GPLEN(pin /32); + BCM283X_GPIO_GPLEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask); + break; + } +} + +void gpio_irq_enable(rt_uint8_t index, bcm_gpio_pin pin) +{ + rt_uint32_t offset; + rt_uint32_t data; + + offset = pin; + if (index == 0) + offset = IRQ_GPIO0 - 32; + else if (index == 1) + offset = IRQ_GPIO1 - 32; + else + offset = IRQ_GPIO2 - 32; + + data = IRQ_ENABLE2; + data |= 0x1 << offset; + IRQ_ENABLE2 = data; + +} + +static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode) +{ + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL)); + RT_ASSERT(!(mode & 0x8)); + + switch (mode) + { + case PIN_MODE_OUTPUT: + GPIO_FSEL(pin, BCM283X_GPIO_FSEL_OUTP); + break; + case PIN_MODE_INPUT: + GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT); + break; + case PIN_MODE_INPUT_PULLUP: + gpio_set_pud(pin, BCM283X_GPIO_PUD_UP); + GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT); + break; + case PIN_MODE_INPUT_PULLDOWN: + gpio_set_pud(pin, BCM283X_GPIO_PUD_DOWN); + GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT); + break; + case PIN_MODE_OUTPUT_OD: + gpio_set_pud(pin, BCM283X_GPIO_PUD_OFF); + GPIO_FSEL(pin, BCM283X_GPIO_FSEL_OUTP); + break; + } +} + +static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value) +{ + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL)); + RT_ASSERT(!(value & 0xE)); + + if (value) + BCM283X_GPIO_GPSET(pin / 32) |= (1 << (pin %32)); + else + BCM283X_GPIO_GPCLR(pin / 32) |= (0 << (pin %32)); + +} + +static int raspi_pin_read(struct rt_device *device, rt_base_t pin) +{ + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL)); + return (BCM2835_GPIO_GPLEV(pin / 32) & (1 << (pin % 32)))? PIN_HIGH : PIN_LOW; +} + +static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) +{ + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL)); + + rt_uint8_t index; + rt_uint32_t reg_value; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + _g_gpio_irq_tbl[index].irq_cb[pin] = hdr; + _g_gpio_irq_tbl[index].irq_arg[pin] = args; + _g_gpio_irq_tbl[index].irq_type[pin] = mode; + + rt_uint8_t shift = pin % 32; + rt_uint32_t mask = 1 << shift; + + switch (mode) + { + case PIN_IRQ_MODE_RISING: + reg_value = BCM283X_GPIO_GPREN(pin /32); + BCM283X_GPIO_GPREN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask); + break; + case PIN_IRQ_MODE_FALLING: + reg_value = BCM283X_GPIO_GPFEN(pin /32); + BCM283X_GPIO_GPFEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask); + break; + case PIN_IRQ_MODE_RISING_FALLING: + reg_value = BCM283X_GPIO_GPAREN(pin /32); + BCM283X_GPIO_GPAREN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask); + reg_value = BCM283X_GPIO_GPAFEN(pin /32); + BCM283X_GPIO_GPAFEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask); + break; + case PIN_IRQ_MODE_HIGH_LEVEL: + reg_value = BCM283X_GPIO_GPHEN(pin /32); + BCM283X_GPIO_GPHEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask); + break; + case PIN_IRQ_MODE_LOW_LEVEL: + reg_value = BCM283X_GPIO_GPLEN(pin /32); + BCM283X_GPIO_GPLEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask); + break; + } + return RT_EOK; +} + +static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_int32_t pin) +{ + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL)); + + rt_uint8_t index; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + + gpio_irq_disable(index, pin); + + _g_gpio_irq_tbl[index].irq_cb[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_arg[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_type[pin] = RT_NULL; + + return RT_EOK; +} + +rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) +{ + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL)); + + rt_uint8_t index; + if (pin <= 27) + index = 0; + else if (pin <= 45) + index = 1; + else + index = 2; + + if (enabled) + gpio_irq_enable(index, pin); + else + gpio_irq_disable(index, pin); + + return RT_EOK; +} + +static void gpio_irq_handler(int irq, void *param) +{ + struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param; + rt_uint32_t pin; + rt_uint32_t value; + rt_uint32_t tmpvalue; + + if (irq == IRQ_GPIO0) + { + /* 0~27 */ + + value = BCM283X_GPIO_GPEDS(0); + value &= 0x0fffffff; + pin = 0; + BCM283X_GPIO_GPEDS(0) = 0; + } + else if (irq == IRQ_GPIO1) + { + /* 28-45 */ + tmpvalue = BCM283X_GPIO_GPEDS(0); + tmpvalue &= (~0x0fffffff); + + value = BCM283X_GPIO_GPEDS(1); + value &= 0x3fff; + value = (value<<4) | tmpvalue; + pin = 28; + BCM283X_GPIO_GPEDS(0) = 0; + BCM283X_GPIO_GPEDS(1) = 0; + } + else if (irq == IRQ_GPIO2) + { + /* 46-53 */ + value = BCM283X_GPIO_GPEDS(1); + value &= (~0x3fff); + value &= 0xff600000; + pin = 46; + BCM283X_GPIO_GPEDS(1) = 0; + } + + while (value) + { + if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL)) + { + irq_def->irq_cb[pin](irq_def->irq_arg[pin]); + gpio_ack_irq(irq,pin); + } + pin++; + value = value >> 1; + } +} + +static const struct rt_pin_ops ops = +{ + raspi_pin_mode, + raspi_pin_write, + raspi_pin_read, + raspi_pin_attach_irq, + raspi_pin_detach_irq, + raspi_pin_irq_enable, +}; +#endif + +int rt_hw_gpio_init(void) +{ +#ifdef BSP_USING_PIN + rt_device_pin_register("gpio", &ops, RT_NULL); + + /* install ISR */ + rt_hw_interrupt_install(IRQ_GPIO0, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq"); + rt_hw_interrupt_umask(IRQ_GPIO0); + + rt_hw_interrupt_install(IRQ_GPIO1, gpio_irq_handler, &_g_gpio_irq_tbl[1], "gpio1_irq"); + rt_hw_interrupt_umask(IRQ_GPIO1); + + rt_hw_interrupt_install(IRQ_GPIO2, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq"); + rt_hw_interrupt_umask(IRQ_GPIO2); +#endif + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_gpio_init); diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_gpio.h b/bsp/raspberry-pi/raspi3-32/driver/drv_gpio.h new file mode 100644 index 0000000000..ce0be096e8 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_gpio.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_GPIO_H__ +#define __DRV_GPIO_H__ + +#include +#include + +#include "interrupt.h" +#include "board.h" + +#define GPIO_IRQ_NUM 3 + +#define IRQ_GPIO0 49 +#define IRQ_GPIO1 50 +#define IRQ_GPIO2 51 +#define IRQ_GPIO3 52 + +struct gpio_irq_def +{ + void *irq_arg[32]; + void (*irq_cb[32])(void *param); + rt_uint8_t irq_type[32]; +}; + +enum gpio_irq_clock +{ + GPIO_IRQ_LOSC_32KHZ = 0, + GPIO_IRQ_HOSC_24MHZ +}; + +int rt_hw_gpio_init(void); + +#endif /* __DRV_GPIO_H__ */ diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c b/bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c new file mode 100644 index 0000000000..35ab7c36d7 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include "drv_i2c.h" + +//Maybe redefined +typedef unsigned long rt_ubase_t; +typedef rt_ubase_t rt_size_t; + +rt_uint8_t i2c_read_or_write(volatile rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len, rt_uint8_t flag) +{ + rt_uint32_t status; + rt_uint32_t remaining = len; + rt_uint32_t i = 0; + rt_uint8_t reason = BCM283X_I2C_REASON_OK; + + /* Clear FIFO */ + BCM283X_BSC_C(base) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1); + /* Clear Status */ + BCM283X_BSC_S(base) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE; + /* Set Data Length */ + BCM283X_BSC_DLEN(base) = len; + if (flag) + { + /* Start read */ + BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST | BSC_C_READ; + /* wait for transfer to complete */ + while (!(BCM283X_BSC_S(base) & BSC_S_DONE)) + { + /* we must empty the FIFO as it is populated and not use any delay */ + while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD)) + { + /* Read from FIFO, no barrier */ + buf[i] = BCM283X_BSC_FIFO(base); + i++; + remaining--; + } + } + /* transfer has finished - grab any remaining stuff in FIFO */ + while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD)) + { + /* Read from FIFO, no barrier */ + buf[i] = BCM283X_BSC_FIFO(base); + i++; + remaining--; + } + } + else + { + /* pre populate FIFO with max buffer */ + while (remaining && (i < BSC_FIFO_SIZE)) + { + BCM283X_BSC_FIFO(base) = buf[i]; + i++; + remaining--; + } + + /* Enable device and start transfer */ + BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST; + + /* Transfer is over when BCM2835_BSC_S_DONE */ + while (!(BCM283X_BSC_S(base) & BSC_S_DONE)) + { + while (remaining && (BCM283X_BSC_S(base) & BSC_S_TXD)) + { + /* Write to FIFO */ + BCM283X_BSC_FIFO(base) = buf[i]; + i++; + remaining--; + } + } + } + + status = BCM283X_BSC_S(base); + if (status & BSC_S_ERR) + { + reason = BCM283X_I2C_REASON_ERROR_NACK; + } + else if (status & BSC_S_CLKT) + { + reason = BCM283X_I2C_REASON_ERROR_CLKT; + } + else if (remaining) + { + reason = BCM283X_I2C_REASON_ERROR_DATA; + } + BCM283X_BSC_C(base) |= (BSC_S_DONE & BSC_S_DONE); + + return reason; +} + +struct raspi_i2c_hw_config +{ + rt_uint8_t bsc_num; + rt_uint8_t sdl_pin; + rt_uint8_t scl_pin; + rt_uint8_t sdl_mode; + rt_uint8_t scl_mode; +}; + +#if (defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1)) + +static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num); +static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num); +static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus, + rt_uint32_t, + rt_uint32_t); + +static rt_uint32_t i2c_byte_wait_us = 0; +static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + rt_size_t i; + rt_uint8_t reason; + RT_ASSERT(bus != RT_NULL); + + volatile rt_uint32_t base = (volatile rt_uint32_t)(bus->parent.user_data); + + if (bus->addr == 0) + base = BCM283X_BSC0_BASE; + else + base = BCM283X_BSC1_BASE; + + BCM283X_BSC_A(base) = msgs->addr; + + for (i = 0; i < num; i++) + { + if (msgs[i].flags & RT_I2C_RD) + reason = i2c_read_or_write(base, msgs->buf, msgs->len, 1); + else + reason = i2c_read_or_write(base, msgs->buf, msgs->len, 0); + } + return (reason == 0)? i : 0; +} + +static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + return 0; +} +static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus, + rt_uint32_t cmd, + rt_uint32_t arg) +{ + return RT_EOK; +} + +static const struct rt_i2c_bus_device_ops raspi_i2c_ops = +{ + .master_xfer = raspi_i2c_mst_xfer, + .slave_xfer = raspi_i2c_slv_xfer, + .i2c_bus_control = raspi_i2c_bus_control, +}; + + +static rt_err_t raspi_i2c_configure(struct raspi_i2c_hw_config *cfg) +{ + RT_ASSERT(cfg != RT_NULL); + + volatile rt_uint32_t base = cfg->scl_mode ? BCM283X_BSC1_BASE : BCM283X_BSC0_BASE; + + GPIO_FSEL(cfg->sdl_pin, cfg->sdl_mode); /* SDA */ + GPIO_FSEL(cfg->scl_pin, cfg->scl_mode); /* SCL */ + + /* use 0xFFFE mask to limit a max value and round down any odd number */ + rt_uint32_t divider = (BCM283X_CORE_CLK_HZ / 10000) & 0xFFFE; + BCM283X_BSC_DIV(base) = (rt_uint16_t) divider; + i2c_byte_wait_us = (divider * 1000000 * 9 / BCM283X_CORE_CLK_HZ); + + return RT_EOK; +} +#endif + +#if defined (BSP_USING_I2C0) +#define I2C0_BUS_NAME "i2c0" +static struct raspi_i2c_hw_config hw_device0 = +{ + .bsc_num = 0, + .sdl_pin = RPI_GPIO_P1_27, + .scl_pin = RPI_GPIO_P1_28, + .sdl_mode = BCM283X_GPIO_FSEL_ALT0, + .scl_mode = BCM283X_GPIO_FSEL_ALT0, +}; + +struct rt_i2c_bus_device device0 = +{ + .ops = &raspi_i2c_ops, + .addr = 0, +}; + +#endif + +#if defined (BSP_USING_I2C1) +#define I2C1_BUS_NAME "i2c1" +static struct raspi_i2c_hw_config hw_device1 = +{ + .bsc_num = 1, + .sdl_pin = RPI_GPIO_P1_03, + .scl_pin = RPI_GPIO_P1_05, + .sdl_mode = BCM283X_GPIO_FSEL_ALT0, + .scl_mode = BCM283X_GPIO_FSEL_ALT0, +}; +struct rt_i2c_bus_device device1 = +{ + .ops = &raspi_i2c_ops, + .addr = 1, +}; + +#endif + +int rt_hw_i2c_init(void) +{ +#if defined(BSP_USING_I2C0) + raspi_i2c_configure(&hw_device0); + rt_i2c_bus_device_register(&device0, I2C0_BUS_NAME); +#endif + +#if defined(BSP_USING_I2C1) + raspi_i2c_configure(&hw_device1); + rt_i2c_bus_device_register(&device1, I2C1_BUS_NAME); +#endif + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_i2c_init); diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_i2c.h b/bsp/raspberry-pi/raspi3-32/driver/drv_i2c.h new file mode 100644 index 0000000000..ff9e8ca724 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_i2c.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_I2C_H__ +#define __DRV_I2C_H__ + +#include +#include + +#include "board.h" + +struct raspi_master_config_t +{ + rt_uint8_t sdl_pin; + rt_uint8_t scl_pin; + rt_uint8_t sdl_pin_mode; + rt_uint8_t scl_pin_mode; + rt_uint8_t slave_address; + rt_uint32_t bsc_base; + rt_uint16_t clk_div; +}; + +struct raspi_i2c_bus +{ + struct rt_i2c_bus_device device; + struct rt_i2c_msg *msg; + rt_uint32_t msg_cnt; + volatile rt_uint32_t msg_ptr; + volatile rt_uint32_t dptr; + char *device_name; + struct raspi_master_config_t *cfg; +}; + +int rt_hw_i2c_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_rtc.c b/bsp/raspberry-pi/raspi3-32/driver/drv_rtc.c new file mode 100644 index 0000000000..8a33e2be64 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_rtc.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include "drv_rtc.h" + +#ifdef BSP_USING_RTC + +#define RTC_I2C_BUS_NAME "i2c0" +#define RTC_ADDR 0x68 + +static struct rt_device rtc_device; +static struct rt_i2c_bus_device *i2c_bus = RT_NULL; + +rt_uint8_t buf[]= +{ + 0x00, 0x00, 0x43, 0x15, 0x05, 0x01, 0x03, 0x19 +}; + + +rt_uint8_t i2c_write_read_rs(char* cmds, rt_uint32_t cmds_len, char* buf, rt_uint32_t buf_len) +{ + rt_uint32_t remaining = cmds_len; + rt_uint32_t i = 0; + rt_uint8_t reason = BCM283X_I2C_REASON_OK; + + /* Clear FIFO */ + BCM283X_BSC_C(BCM283X_BSC0_BASE) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1); + + /* Clear Status */ + BCM283X_BSC_S(BCM283X_BSC0_BASE) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE; + + /* Set Data Length */ + BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = cmds_len; + + /* pre populate FIFO with max buffer */ + while (remaining && (i < BSC_FIFO_SIZE)) + { + BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = cmds[i]; + i++; + remaining--; + } + + /* Enable device and start transfer */ + BCM283X_BSC_C(BCM283X_BSC0_BASE) |= BSC_C_I2CEN | BSC_C_ST; + + /* poll for transfer has started (way to do repeated start, from BCM2835 datasheet) */ + while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_TA)) + { + /* Linux may cause us to miss entire transfer stage */ + if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE) + break; + } + + remaining = buf_len; + i = 0; + + /* Send a repeated start with read bit set in address */ + BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = buf_len; + BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_C_I2CEN | BSC_C_ST | BSC_C_READ; + + /* Wait for write to complete and first byte back. */ + // DELAYMICROS(i2c_byte_wait_us * (cmds_len + 1)); + + /* wait for transfer to complete */ + while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE)) + { + /* we must empty the FIFO as it is populated and not use any delay */ + while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_RXD)) + { + /* Read from FIFO, no barrier */ + buf[i] = BCM283X_BSC_FIFO(BCM283X_BSC0_BASE); + i++; + remaining--; + } + } + + /* transfer has finished - grab any remaining stuff in FIFO */ + while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_RXD)) + { + /* Read from FIFO */ + buf[i] = BCM283X_BSC_FIFO(BCM283X_BSC0_BASE); + i++; + remaining--; + } + + /* Received a NACK */ + if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_ERR) + { + reason = BCM283X_I2C_REASON_ERROR_NACK; + } + + /* Received Clock Stretch Timeout */ + else if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_CLKT) + { + reason = BCM283X_I2C_REASON_ERROR_CLKT; + } + + /* Not all data is sent */ + else if (remaining) + { + reason = BCM283X_I2C_REASON_ERROR_DATA; + } + + BCM283X_BSC_C(BCM283X_BSC0_BASE) = (BSC_S_DONE &BSC_S_DONE); + + return reason; +} + +rt_uint8_t i2c_write(rt_uint8_t* buf, rt_uint32_t len) +{ + rt_uint32_t remaining = len; + rt_uint32_t i = 0; + rt_uint8_t reason = BCM283X_I2C_REASON_OK; + + /* Clear FIFO */ + BCM283X_BSC_C(BCM283X_BSC0_BASE) |= BSC_C_CLEAR_1 & BSC_C_CLEAR_1; + /* Clear Status */ + BCM283X_BSC_S(BCM283X_BSC0_BASE) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE; + /* Set Data Length */ + BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = len; + /* pre populate FIFO with max buffer */ + while (remaining && (i < BSC_FIFO_SIZE)) + { + BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = buf[i]; + i++; + remaining--; + } + + /* Enable device and start transfer */ + BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_C_I2CEN | BSC_C_ST; + + /* Transfer is over when BCM2835_BSC_S_DONE */ + while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE)) + { + while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_TXD)) + { + /* Write to FIFO */ + BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = buf[i]; + i++; + remaining--; + } + } + + /* Received a NACK */ + if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_ERR) + { + reason = BCM283X_I2C_REASON_ERROR_NACK; + } + + /* Received Clock Stretch Timeout */ + else if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_CLKT) + { + reason = BCM283X_I2C_REASON_ERROR_CLKT; + } + + /* Not all data is sent */ + else if (remaining) + { + reason = BCM283X_I2C_REASON_ERROR_DATA; + } + + BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_S_DONE & BSC_S_DONE; + return reason; +} + + +static time_t raspi_get_timestamp(void) +{ + struct tm tm_new = {0}; + buf[0] = 0; + + i2c_write_read_rs((char*)buf, 1, (char*)buf, 7); + + tm_new.tm_year = ((buf[6] / 16) + 0x30) * 10 + (buf[6] % 16) + 0x30; + tm_new.tm_mon = ((buf[5] & 0x1F) / 16 + 0x30) + (buf[5] & 0x1F) % 16+ 0x30; + tm_new.tm_mday = ((buf[4] & 0x3F) / 16 + 0x30) + (buf[4] & 0x3F) % 16+ 0x30; + tm_new.tm_hour = ((buf[2] & 0x3F) / 16 + 0x30) + (buf[2] & 0x3F) % 16+ 0x30; + tm_new.tm_min = ((buf[1] & 0x7F) / 16 + 0x30) + (buf[1] & 0x7F) % 16+ 0x30; + tm_new.tm_sec = ((buf[0] & 0x7F) / 16 + 0x30) + (buf[0] & 0x7F) % 16+ 0x30; + + return mktime(&tm_new); +} + +static int raspi_set_timestamp(time_t timestamp) +{ + struct tm *tblock; + tblock = localtime(×tamp); + buf[0] = 0; + buf[1] = tblock->tm_sec; + buf[2] = tblock->tm_min; + buf[3] = tblock->tm_hour; + buf[4] = tblock->tm_wday; + buf[5] = tblock->tm_mday; + buf[6] = tblock->tm_mon; + buf[7] = tblock->tm_year; + + i2c_write(buf, 8); + + return RT_EOK; +} + +static rt_err_t raspi_rtc_init(rt_device_t dev) +{ + i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(RTC_I2C_BUS_NAME); + raspi_set_timestamp(0); + return RT_EOK; +} + +static rt_err_t raspi_rtc_open(rt_device_t dev, rt_uint16_t oflag) +{ + GPIO_FSEL(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_ALT0); /* SDA */ + GPIO_FSEL(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_ALT0); /* SCL */ + return RT_EOK; +} + +static rt_err_t raspi_rtc_close(rt_device_t dev) +{ + GPIO_FSEL(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_INPT); /* SDA */ + GPIO_FSEL(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_INPT); /* SCL */ + return RT_EOK; +} + +static rt_err_t raspi_rtc_control(rt_device_t dev, int cmd, void *args) +{ + + RT_ASSERT(dev != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + *(rt_uint32_t *)args = raspi_get_timestamp(); + break; + case RT_DEVICE_CTRL_RTC_SET_TIME: + raspi_set_timestamp(*(time_t *)args); + break; + default: + return RT_EINVAL; + } + return RT_EOK; +} + +static rt_size_t raspi_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + raspi_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer); + return size; +} + +static rt_size_t raspi_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + raspi_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer); + return size; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops raspi_rtc_ops = +{ + .init = raspi_rtc_init, + .open = raspi_rtc_open, + .close = raspi_rtc_close, + .read = raspi_rtc_read, + .write = raspi_rtc_write, + .control = raspi_rtc_control +}; +#endif + +int rt_hw_rtc_init(void) +{ + rt_err_t ret = RT_EOK; + + rtc_device.type = RT_Device_Class_RTC; + rtc_device.rx_indicate = RT_NULL; + rtc_device.tx_complete = RT_NULL; + +#ifdef RT_USING_DEVICE_OPS + rtc_device.ops = &raspi_rtc_ops; +#else + rtc_device.init = raspi_rtc_init; + rtc_device.open = raspi_rtc_open; + rtc_device.close = raspi_rtc_close; + rtc_device.read = raspi_rtc_read; + rtc_device.write = raspi_rtc_write; + rtc_device.control = raspi_rtc_control; +#endif + + rtc_device.user_data = RT_NULL; + + /* register a rtc device */ + ret = rt_device_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR); + + return ret; +} +INIT_DEVICE_EXPORT(rt_hw_rtc_init); +#endif /* BSP_USING_RTC */ + diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_rtc.h b/bsp/raspberry-pi/raspi3-32/driver/drv_rtc.h new file mode 100644 index 0000000000..d850defa68 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_rtc.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_RTC_H__ +#define __DRV_RTC_H__ + +#include +#include + +#include "board.h" + +int rt_hw_rtc_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_sdio.c b/bsp/raspberry-pi/raspi3-32/driver/drv_sdio.c new file mode 100644 index 0000000000..c547419ca2 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_sdio.c @@ -0,0 +1,580 @@ +/* + * File : drv_sdio.c + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include "drv_sdio.h" + +static rt_uint32_t sdCommandTable[] = { + SD_CMD_INDEX(0), + SD_CMD_RESERVED(1), + SD_CMD_INDEX(2) | SD_RESP_R2, + SD_CMD_INDEX(3) | SD_RESP_R1, + SD_CMD_INDEX(4), + SD_CMD_RESERVED(5), //SD_CMD_INDEX(5) | SD_RESP_R4, + SD_CMD_INDEX(6) | SD_RESP_R1, + SD_CMD_INDEX(7) | SD_RESP_R1b, + SD_CMD_INDEX(8) | SD_RESP_R1, + SD_CMD_INDEX(9) | SD_RESP_R2, + SD_CMD_INDEX(10) | SD_RESP_R2, + SD_CMD_INDEX(11) | SD_RESP_R1, + SD_CMD_INDEX(12) | SD_RESP_R1b | SD_CMD_TYPE_ABORT, + SD_CMD_INDEX(13) | SD_RESP_R1, + SD_CMD_RESERVED(14), + SD_CMD_INDEX(15), + SD_CMD_INDEX(16) | SD_RESP_R1, + SD_CMD_INDEX(17) | SD_RESP_R1 | SD_DATA_READ, + SD_CMD_INDEX(18) | SD_RESP_R1 | SD_DATA_READ | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN, + SD_CMD_INDEX(19) | SD_RESP_R1 | SD_DATA_READ, + SD_CMD_INDEX(20) | SD_RESP_R1b, + SD_CMD_RESERVED(21), + SD_CMD_RESERVED(22), + SD_CMD_INDEX(23) | SD_RESP_R1, + SD_CMD_INDEX(24) | SD_RESP_R1 | SD_DATA_WRITE, + SD_CMD_INDEX(25) | SD_RESP_R1 | SD_DATA_WRITE | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN, + SD_CMD_INDEX(26) | SD_RESP_R1 | SD_DATA_WRITE, //add + SD_CMD_INDEX(27) | SD_RESP_R1 | SD_DATA_WRITE, + SD_CMD_INDEX(28) | SD_RESP_R1b, + SD_CMD_INDEX(29) | SD_RESP_R1b, + SD_CMD_INDEX(30) | SD_RESP_R1 | SD_DATA_READ, + SD_CMD_RESERVED(31), + SD_CMD_INDEX(32) | SD_RESP_R1, + SD_CMD_INDEX(33) | SD_RESP_R1, + SD_CMD_RESERVED(34), + SD_CMD_INDEX(35) | SD_RESP_R1, //add + SD_CMD_INDEX(36) | SD_RESP_R1, //add + SD_CMD_RESERVED(37), + SD_CMD_INDEX(38) | SD_RESP_R1b, + SD_CMD_INDEX(39) | SD_RESP_R4, //add + SD_CMD_INDEX(40) | SD_RESP_R5, //add + SD_CMD_INDEX(41) | SD_RESP_R3, //add, mov from harbote + SD_CMD_RESERVED(42) | SD_RESP_R1, + SD_CMD_RESERVED(43), + SD_CMD_RESERVED(44), + SD_CMD_RESERVED(45), + SD_CMD_RESERVED(46), + SD_CMD_RESERVED(47), + SD_CMD_RESERVED(48), + SD_CMD_RESERVED(49), + SD_CMD_RESERVED(50), + SD_CMD_INDEX(51) | SD_RESP_R1 | SD_DATA_READ, + SD_CMD_RESERVED(52), + SD_CMD_RESERVED(53), + SD_CMD_RESERVED(54), + SD_CMD_INDEX(55) | SD_RESP_R3, + SD_CMD_INDEX(56) | SD_RESP_R1 | SD_CMD_ISDATA, + SD_CMD_RESERVED(57), + SD_CMD_RESERVED(58), + SD_CMD_RESERVED(59), + SD_CMD_RESERVED(60), + SD_CMD_RESERVED(61), + SD_CMD_RESERVED(62), + SD_CMD_RESERVED(63) +}; + +static inline rt_uint32_t read32(rt_uint32_t addr) +{ + return (*((volatile rt_uint32_t *)(addr))); +} + +static inline void write32(rt_uint32_t addr, rt_uint32_t value) +{ + *((volatile rt_uint32_t *)(addr)) = value; +} + +rt_err_t sd_int(struct sdhci_pdata_t * pdat, unsigned int mask) +{ + unsigned int r; + unsigned int m = mask | INT_ERROR_MASK; + int cnt = 1000000; + while (!(read32(pdat->virt + EMMC_INTERRUPT) & (m | INT_ERROR_MASK)) && cnt--) + DELAY_MICROS(1); + r = read32(pdat->virt + EMMC_INTERRUPT); + if (cnt <= 0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT)) + { + write32(pdat->virt + EMMC_INTERRUPT, r); + rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n",mask, r, read32(pdat->virt + EMMC_STATUS)); + return -RT_ETIMEOUT; + } + else if (r & INT_ERROR_MASK) + { + write32(pdat->virt + EMMC_INTERRUPT, r); + rt_kprintf("send cmd/data error %x -> %x\n",r, read32(pdat->virt + EMMC_INTERRUPT)); + return -RT_ERROR; + } + write32(pdat->virt + EMMC_INTERRUPT, mask); + return RT_EOK; +} + +rt_err_t sd_status(struct sdhci_pdata_t * pdat, unsigned int mask) +{ + int cnt = 500000; + while ((read32(pdat->virt + EMMC_STATUS) & mask) && !(read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK) && cnt--) + DELAY_MICROS(1); + if (cnt <= 0) + { + return -RT_ETIMEOUT; + } + else if (read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK) + return -RT_ERROR; + return RT_EOK; +} + +static rt_err_t raspi_transfer_command(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd) +{ + + rt_uint32_t cmdidx; + rt_err_t ret = RT_EOK; + ret = sd_status(pdat, SR_CMD_INHIBIT); + if (ret) + { + rt_kprintf("ERROR: EMMC busy %d\n", ret); + return ret; + } + + cmdidx = sdCommandTable[cmd->cmdidx]; + if (cmdidx == 0xFFFFFFFF) + return -RT_EINVAL; + if (cmd->datarw == DATA_READ) + cmdidx |= SD_DATA_READ; + if (cmd->datarw == DATA_WRITE) + cmdidx |= SD_DATA_WRITE; + mmcsd_dbg("transfer cmd %x(%d) %x %x\n", cmdidx, cmd->cmdidx, cmd->cmdarg, read32(pdat->virt + EMMC_INTERRUPT)); + write32(pdat->virt + EMMC_INTERRUPT,read32(pdat->virt + EMMC_INTERRUPT)); + write32(pdat->virt + EMMC_ARG1, cmd->cmdarg); + write32(pdat->virt + EMMC_CMDTM, cmdidx); + if (cmd->cmdidx == SD_APP_OP_COND) + DELAY_MICROS(1000); + else if ((cmd->cmdidx == SD_SEND_IF_COND) || (cmd->cmdidx == APP_CMD)) + DELAY_MICROS(100); + ret = sd_int(pdat, INT_CMD_DONE); + if (ret) + { + return ret; + } + if (cmd->resptype & RESP_MASK) + { + + if (cmd->resptype & RESP_R2) + { + rt_uint32_t resp[4]; + resp[0] = read32(pdat->virt + EMMC_RESP0); + resp[1] = read32(pdat->virt + EMMC_RESP1); + resp[2] = read32(pdat->virt + EMMC_RESP2); + resp[3] = read32(pdat->virt + EMMC_RESP3); + if (cmd->resptype == RESP_R2) + { + cmd->response[0] = resp[3]<<8 |((resp[2]>>24)&0xff); + cmd->response[1] = resp[2]<<8 |((resp[1]>>24)&0xff); + cmd->response[2] = resp[1]<<8 |((resp[0]>>24)&0xff); + cmd->response[3] = resp[0]<<8 ; + } + else + { + cmd->response[0] = resp[0]; + cmd->response[1] = resp[1]; + cmd->response[2] = resp[2]; + cmd->response[3] = resp[3]; + } + } + else + cmd->response[0] = read32(pdat->virt + EMMC_RESP0); + } + mmcsd_dbg("response: %x: %x %x %x %x (%x, %x)\n", cmd->resptype, cmd->response[0], cmd->response[1], cmd->response[2], cmd->response[3], read32(pdat->virt + EMMC_STATUS),read32(pdat->virt + EMMC_INTERRUPT)); + return ret; +} + +static rt_err_t read_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize) +{ + int c = 0; + rt_err_t ret; + int d; + while (c < blkcount) + { + if ((ret = sd_int(pdat, INT_READ_RDY))) + { + rt_kprintf("timeout happens when reading block %d\n",c); + return ret; + } + for (d=0; d < blksize / 4; d++) + if (read32(pdat->virt + EMMC_STATUS) & SR_READ_AVAILABLE) + buf[d] = read32(pdat->virt + EMMC_DATA); + c++; + buf += blksize / 4; + } + return RT_EOK; +} + +static rt_err_t write_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize) +{ + int c = 0; + rt_err_t ret; + int d; + while (c < blkcount) + { + if ((ret = sd_int(pdat, INT_WRITE_RDY))) + { + return ret; + } + for (d=0; d < blksize / 4; d++) + write32(pdat->virt + EMMC_DATA, buf[d]); + c++; + buf += blksize / 4; + } + if ((ret = sd_int(pdat, INT_DATA_DONE))) + { + return ret; + } + return RT_EOK; +} + +static rt_err_t raspi_transfer_data(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat) +{ + rt_uint32_t dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz); + rt_err_t ret = sd_status(pdat, SR_DAT_INHIBIT); + if (ret) + { + rt_kprintf("ERROR: EMMC busy\n"); + return ret; + } + if (dat->blkcnt > 1) + { + struct sdhci_cmd_t newcmd; + newcmd.cmdidx = SET_BLOCK_COUNT; + newcmd.cmdarg = dat->blkcnt; + newcmd.resptype = RESP_R1; + ret = raspi_transfer_command(pdat, &newcmd); + if (ret) return ret; + } + write32(pdat->virt + EMMC_BLKSIZECNT, dlen | 1 << 16); + + if (dat->flag & DATA_DIR_READ) + { + cmd->datarw = DATA_READ; + ret = raspi_transfer_command(pdat, cmd); + if (ret) return ret; + mmcsd_dbg("read_block %d, %d\n", dat->blkcnt, dat->blksz ); + ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz); + } + else if (dat->flag & DATA_DIR_WRITE) + { + cmd->datarw = DATA_WRITE; + ret = raspi_transfer_command(pdat, cmd); + if (ret) return ret; + mmcsd_dbg("write_block %d, %d", dat->blkcnt, dat->blksz ); + ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz); + } + return ret; +} + +static rt_err_t sdhci_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat) +{ + struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv; + + if (!dat) + return raspi_transfer_command(pdat, cmd); + + return raspi_transfer_data(pdat, cmd, dat); +} + +static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req) +{ + struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data; + struct sdhci_cmd_t cmd; + struct sdhci_cmd_t stop; + struct sdhci_data_t dat; + + rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t)); + rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t)); + rt_memset(&dat, 0, sizeof(struct sdhci_data_t)); + + cmd.cmdidx = req->cmd->cmd_code; + cmd.cmdarg = req->cmd->arg; + cmd.resptype =resp_type(req->cmd); + if (req->data) + { + dat.buf = (rt_uint8_t *)req->data->buf; + dat.flag = req->data->flags; + dat.blksz = req->data->blksize; + dat.blkcnt = req->data->blks; + + req->cmd->err = sdhci_transfer(sdhci, &cmd, &dat); + } + else + { + req->cmd->err = sdhci_transfer(sdhci, &cmd, RT_NULL); + } + + req->cmd->resp[3] = cmd.response[3]; + req->cmd->resp[2] = cmd.response[2]; + req->cmd->resp[1] = cmd.response[1]; + req->cmd->resp[0] = cmd.response[0]; + + if (req->stop) + { + stop.cmdidx = req->stop->cmd_code; + stop.cmdarg = req->stop->arg; + cmd.resptype =resp_type(req->stop); + req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL); + } + + mmcsd_req_complete(host); +} + +rt_int32_t mmc_card_status(struct rt_mmcsd_host *host) +{ + return 0; +} + +void mmc_enable_irq(struct rt_mmcsd_host *host, rt_int32_t en) +{ + +} + +static rt_err_t sdhci_detect(struct sdhci_t * sdhci) +{ + return RT_EOK; +} + +static rt_err_t sdhci_setwidth(struct sdhci_t * sdhci, rt_uint32_t width) +{ + rt_uint32_t temp = 0; + struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv; + if (width == MMCSD_BUS_WIDTH_4) + { + temp = read32((pdat->virt + EMMC_CONTROL0)); + temp |= C0_HCTL_HS_EN; + temp |= C0_HCTL_DWITDH; // always use 4 data lines: + write32((pdat->virt + EMMC_CONTROL0), temp); + } + return RT_EOK; +} + +static rt_uint32_t sdhci_getdivider(rt_uint32_t sdHostVer, rt_uint32_t freq) +{ + rt_uint32_t divisor; + rt_uint32_t closest = 41666666 / freq; + rt_uint32_t shiftcount = __rt_fls(closest - 1); + + + if (shiftcount > 0) shiftcount--; + if (shiftcount > 7) shiftcount = 7; + if (sdHostVer > HOST_SPEC_V2) + divisor = closest; + else + divisor = (1 << shiftcount); + + if (divisor <= 2) + { + divisor = 2; + shiftcount = 0; + } + + rt_uint32_t hi = 0; + if (sdHostVer > HOST_SPEC_V2) + hi = (divisor & 0x300) >> 2; + rt_uint32_t lo = (divisor & 0x0ff); + rt_uint32_t cdiv = (lo << 8) + hi; + return cdiv; +} + +static rt_err_t sdhci_setclock(struct sdhci_t * sdhci, rt_uint32_t clock) +{ + rt_uint32_t temp = 0; + rt_uint32_t sdHostVer = 0; + int count = 100000; + struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)(sdhci->priv); + + while ((read32(pdat->virt + EMMC_STATUS) & (SR_CMD_INHIBIT | SR_DAT_INHIBIT)) && (--count)) + DELAY_MICROS(1); + if (count <= 0) + { + rt_kprintf("EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.\n",read32(pdat->virt + EMMC_STATUS)); + return RT_ERROR; + } + + // Switch clock off. + temp = read32((pdat->virt + EMMC_CONTROL1)); + temp &= ~C1_CLK_EN; + write32((pdat->virt + EMMC_CONTROL1),temp); + DELAY_MICROS(10); + // Request the new clock setting and enable the clock + temp = read32(pdat->virt + EMMC_SLOTISR_VER); + sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT; + int cdiv = sdhci_getdivider(sdHostVer, clock); + temp = read32((pdat->virt + EMMC_CONTROL1)); + temp = (temp & 0xffff003f) | cdiv; + write32((pdat->virt + EMMC_CONTROL1),temp); + DELAY_MICROS(10); + + // Enable the clock. + temp = read32(pdat->virt + EMMC_CONTROL1); + temp |= C1_CLK_EN; + write32((pdat->virt + EMMC_CONTROL1),temp); + DELAY_MICROS(10); + // Wait for clock to be stable. + count = 10000; + while (!(read32(pdat->virt + EMMC_CONTROL1) & C1_CLK_STABLE) && count--) + DELAY_MICROS(10); + if (count <= 0) + { + rt_kprintf("EMMC: ERROR: failed to get stable clock %d.\n", clock); + return RT_ERROR; + } + mmcsd_dbg("set stable clock %d.\n", clock); + return RT_EOK; +} + +static void mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg) +{ + struct sdhci_t * sdhci = (struct sdhci_t *)host->private_data; + sdhci_setclock(sdhci, io_cfg->clock); + sdhci_setwidth(sdhci, io_cfg->bus_width); +} + +static const struct rt_mmcsd_host_ops ops = +{ + mmc_request_send, + mmc_set_iocfg, + RT_NULL, + RT_NULL, +}; + +static void sdmmc_gpio_init() +{ +// int pin; +// bcm283x_gpio_fsel(47,BCM283X_GPIO_FSEL_INPT); +// bcm283x_gpio_set_pud(47, BCM283X_GPIO_PUD_UP); +// bcm283x_peri_set_bits(BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN1, 1<<15, 1<<15); +// for (pin = 53; pin >= 48; pin--) +// { +// bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_ALT3); +// bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP); +// } +} + +static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat){ + rt_uint32_t temp; + int cnt; + write32((pdat->virt + EMMC_CONTROL0),0); + temp = read32((pdat->virt + EMMC_CONTROL1)); + temp |= C1_SRST_HC; + write32((pdat->virt + EMMC_CONTROL1),temp); + cnt = 10000; + do + { + DELAY_MICROS(10); + } + while ((read32((pdat->virt + EMMC_CONTROL1)) & C1_SRST_HC) && cnt--); + + if (cnt <= 0) + { + rt_kprintf("ERROR: failed to reset EMMC\n"); + return RT_ERROR; + } + temp = read32((pdat->virt + EMMC_CONTROL1)); + temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX; + write32((pdat->virt + EMMC_CONTROL1),temp); + DELAY_MICROS(10); + return RT_EOK; +} + +#ifdef RT_MMCSD_DBG +void dump_registers(struct sdhci_pdata_t * pdat){ + rt_kprintf("EMMC registers:"); + int i = EMMC_ARG2; + for (; i <= EMMC_CONTROL2; i += 4) + rt_kprintf("\t%x:%x\n", i, read32(pdat->virt + i)); + rt_kprintf("\t%x:%x\n", 0x50, read32(pdat->virt + 0x50)); + rt_kprintf("\t%x:%x\n", 0x70, read32(pdat->virt + 0x70)); + rt_kprintf("\t%x:%x\n", 0x74, read32(pdat->virt + 0x74)); + rt_kprintf("\t%x:%x\n", 0x80, read32(pdat->virt + 0x80)); + rt_kprintf("\t%x:%x\n", 0x84, read32(pdat->virt + 0x84)); + rt_kprintf("\t%x:%x\n", 0x88, read32(pdat->virt + 0x88)); + rt_kprintf("\t%x:%x\n", 0x8c, read32(pdat->virt + 0x8c)); + rt_kprintf("\t%x:%x\n", 0x90, read32(pdat->virt + 0x90)); + rt_kprintf("\t%x:%x\n", 0xf0, read32(pdat->virt + 0xf0)); + rt_kprintf("\t%x:%x\n", 0xfc, read32(pdat->virt + 0xfc)); +} +#endif + +int raspi_sdmmc_init(void) +{ + rt_uint32_t virt; + struct rt_mmcsd_host * host = RT_NULL; + struct sdhci_pdata_t * pdat = RT_NULL; + struct sdhci_t * sdhci = RT_NULL; + +#ifdef BSP_USING_SDIO0 + host = mmcsd_alloc_host(); + if (!host) + { + rt_kprintf("alloc host failed"); + goto err; + } + + sdhci = rt_malloc(sizeof(struct sdhci_t)); + if (!sdhci) + { + rt_kprintf("alloc sdhci failed"); + goto err; + } + rt_memset(sdhci, 0, sizeof(struct sdhci_t)); + + sdmmc_gpio_init(); + + virt = MMC0_BASE_ADDR; + + pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t)); + RT_ASSERT(pdat != RT_NULL); + + pdat->virt = (rt_uint32_t)virt; + reset_emmc(pdat); + + sdhci->name = "sd0"; + sdhci->voltages = VDD_33_34; + sdhci->width = MMCSD_BUSWIDTH_4; + sdhci->clock = 200 * 1000 * 1000; + sdhci->removeable = RT_TRUE; + + sdhci->detect = sdhci_detect; + sdhci->setwidth = sdhci_setwidth; + sdhci->setclock = sdhci_setclock; + sdhci->transfer = sdhci_transfer; + sdhci->priv = pdat; + + host->ops = &ops; + host->freq_min = 400000; + host->freq_max = 50000000; + host->valid_ocr = VDD_32_33 | VDD_33_34; + host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4; + host->max_seg_size = 2048; + host->max_dma_segs = 10; + host->max_blk_size = 512; + host->max_blk_count = 4096; + + host->private_data = sdhci; + + write32((pdat->virt + EMMC_IRPT_EN),0xffffffff); + write32((pdat->virt + EMMC_IRPT_MASK),0xffffffff); +#ifdef RT_MMCSD_DBG + dump_registers(pdat); +#endif + mmcsd_change(host); +#endif + return RT_EOK; + +err: + if (host) rt_free(host); + if (sdhci) rt_free(sdhci); + + return -RT_EIO; +} + +INIT_DEVICE_EXPORT(raspi_sdmmc_init); diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_sdio.h b/bsp/raspberry-pi/raspi3-32/driver/drv_sdio.h new file mode 100644 index 0000000000..5c052de90a --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_sdio.h @@ -0,0 +1,253 @@ +/* + * File : drv_sdio.h + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_SDIO_H__ +#define __DRV_SDIO_H__ + +#include +#include +#include + +#include "board.h" + +#define MMC0_BASE_ADDR 0x3F300000 + +/* Struct for Intrrrupt Information */ +#define SDXC_CmdDone BIT(0) +#define SDXC_DataDone BIT(1) +#define SDXC_BlockGap BIT(2) +#define SDXC_WriteRdy BIT(4) +#define SDXC_ReadRdy BIT(5) +#define SDXC_Card BIT(8) +#define SDXC_Retune BIT(12) +#define SDXC_BootAck BIT(13) +#define SDXC_EndBoot BIT(14) +#define SDXC_Err BIT(15) +#define SDXC_CTOErr BIT(16) +#define SDXC_CCRCErr BIT(17) +#define SDXC_CENDErr BIT(18) +#define SDXC_CBADErr BIT(19) +#define SDXC_DTOErr BIT(20) +#define SDXC_DCRCErr BIT(21) +#define SDXC_DENDErr BIT(22) +#define SDXC_ACMDErr BIT(24) + +#define SDXC_BLKCNT_EN BIT(1) +#define SDXC_AUTO_CMD12_EN BIT(2) +#define SDXC_AUTO_CMD23_EN BIT(3) +#define SDXC_DAT_DIR BIT(4) //from card to host +#define SDXC_MULTI_BLOCK BIT(5) +#define SDXC_CMD_RSPNS_136 BIT(16) +#define SDXC_CMD_RSPNS_48 BIT(17) +#define SDXC_CMD_RSPNS_48busy BIT(16)|BIT(17) +#define SDXC_CHECK_CRC_CMD BIT(19) +#define SDXC_CMD_IXCHK_EN BIT(20) +#define SDXC_CMD_ISDATA BIT(21) +#define SDXC_CMD_SUSPEND BIT(22) +#define SDXC_CMD_RESUME BIT(23) +#define SDXC_CMD_ABORT BIT(23)|BIT(22) + +#define SDXC_CMD_INHIBIT BIT(0) +#define SDXC_DAT_INHIBIT BIT(1) +#define SDXC_DAT_ACTIVE BIT(2) +#define SDXC_WRITE_TRANSFER BIT(8) +#define SDXC_READ_TRANSFER BIT(9) + +struct sdhci_cmd_t +{ + rt_uint32_t cmdidx; + rt_uint32_t cmdarg; + rt_uint32_t resptype; + rt_uint32_t datarw; +#define DATA_READ 1 +#define DATA_WRITE 2 + rt_uint32_t response[4]; +}; + +struct sdhci_data_t +{ + rt_uint8_t * buf; + rt_uint32_t flag; + rt_uint32_t blksz; + rt_uint32_t blkcnt; +}; + +struct sdhci_t +{ + char * name; + rt_uint32_t voltages; + rt_uint32_t width; + rt_uint32_t clock; + rt_err_t removeable; + void * sdcard; + + rt_err_t (*detect)(struct sdhci_t * sdhci); + rt_err_t (*setwidth)(struct sdhci_t * sdhci, rt_uint32_t width); + rt_err_t (*setclock)(struct sdhci_t * sdhci, rt_uint32_t clock); + rt_err_t (*transfer)(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat); + void * priv; +}; + +struct sdhci_pdata_t +{ + rt_uint32_t virt; +}; + +// EMMC command flags +#define CMD_TYPE_NORMAL 0x00000000 +#define CMD_TYPE_SUSPEND 0x00400000 +#define CMD_TYPE_RESUME 0x00800000 +#define CMD_TYPE_ABORT 0x00c00000 +#define CMD_IS_DATA 0x00200000 +#define CMD_IXCHK_EN 0x00100000 +#define CMD_CRCCHK_EN 0x00080000 +#define CMD_RSPNS_NO 0x00000000 +#define CMD_RSPNS_136 0x00010000 +#define CMD_RSPNS_48 0x00020000 +#define CMD_RSPNS_48B 0x00030000 +#define TM_MULTI_BLOCK 0x00000020 +#define TM_DAT_DIR_HC 0x00000000 +#define TM_DAT_DIR_CH 0x00000010 +#define TM_AUTO_CMD23 0x00000008 +#define TM_AUTO_CMD12 0x00000004 +#define TM_BLKCNT_EN 0x00000002 +#define TM_MULTI_DATA (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN) + +#define RCA_NO 1 +#define RCA_YES 2 + +// INTERRUPT register settings +#define INT_AUTO_ERROR 0x01000000 +#define INT_DATA_END_ERR 0x00400000 +#define INT_DATA_CRC_ERR 0x00200000 +#define INT_DATA_TIMEOUT 0x00100000 +#define INT_INDEX_ERROR 0x00080000 +#define INT_END_ERROR 0x00040000 +#define INT_CRC_ERROR 0x00020000 +#define INT_CMD_TIMEOUT 0x00010000 +#define INT_ERR 0x00008000 +#define INT_ENDBOOT 0x00004000 +#define INT_BOOTACK 0x00002000 +#define INT_RETUNE 0x00001000 +#define INT_CARD 0x00000100 +#define INT_READ_RDY 0x00000020 +#define INT_WRITE_RDY 0x00000010 +#define INT_BLOCK_GAP 0x00000004 +#define INT_DATA_DONE 0x00000002 +#define INT_CMD_DONE 0x00000001 +#define INT_ERROR_MASK (INT_CRC_ERROR|INT_END_ERROR|INT_INDEX_ERROR| \ + INT_DATA_TIMEOUT|INT_DATA_CRC_ERR|INT_DATA_END_ERR| \ + INT_ERR|INT_AUTO_ERROR) +#define INT_ALL_MASK (INT_CMD_DONE|INT_DATA_DONE|INT_READ_RDY|INT_WRITE_RDY|INT_ERROR_MASK) + +#define EMMC_ARG2 (0x00) +#define EMMC_BLKSIZECNT (0x04) +#define EMMC_ARG1 (0x08) +#define EMMC_CMDTM (0x0c) +#define EMMC_RESP0 (0x10) +#define EMMC_RESP1 (0x14) +#define EMMC_RESP2 (0x18) +#define EMMC_RESP3 (0x1c) +#define EMMC_DATA (0x20) +#define EMMC_STATUS (0x24) +#define EMMC_CONTROL0 (0x28) +#define EMMC_CONTROL1 (0x2c) +#define EMMC_INTERRUPT (0x30) +#define EMMC_IRPT_MASK (0x34) +#define EMMC_IRPT_EN (0x38) +#define EMMC_CONTROL2 (0x3c) +#define EMMC_BOOT_TIMEOUT (0x70) +#define EMMC_EXRDFIFO_EN (0x84) +#define EMMC_SPI_INT_SPT (0xf0) +#define EMMC_SLOTISR_VER (0xfc) + +// CONTROL register settings +#define C0_SPI_MODE_EN 0x00100000 +#define C0_HCTL_HS_EN 0x00000004 +#define C0_HCTL_DWITDH 0x00000002 + +#define C1_SRST_DATA 0x04000000 +#define C1_SRST_CMD 0x02000000 +#define C1_SRST_HC 0x01000000 +#define C1_TOUNIT_DIS 0x000f0000 +#define C1_TOUNIT_MAX 0x000e0000 +#define C1_CLK_GENSEL 0x00000020 +#define C1_CLK_EN 0x00000004 +#define C1_CLK_STABLE 0x00000002 +#define C1_CLK_INTLEN 0x00000001 + +#define FREQ_SETUP 400000 // 400 Khz +#define FREQ_NORMAL 25000000 // 25 Mhz + +// SLOTISR_VER values +#define HOST_SPEC_NUM 0x00ff0000 +#define HOST_SPEC_NUM_SHIFT 16 +#define HOST_SPEC_V3 2 +#define HOST_SPEC_V2 1 +#define HOST_SPEC_V1 0 + +// STATUS register settings +#define SR_DAT_LEVEL1 0x1e000000 +#define SR_CMD_LEVEL 0x01000000 +#define SR_DAT_LEVEL0 0x00f00000 +#define SR_DAT3 0x00800000 +#define SR_DAT2 0x00400000 +#define SR_DAT1 0x00200000 +#define SR_DAT0 0x00100000 +#define SR_WRITE_PROT 0x00080000 // From SDHC spec v2, BCM says reserved +#define SR_READ_AVAILABLE 0x00000800 // ???? undocumented +#define SR_WRITE_AVAILABLE 0x00000400 // ???? undocumented +#define SR_READ_TRANSFER 0x00000200 +#define SR_WRITE_TRANSFER 0x00000100 +#define SR_DAT_ACTIVE 0x00000004 +#define SR_DAT_INHIBIT 0x00000002 +#define SR_CMD_INHIBIT 0x00000001 + +#define CONFIG_MMC_USE_DMA +#define DMA_ALIGN (32U) + +#define SD_CMD_INDEX(a) ((a) << 24) +#define SD_CMD_RESERVED(a) 0xffffffff +#define SD_CMD_INDEX(a) ((a) << 24) +#define SD_CMD_TYPE_NORMAL 0x0 +#define SD_CMD_TYPE_SUSPEND (1 << 22) +#define SD_CMD_TYPE_RESUME (2 << 22) +#define SD_CMD_TYPE_ABORT (3 << 22) +#define SD_CMD_TYPE_MASK (3 << 22) +#define SD_CMD_ISDATA (1 << 21) +#define SD_CMD_IXCHK_EN (1 << 20) +#define SD_CMD_CRCCHK_EN (1 << 19) +#define SD_CMD_RSPNS_TYPE_NONE 0 // For no response +#define SD_CMD_RSPNS_TYPE_136 (1 << 16) // For response R2 (with CRC), R3,4 (no CRC) +#define SD_CMD_RSPNS_TYPE_48 (2 << 16) // For responses R1, R5, R6, R7 (with CRC) +#define SD_CMD_RSPNS_TYPE_48B (3 << 16) // For responses R1b, R5b (with CRC) +#define SD_CMD_RSPNS_TYPE_MASK (3 << 16) +#define SD_CMD_MULTI_BLOCK (1 << 5) +#define SD_CMD_DAT_DIR_HC 0 +#define SD_CMD_DAT_DIR_CH (1 << 4) +#define SD_CMD_AUTO_CMD_EN_NONE 0 +#define SD_CMD_AUTO_CMD_EN_CMD12 (1 << 2) +#define SD_CMD_AUTO_CMD_EN_CMD23 (2 << 2) +#define SD_CMD_BLKCNT_EN (1 << 1) +#define SD_CMD_DMA 1 +#define SD_RESP_NONE SD_CMD_RSPNS_TYPE_NONE +#define SD_RESP_R1 (SD_CMD_RSPNS_TYPE_48) // | SD_CMD_CRCCHK_EN) +#define SD_RESP_R1b (SD_CMD_RSPNS_TYPE_48B) // | SD_CMD_CRCCHK_EN) +#define SD_RESP_R2 (SD_CMD_RSPNS_TYPE_136) //| SD_CMD_CRCCHK_EN) +#define SD_RESP_R3 SD_CMD_RSPNS_TYPE_48 +#define SD_RESP_R4 SD_CMD_RSPNS_TYPE_136 +#define SD_RESP_R5 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN) +#define SD_RESP_R5b (SD_CMD_RSPNS_TYPE_48B | SD_CMD_CRCCHK_EN) +#define SD_RESP_R6 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN) +#define SD_RESP_R7 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN) +#define SD_DATA_READ (SD_CMD_ISDATA | SD_CMD_DAT_DIR_CH) +#define SD_DATA_WRITE (SD_CMD_ISDATA | SD_CMD_DAT_DIR_HC) +#endif diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_spi.c b/bsp/raspberry-pi/raspi3-32/driver/drv_spi.c new file mode 100644 index 0000000000..32de9970e7 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_spi.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ +#include "drv_spi.h" + +#ifdef RT_USING_SPI + +#define RPI_CORE_CLK_HZ 250000000 +#define BSP_SPI_MAX_HZ (30* 1000 *1000) +#define SPITIMEOUT 0x0FFF + +void spi_gpio_write(rt_uint8_t pin, rt_uint8_t val) +{ + if (val) + BCM283X_GPIO_GPSET(pin / 32) = 1 << (pin % 32); + else + BCM283X_GPIO_GPCLR(pin / 32) = 0 << (pin % 32); +} + +struct raspi_spi_hw_config +{ + rt_uint8_t spi_num; + raspi_gpio_pin sclk_pin; + raspi_pin_select sclk_mode; + raspi_gpio_pin mosi_pin; + raspi_pin_select mosi_mode; + raspi_gpio_pin miso_pin; + raspi_pin_select miso_mode; +#if defined (BSP_USING_SPI0_DEVICE0) || defined (BSP_USING_SPI1_DEVICE0) + raspi_gpio_pin ce0_pin; + raspi_pin_select ce0_mode; +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) || defined (BSP_USING_SPI1_DEVICE1) + raspi_gpio_pin ce1_pin; + raspi_pin_select ce1_mode; +#endif + +#if defined (BSP_USING_SPI1_DEVICE2) + raspi_gpio_pin ce2_pin; + raspi_pin_select ce2_mode; +#endif +}; + +struct raspi_spi_device +{ + char *device_name; + struct rt_spi_bus *spi_bus; + struct rt_spi_device *spi_device; + raspi_gpio_pin cs_pin; +}; + +static rt_err_t raspi_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg) +{ + RT_ASSERT(cfg != RT_NULL); + RT_ASSERT(device != RT_NULL); + rt_uint16_t divider; + + // spi clear fifo + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CLEAR; + + if (cfg->mode & RT_SPI_CPOL) + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CPOL; + + if (cfg->mode & RT_SPI_CPHA) + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CPHA; + + if (cfg->mode & RT_SPI_CS_HIGH) + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CSPOL; + + //set clk + if (cfg->max_hz > BSP_SPI_MAX_HZ) + cfg->max_hz = BSP_SPI_MAX_HZ; + + divider = (rt_uint16_t) ((rt_uint32_t) RPI_CORE_CLK_HZ / cfg->max_hz); + divider &= 0xFFFE; + + BCM283X_SPI0_CLK(BCM283X_SPI0_BASE) = divider; + + return RT_EOK; +} + +rt_uint8_t correct_order(rt_uint8_t b, rt_uint8_t flag) +{ + if (flag) + return raspi_byte_reverse_table[b]; + else + return b; +} + +static rt_err_t spi_transfernb(rt_uint8_t* tbuf, rt_uint8_t* rbuf, rt_uint32_t len, rt_uint8_t flag) +{ + rt_uint32_t TXCnt=0; + rt_uint32_t RXCnt=0; + + /* Clear TX and RX fifos */ + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (BCM283X_SPI0_CS_CLEAR & BCM283X_SPI0_CS_CLEAR); + + /* Set TA = 1 */ + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (BCM283X_SPI0_CS_TA & BCM283X_SPI0_CS_TA); + + + /* Use the FIFO's to reduce the interbyte times */ + while ((TXCnt < len) || (RXCnt < len)) + { + /* TX fifo not full, so add some more bytes */ + while (((BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_TXD)) && (TXCnt < len)) + { + BCM283X_SPI0_FIFO(BCM283X_SPI0_BASE) = correct_order(tbuf[TXCnt],flag); + TXCnt++; + } + /* Rx fifo not empty, so get the next received bytes */ + while (((BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_RXD)) && (RXCnt < len)) + { + rbuf[RXCnt] = correct_order(BCM283X_SPI0_FIFO(BCM283X_SPI0_BASE),flag); + RXCnt++; + } + } + /* Wait for DONE to be set */ + while (!(BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_DONE)); + + /* Set TA = 0, and also set the barrier */ + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (0 & BCM283X_SPI0_CS_TA); + return RT_EOK; +} + +static rt_uint32_t raspi_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->bus != RT_NULL); + RT_ASSERT(device->parent.user_data != RT_NULL); + RT_ASSERT(message->send_buf != RT_NULL || message->recv_buf != RT_NULL); + + rt_err_t res; + rt_uint8_t flag; + struct rt_spi_configuration config = device->config; + raspi_gpio_pin cs_pin = (raspi_gpio_pin)device->parent.user_data; + + if (config.mode & RT_SPI_MSB) + flag = 0; + else + flag = 1; + + if (message->cs_take) + (config.mode & RT_SPI_CS_HIGH)? + spi_gpio_write(cs_pin, 1): + spi_gpio_write(cs_pin, 0); + + /* deal data */ + res = spi_transfernb((rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, + (rt_int32_t)message->length, flag); + + if (message->cs_release) + (config.mode & RT_SPI_CS_HIGH)? + spi_gpio_write(cs_pin, 0): + spi_gpio_write(cs_pin, 1); + + if (res != RT_EOK) + return RT_ERROR; + + return message->length; +} + +rt_err_t raspi_spi_bus_attach_device(const char *bus_name, struct raspi_spi_device *device) +{ + rt_err_t ret; + RT_ASSERT(device != RT_NULL); + ret = rt_spi_bus_attach_device(device->spi_device, device->device_name, bus_name, (void *)(device->cs_pin)); + return ret; +} + +rt_err_t raspi_spi_hw_init(struct raspi_spi_hw_config *hwcfg) +{ + GPIO_FSEL(hwcfg->sclk_pin, hwcfg->sclk_mode); + GPIO_FSEL(hwcfg->miso_pin, hwcfg->miso_mode); + GPIO_FSEL(hwcfg->mosi_pin, hwcfg->mosi_mode); + +#if defined (BSP_USING_SPI0_DEVICE0) + GPIO_FSEL(hwcfg->ce0_pin, hwcfg->ce0_mode); +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) + GPIO_FSEL(hwcfg->ce1_pin, hwcfg->ce1_mode); +#endif + + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) = 0; + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) = BCM283X_SPI0_CS_CLEAR; + + //enable chip select +#if defined (BSP_USING_SPI0_DEVICE0) + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= 0; +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= 0x2; +#endif + +#if defined (BSP_USING_SPI0_DEVICE0) && defined (BSP_USING_SPI0_DEVICE1) + BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CS; +#endif + return RT_EOK; +} + +static struct rt_spi_ops raspi_spi_ops = +{ + .configure = raspi_spi_configure, + .xfer = raspi_spi_xfer +}; + +#if defined (BSP_USING_SPI0_BUS) +#define SPI0_BUS_NAME "spi0" +#define SPI0_DEVICE0_NAME "spi0.0" +#define SPI0_DEVICE1_NAME "spi0.1" + +struct rt_spi_bus spi0_bus; + +#if defined (BSP_USING_SPI0_DEVICE0) +struct rt_spi_device spi0_device0; +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) +static struct rt_spi_device spi0_device1; +#endif + +struct raspi_spi_hw_config raspi_spi0_hw = +{ + .spi_num = 0, + .sclk_pin = RPI_GPIO_P1_23, + .sclk_mode = BCM283X_GPIO_FSEL_ALT0, + .mosi_pin = RPI_GPIO_P1_19, + .mosi_mode = BCM283X_GPIO_FSEL_ALT0, + .miso_pin = RPI_GPIO_P1_21, + .miso_mode = BCM283X_GPIO_FSEL_ALT0, + +#if defined (BSP_USING_SPI0_DEVICE0) + .ce0_pin = RPI_GPIO_P1_24, + .ce0_mode = BCM283X_GPIO_FSEL_ALT0, +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) + .ce1_pin = RPI_GPIO_P1_26, + .ce1_mode = BCM283X_GPIO_FSEL_ALT0, +#endif +}; +#endif + +int rt_hw_spi_init(void) +{ + +#if defined (BSP_USING_SPI0_BUS) + raspi_spi_hw_init(&raspi_spi0_hw); + rt_spi_bus_register(&spi0_bus, SPI0_BUS_NAME, &raspi_spi_ops); + +#if defined (BSP_USING_SPI0_DEVICE0) + struct raspi_spi_device raspi_spi0_device0 = + { + .device_name = SPI0_DEVICE0_NAME, + .spi_bus = &spi0_bus, + .spi_device = &spi0_device0, + .cs_pin = raspi_spi0_hw.ce0_pin, + }; + raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device0); +#endif + +#if defined (BSP_USING_SPI0_DEVICE1) + struct raspi_spi_device raspi_spi0_device1 = + { + .device_name = SPI0_DEVICE1_NAME, + .spi_bus = &spi0_bus, + .spi_device = &spi0_device1, + .cs_pin = raspi_spi0_hw.ce1_pin, + }; + raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device1); +#endif +#endif + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_spi_init); + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_spi.h b/bsp/raspberry-pi/raspi3-32/driver/drv_spi.h new file mode 100644 index 0000000000..9e4623b327 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_spi.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_SPI_H__ +#define __DRV_SPI_H__ + +#include +#include + +//#include +#include "board.h" + +#define SPI0_BASE_ADDR (PER_BASE + BCM283X_SPI0_BASE) + +static rt_uint8_t raspi_byte_reverse_table[] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +#define SPI_CORE_CLK 250000000U +#define SPI_CS 0x00 +#define SPI_CS_LEN_LONG (1 << 25) +#define SPI_CS_DMA_LEN (1 << 24) +#define SPI_CS_CSPOL2 (1 << 23) +#define SPI_CS_CSPOL1 (1 << 22) +#define SPI_CS_CSPOL0 (1 << 21) +#define SPI_CS_RXF (1 << 20) +#define SPI_CS_RXR (1 << 19) +#define SPI_CS_TXD (1 << 18) +#define SPI_CS_RXD (1 << 17) +#define SPI_CS_DONE (1 << 16) +#define SPI_CS_LEN (1 << 13) +#define SPI_CS_REN (1 << 12) +#define SPI_CS_ADCS (1 << 11) +#define SPI_CS_INTR (1 << 10) +#define SPI_CS_INTD (1 << 9) +#define SPI_CS_DMAEN (1 << 8) +#define SPI_CS_TA (1 << 7) +#define SPI_CS_CSPOL (1 << 6) +#define SPI_CS_CLEAR_RXFIFO (1 << 5) +#define SPI_CS_CLEAR_TXFIFO (1 << 4) +#define SPI_CS_CPOL (1 << 3) +#define SPI_CS_CPHA (1 << 2) +#define SPI_CS_MASK 0x3 +#define SPI_FIFO 0x04 +#define SPI_CLK 0x08 +#define SPI_CLK_MASK 0xffff +#define SPI_DLEN 0x0c +#define SPI_DLEN_MASK 0xffff +#define SPI_LTOH 0x10 +#define SPI_LTOH_MASK 0xf +#define SPI_DC 0x14 +#define SPI_DC_RPANIC_SHIFT 24 +#define SPI_DC_RPANIC_MASK (0xff << SPI_DC_RPANIC_SHIFT) +#define SPI_DC_RDREQ_SHIFT 16 +#define SPI_DC_RDREQ_MASK (0xff << SPI_DC_RDREQ_SHIFT) +#define SPI_DC_TPANIC_SHIFT 8 +#define SPI_DC_TPANIC_MASK (0xff << SPI_DC_TPANIC_SHIFT) +#define SPI_DC_TDREQ_SHIFT 0 +#define SPI_DC_TDREQ_MASK 0xff + +int rt_hw_spi_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_timer.c b/bsp/raspberry-pi/raspi3-32/driver/drv_timer.c new file mode 100644 index 0000000000..36a4fd2baf --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_timer.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include "drv_timer.h" + +#ifdef BSP_USING_SYSTIMER + +static void raspi_systimer_init(rt_hwtimer_t *hwtimer, rt_uint32_t state) +{ + if (state == 0) + hwtimer->ops->stop(hwtimer); +} + +static rt_err_t raspi_systimer_start(rt_hwtimer_t *hwtimer, rt_uint32_t cnt, rt_hwtimer_mode_t mode) +{ + rt_err_t result = RT_EOK; + rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; + int timer_id = timer->timer_id; + + if (mode == HWTIMER_MODE_PERIOD) + timer->cnt = cnt; + else + timer->cnt = 0; + + __sync_synchronize(); + if (timer_id == 1) + { + rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1); + STIMER_C1 = STIMER_CLO + cnt; + } + else if (timer_id == 3) + { + rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3); + STIMER_C3 = STIMER_CLO + cnt; + } + else + result = -RT_ERROR; + + __sync_synchronize(); + + return result; +} + +static void raspi_systimer_stop(rt_hwtimer_t *hwtimer) +{ + rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; + int timer_id = timer->timer_id; + if (timer_id == 1) + rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_1); + else if (timer_id == 3) + rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_3); + +} + +static rt_err_t raspi_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) +{ + /* The frequency value is an immutable value. */ + if (cmd == HWTIMER_CTRL_FREQ_SET) + { + return RT_EOK; + } + else + { + return -RT_ENOSYS; + } +} + + +void rt_device_systimer_isr(int vector, void *param) +{ + + rt_hwtimer_t *hwtimer = (rt_hwtimer_t *) param; + rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; + RT_ASSERT(timer != RT_NULL); + + int timer_id = timer->timer_id; + + __sync_synchronize(); + if (timer_id == 1) + { + STIMER_CS = 0x2; + STIMER_C1 = STIMER_CLO + timer->cnt; + } + else if (timer_id == 3) + { + STIMER_CS = 0x8; + STIMER_C3 = STIMER_CLO + timer->cnt; + } + __sync_synchronize(); + + rt_device_hwtimer_isr(hwtimer); +} + +static struct rt_hwtimer_device _hwtimer1; +static struct rt_hwtimer_device _hwtimer3; + +static rt_systimer_t _systimer1; +static rt_systimer_t _systimer3; + +const static struct rt_hwtimer_ops systimer_ops = +{ + raspi_systimer_init, + raspi_systimer_start, + raspi_systimer_stop, + RT_NULL, + raspi_systimer_ctrl +}; + +static const struct rt_hwtimer_info _info = +{ + 1000000, /* the maxinum count frequency can be set */ + 1000000, /* the maxinum count frequency can be set */ + 0xFFFFFFFF, /* the maximum counter value */ + HWTIMER_CNTMODE_UP /* count mode (inc/dec) */ +}; + +#endif + +int rt_hw_systimer_init(void) +{ + +#ifdef BSP_USING_SYSTIMER + +#ifdef RT_USING_SYSTIMER1 + _systimer1.timer_id =1; + _hwtimer1.ops = &systimer_ops; + _hwtimer1.info = &_info; + rt_device_hwtimer_register(&_hwtimer1, "timer1",&_systimer1); + rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_1, rt_device_systimer_isr, &_hwtimer1, "systimer1"); + rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1); +#endif + +#ifdef RT_USING_SYSTIMER3 + _systimer3.timer_id =3; + _hwtimer3.ops = &systimer_ops; + _hwtimer3.info = &_info; + rt_device_hwtimer_register(&_hwtimer3, "timer3",&_systimer3); + rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_3, rt_device_systimer_isr, &_hwtimer3, "systimer3"); + rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3); +#endif + +#endif + + return 0; +} + +INIT_DEVICE_EXPORT(rt_hw_systimer_init); diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_timer.h b/bsp/raspberry-pi/raspi3-32/driver/drv_timer.h new file mode 100644 index 0000000000..c85d4c9d1f --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_timer.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ +#ifndef __DRV_TIMER_H__ +#define __DRV_TIMER_H__ + +#include +#include + +#include "board.h" + +typedef struct rt_systimer_device +{ + int timer_id; + rt_uint32_t cnt; +} rt_systimer_t; + +int rt_hw_systimer_init(void); + + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_uart.c b/bsp/raspberry-pi/raspi3-32/driver/drv_uart.c new file mode 100644 index 0000000000..18501b7849 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_uart.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/5/5 Bernard The first version + */ + +#include +#include +#include + +#include "board.h" +#include "drv_uart.h" + +#include + +#define AUX_BASE (0x3F000000 + 0x215000) + +struct hw_uart_device +{ + rt_uint32_t hw_base; + rt_uint32_t irqno; +}; + +static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + if (uart->hw_base == AUX_BASE) + { + rt_uint32_t value; + + /* GPIO function set */ + value = BCM283X_GPIO_GPFSEL(1); + value &= ~(7 << 12); /* GPIO14 */ + value |= 2 << 12 ; /* ALT5 */ + value &= ~(7 << 15); /* GPIO15 */ + value |= 2 << 15 ; /* ALT5 */ + BCM283X_GPIO_GPFSEL(1) = value; + + BCM283X_GPIO_GPPUD = 0; + BCM283X_GPIO_GPPUDCLK(0) = (1 << 14) | (1 << 15); + BCM283X_GPIO_GPPUDCLK(0) = 0; + + AUX_ENABLES(uart->hw_base) = 1; /* Enable UART1 */ + AUX_MU_IER_REG(uart->hw_base) = 0; /* Disable interrupt */ + AUX_MU_CNTL_REG(uart->hw_base) = 0; /* Disable Transmitter and Receiver */ + AUX_MU_LCR_REG(uart->hw_base) = 3; /* Works in 8-bit mode */ + AUX_MU_MCR_REG(uart->hw_base) = 0; /* Disable RTS */ + AUX_MU_IIR_REG(uart->hw_base) = 0xC6; /* Enable FIFO, Clear FIFO */ + AUX_MU_BAUD_REG(uart->hw_base) = 270; /* 115200 = system clock 250MHz / (8 * (baud + 1)), baud = 270 */ + AUX_MU_CNTL_REG(uart->hw_base) = 3; /* Enable Transmitter and Receiver */ + } + + return RT_EOK; +} + +static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + AUX_MU_IER_REG(uart->hw_base) = 0x0; + rt_hw_interrupt_mask(uart->irqno); + break; + + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + AUX_MU_IER_REG(uart->hw_base) = 0x1; + rt_hw_interrupt_umask(uart->irqno); + break; + } + + return RT_EOK; +} + +static int uart_putc(struct rt_serial_device *serial, char c) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + while (!(AUX_MU_LSR_REG(uart->hw_base) & 0x20)); + AUX_MU_IO_REG(uart->hw_base) = c; + + return 1; +} + +static int uart_getc(struct rt_serial_device *serial) +{ + int ch = -1; + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + if ((AUX_MU_LSR_REG(uart->hw_base) & 0x01)) + { + ch = AUX_MU_IO_REG(uart->hw_base) & 0xff; + } + + return ch; +} + +static const struct rt_uart_ops _uart_ops = +{ + uart_configure, + uart_control, + uart_putc, + uart_getc, +}; + +static void rt_hw_uart_isr(int irqno, void *param) +{ + struct rt_serial_device *serial = (struct rt_serial_device*)param; + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); +} + +#ifdef RT_USING_UART0 +/* UART device driver structure */ +static struct hw_uart_device _uart0_device = +{ + RPI_UART0_BASE, + IRQ_PBA8_UART0, +}; +static struct rt_serial_device _serial0; +#endif + +#ifdef RT_USING_UART1 +/* UART1 device driver structure */ +static struct hw_uart_device _uart1_device = +{ + AUX_BASE, + IRQ_AUX, +}; +static struct rt_serial_device _serial1; +#endif + +int rt_hw_uart_init(void) +{ + struct hw_uart_device *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + +#ifdef RT_USING_UART0 + uart = &_uart0_device; + + _serial0.ops = &_uart_ops; + _serial0.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&_serial0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); + rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart0"); +#endif + +#ifdef RT_USING_UART1 + uart = &_uart1_device; + _serial1.ops = &_uart_ops; + _serial1.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&_serial1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); + /* enable Rx and Tx of UART */ + rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial1, "uart1"); +#endif + + return 0; +} diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_uart.h b/bsp/raspberry-pi/raspi3-32/driver/drv_uart.h new file mode 100644 index 0000000000..5211c19989 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_uart.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 Bernard the first version + */ + +#ifndef DRV_UART_H__ +#define DRV_UART_H__ + +/* + * Auxiliary + */ +#define AUX_IRQ(BASE) HWREG32(BASE + 0x00) /* Auxiliary Interrupt status 3 */ +#define AUX_ENABLES(BASE) HWREG32(BASE + 0x04) /* Auxiliary enables 3bit */ +#define AUX_MU_IO_REG(BASE) HWREG32(BASE + 0x40) /* Mini Uart I/O Data 8bit */ +#define AUX_MU_IER_REG(BASE) HWREG32(BASE + 0x44) /* Mini Uart Interrupt Enable 8bit */ +#define AUX_MU_IIR_REG(BASE) HWREG32(BASE + 0x48) /* Mini Uart Interrupt Identify 8bit */ +#define AUX_MU_LCR_REG(BASE) HWREG32(BASE + 0x4C) /* Mini Uart Line Control 8bit */ +#define AUX_MU_MCR_REG(BASE) HWREG32(BASE + 0x50) /* Mini Uart Modem Control 8bit */ +#define AUX_MU_LSR_REG(BASE) HWREG32(BASE + 0x54) /* Mini Uart Line Status 8bit */ +#define AUX_MU_MSR_REG(BASE) HWREG32(BASE + 0x58) /* Mini Uart Modem Status 8bit */ +#define AUX_MU_SCRATCH(BASE) HWREG32(BASE + 0x5C) /* Mini Uart Scratch 8bit */ +#define AUX_MU_CNTL_REG(BASE) HWREG32(BASE + 0x60) /* Mini Uart Extra Control 8bit */ +#define AUX_MU_STAT_REG(BASE) HWREG32(BASE + 0x64) /* Mini Uart Extra Status 32bit */ +#define AUX_MU_BAUD_REG(BASE) HWREG32(BASE + 0x68) /* Mini Uart Baudrate 16bit */ +#define AUX_SPI0_CNTL0_REG(BASE) HWREG32(BASE + 0x80) /* SPI 1 Control register 0 32bit */ +#define AUX_SPI0_CNTL1_REG(BASE) HWREG32(BASE + 0x84) /* SPI 1 Control register 1 8bit */ +#define AUX_SPI0_STAT_REG(BASE) HWREG32(BASE + 0x88) /* SPI 1 Status 32bit */ +#define AUX_SPI0_IO_REG(BASE) HWREG32(BASE + 0x90) /* SPI 1 Data 32bit */ +#define AUX_SPI0_PEEK_REG(BASE) HWREG32(BASE + 0x94) /* SPI 1 Peek 16bit */ +#define AUX_SPI1_CNTL0_REG(BASE) HWREG32(BASE + 0xC0) /* SPI 2 Control register 0 32bit */ +#define AUX_SPI1_CNTL1_REG(BASE) HWREG32(BASE + 0xC4) /* SPI 2 Control register 1 8bit */ + +int rt_hw_uart_init(void); + +#endif /* DRV_UART_H__ */ + diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_wdt.c b/bsp/raspberry-pi/raspi3-32/driver/drv_wdt.c new file mode 100644 index 0000000000..31b242fab5 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_wdt.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ +#include "drv_wdt.h" + +#ifdef BSP_USING_WDT + +#define SECS_TO_WDOG_TICKS(x) ((x) << 16) +#define WDOG_TICKS_TO_SECS(x) ((x) >> 16) + +static struct raspi_wdt_driver bcm_wdt; + +void raspi_watchdog_init(rt_uint32_t time_init) +{ + bcm_wdt.timeout = time_init; +} + +void raspi_watchdog_start() +{ + volatile rt_uint32_t cur; + PM_WDOG = PM_PASSWORD | (SECS_TO_WDOG_TICKS(bcm_wdt.timeout) & PM_WDOG_TIME_SET); + cur = PM_RSTC; + PM_RSTC = PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET; +} + +void raspi_watchdog_stop() +{ + PM_RSTC = PM_PASSWORD | PM_RSTC_RESET; +} + +void raspi_watchdog_clr() +{ + bcm_wdt.timeout = 0; +} + +void raspi_watchdog_set_timeout(rt_uint32_t timeout_us) +{ + bcm_wdt.timeout = timeout_us; +} + +rt_uint64_t raspi_watchdog_get_timeout() +{ + return bcm_wdt.timeout; +} + +rt_uint64_t raspi_watchdog_get_timeleft() +{ + rt_uint32_t ret = PM_WDOG; + return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET); +} + +static rt_err_t raspi_wdg_init(rt_watchdog_t *wdt) +{ + /*init for 10S*/ + raspi_watchdog_init(1000000); + raspi_watchdog_start(); + raspi_watchdog_stop(); + return RT_EOK; +} + +static rt_err_t raspi_wdg_control(rt_watchdog_t *wdt, int cmd, void *arg) +{ + rt_uint64_t timeout_us = 0; + switch (cmd) + { + case RT_DEVICE_CTRL_WDT_SET_TIMEOUT: + timeout_us = *((rt_uint32_t *)arg) * 1000000; + if (timeout_us >= 0xFFFFFFFF) + timeout_us = 0xFFFFFFFF; + raspi_watchdog_set_timeout((rt_uint32_t)timeout_us); + break; + case RT_DEVICE_CTRL_WDT_GET_TIMEOUT: + timeout_us = raspi_watchdog_get_timeout(); + *((rt_uint32_t *)arg) = timeout_us / 1000000; + break; + case RT_DEVICE_CTRL_WDT_GET_TIMELEFT: + timeout_us = raspi_watchdog_get_timeleft(); + *((rt_uint32_t *)arg) = timeout_us / 1000000; + break; + case RT_DEVICE_CTRL_WDT_KEEPALIVE: + raspi_watchdog_clr(); + break; + case RT_DEVICE_CTRL_WDT_START: + raspi_watchdog_start(); + break; + case RT_DEVICE_CTRL_WDT_STOP: + raspi_watchdog_stop(); + break; + default: + return RT_EIO; + } + return RT_EOK; +} + +static const struct rt_watchdog_ops raspi_wdg_pos = +{ + raspi_wdg_init, + raspi_wdg_control, +}; + +static rt_watchdog_t raspi_wdg; + +int rt_hw_wdt_init(void) +{ + raspi_wdg.ops = &raspi_wdg_pos; + rt_hw_watchdog_register(&raspi_wdg, "wdg", 0, RT_NULL); + return RT_EOK; +} + +INIT_DEVICE_EXPORT(rt_hw_wdt_init); +#endif /*BSP_USING_WDT */ diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_wdt.h b/bsp/raspberry-pi/raspi3-32/driver/drv_wdt.h new file mode 100644 index 0000000000..0b59ab79f3 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_wdt.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_WDT_H__ +#define __DRV_WDT_H__ + +#include +#include + +#include "board.h" + +struct raspi_wdt_driver +{ + rt_uint32_t timeout; +}; + +int rt_hw_wdt_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/driver/mbox.c b/bsp/raspberry-pi/raspi3-32/driver/mbox.c new file mode 100644 index 0000000000..bbd5183aa8 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/mbox.c @@ -0,0 +1,54 @@ +/* + * File : mbox.c + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-29 zdzn first version + */ + +/* mailbox message buffer */ +#include "mbox.h" +#include "mmu.h" + +volatile unsigned int *mbox = (volatile unsigned int *) MBOX_ADDR; +/** + * Make a mailbox call. Returns 0 on failure, non-zero on success + */ +void init_mbox_mmu_map() +{ + rt_hw_change_mmu_table(MBOX_ADDR, 96, MBOX_ADDR, STRONG_ORDER_MEM); +} + +int mbox_call(unsigned char ch, int mmu_enable) +{ + unsigned int r = (((MBOX_ADDR)&~0xF) | (ch&0xF)); + if (mmu_enable) + r = BUS_ADDRESS(r); + /* wait until we can write to the mailbox */ + do + { + asm volatile("nop"); + } while (*MBOX_STATUS & MBOX_FULL); + /* write the address of our message to the mailbox with channel identifier */ + *MBOX_WRITE = r; + /* now wait for the response */ + while (1) + { + /* is there a response? */ + do + { + asm volatile("nop"); + } + while (*MBOX_STATUS & MBOX_EMPTY); + /* is it a response to our message? */ + if (r == *MBOX_READ) + { + /* is it a valid successful response? */ + return mbox[1] == MBOX_RESPONSE; + } + } + return 0; +} diff --git a/bsp/raspberry-pi/raspi3-32/driver/mbox.h b/bsp/raspberry-pi/raspi3-32/driver/mbox.h new file mode 100644 index 0000000000..5c59fd608c --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/mbox.h @@ -0,0 +1,63 @@ +/* + * File : mbox.h + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-29 zdzn first version + */ + +#ifndef __MBOX_H__ +#define __MBOX_H__ + +/* a properly aligned buffer */ +extern volatile unsigned int* mbox; + +#define MBOX_REQUEST 0 + +/* channels */ +#define MBOX_CH_POWER 0 +#define MBOX_CH_FB 1 +#define MBOX_CH_VUART 2 +#define MBOX_CH_VCHIQ 3 +#define MBOX_CH_LEDS 4 +#define MBOX_CH_BTNS 5 +#define MBOX_CH_TOUCH 6 +#define MBOX_CH_COUNT 7 +#define MBOX_CH_PROP 8 + +/* tags */ +#define MBOX_TAG_SETPOWER 0x28001 +#define MBOX_TAG_SETCLKRATE 0x38002 +#define MBOX_GET_MAC_ADDRESS 0x10003 +#define MBOX_GET_CLOCK_RATE 0x30002 +#define MBOX_SET_CLOCK_RATE 0x38002 +#define MBOX_TAG_LAST 0 + +#define MMIO_BASE 0x3F000000 +#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880) +#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0)) +#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10)) +#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14)) +#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18)) +#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C)) +#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20)) +#define MBOX_RESPONSE 0x80000000 +#define MBOX_FULL 0x80000000 +#define MBOX_EMPTY 0x40000000 + +#define DEVICE_ID_SD_CARD 0 +#define DEVICE_ID_USB_HCD 3 +#define POWER_STATE_OFF (0 << 0) +#define POWER_STATE_ON (1 << 0) +#define POWER_STATE_WAIT (1 << 1) +#define POWER_STATE_NO_DEVICE (1 << 1) // in response +#define MMU_ENABLE 1 +#define MMU_DISABLE 0 + +#define MBOX_ADDR 0xc00000 + +int mbox_call(unsigned char ch, int mmu_enable); +#endif diff --git a/bsp/raspberry-pi/raspi3-32/driver/raspi.h b/bsp/raspberry-pi/raspi3-32/driver/raspi.h new file mode 100644 index 0000000000..19daa3541d --- /dev/null +++ b/bsp/raspberry-pi/raspi3-32/driver/raspi.h @@ -0,0 +1,432 @@ +/* + * File : rsapi.h + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __RASPI_H__ +#define __RASPI_H__ + +/* define for bcm283x*/ +typedef enum +{ + BCM_GPIO_PIN_0 = 0, + BCM_GPIO_PIN_1, + BCM_GPIO_PIN_2, + BCM_GPIO_PIN_3, + BCM_GPIO_PIN_4, + BCM_GPIO_PIN_5, + BCM_GPIO_PIN_6, + BCM_GPIO_PIN_7, + BCM_GPIO_PIN_8, + BCM_GPIO_PIN_9, + BCM_GPIO_PIN_10, + BCM_GPIO_PIN_11, + BCM_GPIO_PIN_12, + BCM_GPIO_PIN_13, + BCM_GPIO_PIN_14, + BCM_GPIO_PIN_15, + BCM_GPIO_PIN_16, + BCM_GPIO_PIN_17, + BCM_GPIO_PIN_18, + BCM_GPIO_PIN_19, + BCM_GPIO_PIN_20, + BCM_GPIO_PIN_21, + BCM_GPIO_PIN_22, + BCM_GPIO_PIN_23, + BCM_GPIO_PIN_24, + BCM_GPIO_PIN_25, + BCM_GPIO_PIN_26, + BCM_GPIO_PIN_27, + BCM_GPIO_PIN_28, + BCM_GPIO_PIN_29, + BCM_GPIO_PIN_30, + BCM_GPIO_PIN_31, + BCM_GPIO_PIN_32, + BCM_GPIO_PIN_33, + BCM_GPIO_PIN_34, + BCM_GPIO_PIN_35, + BCM_GPIO_PIN_36, + BCM_GPIO_PIN_37, + BCM_GPIO_PIN_38, + BCM_GPIO_PIN_39, + BCM_GPIO_PIN_40, + BCM_GPIO_PIN_41, + BCM_GPIO_PIN_42, + BCM_GPIO_PIN_43, + BCM_GPIO_PIN_44, + BCM_GPIO_PIN_45, + BCM_GPIO_PIN_46, + BCM_GPIO_PIN_47, + BCM_GPIO_PIN_48, + BCM_GPIO_PIN_49, + BCM_GPIO_PIN_50, + BCM_GPIO_PIN_51, + BCM_GPIO_PIN_52, + BCM_GPIO_PIN_53, + BCM_GPIO_PIN_NULL, +} bcm_gpio_pin; + +typedef enum +{ + BCM283X_GPIO_FSEL_INPT = 0x00, /*!< Input 0b000 */ + BCM283X_GPIO_FSEL_OUTP = 0x01, /*!< Output 0b001 */ + BCM283X_GPIO_FSEL_ALT0 = 0x04, /*!< Alternate function 0 0b100 */ + BCM283X_GPIO_FSEL_ALT1 = 0x05, /*!< Alternate function 1 0b101 */ + BCM283X_GPIO_FSEL_ALT2 = 0x06, /*!< Alternate function 2 0b110, */ + BCM283X_GPIO_FSEL_ALT3 = 0x07, /*!< Alternate function 3 0b111 */ + BCM283X_GPIO_FSEL_ALT4 = 0x03, /*!< Alternate function 4 0b011 */ + BCM283X_GPIO_FSEL_ALT5 = 0x02, /*!< Alternate function 5 0b010 */ + BCM283X_GPIO_FSEL_MASK = 0x07 /*!< Function select bits mask 0b111 */ +} gpio_function_select; + +typedef enum +{ + BCM283X_GPIO_PUD_OFF = 0x00, /*!< Off ? disable pull-up/down 0b00 */ + BCM283X_GPIO_PUD_DOWN = 0x01, /*!< Enable Pull Down control 0b01 */ + BCM283X_GPIO_PUD_UP = 0x02 /*!< Enable Pull Up control 0b10 */ +} gpio_pud_mode; + +#define BCM283X_CORE_CLK_HZ 250000000 /* 50 MHz */ + +/* Base Address */ +#define PER_BASE (0x3F000000) +#define PER_BASE_40000000 (0x40000000) +//#define BCM283X_PERI_BASE (0x3F000000) +//#define BCM283X_PER_BASE_40000000 (0x40000000) + +/* Base Address Registers Offset */ +#define ST_BASE_OFFSET (0x003000) +#define GPIO_PAD_OFFSET (0x100000) +#define CLOCK_BASE_OFFSET (0x101000) +#define GPIO_BASE_OFFSET (0x200000) +#define SPI0_BASE_OFFSET (0x204000) +#define BSC0_BASE_OFFSET (0x205000) +#define GPIO_PWM_OFFSET (0x20C000) +#define AUX_BASE_OFFSET (0x215000) +#define SPI1_BASE_OFFSET (0x215080) +#define SPI2_BASE_OFFSET (0x2150C0) +#define BSC1_BASE_OFFSET (0x804000) +#define BSC2_BASE_OFFSET (0x805000) + +/* IRQ */ +#define IRQ_SYSTEM_TIMER_0 0 +#define IRQ_SYSTEM_TIMER_1 1 +#define IRQ_SYSTEM_TIMER_2 2 +#define IRQ_SYSTEM_TIMER_3 3 +#define IRQ_USB 9 +#define IRQ_AUX 29 +#define IRQ_PCM 55 +#define IRQ_ARM_TIMER 64 +#define IRQ_ARM_MAILBOX 65 + +/* Interrupt Controler */ +#define IRQ_BASE (PER_BASE + 0xB200) +#define IRQ_PEND_BASIC HWREG32(IRQ_BASE + 0x0000) +#define IRQ_PEND1 HWREG32(IRQ_BASE + 0x0004) +#define IRQ_PEND2 HWREG32(IRQ_BASE + 0x0008) +#define IRQ_FIQ_CONTROL HWREG32(IRQ_BASE + 0x000C) +#define IRQ_ENABLE1 HWREG32(IRQ_BASE + 0x0010) +#define IRQ_ENABLE2 HWREG32(IRQ_BASE + 0x0014) +#define IRQ_ENABLE_BASIC HWREG32(IRQ_BASE + 0x0018) +#define IRQ_DISABLE1 HWREG32(IRQ_BASE + 0x001C) +#define IRQ_DISABLE2 HWREG32(IRQ_BASE + 0x0020) +#define IRQ_DISABLE_BASIC HWREG32(IRQ_BASE + 0x0024) + + +/* Defines for WDT*/ +#define PM_BASE (PER_BASE + GPIO_PAD_OFFSET) +#define PM_RSTC HWREG32(PM_BASE + 0x001C) +#define PM_RSTS HWREG32(PM_BASE + 0x0020) +#define PM_WDOG HWREG32(PM_BASE + 0x0024) + +#define PM_PASSWORD 0x5a000000 +#define PM_WDOG_TIME_SET 0x000fffff +#define PM_RSTC_WRCFG_CLR 0xffffffcf +#define PM_RSTS_HADWRH_SET 0x00000040 +#define PM_RSTC_WRCFG_SET 0x00000030 +#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 +#define PM_RSTC_RESET 0x00000102 +#define PM_RSTS_PARTITION_CLR 0xfffffaaa + +/* Defines for System Timer */ +#define STIMER_BASE (PER_BASE + ST_BASE_OFFSET) +#define STIMER_CS HWREG32(STIMER_BASE + 0x0000) +#define STIMER_CLO HWREG32(STIMER_BASE + 0x0004) +#define STIMER_CHI HWREG32(STIMER_BASE + 0x0008) +#define STIMER_C0 HWREG32(STIMER_BASE + 0x000C) +#define STIMER_C1 HWREG32(STIMER_BASE + 0x0010) +#define STIMER_C2 HWREG32(STIMER_BASE + 0x0014) +#define STIMER_C3 HWREG32(STIMER_BASE + 0x0018) + +#define DELAY_MICROS(micros) \ + do{ \ + rt_uint32_t compare = STIMER_CLO + micros * 25; \ + while (STIMER_CLO < compare); \ + } while (0) \ + +/* Defines for GPIO */ +#define BCM283X_GPIO_BASE (PER_BASE + GPIO_BASE_OFFSET) +#define BCM283X_GPIO_GPFSEL(n) HWREG32(BCM283X_GPIO_BASE + 0x0000 + 0x4 * n) /* GPIO Function Select 32bit R/W */ +#define BCM283X_GPIO_GPSET(n) HWREG32(BCM283X_GPIO_BASE + 0x001C + 0x4 * n) /* GPIO Pin Output Set */ +#define BCM283X_GPIO_GPCLR(n) HWREG32(BCM283X_GPIO_BASE + 0x0028 + 0x4 * n) /* GPIO Pin Output Clear */ +#define BCM2835_GPIO_GPLEV(n) HWREG32(BCM283X_GPIO_BASE + 0x0034 + 0x4 * n) /* GPIO Pin Level */ +#define BCM283X_GPIO_GPEDS(n) HWREG32(BCM283X_GPIO_BASE + 0x0040 + 0x4 * n) /* GPIO Pin Event Detect Status */ +#define BCM283X_GPIO_GPREN(n) HWREG32(BCM283X_GPIO_BASE + 0x004c + 0x4 * n) /* GPIO Pin Rising Edge Detect Enable */ +#define BCM283X_GPIO_GPFEN(n) HWREG32(BCM283X_GPIO_BASE + 0x0058 + 0x4 * n) /* GPIO Pin Falling Edge Detect Enable */ +#define BCM283X_GPIO_GPHEN(n) HWREG32(BCM283X_GPIO_BASE + 0x0064 + 0x4 * n) /* GPIO Pin High Detect Enable */ +#define BCM283X_GPIO_GPLEN(n) HWREG32(BCM283X_GPIO_BASE + 0x0070 + 0x4 * n) /* GPIO Pin Low Detect Enable */ +#define BCM283X_GPIO_GPAREN(n) HWREG32(BCM283X_GPIO_BASE + 0x007C + 0x4 * n) /* GPIO Pin Async. Rising Edge Detect */ +#define BCM283X_GPIO_GPAFEN(n) HWREG32(BCM283X_GPIO_BASE + 0x0088 + 0x4 * n) /* GPIO Pin Async. Falling Edge Detect */ +#define BCM283X_GPIO_GPPUD HWREG32(BCM283X_GPIO_BASE + 0x0094) /* GPIO Pin Pull-up/down Enable */ +#define BCM283X_GPIO_GPPUDCLK(n) HWREG32(BCM283X_GPIO_BASE + 0x0098 + 0x4 * n) /* GPIO Pin Pull-up/down Enable Clock */ + +#define GPIO_FSEL_NUM(pin) (pin/10) +#define GPIO_FSEL_SHIFT(pin) ((pin%10)*3) +#define GPIO_FSEL(pin, mode) \ + do{ \ + __sync_synchronize(); \ + BCM283X_GPIO_GPFSEL(GPIO_FSEL_NUM(pin)) |= ((mode & BCM283X_GPIO_FSEL_MASK) << GPIO_FSEL_SHIFT(pin)); \ + } while (0) \ + +/* Defines for I2C */ +#define BCM283X_BSC0_BASE (PER_BASE + BSC0_BASE_OFFSET) //for i2c0 +#define BCM283X_BSC1_BASE (PER_BASE + BSC1_BASE_OFFSET) //for i2c1 +#define BCM283X_BSC2_BASE (PER_BASE + BSC2_BASE_OFFSET) //for hdmi i2c not use + +#define BCM283X_BSC_C(BASE) HWREG32(BASE + 0x0000) /* BSC Master Control */ +#define BCM283X_BSC_S(BASE) HWREG32(BASE + 0x0004) /* BSC Master Status */ +#define BCM283X_BSC_DLEN(BASE) HWREG32(BASE + 0x0008) /* BSC Master Data Length */ +#define BCM283X_BSC_A(BASE) HWREG32(BASE + 0x000c) /* BSC Master Slave Address */ +#define BCM283X_BSC_FIFO(BASE) HWREG32(BASE + 0x0010) /* BSC Master Data FIFO */ +#define BCM283X_BSC_DIV(BASE) HWREG32(BASE + 0x0014) /* BSC Master Clock Divider */ +#define BCM283X_BSC_DEL(BASE) HWREG32(BASE + 0x0018) /* BSC Master Data Delay */ +#define BCM283X_BSC_CLKT(BASE) HWREG32(BASE + 0x001c) /* BSC Master Clock Stretch Timeout */ + +/* Register masks for C Register */ +#define BSC_C_I2CEN 0x00008000 /* I2C Enable, 0 = disabled, 1 = enabled */ +#define BSC_C_INTR 0x00000400 /* Interrupt on RX */ +#define BSC_C_INTT 0x00000200 /* Interrupt on TX */ +#define BSC_C_INTD 0x00000100 /* Interrupt on DONE */ +#define BSC_C_ST 0x00000080 /* Start transfer, 1 = Start a new transfer */ +#define BSC_C_CLEAR_1 0x00000020 /* Clear FIFO Clear */ +#define BSC_C_CLEAR_2 0x00000010 /* Clear FIFO Clear */ +#define BSC_C_READ 0x00000001 /* Read transfer */ + +/* Register masks for S Register */ +#define BSC_S_CLKT 0x00000200 /* Clock stretch timeout */ +#define BSC_S_ERR 0x00000100 /* ACK error */ +#define BSC_S_RXF 0x00000080 /* RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full */ +#define BSC_S_TXE 0x00000040 /* TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full */ +#define BSC_S_RXD 0x00000020 /* RXD FIFO contains data */ +#define BSC_S_TXD 0x00000010 /* TXD FIFO can accept data */ +#define BSC_S_RXR 0x00000008 /* RXR FIFO needs reading (full) */ +#define BSC_S_TXW 0x00000004 /* TXW FIFO needs writing (full) */ +#define BSC_S_DONE 0x00000002 /* Transfer DONE */ +#define BSC_S_TA 0x00000001 /* Transfer Active */ + +#define BSC_FIFO_SIZE (16) /* BSC FIFO size */ + +/* Defines for SPI */ +#define BCM283X_SPI0_BASE (PER_BASE + SPI0_BASE_OFFSET) +#define BCM283X_SPI1_BASE (PER_BASE + SPI1_BASE_OFFSET) +#define BCM283X_SPI2_BASE (PER_BASE + SPI2_BASE_OFFSET) + +#define BCM283X_SPI0_CS(BASE) HWREG32(BASE + 0x0000) /* SPI Master Control and Status */ +#define BCM283X_SPI0_FIFO(BASE) HWREG32(BASE + 0x0004) /* SPI Master TX and RX FIFOs */ +#define BCM283X_SPI0_CLK(BASE) HWREG32(BASE + 0x0008) /* SPI Master Clock Divider */ +#define BCM283X_SPI0_DLEN(BASE) HWREG32(BASE + 0x000c) /* SPI Master Data Length */ +#define BCM283X_SPI0_LTOH(BASE) HWREG32(BASE + 0x0010) /* SPI LOSSI mode TOH */ +#define BCM283X_SPI0_DC(BASE) HWREG32(BASE + 0x0014) /* SPI DMA DREQ Controls */ + +/* Register masks for SPI0_CS */ +#define BCM283X_SPI0_CS_LEN_LONG 0x02000000 /* Enable Long data word in Lossi mode if DMA_LEN is set */ +#define BCM283X_SPI0_CS_DMA_LEN 0x01000000 /* Enable DMA mode in Lossi mode */ +#define BCM283X_SPI0_CS_CSPOL2 0x00800000 /* Chip Select 2 Polarity */ +#define BCM283X_SPI0_CS_CSPOL1 0x00400000 /* Chip Select 1 Polarity */ +#define BCM283X_SPI0_CS_CSPOL0 0x00200000 /* Chip Select 0 Polarity */ +#define BCM283X_SPI0_CS_RXF 0x00100000 /* RXF - RX FIFO Full */ +#define BCM283X_SPI0_CS_RXR 0x00080000 /* RXR RX FIFO needs Reading (full) */ +#define BCM283X_SPI0_CS_TXD 0x00040000 /* TXD TX FIFO can accept Data */ +#define BCM283X_SPI0_CS_RXD 0x00020000 /* RXD RX FIFO contains Data */ +#define BCM283X_SPI0_CS_DONE 0x00010000 /* Done transfer Done */ +#define BCM283X_SPI0_CS_TE_EN 0x00008000 /* Unused */ +#define BCM283X_SPI0_CS_LMONO 0x00004000 /* Unused */ +#define BCM283X_SPI0_CS_LEN 0x00002000 /* LEN LoSSI enable */ +#define BCM283X_SPI0_CS_REN 0x00001000 /* REN Read Enable */ +#define BCM283X_SPI0_CS_ADCS 0x00000800 /* ADCS Automatically Deassert Chip Select */ +#define BCM283X_SPI0_CS_INTR 0x00000400 /* INTR Interrupt on RXR */ +#define BCM283X_SPI0_CS_INTD 0x00000200 /* INTD Interrupt on Done */ +#define BCM283X_SPI0_CS_DMAEN 0x00000100 /* DMAEN DMA Enable */ +#define BCM283X_SPI0_CS_TA 0x00000080 /* Transfer Active */ +#define BCM283X_SPI0_CS_CSPOL 0x00000040 /* Chip Select Polarity */ +#define BCM283X_SPI0_CS_CLEAR 0x00000030 /* Clear FIFO Clear RX and TX */ +#define BCM283X_SPI0_CS_CLEAR_RX 0x00000020 /* Clear FIFO Clear RX */ +#define BCM283X_SPI0_CS_CLEAR_TX 0x00000010 /* Clear FIFO Clear TX */ +#define BCM283X_SPI0_CS_CPOL 0x00000008 /* Clock Polarity */ +#define BCM283X_SPI0_CS_CPHA 0x00000004 /* Clock Phase */ +#define BCM283X_SPI0_CS_CS 0x00000003 /* Chip Select */ + +/* ARM Timer */ +#define ARM_TIMER_BASE (PER_BASE + 0xB000) +#define ARM_TIMER_LOAD HWREG32(ARM_TIMER_BASE + 0x400) +#define ARM_TIMER_VALUE HWREG32(ARM_TIMER_BASE + 0x404) +#define ARM_TIMER_CTRL HWREG32(ARM_TIMER_BASE + 0x408) +#define ARM_TIMER_IRQCLR HWREG32(ARM_TIMER_BASE + 0x40C) +#define ARM_TIMER_RAWIRQ HWREG32(ARM_TIMER_BASE + 0x410) +#define ARM_TIMER_MASKIRQ HWREG32(ARM_TIMER_BASE + 0x414) +#define ARM_TIMER_RELOAD HWREG32(ARM_TIMER_BASE + 0x418) +#define ARM_TIMER_PREDIV HWREG32(ARM_TIMER_BASE + 0x41C) +#define ARM_TIMER_CNTR HWREG32(ARM_TIMER_BASE + 0x420) + +/* ARM Core Timer */ +#define C0TIMER_INTCTL HWREG32(PER_BASE_40000000 + 0x40) /* Core0 timers Interrupt control */ +#define C1TIMER_INTCTL HWREG32(PER_BASE_40000000 + 0x44) /* Core1 timers Interrupt control */ +#define C2TIMER_INTCTL HWREG32(PER_BASE_40000000 + 0x48) /* Core2 timers Interrupt control */ +#define C3TIMER_INTCTL HWREG32(PER_BASE_40000000 + 0x4C) /* Core3 timers Interrupt control */ +#define CORETIMER_INTCTL(n) HWREG32(PER_BASE_40000000 + 0x40 + n*4) /* Coren timers Interrupt control */ + +/* ARM Core Mailbox interrupt */ +#define C0MB_INTCTL HWREG32(PER_BASE_40000000 + 0x50) /* Core0 Mailboxes Interrupt control */ +#define C1MB_INTCTL HWREG32(PER_BASE_40000000 + 0x54) /* Core1 Mailboxes Interrupt control */ +#define C2MB_INTCTL HWREG32(PER_BASE_40000000 + 0x58) /* Core2 Mailboxes Interrupt control */ +#define C3MB_INTCTL HWREG32(PER_BASE_40000000 + 0x5C) /* Core3 Mailboxes Interrupt control */ +#define COREMB_INTCTL(n) HWREG32(PER_BASE_40000000 + 0x50 + 4*n) /* Coren Mailboxes Interrupt control */ + +/* ARM Core IRQ/FIQ status */ +#define C0_IRQSOURCE HWREG32(PER_BASE_40000000 + 0x60) /* Core0 IRQ Source */ +#define C1_IRQSOURCE HWREG32(PER_BASE_40000000 + 0x64) /* Core1 IRQ Source */ +#define C2_IRQSOURCE HWREG32(PER_BASE_40000000 + 0x68) /* Core2 IRQ Source */ +#define C3_IRQSOURCE HWREG32(PER_BASE_40000000 + 0x6C) /* Core3 IRQ Source */ +#define C0_FIQSOURCE HWREG32(PER_BASE_40000000 + 0x70) /* Core0 FIQ Source */ +#define C1_FIQSOURCE HWREG32(PER_BASE_40000000 + 0x74) /* Core1 FIQ Source */ +#define C2_FIQSOURCE HWREG32(PER_BASE_40000000 + 0x78) /* Core2 FIQ Source */ +#define C3_FIQSOURCE HWREG32(PER_BASE_40000000 + 0x7C) /* Core3 FIQ Source */ +#define CORE_IRQSOURCE(n) HWREG32(PER_BASE_40000000 + 0x60+ n*0x4) +#define CORE_FIQSOURCE(n) HWREG32(PER_BASE_40000000 + 0x70+ n*0x4) + +#define CORE_MAILBOX3_SET(n) HWREG32(PER_BASE_40000000 + 0x8C + n*0x10) +#define CORE_MAILBOX3_CLEAR(n) HWREG32(PER_BASE_40000000 + 0xCC + n*0x10) +#define CORE_MAILBOX2_SET(n) HWREG32(PER_BASE_40000000 + 0x88 + n*0x10) +#define CORE_MAILBOX2_CLEAR(n) HWREG32(PER_BASE_40000000 + 0xC8 + n*0x10) +#define CORE_MAILBOX1_SET(n) HWREG32(PER_BASE_40000000 + 0x84 + n*0x10) +#define CORE_MAILBOX1_CLEAR(n) HWREG32(PER_BASE_40000000 + 0xC4 + n*0x10) +#define CORE_MAILBOX0_SET(n) HWREG32(PER_BASE_40000000 + 0x80 + n*0x10) +#define CORE_MAILBOX0_CLEAR(n) HWREG32(PER_BASE_40000000 + 0xC0 + n*0x10) + +/* For SMP IPI use MailBox0 */ +#define IPI_MAILBOX_SET CORE_MAILBOX0_SET +#define IPI_MAILBOX_CLEAR CORE_MAILBOX0_CLEAR +#define IPI_MAILBOX_INT_MASK (0x01) + +enum spi_bit_order +{ + BCM283X_SPI_BIT_ORDER_LSBFIRST = 0, /*!< LSB First */ + BCM283X_SPI_BIT_ORDER_MSBFIRST = 1 /*!< MSB First */ +}; + +enum spi_mode +{ + BCM283X_SPI_MODE0 = 0, /*!< CPOL = 0, CPHA = 0 */ + BCM283X_SPI_MODE1 = 1, /*!< CPOL = 0, CPHA = 1 */ + BCM283X_SPI_MODE2 = 2, /*!< CPOL = 1, CPHA = 0 */ + BCM283X_SPI_MODE3 = 3 /*!< CPOL = 1, CPHA = 1 */ +}; + +enum spi_chip_select +{ + BCM283X_SPI_CS0 = 0, /*!< Chip Select 0 */ + BCM283X_SPI_CS1 = 1, /*!< Chip Select 1 */ + BCM283X_SPI_CS2 = 2, /*!< Chip Select 2 (ie pins CS1 and CS2 are asserted) */ + BCM283X_SPI_CS_NONE = 3 /*!< No CS, control it yourself */ +}; + +enum spi_clock_divider +{ + BCM283X_SPI_CLOCK_DIVIDER_65536 = 0, /*!< 65536 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_32768 = 32768, /*!< 32768 = 7.629394531kHz on Rpi2, 12.20703125kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_16384 = 16384, /*!< 16384 = 15.25878906kHz on Rpi2, 24.4140625kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_8192 = 8192, /*!< 8192 = 30.51757813kHz on Rpi2, 48.828125kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_4096 = 4096, /*!< 4096 = 61.03515625kHz on Rpi2, 97.65625kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_2048 = 2048, /*!< 2048 = 122.0703125kHz on Rpi2, 195.3125kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_1024 = 1024, /*!< 1024 = 244.140625kHz on Rpi2, 390.625kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_512 = 512, /*!< 512 = 488.28125kHz on Rpi2, 781.25kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_256 = 256, /*!< 256 = 976.5625kHz on Rpi2, 1.5625MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_128 = 128, /*!< 128 = 1.953125MHz on Rpi2, 3.125MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_64 = 64, /*!< 64 = 3.90625MHz on Rpi2, 6.250MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_32 = 32, /*!< 32 = 7.8125MHz on Rpi2, 12.5MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_16 = 16, /*!< 16 = 15.625MHz on Rpi2, 25MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_8 = 8, /*!< 8 = 31.25MHz on Rpi2, 50MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_4 = 4, /*!< 4 = 62.5MHz on Rpi2, 100MHz on RPI3. Dont expect this speed to work reliably. */ + BCM283X_SPI_CLOCK_DIVIDER_2 = 2, /*!< 2 = 125MHz on Rpi2, 200MHz on RPI3, fastest you can get. Dont expect this speed to work reliably.*/ + BCM283X_SPI_CLOCK_DIVIDER_1 = 1 /*!< 1 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3, same as 0/65536 */ +}; + +/*redefine for raspi*/ +typedef gpio_function_select raspi_pin_select; +typedef enum +{ + RPI_GPIO_P1_01 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_02 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_03 = BCM_GPIO_PIN_2, + RPI_GPIO_P1_04 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_05 = BCM_GPIO_PIN_3, + RPI_GPIO_P1_06 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_07 = BCM_GPIO_PIN_4, + RPI_GPIO_P1_08 = BCM_GPIO_PIN_14, + RPI_GPIO_P1_09 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_10 = BCM_GPIO_PIN_15, + RPI_GPIO_P1_11 = BCM_GPIO_PIN_17, + RPI_GPIO_P1_12 = BCM_GPIO_PIN_18, + RPI_GPIO_P1_13 = BCM_GPIO_PIN_27, + RPI_GPIO_P1_14 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_15 = BCM_GPIO_PIN_22, + RPI_GPIO_P1_16 = BCM_GPIO_PIN_23, + RPI_GPIO_P1_17 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_18 = BCM_GPIO_PIN_24, + RPI_GPIO_P1_19 = BCM_GPIO_PIN_10, + RPI_GPIO_P1_20 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_21 = BCM_GPIO_PIN_9, + RPI_GPIO_P1_22 = BCM_GPIO_PIN_25, + RPI_GPIO_P1_23 = BCM_GPIO_PIN_11, + RPI_GPIO_P1_24 = BCM_GPIO_PIN_8, + RPI_GPIO_P1_25 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_26 = BCM_GPIO_PIN_7, + RPI_GPIO_P1_27 = BCM_GPIO_PIN_0, + RPI_GPIO_P1_28 = BCM_GPIO_PIN_1, + RPI_GPIO_P1_29 = BCM_GPIO_PIN_5, + RPI_GPIO_P1_30 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_31 = BCM_GPIO_PIN_6, + RPI_GPIO_P1_32 = BCM_GPIO_PIN_12, + RPI_GPIO_P1_33 = BCM_GPIO_PIN_13, + RPI_GPIO_P1_34 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_35 = BCM_GPIO_PIN_19, + RPI_GPIO_P1_36 = BCM_GPIO_PIN_16, + RPI_GPIO_P1_37 = BCM_GPIO_PIN_26, + RPI_GPIO_P1_38 = BCM_GPIO_PIN_20, + RPI_GPIO_P1_39 = BCM_GPIO_PIN_NULL, + RPI_GPIO_P1_40 = BCM_GPIO_PIN_21, +} raspi_gpio_pin; + +typedef enum +{ + BCM283X_I2C_CLOCK_DIVIDER_2500 = 2500, /* 2500 = 10us = 100 kHz */ + BCM283X_I2C_CLOCK_DIVIDER_626 = 626, /* 622 = 2.504us = 399.3610 kHz */ + BCM283X_I2C_CLOCK_DIVIDER_150 = 150, /* 150 = 60ns = 1.666 MHz (default at reset) */ + BCM283X_I2C_CLOCK_DIVIDER_148 = 148 /* 148 = 59ns = 1.689 MHz */ +} i2c_clock_divider; + +typedef enum +{ + BCM283X_I2C_REASON_OK = 0x00, /* Success */ + BCM283X_I2C_REASON_ERROR_NACK = 0x01, /* Received a NACK */ + BCM283X_I2C_REASON_ERROR_CLKT = 0x02, /* Received Clock Stretch Timeout */ + BCM283X_I2C_REASON_ERROR_DATA = 0x04 /* Not all data is sent / received */ +} i2c_reason_codes; + +#endif diff --git a/bsp/raspberry-pi/raspi3-32/figures/GPIO-Pinout-Diagram-2.png b/bsp/raspberry-pi/raspi3-32/figures/GPIO-Pinout-Diagram-2.png new file mode 100644 index 0000000000000000000000000000000000000000..24238cc23d89f18fca2bc5daa5e3f62abc4c4390 GIT binary patch literal 206936 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

Z%o|Rx%#Kd+F_b7U!Lrx6>DR?QLI!sRgi(_P! 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

4u*$+h|`@e-Gj)GFo=jzn$gtyWAbtfxGW= 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 z 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 CGth|u literal 0 HcmV?d00001 diff --git a/bsp/raspberry-pi/raspi3-32/figures/raspberrypi-console.png b/bsp/raspberry-pi/raspi3-32/figures/raspberrypi-console.png new file mode 100644 index 0000000000000000000000000000000000000000..a36f6f75e050a965fe547cf190925400ce029f7f GIT binary patch literal 1356117 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 (D135-izfP(v=6_tPzPy#cFzz`uMTM!Tsqgmi* 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

*lr=?(E7vr29%h2`B+2 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 literal 0 HcmV?d00001 diff --git a/bsp/raspberry-pi/raspi3-32/figures/raspi3_b.jpg b/bsp/raspberry-pi/raspi3-32/figures/raspi3_b.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03db419bd89fb16803c1d3b4fc990ca2d662fdd9 GIT binary patch literal 184309 zcmb^YcT`hB`!))PDoByuJ4g{wI)pC0Bck*sy|>UiqDV)2OF*Pa4ZZh{NCE^1U8w;A zA{{~S#OL|m_jleuzIE1F>)d;1=9+u%>9Z%ZCs+P1{`~_`8X% zsHv=M{o8_CISG!7J9Ctq>4=j0C;%%`My+FVly!{V|y?SAOH{nC;_4XnKyPI z@8>UG=m0R{>E-G0&;LK=ashzJ2>?I{{>$tCjQf8KJ+$-o^}|^G!F)vQ9YA&f0G1F2 zy9N4rWAs>H45qSm`wy=FhkakYRL1CsF__fpzj*E+w*4>O{)c@rjlkHP|Fd`c55^|= zhi(6hnf_rvhoFDu0+hYHgMD3`oc-8DgoK3Hp4)rbIh-8vg4sUSS|mitj(#{|}virX*sw! zSh$#2SXusMf`v)?0RI6g0Rbrs6*(2l|7-a>2p}iGUc~u|gT(>BCda}d$ND=Azzi%l zHqO6!{l5hZ8y^Q3?*RcOmH`uiiTpofF_HLxmjT2$SO9D?9L#foRs2bDv!5K>q_WXMnTICuacuCXNmnK$ryZR>g!cJ`SUz zizddDMFyD0Q6%u-&@4`HlmKjr2;$&sjzr}WQ@$h{7vds*``b}=3JL}rZek8$;bH)XD_cK< z4uFA7Y`7nQsTrnx!grr2m9cP?DK!cdmov%o%@q;22nHXlQZa0Rx6L~o4SOeEO$|ME z4z@B{is5oD)dWrA=R9N{?4RgzXECEm!9k%J!=cHRsYWQGIc$p`;E|0fa6EGcJPQo6? znDh=X{Cp%Gv)Z^2W0j8l8(j)TTYPLAY)agE4PW#ndcq)U<|VL;@y&+^N=_0If^>Z% zGDC7W#iH3==GsVWYwYe3M0B<6rr7#wa`4ePsK+%RS!;i6Y-XsH3Axx0QE#Dg)(>WI z^I=%Lq7WQ+^rdJ!Df`6VEnjXe~Q+X2|=V~cp0c17#+*xqIZ|&t6@E|tH;Qz z#pfPeA9Eg4X#%7ggtQf<>ha&RQ%pi#-&Y=LJI0o55s*VHA{I|`6ZV}X5O|=#`S#|d{ zXxQKlh#72{n&wu>6QbT#V)Eb&kFBq-P0@aE02&0!z`C_k?K`GBLAD^ zHMb+(eIG$_l!Z2g+8yFS^yrb=sAstHBlT&{S8WSYevx|RSHEA4JYHJGV#93~a-m36 z$xyOo)Bq4Eu< zQxZaUxqUA4Wzdr8js0`q?W9$^bQ>L-&RS^Ve1tZ-P!$?HyK{MScD~LEir+Smm2a!w z1o_L%FKRngGP(_A%FIvZL6I9Oe(Y3kfJIOVU@yk+hK+9>HDG+4KDQJtR*M zK)Pp4|l4fYXFLmC&#ZxDxm+!vb?yl_aZdzEfy_)k`^Zx_7Ole*Tk z8FOK6^CxXDn;dFDr@^OgbE}z5QML>Z$m}%f;<;kk(s3#sYOc;8y^#vVED^dMxrT|> z(!n?F4mPpfOpP>jWR*-&tb9sose*)4Y!w7fqJ^Y_Oc33 z-x3qyQ{b^LN^bp;XOsOzihb?RleROVm4o)%4v%xWGNRB5tu=<6uNEaluSMO6RnbMJ zMtftRGN+`PtcnCapSjxY*4d^xkiLQ|7di1quA#$W5Epo|I%m z7pqZuF@8vab`ezi^6H>;%-FMsVRmJ7JEN?~wurE>_s+d8;0BiMP$SbqXZE|RTj$j% zN`I`-!)9;xb&J5oVFRSKrJ~n8@LHxjIp(q z>?6^I>oP{kty?>Lx47sZp|n-6f%TJiR9i_?Z~2P?a}7Ngiewx+-+;BxKBniZ0m+jl zKQ2g?2ue0@l*m2le${np4~y---~^B=O5e6CjC}-MM$2tTLzy{PlZMj zS`x};mD4+a<857=b-pbZvNw0TcVB(ZtGaSsvQSoC zwH4}Kh;IHiVNmTayCS)!fbEkYU|CxqcYJm}R|b}t*sMt$ zVI|HBO0}Iqh-c~Y6J}2}3&O9WsA5W7fm2A;PFFJJ;=qBF-+4D9qPtH3WYvv;K1A&W zeW4Sa@w`Z7Jns>M&KzC*>8Rfi3^bYd4>iJb?htV^%2--R=#tJe5ipGNW+&&0&l^rs z&X#ac6YZ${Y_@WP9k+-6VT5o&4?d9^ZC(jUD-f1?w>iok-|d@sZa%_tGJ`${zDvyi z9=|r-08!4G&%f>*$$0cw)5+LSLXw(W1$NS2;baE4?)^10$+t3FE%5}@Wo~FL7L2C4 zqz*Bz164KPR-+s;9jCS?lEo?>wDqoXr5o5O3fU0Y0x%n;5?|!2)|Y-w31Lfv-jnaK zv;AYqJ)zPhlHpqAG8fD@@Urqec>A=QwnPhD>yD~sIwcJ7P({x%A{y07bo_M=?2=^h zIUd&*N~7bV;i61VmTtRDHXz#|K?(~!8b)^i;`ZlU*Q}_?-A{OF@KOLPE)h4TbLvJi z!2uqrm(ddA(83QLJoiIi1VhBbUZ^X?4Xaw|yvdh3)hSCbbYp#{HR2(qx6kONJ7o`- zF%mZOM-)#98!8x1Z@YePY@Tq~+Rn89YSOr=%RapFJwwT!o0w~QlnwU>fDJclrG2KR zxk$Ox>>&5oB-4f$5GOaufsXP+IqW_-aXr}R-~|j*1TIVKZSUEKxdCH0?&fNCq|Knjh*YGj||<70U~6ougKiboIfO> zC1gGn&&oH`FH3kO1&{dHLNr^RY6WL3y(8OoZTZH(PTtK2IlFOw{@bt>g}ntQdK`&s z4D;R0X5npg&}*)sk~4hV{Cz!D?dBA=TRgH*zu?;K?&9IKr?2j%#EE6JXP7M&P@L+| z3vmDT1_GS9HQI+xd-_F0$~;bhdd$j^%s1@snaEbmhE2*_=uu3<1{!MfmsQK_=sq(Eq;c1(7m^ zdgh(b`Y@@^ZL6674z2HP$@}6IdsP}7SP8epo;2!!iJ4p4Zq~9%H&15Tk7B-snXT4$ zv^{%dnIrr~KY&tOp00MloC1r@HVw5UpMmryX_fOj`aI#!DqwM_;{|uAvlG!Ru$yk+h=>Mh|q2b%@BA!CWGj% z%5z*)onfN$pp?5+6ax>UwQA)k5Vh=Zd$_Go)ej=)H6@MH_+Xg*8CNQuBCI|P78q$ClJcmhuJ-c#B9TSV08mYH~1o9JCm#Q*Uqp( z8ExCNMD8#pC4i7HnVc>+io*GMy_=;oGC%k?yOh&V`V>s;C(7AGs%2!-e4g_4^nvLS zVyEd4*|-6_Xf2nJkO?|oGX3D$Wo1!aSxmL^eP+*X21?AdZ0!Y7rj$ofD+x9G0=JK# z9nkdlquuR}y<@*B?^a3IG1)3PmO!1_1es7`Ef2vd<}YeN^z)Nt46w8ZLAK;}KQ23f zzh_;=2N|U{{b*WU5G8`7F`l|PG07TcZn-6lw6wL>g|$aL@{@c%r=YxUH!fo@T!OL~ zdBMqp^UnEwWJyd;j}?gM_6k)jd9vH+fXJc2$3 zs-{!Y0s23x&_xSjvkmjh+0K&&`u5}?Gej|IUj|JB= zdlu360YWszQxVkR+jMe%?s@N4lvVV&I(5CqxByaAHj}qe*IaES+*C`?5j36s>bYh? z0(o0;OH)j(?CR4%>olFt+s>5`FI61`!YADf*l?tbn^fA#kXJ36r)C^i&M`EC_Gvn6 z8l*#KkA~4_Aty7$R;-KXP?9J$$|T>7pNYODZ3}rr7RR>MMROvei29AO&^JH)fWJ3~ zRT&d?>Yd=CaQF;T2itYu^RR!YP)j80lG{g{+qrPWy2GM(uAKko6yPaBsHTX;H2}c2 zrKE7)TXi-1wmb52c^)1cgd#lqNcm7CS-bLE=DyeDw}rky2Ja4JI)vprHfOlWIdsWr z>ELEX;pvuH74=wghw)Og$C*F}?S|5XMcp&1xtCgO`J~w-;-1y`@@%66mJTj9OSKo` zM_kv; zpbzn^chA(H%!ay7Zceyu6Ns8zF-8 zvT_WkC#}+d$^_}q(oHiC+l}2#Ew7;xvqgxRpGsBT>}XPoic3) z&?Mx{1Fj)4(cukGmCp?yeYu6pQ~LOuzQSP!Fmy_9n4!q-B#tqUo!IfvF(~9DoDOuV zXWH8ATU(qVR8HIlp)+}6M2c4lW0(Zf^Q-m#OzD}g>&TZ8)BR~=$r9aRG2wjZe~f>wz-F`bjAQIq!~DE|L3C8COVA4De3O?NzGykTd?Ck2(%+WWoYRJKkXwO-I_W9NYobwz#WmSnlOcu%#$vFxg+b!Q&isL%^O}2XSJu>^<0m71D=2lcKfzSk+iTi7rXNpzn>DF`yFCB% zB(1WoA(>0!e1DuR3A1vyK-X8Hu-i2$x()g4x!;Sncd+-KW2Q&t=|YS;b=?m8*1H$L z%+muwhMU@`Wjg?VeDiP=rEStj?&Qfb=_AehIZvv?pfWU5mmtpa-@nJm+aS ztY&%Ttx)d`|e}~t}N9aBuL8B#dmkFgB z$|-QMZEeV%v6vZ?CAKt|b{&VTVocd}Vg#pCvZh4&+ z%Uh)3$Rf|A-i&RNV~MXRs)ZEI3tc(LVyzAY|Jq&_k)WrYtnVC8!CJMvX_p)$-Kjb& zi*SapW=A@Gy$WMUf=9I+>2A+x;eEnl0I~&n&oyQNrb9C1{?;H&2a(j-xgtHIlP9p~ z(I#nU9=sBhh={2GRg6y(6~uv4o>E|2Sgw;!?f36o0R2v@NaVs@*tn*JY=~`00Bn?s z1d_G$M759iEnKO7WbzQ4jpmkcsir(0E3WC2ID0wMdL?bN;9QH+i|?p-{Xvq5I;iVU z3+|~jIQhZ{rL11kHI#Q??xHesH*@KDIyM#?6aagu?*B`lW8Jl*KLk#^MCQ z4e2rl)JYP|Umf+)9Kow~kIsLVyUqt*G}V@vb-uFWHGOh763`LAV%fUk4_tV724=Zu z^st7zqRQJy;d13|PN^;QV-4T-+u*SlE&)|E>j%7@J?^hICMpW3>ZE^-c(h)&#h<(W z@q~nQnzV|yadX8>o!Nf)xRjxEw}W zBcEBK4WL)28<`GtXZ=`0a$3pg&Kr6^-|e=*55IO%`08qvAGEF95jDH}dum{OOR41kSAARRVB5~*0S zhDPnaD=8wVfhR)PvAN~qk@<00#cK4g_ zD?F9D_1LVM?zsF|0a9V3W{U^{tE%N@`g-DW!zjlRqn1y#6S~Bw+5tI|lgfwqfM7K3A;?U)ilw*#SW242S z>NP)g8~i*!I~_HEze~5(#Wsu|NcYX-YAPX>8G9(Xp)LaESd0VW0I<2@VsJmuAY4S| z#eZIYE#r(k+>_OR#u-@D1uHnZIuP#jTqh3Z8%iSms=>CRC@dZ#qJ4qfn~UTg&+eA>CcMeynu68ZHu?MYHZA0aw~XxS>2O5}b+#rj zYi-BYXlTAXl)5tvvs*3?Iz)F2Ev?sCR$W?|%N#R;+C1~?DmaaS4X$T_(Dy}H z{0o>A3`9&{hQ;nw_^X?F@19bOmgf~VC%=!@K}}Sr)7!CYRAS>h4bh5LG%@izUOamC z)4FLvHdrlSWnpy=N}65dmGWF%$HF9!gHs9DMZjKS*TSssIX!`k)Vt$4FO{=C#ojDI z`L>5*OChG41>LoGyp1feYr}|vk+PuIWnFcZ3{OZDA6u+(s_r5z;uv?)fG8b_m(B^=PSe! zIiJvz6i;)z`|A{whKbWO(XS&`NOLsqB(Ci$qH(|Ni4k*Ni#6hjc?J?uwHkKAzq)OI zpvR=kZ$#vxvO3nMIZ#MfIl%#(Hx<4j4Qc9fsR*oGg6;>meC|S~Xf52QjDSKdNNYO< zE<90BfNelaSlD+w$79PxAL&rCr2V%cA<3USMd)wYZ4QQU+=@M9K|V`_-2_-=9z zDZf6gm(Fdo$KCv8)s^%g>lpJk7ery_RlVC<>O)M&G<>U7>5a zKu>i<4^Pm=jij45kZ~DHQK-E77?1lZ-MiV^6g7~}FJ~F|3|e2VO#^FeKW`JO4J(Y+ zYSt~xzW*#C?(v7OjYzv=wA`f8BVc!a-J|UTgL20JZ1ns1%6gwV4yziuZVD+8m0^5A zq^9%6&jn~NQo-wG2O<`_r#VvA!iFo6JN-}tpeTk-e1CTK7f>_QrQS6wytzI#IVNif zVODV!Y@tk{$92owZUt_BjdK8JnTNDHuBVyQjjjcY-LUjfpTv8uKGvQ*j4;&&YPWTH zN_RFb*p@t|D&$l1NQKzeim$J}AHAIsUVY*>=q7IhmEkVD03S{0@$xWCt7WbmK6V>$ z%rs`Pv}mB`6gOiZ)f3Pox9{yNknRF;t3Pop&ihPP$nQep(XQJnK>g>$oDlZ@=8%Cw z`bx@@m_T` zfP2=gR7Hzn_CtGBy!LFS8koZN#>A*c?bXWXD)0yg zpXkZax5*fdjV22_4x(f~eQrp93~i}xkOqY?{d@;=aGes>T4#?J^jrONtdwkv(U3bCDse%Q=X!AZpL4y&U^}uDLwr`E6?puozXHHPcz__2;9@+su z<~tUyR~2?K)rG!gSQStnGT%5IjgM(UxME@ez{jBl*@A^P>!p_e`T-OJ7jN}P%7I1& zmP4~5iXL?oQ4RT^PEXA{YCA;N`@ZXo?SzgcNbDZ1?a!oquMUDL-MZhMR=MLq%3x(~H&L>vnQd7ooCm7FVr0c*q$NRw_csfQa zNUkDjZWm5f1$i=NCJ0AC?`{o>$iB}PjDf5M+~zNQUGzG3nymHij=wSA9LjYv&*p|y z{qXlW$DH+#9xYs0+n#(kYIZo&-g#7#7@uQpry!AzKrVWSH3&xub0}ilT0>VMn2Xccn( z2?`D+Dw*wG5MBvB6Su6jbWSN`T101tc9VQ?Xf0aY9Bn-Qmj^?ZGX^EL{K>aA#mpCo^RVHUqZO7RDFQKIkU4Ecs z@Li$1ooooG8|XdUp)5?l<$Ubn4YGDBZmG1`nccY(?D+t{(@OR1yrfs_HlIzZPNC-g zhRW71U5~x=B&lX9Qbe_G`&X|`u9!@GZd2-VKpC^>J$pVxKPz<6?tZGxku*iy*(#X$ zuGZD*jcE?%oYML=_}FaY3q1;@Jj3Tt6G)|hWM%_?8ymM-5COdYuZGN zF+Wm8Y{6DNy{dn&9>aqDw^9RnWFmMsV;tcPS5r9TMYvKesM0_g zU>5vBw)$~Ue#7jffs20*XNyJP4RyDfS6>T!4@p`M7lC?0Jw72?^PLc@roUGw9FeU( zL{P{T8WDO{pvwnUc5Oc&?wsX7hT6S=$9T9V99>qM2=?dXp@Is1NfP_Pu@ zZ~4=6q41e`Ad98=z`?z7Y^Y3TU8+3zYDGWG!tZCP89$xKk63M8r8Ey@yMHVC#Ixkc zI3fGSObR`BJnz10Ss48CO1em09en$=ERpZM(S&;NoV|i!od!MvKMMRjK8n3O>LrD9 z(z~Zc!hB&_${jg*2;hjz40}2*7a|2XLk!#m2Xk1vIE+Yxw&O;`={329w`&%qsn>I8 zG26e|YF+=|jQKsipfSlh6XF>)61{A-{B&5>u#S;P0)B36l;VZN`;NpCzBZtr1#nCe z2oDpZxpvm}*Vb4|gG&x6ekXBgR1s*euWo_T>70xI;yRuL&o3c$!|N)DK8GBqxc^8= zQ7}_Q92<|LdS3gTI4%04f7_)T=T~=)>|OczTsK)&K`z~ie;lRXNaFf2!5d#N%E|Q$Up-D#7HhWU zmEeuKOy2BtX}0T5{*2jl2sJp7oVY_gCe)fDd!jD6rW32#O)3=1lGh-5(0vfl!#!a# zzdLO5v`~NHsb!H!e&`L8pqN!{p?YV?j#k5P*V3P>=s{`l3niO0Asqm=)yc*Zw;U>T zMBvxC^hHEnsOED@|4M`3XH2tNT+VbjnI;1i01q4hR}{cmaT+iTh{800Perqsguq!@ z5x`AggWASN3i24JXf|Kams$U6XhHfI0; z^9%s!05}*5(I;DcZXp}MN<14@B|r#3^>F|Piv$25AgEU&Xl5_Q>`s*xbGfnqCHTJy zRvadP^$DNN7Jy;CV7&#jsf6LORzVOPK)8V#DC(-jiyi}EGEXq z*5SzI8sH{pz_5)J|Jh@>MgLm}=m?|oZ7@N?sQ<0|FAxLtV*oxt2tSvEf)YQED_3k_ zRFS|2qhx;zPy*oQlVLMp?*El5M*qJA`yYLY%?8sbTa5F6m+5I@3;_}IhCRyWf#b|b z*3YOo8pXvOMZpzIpp5%agHlO1?Il6^coK(DJX<^$``ecU>6ojPoC|X?atL9LBL8#u z|1a>rH5ek58i6||5!-*GbO1J(VMuzZga1$ik4qCUJlv0YrMJQGApwd607U@yf2*a4 zAxr&7qA;$a1jgY1j|k!7004|wLYR|(j0IK{fEB|;lfYz&jg5tk^8gnM_dkR+jDrin zBd4GwqhiOWX5$bN77-Owe9lS3C9d@Ng|dyeY7~a0Mt~u&Vc}sHm5m`#LpS%t;Tkur z$RP#d$VWx7B4G;9N5@Bho>^~3T2nd6_q~kFk!M8?T;5pavEJzGL*WBsWBVI-_F=5w z7ciuP^N0@Ce$?iDx16j3G$AbL`Y)ibQb8-?S>Le>zt5W>V3n`iF}X z^)dJd1*&j`V}-uNo12It{i5Ql>!5qqm96vfiJO!2lD)HYp5Nd<15p}RlU$nU>}w=O4c8cy!+D-`q* zd+-66n!W<9yh0@XNoq_{fq{(RJ>E+F zfY`k6%cGw)C2};Lweawnw)i3T2<(~iqd<(-21nKJotR{4-sf(qHRb`6y<-i2^`NBl zoKGtyopcQR_Czyle4Z(L1!59-ug@Q`k&sL{B$Ip+y$l!@jDRhrG2{K_zLj&=?S-4X zuUO_3~0geo}F6geGY=zNC-Vl>04OSj$+r_BXeoenP)lobqAaj?*yonPKZzh7mm$MWH$k_W)22X7^5MnH@B#9}ldrFfTTP^i!upo32=$we zH+!Q;Vv3)h-4*h}&(CfsKQ##a1?bD<+{$mHo}bD19G*3XL+mwgf%gjMKm1CT_H&;( z^#+E@2=QO~N-Hld4qOI9kfAc~4-fsIOG~IbIeCY581nGh()4hsEVKII$q?h=!6%%h zW)04zfx*jwHyMXN0{#LJS-0Ak0ij8kKH>eB0ZB9nW&URY)=7fl8?jh5z1?@x=O=~_ zQ*N8SNfrqmo(YaOezWYx2C>&QgU|HfB8O*BVYjxFHeaP7W1)Fxc#un{;Er|Az%>ZU z-o%MxH!aEpeAGry^8l~hl+;CEF!xwe=G$PsGV`ueaNc*%zyioFD%TO?E!YG9rCWhq zf-qhlMjhO-=BS(k>i%{tD)S9?2I~BF%+%k#MK~t9=ES_P-M+>C4g9lBre@qtv~x8F zY%lgZn)hF1Is}4TwJm2kR_Lg|9m7FJVAW+q6 z-r|)nSm4#Xl4(Y52Lz*lFc8>eQm^w9zATU6XCl1!3jsuJP^3v`Pi)Htt?2Lzr1b11 z!xh2;POfb+Nwhc}&YQQz>$>=3@uj~k$0m8r8}2(}!#t^^vKsEXJ4XaiUf8VlE7aIu zlKdoLUN&}_)nLs~q(_unu&l*BY}9SGQSEDi+2D_FcV8_li1>SyJiIzmV`E;N$1rWq z(c-O|yYXc+g+!iY(g_oR)2G*y zn`La_0Fiso`>2ZVbvUAzAK)r2K@7c~otF^ZntMVH?8e!KVa)HQIDHn3}1WvuyGfj^sRTSaiC_l~#Uc!tgVA z*!g}eU>X_GU+(w%*3NP2ZOu`9YG<`y@`}+8WjhDNK`(dFvgL`~+&9F6BI)c}3d~FE zu~`TCQtx4$mm|S>dVOy|r(J~YB!g{{oMgi5zFfK3grE)yOYtkv`qCa@_(t=@RKt*j zJnWk?xqDoztR7y;rtrQG zB;TrOqsp)Rw*zKDr@G7F`sAaH@1xTgA56&+?xWY3T(G& zFD%L*o@dSE#402<<-YZhD6b*x2R`;gQaYo62RO`FIQL3#z+@HrH2y|66Vu}BrfqSwAQNa5bKs#`E7lK9H^WwTA`A>yFM0xguNt5VI=oz?B zxZ3N*@A!|Bb{ZL4cSjhVR#eglitWLk%G$eA=!l!n= zaq+Oly&TtozHUx>Il!#Vz*I-&#hiSe^Tu04l zrX#UOcTP_mtQI#B=+c=H{?N_&CM%$tuT$Q|D*lw_#WIWxEj-=y`K!6XB(@ul@_3Ix zwLOh)VEe=8Q7*o(jF_g#`@swhS~v3K06mm~=O<`la4O@tgKG6~E8lQcqf2aZ$}0>`g`M5In1QyOZ;g z!*e%>Xt>@eZ2n1hgkdsicg^mnT8q#D*Zoumvz0)O_0B0Jj_70$29&kSi!YrTAahkc zz0nM3Sb0%lYv-%%+WQv&1vXX41H`Oh#y1BEe*%~Va=umhvkn7A6&g7CVa^aHYG=u7 z*$y#$kk#cZu6TIi66f^!ew;t6V!}CSOG1Wf!6Q*Agj8DVa@@7gc0!P&orqEHBeJPk z-e3HhC@?_Pw5ueeL~%g!+4n;kzYQDLapU@~=FFxrOVdhr%Ujy@)?3AJ^=)wmb#awx(Kc1G#!%F_rzyF!7>h&?#k3n zJoHTRu*_>*_uFlS?SR~yR}k>x{BoUPA{Ryk2Lintx;Lijj- z&Kwn0wHCWR6|)i@`Rgo2N?|;Et~~+avOQlZ&3hgO|H_RY_~An}(Cqn=T0p!3Rb}|W zebiQX7Pr+mR(TvA>7tUJl9y=ZC@DiOek*B%oBvDWsCB|YSNT1^3_HU_rqY!+r-Q&z zx+NZ&>HNE3$1xV}LTnDHy#8|>Ixxq;EtQ(ikFl>d9I|H+PIfu+4A~#VemUx*Xd=pw zz<7~DyW-$`VYntN4s5St|4W&rc%SkV7CwH%5%e}1$oJch8+XJleIg|{EoKy_v}Bt` zMO3P3lIZh8nI^v9iq|oujnopLqhyxP?^}KCrr&i|w3{gKrY+}ZPJHn@S>3-d82`Zn z0&g_pGc5rd6ps3!=&|FiJD-!2U#^kcvs^2ZFNaI-&*1$=+7r@f-TTv>p3}3ht=ar< zn%-|~40CO8$q9ph=e>Z$Wto!(Qs=r`xKIz0^#I_Z{cT0^mi!wQ6C^X zgdPE*1mXY@K>obKnQbnV%wxFy^$|@#BD>R=bNi9g8;D%Ypyu#p1-nB!E)WMp`hoyC zrPwFP#^jis^n8HBD2#)E0EbVWFzx3~pyX|z@;oG}Xc?e=wWAwaSS>!ql~5&a_~r8= znYS)jCFkLmyor=l{Lhby%K`;F?+oQ>B0c`-sDQ+z6*t+ z`4IPg{o8J@9R)mB7stj6GF*rXzujw1&#fxq9p=wI$YvVb^JA~a`}MulG`9Di0VO-< zT{K@Z*ULhcy~DC=6SYj;)vesCmP3V2MC__1VlNh-|E{9E=?ZPN{Udxd8);2j2ilmI zbvq<6SMR38bJu+BezY*mX`^Ww8imJ5clOA&Y^*~R_YjxbXw1e%Be<$^6@0FBX0H=cKJVtn zp)UfC-hb6EA0Lp5<^iW#$E1M%NMzYnG|3k}~X;p`rqXS@<3 z)vV*mZ4d7(U_5g+W>SxW!^xRwOa1(c$iYrEOd(1F4{VPLx1Y{FEW5l|qW}41%&S2U z!3RMP`j`L?k(PF25yD{mAd|bkp{r})jUVUT)nCB;ScFwiB(1Ci33KZxLO{zaqc^yu69zHlYvt*B9L0r@cIA0qRMm8Pvc6N{&ZhVMz0tBaZx)*|D|yG7cg9MyO+xhsg2^I|4ln!N+9@p zIpOFx!%0ZvkHE(9xHs{&#bk5xYZh>0K(Ezz@})xA;2Yt> z@%vb>#YmKD0{dmuoD-3_wwsTIO5t|j;XAzf)9u*rLc z9e56hBe$a?sHTF$u8K4I)=4;FMTlm%wy9r_H^dtaEj~X$8b1B*$T;YBpz+%GOb2@K zndkKp4|x^m0m1l5!)@fILE$qdouj8;5OoUOcch|8?shfW%tyikRi=b{<{3LZB_Z0@ z2yjs0gDnO7*twQj9ogUYA=-POf3HHW8f4zTcqhcpl`l9Eernlu5iKKCp&mLe{cp($|?0RqFyeJ0A5d?n;&fE3p z&wjE!p*Ehw!1Wi9$6P<4^g)m{`<+RCvd3Fc%k5X{eNTy&0IILS1lO!Ltixpr$LdHw z2{X21SOo7cG7(mS<0lcG-ZJrdDCnRFXs#ZZW`7oKw#7?uCUGENx>D&_s$hc~>p02%302F)_vH_uuf0MhgAMtoqnKsCw9v&>E?zc-su zoeJyns>i);TY48j-SiiblG;qJ{x0aQ(Fyv*m}lH=jqR&0wQ1dfry&E!pqmeKFZ}&r z8betl-m^3<1IY;&3p<|e)VKd;SX|?tV>vwJd@E99YZH}(*k5QFR#80)ce4xVm}?;y zid?)9U%q=eNSfZU{E|9H_Bt)I7R1bD`n`dA+Opire{^cWN;W(v;p=>RpZ7#|M0w6P zC9f7(ZT%9`F%MR`tnKL zSJzU>%w|tUtC0dK!ONhu%;#@Ae)Zjiw`itZoI8}4#*N^c34GjwT*nWBJO52`C2m9jSO&^{!K-x~rY zWN54mS95iXV-H*3@kDN>GTZpick>?}et=r4s*4A(cr4cz*xJzZ^JZs>4Ou; z;j3(>F@?hLCacn5KkgFo%P;TEvR(P%ZC1s}@5!w+RG1C^C-GclrD74tT>@K)y5oyJ$UvFqMR;n9)uD{b1N6zd_Twev8o!iklm>^r4@* z`Z0=OR$HL&6UzkXEU8F|6=B4>!}4(=mTdIVWRU=F(8)*P;cLxrAKtFceKcyJPU$k? ze9>Q^H6*l0nA7==Ub@>K+nxJqnZPIeh{N%PZ8T?<_y*mb&)fEciGui&zMsKgwo1pq zuT#L zWG_7K>c408fyrBeZco67v3t!?T|X?Ua29R3Fut67mL7+Ot3g=pJ4bi=1GpYN(`JDN zEi=n6JfP9RbLt}5y+-m02=M1?iQahsWwYGHC@fjD8$ivQj8EsW>{iM{kvQi0wG!WP|dY6gD4eflZ*DKAWhE9Lv}T#|n}-`!T7!Zg`fPn>QsJx$U&zI)3@|e5xo)rGkr8 z{s}wY7mrSM@>e7eM%>I{;!O z5_i73;+9b8L!6v@u<$_bd%&uG9ukm1BNu}C_jBMYgMe8S?C872>G+ihCH7E;jnXDj zBIIj@Us1yY>;~}pziIjxFq+zNhZ^jXc_fF}&44b}7v?7Ap=h{<^vah=4)m&HnADT~ zuQX2W$Xo4Zx@Zj=PoNKOEY!h+6;28+S1g-0j< zU1t-6Nxmom%aR&*!5*408@9nrC@WnVi_(%`4+e8$VI$zbkm^l*q3*h_3=tu2p<-PWvWVwu>It=$| zc-%v_2nBQ!_+fx1i_zSZs+TTLWZk@w2~%HRg$=sQdYCs|U1L9ZRPjYRC6Q<9GV2t zc3b?Iv*c(m)$w3`+>-&>V%_}2(Ua4E2xO8PgIU+}EpX?bZcz-Y{Lv1XA+`gPf_F`o z$M%DtMeE9-BjKA(6CXnSX=n{#fiK;qwkBi-_R?@irRR9eQcSVwaZUF z(7zuFkQ=K>KO+c4kt$ta(IwNew1$SxCg$p=1>Q6W!Gd&FK7`awfDnyNffTHHdS|-I zk_{dH-@#PiiLW(SLX8tk&*TRy#CXHWwcL9Xd3!;eq8ft;oP%MM+u@Mc`C)mPU+r`C zG&tKp6dZHY{bk>xjRaTxD|Hx8Xw~vW*6kjTg|M83Tic#3O!SCN6mlK4_?HPvKiUXb zR9~t-@zh_l74Htm{pOLT@>z~ns#rn93^RXze$b+EdNBrpg~02Phpfff1jw#cnWC@Q zXo~*WN;0V-aBQk2-1brvSUPsZzbz$Ms5>T!{kD1Rg0G53BtyJ!7`!(#3zTY%4@rdS z>ujzUYb!FZ(9^Du6rOxkC^eA(ZHHB5$gKUbmO>XFas`=i7nl=3J`PCJo6%9$?^tOv zTy21UX|NPo)1cT76PZ!W1!+wFM<)mD^x3#`&MVsbYtxiwk^n!-bXuq3K(6<&U-&GEz7j)Q3=8_iB|=KFwl1vKMPNI@7fqE(xt-M%TUmw~W0Tmrj zd5`0B0>>RhOARx!{!clX1vZiZ#`jWZ$-TRS@om&DyuDF2j_+_2t z;@-fqh;k$>3G*r3gilCF@!@td6rbHv5$h`Uo>JSBb>Br8>dx0yO`D*<$kiL@R~=oa zI^_KYIVrH5XP~f`se|xU>Tylf3WKRZ-r7{IIgk@&;Iiu8C6X7Vh~mdeGmmGjN8d>? zcH+^bLlMgWkzT^gRqBcLJYYlTILcaMvyP#+@BFXtA26&)*qH}LO$3y&z{VaeJLaJ z^b1>n#06;>3khERLx?xj`*5M-r8>xsOYo9gXUA*6LP&hAqBg4&d{N3CAh3#EuWMT0 zxxfy2;{M8}NAgjmw6un!G7ItSrX)-E(V`=iQkd9UGk$q+4N z3fPe4HY3TXlda9B?KXF!a2OH*)7E88NgN(Gl{)pI8O%k1FHk$^B0da^ldl8{pTWuf zv1X&=!l>j2;?_FxC&c)p6=7;)!K+<>5%3;cm;)m?|F*qC*b;G^N|TOXJ9z=!3f-$0 zm7zzppTBhs3*6i8HI8TvYssj?#AO6L74^oc@U%Dew-i}y)_k=gR_AF{d7<3?Z|%49 z7+>|=H|atK0IV?@Qr}tgl)qT9^Gy#8Qr_>4D^5W%tlK*)671*^JNq2=cYw3Gwj8(F zYwsu;mq`W9&H2E5h{TVMg6-M{KKnmUWu{47nqstn78D6_dM$A|o{+hLtlSq@8ZTOR zMpQDBXR~d}TQfTnr|U0s8)0fI?LGjK#7|WBuw71BTloeZ_r@JF)~Kn&H~4r?0W27_ zG^MRxtt)j##gp7qM+>-I&UX+>El^dKUKFh_=oFFUf&fD^=&|PPosA#);-f} zlwFHue!PM0oY@1(VLovD3zf$!+l~X{`;HCiqwfwIkCdv9j|2tfdjy&>8Jcrra2-~l ziJx}kvQyUdfI#S|q;Cl^Z!zJY(1iIUaMDezeRyn}+=;^C3FX(F^I%6hUoI|uerYbn z7lGEG@Y)5FLJ8tBkDRrr`n{wfp^^jn&zdx^OEU`w%*%SWq}C=Z-&sz@?KcZxImx#c?ajKEc|=lN)~EYTYFl=QP1<-oPI?QJ>KXxs zN^KT|WWIsQn5#O>H?w2tG^7;-Cz0n!Oux9sC~Nx;?j-UH4DHb!*~CQejr`je*|J^b zG8@_IOx1}LCi|g_gm@D z1JnAb!)0K04LeuDSHn_F{q6 z3F~pAh!*uFDI6p8Z)P`poM&92O%qI!Z;(_mYl^k|a2!~MN|KGP3E2hMmmEnad1e_l z1q5W*W>l_pK*nEWJA&W{#6;`HkGKuq+7d;5gk6#U5E6bZ{ziY|LR{(kD;6Mz0`&q@ zOOmlHu+lj^muyz(qgJ&@QK2d;b|~SKJ=nh2LD~#U)3FXdQ2fvvTPm;r73N5N>vfP& zw;nNmGi8;W9d(inUBUt=0^p;xK_XnGSDy{mtx@SsQ>a^VE2Ycs@Z=;t%9-y<*J%?nSUvk4NUuq11XsVu z3yVi6ab&`+`Wk-N-FLv-4=uLK`BtZA`NDO(~~9 zTDk!DAzH(7{oH$)P07%-d3W%re~Tu{%Kb}ii#&X`P<(~+%4pp zZU0yxFOi+JNYIJVqCjfpe&b1LEu|C3DI3@IkNQ|Q84D5ang56OdR?V3DGHK!dazEM z#xEM~KcX}*^PUMm8=N3XQj;{mAg`uUwi^r?F#Eb`)2y-gtM<7g4*dlX>TKoKqF_4?*%iS>XC$>=dl! zD2?K$c{R8ZeKd+I^3l7~WLg-zBmTi=d&$rr#2~3{>^NMdySAlHgzx*l!u0leO_X|KJw*%9CYp4T4EvqhF zn$}>wO_{4k7a7lbpGB0uB85A^=D(fOD0n#3(B)XJQR%>oz_R4v1b8&iW(N$e9nbxC z`Z;f!R45O?F2lC5Wi*OhUTbTc`#VeT_A|j?jbY4?8MVK)-=+xUkYU*)iq$bnNJNH} z3+OdCae`0%>My7MBN%$kp2w=cwSlZ85hRe)F}$=liNXgC=F#P|LxSEM_9GaURwKPJ zaM7i;OLadwd>dUcUxbUF(_Q~F@u~EUBP&x9H|wLs0H!>#s>=h4BnoW-;i`Lv#t^JE zEP6bDyHxN`)pRf&=_pI8X4^ih&Yx7wAfW&}zH~TRd%M)okX38kIH(Gao@}i6?lDlj zUftm;fF%-m`{Tf}uH|5HXp5lR)^+pK37wEHWkvc@)l4+r{z zsLU1l-0x4=+5YmkX*FYg2K%R~w#wax(FZh}OM>M{d~)b3I%O-muVGgRg{n#qLW!cW z&u}s4I8Fb%Q#l)lwbGG69C}0+xOBQo-3Qwl^i`2ElbRo5cJ)Jp`$0BnZZ2VHjF-D5 zdvRjl(^9Ao{`uDy%-u$^7JWY8Ss*l(eK>Ks6-}g@R8txmaQ<{@*}NFUU~cvWMSrlQ zT66I`KilOtUnMov_k{U#&oei`czrL1{?XIhgdZW>qPTYi41NevV`;`q{M_UKHph$L?8zmC~UZ@Z%7$dNS zS{19VWqzB{z-KL zi>#-+^RYt6IY#xh`g@~7$kFPUtgSAlW_TQSsF}c}zK1Apar-1cN9)-+{ik*aC0C(rq#5W&5CAe@%GJh*IQ?;)jh6 zQ5(K~4eZM=O@kRA)yff_R`p9o$KnOO*FO8eFA`%IZ*+NE+gn)XL15!M=O-aEb}myL zFw%CB_Ck2zu7!K9DUSSbtb1*G6o6pE^U$Bz-HsJ;+baV;0J;{;XKd|6r7LU1KxekY z+wxzZFD+-5fNH7d&Yx9cr>1Nt15>Q)0fVX~A6cE%2_N?8`~vy4!(t) z-)Lk*k1`^7xE3B0DG3){e%1q0t|^Zpl`)WbBj*<1cu847D|%mgnuv8BFWxp{>B^aQ zpkcMPVN>I{xvm2&on?pT&ZkPzkUG=k@@wky&OqnClvHoYcGDkez6q2KDv6}x4UdNf2g9?v{$gtG$CTt zl3^c(@XJ!b@~Z_kx|tbHVlIgZxE_{Wd3N9|NW)a1W8Yf%Q0OgWl?GHho+&C#olMT# z)i-HiaU`5R!?UNtIsDX~QROFwgUS*8_Ncdgx>U$Jfsd7<2~jAxj-aKFcAUnc9Anwu zM1L)di1Y9*YmRNKEknl8i;S0qAbt05(@gDy;%v6^vg3ng=?VYRnZ75PmhsMh-4xQS z=F~1z0IVnK) z3#c*Hb!?<5sg>wpgQlKfGCp84<&^yZGe3A@dbRzhS$kc&%Z-aZjKLDg;>?oby8#pngs#-y z!KQGVi&nuC+2OY**@V7&XV!Ud%$ds(>|4wbs-IqBbKy6qNPBQ3R6{4rI1#cl*NBTb%_2x<0)?E z60bw1ONa1#1Z{j|+T2!UZEJGYckvP^Tk2UsOd7mL8?~>l61%-;3pQHpq2HPPgop}6F^yZHDh#+;{X9_2}`bS9=1 z=A=8RAwe-TzErt4o30W}?M8-Eyo0yPi?u19UuObHxEUA%$z6ky+ zi;sKdXSAx8t;-lAAd0843=+32*2UIlp2#$~BqG8b3|HJ%yCm|uE165)ek-VkCFT7f zrYDI~SDQ%SeD3sIGup=~zd>8ZtnRy8K&wPYBdxlH<(RRw$I0kuz07};GM(v~6Hikv z^iF1!y~(z6y|#rL zqJ5T5{+9%+y}j#?hCI8%yX@5gOCi}me5xi=nwXR-sl{p3MoWM^cTN&`_k-tMVH#Cm ze0|6kRxmm0g|5R^FKihEXpnz|Tno~<$mv0_wV;pRoyIF1ZADh^dZ&5$h8_L3IOFe= zJ)5iH5Ixk{xIEK4qAnMo%YO(HW^OP;Ug(@6=vp4o!ME6DcDCy2_xxzx!;~C6U}%sl zj?XMuXwCzUif;40-Sp*B`2OsIS}aU57ClLed-B)z?H{J&iHw7Y%k+Lm&gGr>hg8?T z!9M9Xls<1#Re#6L8rv>?Dzo}g(X3Jcu_ApP`>pV#)&$=QEZ_fO7UnigE%j&F+3#%6t)d0g;o?NM}`F%_`fpY(P5?E0R z`qb-dTK_G*I+Xn5KzaPm4$ZF-MA7@VtdR7bL)l}1LBn7>>M-cR+Q@4GsM}VR#TMeX zT!nW6-BHLmCB~5%!?88lV~tJV*Z0htug^Fh+8NYPM7-`LJmqvRnL5Qca&Q2|8}g8b zoJO5fpL3X`O;79A0M=W(UKN--oEG?jODe;GFadW-pf3@SuLULcz_F|GmCk=v|7BEk z^7(PtDLWT*%Nu0OMAXrre>CtG@Af5!KajlH5-)zF;CFLRu4yllmpkNOL0@xX^&i5! z(CyNhmY)msBe@b0`vdK>O$2jaC}p5$?5)&)?`6Z(t~rmyK(eD-1LRUti_KKk8y>pL ztJkSI1M&||OdU_zzB->XfUy+Q%kA+aLpWXZ%1W#P)K9kT5D1Ghog@fI@ z#Xii=C~A{HA%(Z-w;y~=HL8^K%*$iF|E>vWi}9Y zxfL^?L<5$|B3WvM!=L+Wf+ZauaI-_#+DM989GOd=oVRsfyv15<#ICDMJ6$UiaSJ}0 z6k@jlh}kG!+Nf3n-wn{(l9RK`z765^uaKBgJL~NMLD5 zb^LEv>5Hsy*fkSw`V%Nxbpw@_mP-`wQDA!PI-nkk#bqSj#3T{P92FA*EK2$5`NI*VvCU&@jwSW zj3de6uE=<}PMpZ^=1`4v6I0)?QHm1J#*D2znp6@HUF{2y-FS_{JMNFs)wwtkzBvHW zA+CuzRov9BOcc>KGSmPz@0guiv|{EfdvDUFGq~T@+k-VvbDcP=j&!E6mTHhka3}36 z;ZA(-GG|_S2UuzHnDdxAFv4Hie~f3sZIBBZK9DEkPSion zy89@?aRc7X(Xu(x>{0Bga`-RB_|PdIeO@g*F+``@&6R0AEipm)hj8($gr)2@LvZv3 zD&*~;jwj-o$8;? zmun=LW9-mkKigFUJE+s#U$x46d7e~+*S8>oyYEj~MCSI-!t{&=^-2KiS<>@01xGg` z*>I$Wu>XPB+bUco#a7@_VlFx_N;AbZdg0@Nsf)$d{1S$CwSEYjxBT5;=Jx#ANL_=c zl+@41Z_(vx0x|O|I^4gZet09P85(ab-(VhRn3n#<2|_IwYBZO5iXI9-#NDCgE`a}m zpL}f3#Q@2ttD{~kJUxDEVvK3sVsF z`-&Uxg_=U{bCg=lvzr~lS)mto+R$q4`MCJ}nd<2!R)V}VzGc#6&5EDF%AWIvjZ;O3 zaqiXVi(uB=jBBL%j`h806UZogKF~PgBouDl@0>^zOnMT#&Ltzi^_WF}Ih@x-I%7@| z>K+RVp46&1OF4b`-sGf;8842xNsLHS^wnr(^ijXFgt6=N#;)XR+}=v5wjX1)J#Qe& zNNKgHm_OQ;^CCL3yXU?lRRYAS@0$!9mv}e%wwPhuN%7|krazHZ-Iz{2R=gL5CpKi$gI&-`Ijic{-??)2?3gU>Z20yVKnY86>2vp|*ULF44 zmd9}lP-1dd48G3X9~HO%J})V|6xn>%xA(i0q+UBW7!iQ4Ln<6sm{Sl>eHKGcEQSv@ zZ6nHbmk37SWYgW@XJ})~g<<((6g!Hp*Q+HngBhzXz(qHF03%XwCuh}-S!f(6>H1V_EE-Pt5A)h0wHAnV3SgNJ9eJo& zZtlMeyPO4P_-y2rD?n3q>uzI96aFEJed)Sf_Vd0bb(4N`$pf$aoPNwxneX=#0k zd`Fn&ocVa6!Kn2Qp)JXjiHCQg;bWVVR~}sMpcXS(I9Fu#D*{|wSVUQCYHjJH?A2H7 z#iH}~uvdOK9#=irI9_#Ks9aVp-^w06ZvOciJb_G2MH<3Bu~_*vXHQXPA@%m<+tA0{ zNca%w?rcg9mAE=8)w(BL6l`qYPYrt-pyl#*6;=y?lPbu_God zjNI&%H0>Wk@W31IkDt1RKS|F~K8Fp^h?=KICw|CyV&{T2O|v|a@e#oWQ3tiW`r_aK zKrK*W1>32yyP-wjp3E^y%0C28kJ2QL>KE!6R76#n%`b(5z{R!9V(L%wfg_#cOMn`? z5omkEK`P`=eadDk$BWqjoTbBGfTk_1b&n~m65Q*^dzFGsj%YQt4Fd|-cIY(?^dMQi z0Yd0Ldo7xd*o8EkirQD#oonx3uzEK)$`oZE~YhEDAloA8Y6VpVAtp= zMhVw{4(Ja0Y=XbN0qw$zCOP=URCv?KGjh_IAPxCD?#O5AE|UGg9x(57E2#H@(t&>h z6>|2uRt$klsqrj|uxn_zLJvomG#GoJxX3zop3Wnyv^ptnz*6kwAA%Y?Bs?jH|E(ys zsL!?~y^F8Ap?p)$IBU<^ul9Tlq=JuiG;_bnh=D-nBt|tNMw()7(?yxam*4?d@5H)M zz05I*(Lun_IT6@6v1H&2P8CZ|n&1CM!XG{o4_B<#=yOL5X2}K$8y5A#j}P`_+|&A? zRfQkWk=?+&$HLb6twdwR9E%8JLTTj^nY|_w-lp50vxo2rNchmC5pF7;=G*rIGl?WN zUHse=s!^P#u}V_AvLBqNm6mO@8Xjslu#EfX19+COmbD2p^YmmFg)wqOXz=pAiRp;) zjKPCTOX+ZlelMGfN$W!5Ce@SkfW;x?>v*o35CAH|-hNT?B9fFxzN{&z^beu=RTxAf zh5N%YM!lwe0!&6f>U4NkT!kYTNLI9Ab<$&e0J{PZKZu(T8)M++Rv~n_zl;ypnVWdjs`rKz%Jtbyf*H-6&&7ex z^nb?OhW>te-J&1nqGF6-+S#OjAHfwJrx(7jtb`eF%Ioy&2d-SAygp|i$6!G8z5u(s z_FyjJUrRHK?m=tQk^xnc0WaJ74Q4XCAc7$?Z$<76xOMvqW19g7qvBoG9PLakGB>tf zD%_dulWugjK3h~?524hM7d;?Y8mLCq08CB;ax0i8Y7ff-=1@fdDSTqqrT+wZmw08~yKx^=-Z1w`X ze?R^Xch2}6nkKPToW16-=^Vbr+3UT=EO4pTI?mSqgJ@GK6!?K8$A%#q@i=;V8p9nr zCz*EbapLcbvuT#EXfc(-F_?>mQ{|W80g@nuaasLC*pRN#)NIZ(aVdcm&ar4W0k(t8 z6PlXswKoAI2^Pip$3$E$Y{j9U%urK8tMwHg=FrD$*HV8CvCJ$hRGjhZ=B!_HX3;CV zZc|5_9W+$aEZ%#I_JGSRc@uizLXBAJd`FxJ&$*1yg@7o9qvZYxTEQFxO>E7Cg0ngOr5)uJTqNK?_^P&neY9{nUl}*KlKoG0i^&0Fgnqf+Iz+ zDmh41u}tqwgtupziF1XPjZwEj(kSCk{F7+;WfW#AJb>3W9O9@+-ZzB%1{ehN0h97+ z6BHV_Rx*7|IrwT#S$oiMGsN-D9+=|jus{9X^h(=lI&9q#Q&Q+A-^LQI6_^mV;gW67Kn8EvGH zd?=2E`v%%F$TZhbR9Dg*$Us(~LO!qcN4 zxPNrp;;ut3R6I-QTDZ7{2hiS)Vhe8D*68}zl3_(lA%GMPrr-_)11BtXt}A%bw@(^A zd;lGiJ3>biBZ{W#av>HPn;yb_){pI^Fj)_fCn4j77mp=b)L|`#hCxc^6Gyc%rqNDv z1-fm08D!z;L`z@*^6o5aM)&^lNhB%9!osXRdWV04fgf@-5q&tpCDqs4#J%QFXgL!X zw6JLuPXX@kQw>lt@DID8f!LC;P)~lUr!tlCSto~kKHbYD+ft%db82o)fc^tyYv&^J>dmgn*p%H|1UYPnE+SX{+IlhbNF9k3;3^!{XMgfIfjK$#@a;Df!BYg zo{4i$_m=E2^wdmD<7y$59q8$qkdW%cXq|k0Xc)b~4N0_iPIOd4h%@WPSL>BQ%ZHJA z^G_9WRYfugPUCfMtcFZ&iCB zRM`!bc|TyyUXP*d|5=3`--?X<9|G-Ysv`PYPW1_Q^MrSFxA&m%S~XoX*Tya8@zRk&zMMCyG`lnwVjSP&mB)f_gHvi!L@s61 zVqqxB6*kS3Yv**jqUqbT$orC8fID`4M*x`7WOB?shaI#AAp%op*35HGF!`qEgnVnO z{EgvyOWfN9->SYFf6E6!!7?~}8ou=NrH1KWOx`A((Rz3K{){DS=N@pds&$Uvbk2QW zwL{c(gB%UsA9bHhqiXu5uxwcV-H~;e8{|_h5IXP6Ji&Z%jhRK-F&Byb4?)jx z@+PLzWN!-&)z=deo5vYXoolN4-TJ7)bj(pAF!?%$Q-bT=K*a7DZj2jbffQxQ733`T z51|?!^Wb%jlKffoAHunq|33tqxRRHD2v1?~a1flh2yc+yAR;5d4=;kpcla+(1Onn) zTs$PI_xRMD>I9#-#6L@Ln{`hJUkT>%^U%zfUHMQlnfB*lK;opWAn!o)=E$}KI|5qz4EAK4I0h1zg--XzNpqS=1{Hpy}4}5%rS%jv)5zDaJ*j?|E&YP{Zi~v zd=Nd0ItD3QS?jl}HE9gR@fS8JWv4R(xwow&UvS@a3*_XO8^`S~yjH0EdU&hgfYlGA z!5xOqD3ML8C;T)nE8G{H)i6^_DfHAFP3?`lf9;nGob@MBw@s5s7h^BdG|QWK)XIAR zG4ML@sYQrMfATYy-*)hXXSFV$o6ZaIEobxa{K~o?oYxeVT#wZv{Iyj_pES{cWfFAN z$#1V;XL}5e)zMs!lqW^n%7SyD(aN#I0S}IAO0+LCNQ(~nz|mH%aevP$jw__|qbS2i z_zFKj)UeJJ%L;`fpnMS9fW%k=-%d?yTfAP1XIqfrlj~ayXr4uuLR~sHm zdKB;8Qo}GTLo%ByiRU^~{_IN7p=dAu*>O45A-oWTRfO4ms+D9Ifc6+V9cVTsEeiB4 zV?b_Ww83&DIC6YovUL(-w0YB@p7oN!WP{v5p!s8&QTcT&dFD%FU@Uk?npeTkTA9(^ zjvhc3dz3hHT2_QjfDgjzmt_&BE!)L*L@t~~`71!mG>L_7{{W3VyYE@xt=q{k8mzXw zYE>UNpomOlKvkDP-Dy#iIbJN=aW{%mSLPbvqDXZg;awAnwH@-#?Aer)!TVi%3i*v( zK;jHCj<-(4byku4n<;GoOI`gm-Dy1gXxqDHzz(z4U9OEX41xP$Xb)!I-ZD+PcS>{b zihVHnhp-TD(r0ZiOQHBh~^+YVH zVLS)N>|N%`;dJtHDtof-6XlI(x4;d4cRdlA&MNX3{}7gA3R+V(vy)z>Jr%i2AHc5{~4uX`Be{k4=>GpFkKRFundrP z?pXi@61~L7b}q1;Q%pJhaMH0%k?%9h{@=|PUOR{KxClHX8kyH{i{@z3sP-C+ioypx zH)TdpQP!oud}*9n{-qUA(A4!Yh2WdR7C^7Yg*j2BJv$cuXHl|#L0Jo%nARsl(~Mkg_2$Eq+$>*iK7s!(bJ(;73dxn zle|Ebr92ylE{}0f0A@*X7?%4z1GRcHkU*f#%p4il{FPa&Orx5-_Rgu0`gW^02|?Y~ zvvk?Bh(sNFMKTGXTOYctmmRf3Y)t9@gruY7{Nk_0rzi)D5_ad z*?ev}yQ9WF!*F6$>&FN0t3FHMXBn&~C4W|;7V9lJr7wuTn%&7EJ}&Ia_dh*XD=p)f zKg%Ej4du$1?*nGxtg&^ql_A|%#dNq;{;9(r@-_`rF2eK=;eCr$UP*iuT2JFPaY#-JxDb~5M0kNO*#FXhr$dWPs&iFVa+XB7U-uH^UL4lyw8!T*E7#zM@X!Xkya74xjyrpkzZJ*c3p@st4X@04a& z`tFr{qGX7G+-bJCq-<+!1*j2YTC~axvZ~BjbkvW%{^0#YhB0x>o9V{!L4&+-Kc-9+ zb*{|Yl@b}@6SeO&deT)$&C9p&Y@J~GBR74mJiB^;%UF-QVPIgLLF9gj7zoqRy-CA< zfVUv75}90=3J}Q}AYN6tHDj0PUD}qnvVOZ^^}70DTQuIiGu}HhON6XQ;8>M{iYM>v z*exEx&IK?AR`>DkSA6b@X7fK8q^@_>rDrBWb<&z@5N42C)#A*AmByhmu+qK};*DhF zKY+5Pr2ZY2(|*Z+dKZG@A#xFqAi;qeq!?y}EmSN}ctaJGEnY59<2fDQ^ag58aDRIm z3E)vwyxbHC`Cl8Z_XWMYa~e2iyu<=2;B=Gg=^`BLW9fR7!TDP{1hZ<%(Ez8N-LbWW6k8PuA{Bvjo0=~07MCT51hly)DF z7cEwR72<%jcz9l9_Fxc+`U7iaRjX_CfoE{%bXtam zoir7t%eo|v!MRr#J|Pw2Oi5{=q<*ac92v6|c~qx3nqFDG&uE?oW_mLLM{M#o#8p|c z>(GWenxEs(TO%VvB~@gVCYhF9kOLuOA0c`YI7kKw8A6{RgKV`mus4lQ;V_0jugcEg zD_C(lc4B?iNT$(hUK%m=A8$6Pc}}UMUqU1QHRaZCAn5tVBa1LfZ`vu#aW=Z|r@g06 z@0u*5h4(e@&q`i{c#H&J2F3Vl++u-7euY!L^gmWj48l%TRyxuvtmOHLjWS*`0Hci} z=ga6|PZdb8ani+qGs}t{h7e70JVucZ$Lb(T>ausQp|z7Yd+~Exg|$J#l5=-)N?@Z@ zX+H+Cd=o9bRz&`-k37&ak{VLBm|-wq5tXCv9oYDzJG$vf1^-b3z$ zT!^gqBi$v9n|3gaA1|?Jf2#(Z5~e3!ZL~!2_tEoZBCjE1lIsSiiOA7 zAHLpS8xCAC&N!8II6U5smRK{4w#H-#CjB(0NQ#?&R92rHbpw~`rovV`K5`B#j9P260d~WNZjXHL;!O#*PqBlmo4!(w@~yR_Nz0D zGhAzFnsl&+aQo8sf>X9(31=HM=aPl4$SDDl6WY%=0-i<6&Rl)&(mE%DeON58VC%0LXw9Bj{ww%ZAST!p7m$a=^b%5$i%UT zkP+L6-h-|6u&=R;doxN^syOaWxT#$MV3M-ILMUY9v;}!!_SCzA@FSm!CU~)Q=$FR+ z8!9SUdM>A87k>q|L2Jgd2cC@@BD+GDhWpiC6{U(bO(y&0-^xsx8t7B@kJ)t)ujcQ`_iCLdKt&=>J!-p^;#EX9bY!W3pzO>cIGV$W)d3(CK z(ndXJUMvKI;u}t2H8dq7K({a1BeW!kTL$eI&{Q8QVcFuE%=pk4nq5ikLjZ|*xkpIg?{VZGc#dO z#DQod^;_*FksF6qEi;c{S)DT-L9KWKVb)mrTUOPMSPQeFE0jcm)+I?%%b6isDFj2ogzZZXn_i#InucWMOe14<>7V)7n=TRdZ z46y;(t2y?lDP=b5DFh_vT6Jzut~SX;ODb{1+ggt9lu8ECy=uG=g7+E53XXit;k*qS z*w`1n^4G!)4|#cXP2R*bZK$7 zBBxg%?k8xW6L#U6GCB+E2AppVUS|LNSpGUqRz-yg*FgYv_O}t#6+SFec_nNSr9`L+ zr8?AT2s4>xz{nFq!wkImHD*FXPhlW)-XBY3``eQ+_Vhu+YDwl)0);fW!=;oevOh5b zIrxT(dZ&P)^yNChmi{IR471I%rk134f*)NM{Z7I~%hYn+c$APLYh4UZB(BBzhJHt0F zKWoN~SVI02b04>$E1???7;w!7D=s|H<(s!~#l{;X_zBDZz1|?=QoYCHeEaFMI1)9N zx;egt>ksa)Y61UKY9Rg}rG~Ll%-HJq|4nN&9x>B=a%qOn)DKKgd~$0v?tI+;pNaE1 zgwjgzSb8HS=2nIukF?lht`6VerUZu0mDMd8yjhhC2SNg=BbY5CsY9Xs`7Ces^NOT& zu(|-GTGD1UFg%6uB59ilTE=p`;r~0yXQ54Tag@Fde)5WQDQ??8ruZ@6KVWHMP_AQum_uC9x38Hp?rs6k@caC z0$w4Swy7*Si+Wy#mnabWpkIG$2v}_QNuBJk&@HHI*A~8m618>|WjNT$;AcE~VO)#- zq9Z#aMHr(=n}Vyy`w~-PSkj>e`8j-JE2{td$lsm%FllJFG>VQjRw2AgGHrQ~PRdHa zx6(~ZMvsG6K_Pr-?UoLHDTFmKkst+aH>pl8YM8+yk$Q^3cIe3IiCRQnGN1+YQ6)^( zR#YG{=giRNG$vAzzk#upV!cX6&t_3dSyYIzz-~uo#=ap>noNQ8?AtUfKc+ky4X{N# zLZGo}B0yMSr`?=DPSqZhRqHgK6_&utI4|#KKbK9X8+oqbgX4)JYw6T?U0?~;moh6| zj0r#XC}7Nf$6tA8f>t;+(=1Y$tNWOa_c3aalOE=35i3h>7G3I03wIGKYF-Ym>38TH zJ%tJb+0i)*rYeCK$_+3Rfox?%wzx7Y!WgS$4Yn$aXKz`8n2Hvep{smKiUu2*86fZL zU#}YS_*^SX%K(dESd31E5?=LfE#o5{p5kA1X)==p>Z^)x(~;BBfP1nStmAfv#Ok3} zLB*t^iEQPMsZ22&4#wR75JK%@Q4@BHHK(qMN-GnnlcWLhm(<%lJ~*-iF~{vmQ<87B z`kCq2h)}88PV*|0(;U8&6|(R170=Nn;8G72oyIp4Bf%Wj!?^8kOym!%sFfo{2QhY} zDi?WVQ80;%^2lO(QxXnzi-7F2qxpxgdh0P!0ZW8W*2L2jVYErVnhfgwMg&A?ntm(32%LA}f3TAfRq3G~!c z7Ww!p0s6PtC2TgXQNInG&U&|#F$=zVj7*aJbQ`lj$ilaowEDMhH%6^ItQ(fhBV`(J ztH~Z`&@g-gkKRfh=QOhsYcba!$$RKB@b1!^wo5{f^lu_X=IOLPV5ap&*)opuh;pb|XFTJPGt>RuH`y@1$l{jSEg z`c(a5kaN`2!&>q?RP(bS2XaJ2jqPlHBx9bLgGRA&KCiqGdkdL`e_g_NE=N*g>u_ge zowzy|@2k4<(`Z*q9c>C8XZiB;?jV#e-7#!LREd)`DVx^tuCm26M#fkFEs_AlbPi-3 z-mGR^42uqpo=EsZ^=(xQ^{w`N&%dZQl=DWbs+PqN;_0(TDEtlo`zrOvqG6SH36?&h+5-t?l=q6*0a1uYmY&Qp4J~gDBx;yv5 z6b4FNNUQM3&J-3mWoYDuQ-~Pz*Xwk~10(ayBALTRI1jhta><)X&@{xD@WQjnA{1@_ z;dAeelGthH0NL2OMd=*B!YcKCZwh13t9zKi5wg3qUX-y$n03%6i=!nbW&#&!eLAJ( zfr`4X-j^bY_^`ND@FBnS8$)`Ov==*4dPBLWhBn-^iKM`pyq!TO zcej)F_Dq_KtCAZmUnhy;!`rYDFaWbNS|YT{kNnWjP-FoMUw>yeN+wuqEIz=dDHyML zOYeO(8jzq|5SFM#1NexY`!)uuPOv=HI?NIOf>HCu<1rH0bW*4t%TrE6M))VJB{@>k zv;epe@GIIeF#-l5rrWJi$zl*OGMy5^J0fupQD{FFK< z$qGwSL88J&F0s+&cItKI3+DRF=__{y(`@mZUcEAW`gnB(fv0W)QkEKo`dpj^H7prZ z_g5=!qN?K3P7znunO6-jcwJr$`jRO}?MJ&c8_vVAtcRek;y)l!BS5}~Wvi97R8eze zT^LHYySX?^FF42zQ057{{WL${%>FT&VTY9eweqOe}E#KR( z{s7bD>;C|NwfYW!Ma$%}`W1a_{zp$zpDCBoxqSk^^Su6r*Z%<6%)XtM{K}rbeOJ4RP0!K7p>zH zM^g2c$^H*Ow8tUl*1JVtWYf^SQNlRKQuS*@P9Io33rsRsqx3|%@HF(lR4&;tbuUz5 zib3^*>G_~pEKh$n){ENB6i242j*t9vuWQtbxtq?4p7eAYHTl2uf(^LU;4IOV( zWRShRZlVQ~!sqjDpNcz4p^Wkss?E?3=Tu{%dwShO3nqo{=H7_yW`-lkYN%fT9dBOF zSY9dCilS&7@2geqC4xWZs{P^*i9=;1Qx6&<>*2rZT({(gKjx~Zv8UF(0LfyOyzaJ& zrx#a!T7IaBBxFO8y5g_rV{FmU7|8^B^I_Lm=u+7VatnQQJ=xT|MMj`D3$`f#0I`ILMv$vP7Iz zH*y)~y|mFr-nFXz>I!+UWr>DE(}h>k;=Y_TTiB=@@hdE3C&;00HJ9_Na!34dx|wcs zUf&rUXZS_P2IC_w=50e`i;c&f!ieoLtq$&GLf^+Ucr^g*R9ilyUxFJPV+iMSXt#09 zuR5`NOl)9(3reS@vtiBN_rZG%S=!g%(R*BQA7zN`v7+C0#;Qk)h_k5~uV;)dcS6;@ zjy3xT?eU;=v8dA*8=3GcEOz(V$$tEHpJOC;xX8mlg}I@##``*Fb8|xMOs*XHE3hQU z&#HKr?y~$Acv(mCsz}!~_m8FBFTqkU8{n&XUpt!l#a*GNeoDJf#cw`Kx&>B6Ki*!_ z=B^^RisCA}MU!6h_OewmzwaUp&SB`_jk48z;a@mc&K2{8eBo5uek#_z&hS~tLiy(| zB7D&XYfpOJlks0YpGC%gD~zg{7a3nTSI!m2R~h)OJy#iAWpN*h<3AO|RWCL1Tz`t= zTxERWUpQCJABy8EjIJ`c%Hu033e4BdWa1YYUpQ4vg;!`-AL6+G02Ri#%FX`(isLj{ zJMmn9isGu`C=H>_aTM#WCzflCXCVvc{{RB1x6i<=o=X1f{{Z@5-G6nFubTerj))DW zz3b~0;pb0{{@Lr=wT8@swKtH|%_J$px)R0Gtg$;z$(xMXUaz}A3u zTU*-@;0WTS()UNkG3 z25I4i$C1?t<{*b~yl8tHw8X^=$gPJ|BA%5Zts_E%K&d8xbzajM6Cd?PYhx|FTH&Eg zYj>RNfL_xZ6mor3V49b5BSH|3g6BIR0?!o~o2Mk`Wfr}uu|_U?v{dxycAr*>&`d3O zLMW)`mHYHNPpd@eq!fE~2t^R9kKll2GBY-JGB#m6K1Q93t^ zUfhUV7->oqhi@g@bK}|{Iu7+VFfX%e0 zVPr+EYj~b{BKW2gQ{A?R6ht%)ZxhaoXxUph8j4V?xvQLbd-7MiGwM*PjTOxsuKEVP zvoUdL1VNAPTqcM!pzP6aI0ci3Y2fjF?Js8R-SE6%6!-&_r*6-{w#@(cYUVM08g(Ck`f_U4h>e zRuJrr(HMXNvGudu+hAN>g2HdN?U(5G%tek4wN`Qeh8W?6ZsMkDqLs5cDWkLr zZK!cNgv>C*fouMAntiOyQsY&O7g9nY20ui~+S;3cn}6j8Siv$x)^zAAGc4$~zw8M^T8?DIY8t=Jg0V|m?ErH!_=&NLNR zfC#;>H+5MZFmmHP0j}Fy8_}kL$PC7nd+Wn$)(2H^gv~oX3|d~%&%u0 zZ5{cb%u545h-ukG{;kjG&6YNsBHn#?R*m>0u%bwOQrb5K_uDYjRcW zh>m8{;Cl~ev&0tjvBIFLKM-I1Ep4GwlB7~qpH<7+O@D9{Xj!U8@aBD2An9f@AAk#0 zXmN9S0#i%mbBODwlCQEdd0M(S$B1e3Ud z$&9wXB?|y(=!4^t(VneTG7%p!rN~$`TUaD4an)NSyPW`~Rh`QA%OrKy)$I(DcVx!- zpgQG}uVIgq1v^`IWrp6#{=xY?{z?Wo0t|pqtW;6evF(oSbnNr&9taVwO;fMZnW5Ws zZYQ~Davaw8=hnCxtlNFi(UXr^dLTqKC)cSTyEE+Y}J zyD-{jgUiIQoUW#brpYYA8s}{@K*&SmCV~Bd^I{tbIom`8v~wN8@Tfir8L>h)pL7in zWb`52E*#YwDoQSw5E|-a0MTsap|1;vG#bHD<3JT(iECZ;KwBAxe2*fV9Af7<&@KF1 zM4wayVVDZ)4^$Q;-GX07Z*j%Q0~ws5l6_FK_uUgd_Bm`6(y zWh}deNckI9+H!GRG|58!lV@Y10ibeE+8m2Ca?he;wgVFz*ex~DZ~Ma_N@+dFI!JvX zva@x-=!;xxU6V&N%d`#^L^=^Tcmz7S4&=+tONg~Z=kSRIRFRkj)fqmzWywO<@wkH3 z3*10xkW`*ZST+J%{qHVI4#(#$a?M8h8qzP+o*wlq9*eZQNh_yIYRD1{g!L;(c{eN;pf+7BVY8reS`E|FsUBZx_GbJHO_^_MAGovoX|<+saoc<1bFsl0b8I|8H?T@ zymZSX*GA{K)Cv);MT=xJIp^A@l^36{7 z7YY{e>#D6C?Qa(Qy7O2aiENE*l&4cn)NBT&v4B-pzNH(lWmRh|VcCitir#bNJgz!+ zTG?FMod~EvnO`CA)3S`6(f3lJ3e5Qre_#T43UV!|TaJ;$n!33v6>p?IG1A(h?H?f= z+_O~lr#HIVg;4iMezTTq_lE|z_-jRV&wIMLP=r0C-WAiqQZ}C#9LnC&1L;x%31RU2E zJaY<4?kJBVNd}j+3J}iNdc6#r!W=LM^Up4 zHkuXbfKl5^=!AknL*AYvH}rQU#tJTqTWhGUNRiL5xvsXlt-=sB%y+Ner#;7oYDwyY zYG@TIY501-)p57rRRMAQJ1c+k)3Ut%UVjD8*3kXcqrU2d^hw?|c_O zy0SIvyP~ZfPX&-a1(+krWna3v{ng#!r>(_rdbGS!w7D7@jz{DVf(4Hx^U9Q2E`(@{ z-J6Qh8Us|)(n#mJLbx+^Z2@CP@f0!=G>flplu$YM3+1%6=XMf zlT=x!P`6KV?_0S$Qh~HKrz#)OXcr)}J(7Ks^js}}>V=B`09dOD4sS;auRoCz0wIms zUC+rhO5r3dIT6dUH)70}Ka+H7Y_Pn(CuN@`Da|r$VUW50>wVu8*H z>C~%Q#)k9(dSnd^An$?A9h6Rzn$bF4fVWMeWfp_bNm&rX=}O^ zDB9Go-CnMA1Oe)6>ucB=-0GuyTbz7-=my~-**UynHSB0><8_i#nr0#FxG=c54PD%) z#TcV5y4JLf*40e*v4rgZ0L;>=g|P}7eV&UJ{hM}TIFAnP!O=Lg_bnNss?|W z?);Z})79Q2_V=9?0CUfBp}DT;S3}#pYulOux|K&|`Yx-TE26*BiyN6N4gjV;_d4c- zM`vn?>>3yyT(ShGI6&7Iy6SW&wZOET%|giNsvVlS!kN<`sZ&HR7Wj~PC4iH_3dJ1T_~@kwpGY&?^2%-(QyNkW{IQb8pE8_Zsb4X<;!yOzM3G@795qXTnv znJh$)silU1(z&6PWRm{?drFmtWD@MlUq;=QX@R5}Z1$uYimPr7uQI(77rH2815B&l zpL^0ituU2Cr$QenVc`Cd%etZi1+^;VKXDrozUWi7&0+f|fSn zE!t{s=Adg?^KK;P#1ADiT?Np{Yh~IgUn~H|_E}&wph3_=Vrb=cQ=75L*L&SlF2l9+ zMlFrx=%yCeYRh~SZk6^l8rGFhmM85R<6S6@E-56fxkF74ihOvNx+yDA@GIp-6CkOM zCRiMKtUGY?nH>{t;iqSR=C#Z6R1~jy>@B+1H;AvDoA6&dKj6M{Z^3-z-w?ibZ^2h< zH{h*?wB}BwIGtK5535nxYe6SeTH&EtD?!h&ZD6{uqm8_~ii$Xc@@8esrD~&)%MoF= zhMAu4CAEBlMz|U|pNhP?-i|z#uGMs4)UCD{n>mHFxukL&(RMN^9V^>dMQOXfVkEaMqg}6x5V4ym$Ggm?=RgffS3eCs-E7T1 z2C_*0t<3dnR?urx@*Ci(oEr|sfu;i8d(@POx>;Lt!r~m((+*v<@EL?>YoKU*j}(9` zT-1%zM`#C#3aYW8x3oBc)UA_ej>iBDVY!7U5i}Oa+Pj;(8TNvkcB1_h4r3bH!qaah zP{6^`we@@d05#qDEn2Y$E+N=l;u_JZD7(^Ov}$h&rP445aGL6jjFpaH)xhMcGX+Z_ z6}6Dyaw?yWm>H+VT|*>haxofbfpFw;YOL#o~TXq&sUiGqMtGYcuH zYwl@i*Q&lLD;UXw+FF|gp@N2@rzar}%(~C>27|c}ZZSJi`lA$2%=7A_W6iB|sN+S8 znb?A5X{0siwYxqdGd`@JWc?No^&9!DSpNXdAE#%U;;8uzv*q+_hb|?wbo+SO@c}n) zd5*i(=%Cp#yC1F5GN*d|)YXR&hQ2Zd9raZuB)FZ*bx(ARF4^_bWW6zhk~Htrm_$O_ z)4dt&7L9YwHfuK=XbQ4m>#1Er_rC@2ehB7%@LBmTBBU++Ja*=*u%)V<9ax{6qa zVnI&@G%TgE>)7_RMBwq8WYIcTk#XpZt_==6f_@wUYup@r1BRg0K4$<6&2mh<0b>IN zJ$+WCVm{dXyCsw}X=`h5Rfn9h(m!m+O*NaNE)@n9>;Z`p@;HgRf00d2w)4(bVyy&Z*UJADx`VpGbwXS|G;m1~p z^k3oRbD5TDn|mT{4;l`6x-F>S(^S_oIPw(+)WctF=V{$Vgqe^vw>IbJTB7jUK^YrL z9O#^2Z0?Un6VvotE3@g##bK$ldz->bb@8g0otsVC4Lp`WR=MZu$@WjtV9Wf*{%aT0 zY(GVCiSKV+7oVzRd~L4xw7W4)6itdSBzb6U9mP?aw2x-kuHLA)sA79SXqQg~R9mY~ zMLn&|2N11=*?m$Fej(MOp;pBG-h@;u=5w4=~@36)SOViGi6?lyUFySfBLDKFpsq;8^Dq-mEhwiU?;JN%4KZ4Nw z7rkEvqrMA6@LD_WtgiScY-4k+*Cpv2C+zD=(MKDhebR7>FGp}KlIwF!Xe=et81?9- zYYRP@p{duwZwLGqS5v`r_%D0lvb*5D?}E|a1*5(TpTT?I1)WEiW+Uy7%d-M@yB}-E z^?THKye=riCArAf*81~P{?D-EVr)iGG_ap}I!LerOiUj2b9GdbdI^ouiwuPS0PR?h z^vdD%pFh@muPmF`AB0}s`1i+-EDja6FP>yXt^ zjSjCSmnde#&Lwk(^Le#D+ec%Wv*6TpP~n>#n@II8cItToH@e)1Dk;sa7iB;+$zikq z04!*Ts2k%l5EZSyte<5476bnPnBUD~fYr~ZGiW$ycam?YPdfYQd~SffGq~R^Xxcr zJ0WRCjp(_o{VQ!r0u;G)7M8;P-hc4wS zc8qj#NJ)2cbzT@d(5r)c$}}|{enpwg;m%O@+Och8?`V@F*R%F~F0HSWw9!TTHdx~k zS-9}*=rpQqQ5hW&kU7#njl-DmQpJUNkLy}2a84LU$#WTNg*S5N;;|p;yR%CA`5F#n zj>?sbV@1Wy6!@>&jSa0W%`w!rfuW#{I;h<6+J@V>azid0f}m|Y(2C7U-WIwz!VXK2AeCMpx8O15A+E zHxSZ!NQk0mw%==rrqph#!!^%n6&p&>)o7aSpq0c7jKQ_*;H6{|6BTJ*sF;DvT5?rs zp;fQQ$6OvVj_U1JF2rNBG8x z(#eN=vCb8l?LRha%q`qxGPUCK8+8R@f73mNj-}e=*-EW@a^dDvt#cUG3yFEiDIC|t zY$q$LeKjfvT^Ta)v{t#Q2|;x;EI-{6CbTdE#`(OUliszFj2T}dT< z-aX4D=CWvShpyRiY!8&@Y0;{HP%mi8JClZ~&`HZf)ONNe9aTuD>VP2Sp;tuPUEQO- zM#gli0;-E(*L{z-eiWp5U6;aF1s1 z0Tm=xrAYTS(p{%dm6y>iFLkvf(%<*d0W)2>A-(QAC!j)MDK2#=E($HC*16xhKLpcP zRPj|Y*m+o9=TeP*Xrm(uu#0u2<}gS+!k1?T$+vL3lHm)4E)cjv;R}Q&vliDfUZvZv zPZ((F7|SzNLy_%n8xb5%y4}*_K<=ZW#0*PqY>&>F+E?$9C|x!(A|f@nkxy@?Mho9{ zdAGPHyZ$Bsb7&j&d(&>mvETJ8{%_h(G2-DaajnPlQbC54J?|7JkR7Ep`x3_Ke^Qz@ zcGFW{!=CRls5yVStVSMZ?8KmN+gekqnXqDZa=N*_o5iXYncX$7X#lpCQ8dTxH+YU! z%{k%VHH^D;#d}D+oSGgQ4J*5+Ydx5L_Lc5m=7xLi2Q^5j?v5_Y%{7hZq9C-Ia{&y1 z&()LcpQ9hz5n;BGMOxQQ7tF!&UVgkpwyckM{+*ikMTltABjMSSl4mn|?5ojdkXdGp zb5CP|9LH$1(^TNoKz1KnjuJxP18Uni zyZe+za`58gaFLWgHB4kUsHBpjtpm9OMBSxBdC@T8jv#>S?`Ry9P{_zFmNtirNo$8+ z9|bX%jW=g+=&4Dnw3S!eFY{=$m1!yx{{X^UC>qG~nH~xk`ZuEk7~#Ke1jT?|DtV*0Q;}m7;bd(;W8lEpKkRQ!2W4^9 z1?TI;=?xm~-->gqph4S8KUz>xHT?Ogu#DtxcWl^ayxqjw^i74209#s&(4-Z zcYAsv{yPX*%!jr>dS(m%0J@mS{{U*?tr~k!jIv{}ZgJAGp>{h9dC%vU?|5$wxAs)@ z+$gS|*=LNxAO8Tdw(Z14Bw*3jNmSC(?9DY;DPT8oP=;2~T?&gf+#(yHw9CO|r~d#I z{9l^Qt+*a(fW#ehM)k(2wm4t3qfI;VRfaq{dx>kNZQG~8H*HfLcd5}9?AmMp08NBb zr<$PEM$*>SM_MTEedvR5aNRUMp<}L$#?iXpa-Q%}N3w3fI^n3>Q&OT3Vaz3?f1vI{ ziy%&6I0iCCJPNhqqgAqeFuPI>G^&hWcFordvq8i)fufBJ&;-`C?%p=)eh4;r+Uv8S zxRf^=o{a#YM?gDcw(GCT-E=G2xsU$%*rrM_ga1KYU7Hn24=b`TZfg>IQ!g|(dMo_qDY-bw?(y@ zU7OD?N{*8vDk;qdH+6&YRPAn5^X&2qH#BAMCd6JXCug4{c+?F9b-4;33&(B~Iq z9in(<9|+RUk^ZT)Hq_F+7SZ^lx42sOMlB_5-t9>)AwOld*)f$Mk#$xe`%x@4Amu=+ zb>>yQRCqGTgBUY#Z{^Vo+H4wus*Sj8DUHLtCOMcXp#|a6IwM<$MI?efoyNBG%}FK^ zw@i$m$8Tz-dCT?3zb7a`u(f^-M9y9QS+G zBGqHJdFFo=^NjefosaJ*?T}>u0Cmba9~7(yguj{*mYb_?T~KVywD>Jrd=NDn^7Ul< zC+R!QAounMKRa@0@9cX`1Aw`XS@uw(1#{Omko9vFLanVb74=7n>>cB=rR{TtuEaFah{(eZBG;2fzeji}TO=-gx4x7CHEOdUE+CyG zalOoM5d%ciX`{G%*27~a)9TYSLCE$+=lLR=Z$#^TUC>J4DxR(?xdSUJ_^p%-cHf>^ zKl&@Bd2^34dniM${1rfTdDRyYa0D84TXx~v!CKe*Cb`tuK1}PEB@_^F(zh|Ws>hRo zsP0Ahk4J6v6%p?{%?_1KXZY8T1+>F9>q$BNR2vWM`#EgG__^ke*9yTTq1MS<^VhO1 zt<8=~1Kt(j)-p(MR2abW_ZoL7&H_h0_it4hhBih!BKufrr!J~Xp68pmoG40uB3Y)1 zm9yFERHe9?=*?U1Yp06BHPgL>g7f?y3A;D8cA7X{#NeWQ&^Hb$IBHZU4I`Z3Yny3B z88;tydpwm{OPi)hwa%zL%Hc|){7<5=I@a3qX!mss6SHI&2`WK3gWRBi*y1yweN9T} zvuOgkclxjUC+T;a?51|=Iu&ul?+|yIcUHyOeQwJ0Rz}kIcPhNGod%^jSSuQIr6aM<8d3 zhK#KoPd@})@#xhQHoLp3nb?pRY3#^&%%cwI3BEZGnj&a`Snwl zI_8(0`yuoEle|_()E_sVl?tw=eG%cOdaH{DPSdKRn$k>nSJlQJF-KV+qd=m3Zj5EAri%*3IKDn75Xu!Cn0Co&XS|#1_f3+1Wv^iQ@?~qGO+RHKGNWw~~{zfwDmI}Jf6mVKaF(N2S3RvTCtGst)&>hU{1LCcEey8C?9#o_yhB2o4> zyQuYXe7&nGxzgGuG!sR0YBQ#)qbGA6RqQ|638#Ft8ri8*O34UeB=5U4$Ko*!cOgn> zwsA~%2fLjVxP75Eok*f^aT~{`h+OO4*0on$(LvWV&7%dIyW20-2i|V$Rjh(P^Bh0k zsgJ>8ZI(8QS~c<5jTQM(baA zX$J4X2t<|L05jePzqvMc;sgKzbXz4fFQgZ{apjfEqJkJ)By@VoWh$$ek^;4-W{Xyj z61e00>QAzMjkephvp~SW!<(d6dK9$qR6Tor8HBd3CEejeecKrA_I2o)ifd(c4M=%a zO_9#tV@;!~HFqTJJN7MU;X5qQx`2V0s%(xlA>!WCG;h7nc6n*swvCQA5%rr?9`>=c z`i-I$Qnn}F0naXIKhqvX2eD+7HRhyi9$q?=R6JKdUoP5nTVV^WLH>^FXU#fki8pVXq|V)h!ETSLUWrP z2G7gY#!#EKjPhK1=&Jdw3bD&`dzSmRxj715cX-iU&w?T0*L0$7q1PVm6P+Z@iIk;W z`U><@T_x_k(6=z}G%0y;n-F{ zVPxUkNQ{^4vuN-`V=D}ITURuNX4VstJkz3eJi9IB*;gFZ!(PKfO6r7d2HFQ^-27Fx z?q~j5Et?4><$~d}%i^u{NgC4IZucow4I+{{MA5&`zp=)5%U3?yG2Fa4tUIE`ONe7? zDEzI<)}~!}sH$nAaA^ZgQ$yKS=aUUlVsijM*$WyFfQ-Evz10Azp~TDH=GdC*Z8SH~pmL*BwHx`w@UMnNom zVX3%Qh6h(SD2;I9=GM&9-17^~)XTwDn>G*$B-fHJk6;?Y2Q?-cxM=4O$hSag&0{d5 z3k_dKI*y=kN+#lButyyU_L*heh0TqvXrN;~T~>K3V+F^$rClRl#`Pfo07aaDd{@p7 ziVY^6GAg?nDfUXQX<=_YZd3r3N)mg8Q)Ub~9&K0bS}kp%lp@tD+-gm0^jte!GBP*w zSdtnW?Q21xRbFc%Pmiy&_d05ec1~ltSDGRjBaP=Qjn4kwr+7fUhDP-oq3G;1rl?<; zM=?RFYYYu_8D|m9B3T%WeNdR|B=m{~e-2A(?XZt#7z+&uPV{$41Z3pUf-b} z?528lG-p%I0#2yMakUNemWaP->yI?~1Fa-bnx@I=PPpY;vrKIM(v7A^^+nX8j!7|1 zYh3#SN;n9y&0}K(R_)TTqy8e_Y<{;7iWr9D8tWu20jHl-@&5o41hPBxci^OkNp^y_ zIJ;EH3}dO9k7U+{=Gu*G-||7W(DQYDMq(vno*7yJ%&a`IL$S(~@;qPT4U9_zhaV9)0msA=$3u8Ql0Tb&hZ%_~KlY851Fnx~1lmNw&*c4mCk zM_u-k3v~Xetk_!SlXtTCC%X*5*KRh2lsR-l<~X=<3v^b|_EU<~@L2KCQ&b!pZak=m z7Mxc8ixV3rhA{DyUN?%3(z5rsJKe1+p4s5qImA+p0ZAYf1<1Ys0JGd28^viYawV*= zA9ts!WMFGqrOtH%21bqU7c|r+UntHu_t4WMJsRge>vC;qvUVW<0OrTUvJZ+k^Gdv#DULeR_V z;Cc6UIgaKiRqxHw(9!mp*E(cyT=z$~@m8q3#`n#Q@P#YK!B=Y?@s{40WMKFH8l3vQphjwtPT+ zjTGJ2vA0M7Cp@(8M}@J|DMliv;DctAS=WcjNh@a!ZJ98f*zeRL>`8ey(ty%~s*Uit zM&c^y>v!YY326Z7-|95t8XXpQ1K^;15w;kGXwXe`@Ab4<_5$39>bIVKS>hnpM>Mqf zE?))9;I68=xvZOCBsTXp@MZzZ6Iv$F7CBreSk)q>GJQVH1 z#}J9sySu@EjEXI>Xr;ai7wuVlh`3PHCc(FlWo~3N)B33&3pR{zyar3=n^8)+R7AiV z?)60TDmi6>u47s^CnB9H6uVFZ?#`Net;3jbt}LyMnzeU=W*V4Sh4n0n^*(AQwZQeF zYoc?Q>;C{m1lYPTw(2p;{{Y$;nPLY>?yQdT<>sL=*4qUu*?EbD{cX?JFMESpIj6j6 z=MtpwKSjdx_N~{&V_VJgTk%W=84W3z6+_h+W*0XyU7r$;`;1Jc%D>|=d zhMqYKg|3r76cv}gn(BkEc3tR`sqAfAc6xPAg_vgtirpT`x%VM-22q~x>ZLJ4>Iw>M zz_k5j_sxbcZS=l?`DUPdSU@0~%Rsx}fo>+}?&cgbsxI`x*8*}c8KP%})0Y}Edm;VN zd!T4=cwlfjo~j_o_EH^Lb!a(Pzpz{h9O$Bv+lnEwFsruLgn?k>KlbQ=alG;`Zh zn+&rx(u2Gi4Zn(RJ+6tY2Z!E9H#=PG(HF&t!-*Y{lEZiQMB;G)q=zb=0ER+gEb8I<2>(NW#OL%5&hrMYhz*T|AL+ zh%}6x*JoO%m@qL$$L_q}sQnR*@G@A*y4P|ku67Zz#L>6|w6ErlB+GVJQt?&kyGk2L zBH*1K8V0?mdoT~0iIX%mTx0{iUiji`xt5K4VGqn#^hedpu-1raUmsf;QCnnU-Uo`Q zn+z$8IsVt#hg5V^RfUal;pn!F2HyV4P}NHo-WJsG7Vi`;sA)m5)zt1)8m)`vl*ds( zbWjFM47ReK%xIp=H|`nixlwG{1z)ou`#K;aCC9>x4%x7h%J6-m>)@|ob92a3MV0Qz zxyH>F$7d$F3ktN{(0?CORYc5Q9$Aar^LEdb6cb`(mbVc?(f;V8wm|sU{o%<@-j66S zx`gN!%JFf{dN-lJ6lr~;nGUOIhl68r-W1Q*k6^;yq6N6OgT(Z0e{A%s*k)Vr!}6kgY5DB@;;dNePoJZaHR?Zc;vy5U78 z76V(dC%H+paTIP~G&;W&(J8(PjqR8Qy*nb0&~B>+^GRtZ^;m%7+&e)O6CBmBIJni^ zEv-|ATUvX9%wT^IEZE9*76UG|q?D;ml)+1<5!QCjO5mw5$S7%yztLvRLP?z7c zt7*ATNY@hGwK#0=>Y60PQbN}@n=|>UOzCszLtAfN^v#6EMiG!Ew)%`?v^D&>e1=WB zoR;t-)|(FU;AV469GP^_xz5S9@=XlIMClo5dsxmN6*!cKNqM-As%IHjxU~G|(Xy5lRA!O~1-&6KN2wMNL=C(Uj8UYY@7*X0aFGplC6G z>JAWxvlep|SZ$Ub8$2tJLR>I*c_P;Y*e3aE~t|ZiSQQYcV%cw-Ul+))BkYf%SjIi_}2w|PGTd4=v zX2I@lYg!s6w8ty5=Ps&KiDi;x2(NN~f%+^hy4uLmUp0y|;kK>XQH?Lt`mfw6;UQnm z>Wn^(1f6wEloG|D?1`?;w`x$nj$^o7-4#{wK_$Ou`lkm1AMaFVxrEx2uVXzU4Cx;jrC9o8 zrJbz>(o>Qzb?q7a+V+yj(M~e#{wjClq;TEb_PVE#=^9A)PkNNNmlEwxsIjw31zk`a zXszc(W%D|=(&A{FAEP)q!*_RDqQ;3!*xfn+h8kyxq`L6?Zm9hfO^15M(7xMl^&#FD z=a-TvDlM4=3Qq&{ zTrvLu&2Q$hM?tk8qB1rXTgu~_^YvXT*`D_O+EYaq$}%KzXdB#h39yLYDB1OH~A}pYa@M+$m0}TtebGxc|rs$Lp4AZ07LNfPTn#KAw2Wa)3HWQIypZa)wB((MY=?52ONNa>&2_`MPG2eE+-E|8^;-R)srP+I=h?aChc!_K zEPv{c=#I||jeRwv!TlD)(eY+Zn?d~%WAOO8kNna77w-74{^QM1ln)Gpltb{e9hciUiO@}OFvKglz_o|JzFjc^B9TZ{Ch*Va9=%lw0BLVttt>lFn zzA0SRQ42uNc{%uuLm+*`wYHP_E2FZbEZxyL(OMkAT3uBuM$PUUlqV(Wfvvjzr4W0- z4g#B@Usi{HHB|SzJc^?j=NfVf$*zodwPD2%&MZwnxluzSF4`I=n6P8nyNyCx){`rm z(RrZHs+uP@3!%RqC zT-eLA@T$v7t>I5mv3so~p)F|UfCW31&kd8=?Dx7W+epo7E#!cmq#ANgWF(8Vab3x> zNr~8(=GK6NWg+puh2dOINwdv}*azm;ft?d}j@m^1A4Ni}5x1P)#OrzV>99jCGWjcr}2Evl0k*xFqE zO}S=_^0LP}T&dXkFzpU|n@ty{wZ78(^ya-HW`OEbC2O?&mSQvBvuj66lE2IQ#ebLg ziuXS9)<3*gx%Zd(e|dkG_m}x!c%fH^5yAo`#-t}i9g>0kR=Xk9F|LWRy4@oh{8gXt zRR+qnycTGp^n&-vVWntltFvpQJ$a$tg{F=?m6zzh!^yJ**1c7BrJ(946p|WM`J9!t z-04+8{{YA!J?bpEc7G{Mg|cEW<(awcWkbFSCN@c>wckGG)5t6@`k`W7{{Wb3nAsj< zlU5bz?={-yZaS)BO(FzRoltB>KxW7n1D~%OVQY>=ZiFKkj5rPHRUpKcx!Gpj6rKm@ zxO!`~Z|1R$=3hme4>=AIRp;^)?dlXBjAPmR!%_P)7yty7a(M9Xwclb zl^mgrGk+Vcv>o#sR<)~VeOPRE>g~5lJPQ=d?VvWg`+6n7LiDTIv1NLm) z6|aiVX(nu@Bjag ziAo64NJzsFlreu3hI`*Yo*&+#fFE9kLwCKb(nav&-t)@0(~klHJk?V;|piOw&uyvhmrX9plD; zi4r^>?)D(nCz`Wv3t9XJxQM6VuxQC-iyw3 z$dX-pHz1Vrzb8Uy8wgh_YlECLHAr;)D-;zs|m1gbJ&Kn5^r!(0V{0wkG4e7IvAH+~tKk z%$Y7mB8b?TDbYbqAXx#b@IXzWVldB;dpld>lJY>~FX4E@7RKe%{_1k?3O}C}<)M-AX{=)Yvu-`m z%Vy9Z6x%h=S?*6w18%9*kw|f47mFEYE{uLKtbBuYdQ%cL-bDL#Q>oFPHAb|cLTc;N zE%nC8`e0;p@J|ZKB>?c86VYyvyCm(^75{II5B-6&0ovr<>VwijkP14wCaUpRX>=s8G926 z2_fHs@4=+WKO{AgQrejoJN&~VZN31HMDu_0sD9BnG;m5l%JLT0t0>z9zw2t(;wEOF zo78=6MRn30F8wa<=iJN%Qgt;bnvVa~tXO@rIXA4mVPbwr??hfTn^A18>(Dmkt;8w8 zr{7>LXYUV-Z}$ahJN`WT^~vE7YY-wq77nU!;YS_n@} z!~b@M=reC+Q(2@sF{MG>Vm=@(pW%J0zSoQSz5iNmVfhQz9Xf4h^+{K^wq&-I3VBYD z3eD8_rcrp0AvOXT-P{gjpR6G-J<3Dfh(EuwRU9VPO3RRH+FV$<^5WK$Mew5 zXW!P2RW+Ys-6p`v!y~yz9ea5)E2J=+)Yh`LqIuS{b%X59A!9 z66vu*>+#pHSFPz%2do0$#O{W8$iAEa}yyxqk91f!mDB4NK!tnaK@l=CUiO$=k35bv1Y0RjKMZ}s8|;;heBDZ~pAajS_e8~( z%-E}uK&ikLP!$RIs>kxq_(Ct%feB8kkLwg+(%72%uYwy0gGj%lF?< z)xF)GVZM1+%9-%T^x0wl?VRO3-Q02exB7|0pvU&vE(;rfp`NBD>t%h6r}W8A3Y^Mi zI|(`+-E5gPA7*W7%A;3hNLruw@jf^v`0`i&{|*4Zf*bQDnU{_P1^0tq*pOiwC8d~?VQrSAeuCRCJ=^if zCn_vDsK&QPl63 zuvHStZifMgL9OP}Q@4?{kr(K)FZ;pDs`>!m(RZiF$&ETnfwdL>`-@Jh;lR9eFUUn* z;X)o3?D4wtlKYcDE3s^vinQGYl~}-^f&gfPi;A0jQTm6!{rc_R#D#F}(Kq4!0qbE` zBUi)HS8_GcVlr`OHQy@g>goac!Ul&3VPurkKKi^Y%~(|i4QP>U6ujphn)2iJ6)$&3 zr?(uNIn8vX;ke8J^DAOs7DHP_i&OA2WDoj0Zmts^T9enOI`+zm!<+=jOInqtRs^c# zf9}#9x^ZFnrVSoAJ9+@K^mM<0z!IB}7AZTHbaGMD@bAdbWi{fYW4>iB{e5%F05Qk1 zCHVzVnTl5ygt5*RaAVUh*=R&1O!e~abD;C&uiCfYTpPt3rARyxDWr$_5yebDu@I~4 zgykbnuNj91&jLmA*l7JrG#S&&WP5Z>c2uhSS!yqQfn$uR_u=e8Ce zTVXao;jod_Ql5Kd%D?c%Jq?G;+5G?L!OSV!m{lQKC&r#nKu-y~{URp>e*aOUKNhww z7Bv{V&BFIi2gcni*4#-D%4NJs6Xqy?Q5ZiPLFjeV+8U%5_RQ4cj4l4P+wydAx-ZKT zDBI+?7s{0RYS4ssx^bN{>>w@Oa-`Y;{Wr<_{h~V_A)L5#19bj<M8_m_Uc!aKql|@ zqx^ z%ff?VevB*x*cyf_9OZTKT%Lq}d-pyxuNlwc$ia_&U$`n6usDbFZMKa_d@7=8Zegs; zY7>&+Z}PxV*_HrPo{7ueet(`ys`&FFU#;O2?YypX6Np}w<$8bPME`MD6COmiQE{_b z+~kwE2h<~nCr^ohmMht%XTQMPXIe&ZjRhsQ?(sw~Y&Fan+|d9iqiPvsYp9<_%<7G- zK$YYxWnC96A4=YurMvTW0Ydfx8@jjkb)yd{s>l4bU z?WE~Vr+Z{$n4yFxv~bb26MvNsT?oxGhMrP3SW%`_?a}c&+ThT622>-HCVtzz%ca*270D%x>DWxp z?NJ}ag0J6NRkm`-5U!e+ilLO@SgG{M44{aOTcCCMn&T-g-J;#IKXxzXxp@ewPRPI~l;yMu_aX4(PP23Cz3P#I(8CIt z(^!cfVlMQ#QX9_LR#)+gHNJ&@hk^W4s6?icNK(kEj=>^psk78@6?I(U+%DH8=Pk`t zSeAsWjN-yl+@jb_$?Ib8P$KJk5dLZujf7c~poXa5CUtwiJ=$R52WYwA%X+?T5lB#< z%6TP+cdPbI)czs^GouN_E^#GlX{vMt7tJ%OJX^Y|QcPO2O%`C{VQQ;E@sZyUOw2fw zL=PSI1l{fj@W21|L6v49-PY92JCsguhw|JSDyn8_r+C_A#*w!&?%280Zj#2@B%IQ| zwqWhk&8F@mO<^e*v@=3>LFvZW))4!bieMjWGJ}~*Z_JITX z0CB(9G}8B|4AVv=)h}5JFS))4wou~rxR^lDZc53cra2AO=zx^Zd)dZxW=|H0pShb6 zg2Z`V9-D|@8eRJxR-!M0xaE#bo=2}!1lvLoNJYxtw%H*;G*EGC<;{NfsgB24&CHQS6C4-OjMFg}!} zrS~Tu>sEXAY-2Th+cxR^#Mvvnse*O)7C8!y+mC{QieSf2>X2esxuLBVSW{>mexgRC zVoyEm@>ux*4dqQ()I};Tzg2fzcLk9&DD|!S;_42g#h3J4@2n!W4`#)xR>ALQ4o2cq zWTlXCm|UZ@RC=6Ng?+Ylcp%TWgc6^e`F>X$V(8YgO3U$+{Uhuuf8)AZJ(5sm*;OdH zsqIc}&JNR-Z$ASh6%T_T#Lg3?HM`in-Rbq`Ne(u0&bILWw#)kOZ%y*L84fIPO*ky+ z6RUKe=%4KvOlgV{Loc?60z!_oPLx`GV!z_%$?PQUcJs8U!-Tv@FK68DiS}>>!ZTM2E}p5H3MKQ+Qmm8m@c#MM$LhPT$6N9)FO}JzZHmi)cjfXo@05~tN8hCNg2tpD zOYL2C_C#4uW>!W~&{86NJYPor^TLAF26T|)Ake(o=0H6AMc%huv)sat_Tn->!)@yLCTVqcyg{OVkNXO z&swJFH7V``Ov^}L0v6+0kakZG6wFsJrJdV9693`NO7u3*?NqzCa6_;S)Ac(Cb7^~! zS4^1`?+xOp81fsW7nD%D3t2+4Vsr73g&B84b+Xu+aTr~i5*Z?$U-lgVK0!6_xgtNB zu3Jy|F+WylN%i&gD6}8*z=$9$jM}}-wsc~N5+6GV7AgZ4jvU;ix<<<}E#etHC&89~<9%vg zxFYKyMN}0+suc@59B>L`9h{e zW5d8o$;#Ag!=uS#e|^u#ZKiE}r=S{g_KhB8bIWBrPH*f9fcZ9milez$8!74i<^{3) za^wg(a?_KDKV@d2F619SYbKSefsfy_Rofj`u&KtTyS1CoT|8>=TB}WTLih>TmD&5Y zL71uGFO9}BW@gdmy0+f0g4x7aK?UmG?$2be%(tJX@8}kj4zR)xS~rSH$=Qz6w-1n# z!u%>Mj{nz_ga7MEjjZA_5q*3mvnxi=mvJ`NklOkjW6k&O_kKk*ZGO$8UoVKr)KLzS z%3FK6tmaT1H%sqV89kx9;DmeZIf32G|K6AkKB#l~Q-CCtDQQ&nHEoNG^rwo+`71T_ z>6kQw(Sx2sioT?W8eE@dA8Iq>KNa>4~g`|A>%C#1=fP6JIoYk|L*+VNW61 zv{$-tF0h{(@E+3PP{b$IA}nFHI1}v<<3=)Kf!aYP-9>h#I=#FsJh?EVSG*%#juJe$xiw>kb@Xn?21KGx^C7s@kl<|+|wP( zV2J}-Olux1=jpOIf8HCVLvjTYDCs#bh_)(=(tGw+>*oIzj3pY&5ThEoGd zBHMlvK(f#4#KpJumh+a+o;8Wgm+$0TdZH@w$X5@wBc6MdSeNp`%tAXS*#4%eTP=p1 zwo7e1Zwhj0I&;|88yZV7eFblH39?cbKIW5b@y-(~;vv?b?(tL1QOm3r+*RY~wliay zomrEMjl|W3{aj4r_%6I_QGYc#W~9=2!AMJ=(Ev(g&cYgRmyRE=^jHfEk97lU zk}a!!_~LWE4rmPmz$WVFcCWZibE0>AQ-A#iO-Uk)^e^X{-$P#}dog@|7&pQ5M59kB zi#EQ}E6|_wrH+Bg+4kzU!gx=FiG6Cw?7~Alh6iVW0Xwa7 zXcN43$MD5(GpB?jaEtM9!(72(5>F}*uQu`_ytn?4BEC-Vi zRPhflA(~xuazIrx>(>PW?iQdT{14COlv4c2)8&Xwcnn-XUnrb@S4kS-CBRd?;?((8 z7)Wn&0AFOEt!A`g-n5GRID4LreCrCb7*q`uJTUTACKoz{#Y^RF9+{=OKOQL1T=Wz`gO2#5OA}*0U>qXDq0^`q4m*i zQCc1YL={Df%f3`!aOqTo!@xO{&FS$Wx*)brK(*V%viq8A|L5l&tuHS!5G{uQov)4* z)wmMsI7Gjb?tDGfM6dj$ANh)Hd8a-_YL(j|G)?=bVds$r8$4hFNfB_+p`bP1R=^x%d3Wj1%aQt z4`DRYC-b~r@c(rU+3-rVkli$slEQDT7{dUA)SWLVa-ktdh>xcVi=NC18?KA8cWm|V zt}B+BZC*6y!06QZ5t;F64Ib^)q<^d_1~2I?d1H9ew`l8D67>0!kl6jj0if3U%Ww5P zt_%G3p#oRMX(AnPkm~QIOoT3Sfx_jgKW0FxKym|Gl87;f+7vZqf3^QoW;__ z=po-fPm=nFpD#)<(Y&cw4x51brjQY8wI4NEJFKmj zleBG}HeLkM!2EI8TYi7ZTStoGRe~?P6hJ{AqTf@>z*YwuZ{VlCuN+l3+(|ta z4@E?hUgGrT{4753$|-jHCT~j*ZnMd?F`h`UhN9Ub5lMPHNLFfbs~Fgs1n+y9pyl{^ zb#+c>lHO##dzNo4lc+;W{1KQ?_d>9&CC9wudpjS=8zL#3g3<46SS6;SBFMVhz(FiD zX+H8)X&hvIJv4opzH4%K7jxMur{E@;36%@(hyXV93-vdzUvC-K4^|0sw9j$rt?8?KpK?(aF{6*S(X~68R zuSv5iU{#_SLp`aNPbK-y1i-t=Erd7bCf{y@)?M&)cblVNUh!y_GkI&4Pth4Dk6Gs^ z{7jZiB~yZ!Ozxb8Y+vio&C|Y9Ew38>81`MbDRO0lp9lfiRd2*CRbG=5-7i{JxiBiR zvTN^@j-!g{mY$GF_Jmo3uKPibJq;Xy&2&gSc)_^g0o+v#_NeJmIdc|k9C4qde&5N# zlX{0m6$>kg$B(8go&0Af29h{rQ7K2Kap!kTPqT(;Iw66A#a*iAD6xkFpT3{R4Yfj; z$i-Z;cWNG25tZoiRR3hk0F=LHdC+rVmU~RbBUlntEvUZ_;3sy4c*p5m-;0}yy5S*u zdTi=*I<|pojt`WGwgCa1d4!Jj{Lewy9fPQlrAeWZi0o#CRwb&2z%fYEj9CuK@G6+% zAixlQY_Zu-LTqu`t`dDJ1^2zEc3;=$X8@!@B@pDh6SZyCn;C+KtlXNu6da+_mdU(M zn$O${RzMG=&1cyAW zk1Bo662UA3U8K`J5BppD7(%|~gRZ6xB}3ua zK9b}B4Y$VTYaRHjhjFPo)#A}U9NyR>Y9MRUcYkH`@?=leH$w(xjZ)+v!oZKd*N=SA zAp9hGDO>ntDzrmWtneo-i)-ru(y4%DR{uz$6ef0}(>A%-xGok*`-UngFh8i8dAL)5 z$*_`jzQ%drOGgMu#m^bk*rg(VqMW7?^()Gj>bW=eCdJETky0c&wII6}$*F2eELzE5Ai+~3t2ePx}05Q0DPwXWcYpuzoRbiu2wQLn@l6AwkJ zRcXg7q6simO`6RhtUjDj?0eD{_ptMDJzqvN5j`dBvf8XQ@7Sar)8yR`-e=%OFseAY z&$MpUEGHGZ>S|~EPnHVmiTg$L;G#wlNvfU~yKxq)v{HNUDrt(t&+sbN69*%2d2ITE zatQLV@)OBxmRcugmwFjR+vH&uEcQfYuk5nsVpflqcB+$f`H4%86B1uIZB(up-0W?i zWzeVt^+i2u!CTHRAXdu?f6VHPGNk~zRfE@yQokHcxBdLSK(p?V9mT*&#?;h4{ve8~ zfp}=;1Mr^wZDQ_C->3p(D0Kj9y3pMP73+n}3v;I}ZS~$78$|=iUJZ?qkG}PxhAo z-k0FK%{e8P6)V)(LpK^KbJ2w{tvY0JR;uFt!y|649fY=r`==eAb$u@&`utb`8cG@+e~EKIxuc0CRIc-@WTENx+Fgj1^< z5u(3#M9doZaF055gz9S7lO;JaEf*C*ohEstlZfaJ|W085p%bE7@+?Kzq3M}UBrQX?8{C~jtn^+KhLzUv6sCe zds7Wa4P)Q0NX)9vHCvzy9ct=P{#)_m{pxpq@icjtlaUpSfVaRVEQ_~r$Emeky8 z+;PGeA2lYZM+Yzb!~0t<9wEfBAfp_4#{2i?c{HYdB(E&Hy2`>DT4iXaoJUrgBGUQz zoEkMKm7Yfg(5r45C-mg^e*8|FDIov++*&&N_0GxiAvr1}>u0@8-iK%}{I_Q+Ps!99 zmZg^U>7#PQPb3Fc4=_>S}yOpg;VQLv2x=%r{OR z|M={S&_Rt;fMM2$$wrk!-v@g0Yp2%P1-78YJlz2Dx6iBSHqA4hc_dk|M88^cEeZ-W zknH-Bb&t8@=6R@h@~MvPZ~)1-r>x-D#CJP4E!TgHjM)RHUGaU)lTVEN1Vie?@3_u4 zUz)eC$+tME^I!gN#02y0IrWx+{)*6R|BO6HT3GkxP~hhAf>cW)NWEU3`-izO)hu}& z7=ALj3=w?Tq7%j(cqk@R1W#*pevBO3*lB7)AdCVNts?WTPYmDTxoy>vm)VL;9plAh z8wvj~5ik3q`cgAsdSRYzYZkumFs;Pl!}wPpApalCLWOP&O!suSw_#!y?Q)?Fbz}J< zAY^bS6(RoC(XU(zZuavBX+)Ce5YBP1d^essd%o>A!^bm?q+At?4MW<89R9a4Es|*t zOT^(KHjXrDA0WdZDcZn-xkjYf>}SI-a|LVUIxaI^S+|xC@sh81^MEHT{iJAZ{*T#L z_?>~=n3#%t2b0_`gf-GpiGwLdiw~(WBK5jTuK0REjL8HT-zim$;4fntwP4ihws zCYcRi+n@swT5lj0Q6%@hf!E4Ia`5A^N*}~*x|96tk`ni_nxP4^@;7H5aAZ z_p+T|`xEHKftS8Y3=<*G$`$t_1+fL|9W(g^3W_cX4ug+e=41ySD95Q}gH(tf_=lco z*nq$r6y%R{r*D~Z#IXQyDaiw=m097!U1V@q<#=Tzrzy_tG?~6qb*lPqxS>DVd4j0W zZ%J#_90VXK>qwM2POshEYbth`J`Z!_=|EN|fA>Zzvjp{}q@Z?m5rV2WHuz+n`ASBd zfu)d=uG~izkK=jBL*F}KTb8W~rMaK_f1wb+WTt=Z0yC2f*bDa6lB;M3kpJ3<>Zz(v zjisH|>n-t0JEAaizAXM!-T;c1I)i46o+#$C-vMyi&KSnUr+2uO(u_YfEkHeG1$@tn z8SU$s!*-lKN$O4H0j25;|E?!i&K5MTF5LtNgnjr0{%);1s~3H*P)q23QtQl#?x;cJ zSZI5$G514P+t6G7AYhXCa*1e+sjNhj9YsPwM9L%WrL~RNV9KxOCJd|SG-JDxcneCw zt~`A)PpHJJ2e!6<=nWRzyDW*(FM||)z6K%pnT*asz(mQ}cO?UH*A*GG`3{@wb;QZv zjrfU+W@!kVSk{B|r;1dJS-cyqb2@7>0GtaiVN7LZP1rE!CbZDyY4V9Zc_nT&enm!h@}+Qc<(M$+(5}BwpLdhUP}!2 zgFgF901xU{ zJQJ`y*Qjj?tSyxVPWwV~x(K|uwM^gm`c}K$ucM-|r3XaE`TSVBx+1GTOc&`!(Pv1i zN6a;Rr}n-!D0-ri?61G%%pkM6w;Tm+b&7Wx7-zvZAw^o?1;+oftY zpE5`d+jq&WeTacGI22X)1lzr;{lSx{eO?t9`>}85u_6bm6ppN;yE2*NTnc?ib*}(mN=ce_# zePD88A3=cj(H_{#lOs?2_z9TR_E;a#!w_r&{c@QqCXl$(5rJ*O`GRGlMe@}b+Nel} zk-M9ETVr-2Egwu^no>RHi4+K1HKfwZOFA%#>}g>?6aU6D?Nos@4IxIXb~3s63{T9fhbDhC%lA;oFwFC@ zhjz~BW+y^uD=hOm30h;28sKkTvUvEA#g>4w@PsRuQ#4^7wTk+QK&FxYGV*Cw({@`Uy^FlZQ-Edm&!QoSLJ_`Z$gLH=K^8 zgyY4_eur5#zS{i<5YT-AS^mWri(lCz9)X#F_o|Unv8-=rOwUvm@sp(~lrrrMvfC5Q zWJw$!Ip!|#Ll-eD`9Hb9p@hAl2U7DZy4Y+!pXw6h5;>UT#qN$>J^R%68;-528#$TU z%Zg)ia%-pqnT=D3Q}~CZDVML?mT7%(kQ4)`V6Mq*?c5|+tMtCU=d(tN!>8llcrr1} zZ5%#cCe}7_TL%^dKFM&XdGhECb6BkxbuGdfMt-+n%e@?{)8~&38jZ8_q4OD!V;5DJV>(&yAtQty+cb5Hd6h$ykeR&W zs5~Wqn?9hH36eBg!2G?(BuAV0H@&I7k*GS!Md~LkfcfmW1Bb*`L3rxyQ@2cGYEx69 zFdy%)i+FF)VjPFViIqwtT$_>RY&e)t5Em@q>%M4+oHudr>+zD{7oDkuPQfw!VSId% zm4`$UoTZFEgQ8bR3VsFXb9Tl~eBA1648P-wOT9m|XsLiu(O$9u!lK4Ooag4N(G?re zx+Y%Dq%ll&%QO2~+LV0guV0odCr?Jf51Zlmp@ZrNR{w|#l~vVBf2$b6^pA6{3u_bGjRz5#l! zZSL(hT5Xv$+F?~tRw7b7{NvsH7W|RUPVq=s^2wQ4`4@pjMx@P*dN?haZJ;BjvrJF7N3R{U7t?uVO)V#Ghzz@NofWzy=^Z@RfB`+$SNSKE?z?dSeXLkqtuD$p^Qsm zP~vB;mglJLKj`C>u;v}BP506~e~y$-`G``-uval}8Y1k8IfGd`4KQ!93633oyOrj? z!$Riwy|@r7L7E4y)+NdD5ADcXgEYJ>7@B|?)&c%(VYv7T za)=YVu42uoIn;s*<{e=l>Q#9=!@Z;)SqLdDrT*=C(xFq5d`}N{ABrBdD!Xb!&3njS z2u|*LRbc2-WSc^a-CPW9p|%66%nsFNsKMx;4f5v&o%%kXjl7icz)lw98!P|thV>Yq zYcM0tC^KiS(ULOKitDUf$@%jT=#C8P)XO%XqIZz9$+`2F?7e$6 zT5k_AvzN9?w*PK)*dO72Z7ZI^*tqzb(^g2PIH5<#b}P4wVuaaGO~9es=nRCwF+|S7r&}yY&)_yI;S3O5%^{xff(`3%2IhidC+%8#g#~c%abwEcyZ` z^##@p0e^kU>dQow_a?t&7yjb@bbLX7T(ANOHI8EYesJkGyMIWZmev?N=K_WGsi~+v zWDXCB+bd^+a_~1A6ORD$bm@H0?Hc!BEZ-t5DuIN@b6K^978_QO_!iqrwR4?!O0%!; zPsTRTww_<`;y7f<71E58<-HQ-^}g*)rfM97Z_;xbZSOw-<~QjHmdkgpMB(zoIIoyA zIeSd!M8AJQ^o0z?K@gy9CCaSpSif1|w@yuo(+Dy-0S+&sTXdZFfClj8-nyI~0UC^d8M#i3sXf;@d_Uugz%ATQ=%_DJO0MfTz+aOYVPea^4pmnNp9V;&lL z>&qXfdyJ+H2B{gGwjP2!F3F{)Ho z(K)+@FpdC2vMz28#{Zd?9YzmzW152d{dc+N|2tdI@n7T%w@*MDJ7FM6W;_IN+e?bW z0DX}zZuDhMFb0>5ioUo5w69Pc{xwLjxah}Gx^Ydz?qd@vAT#oR2L=h3Fe=>D%WB4B zW4@lx?U+{cV-pEXqj$f(V*0EqcW`yB(OeX zwp&8CQ@Q=%@KG+}rYB%m`p9JPV(xup@LSUpw4aEOD}i`Gez(HwXkY5-Jlb`$Z5vh` zUE^y0b|ZBv5Yv$TzQgck7kAVO1>}t1jln5yg<{|^`oGJ4htU;mc4`!@i}t88VvaGQl&NjOnGQk(qJ!v0SH@^F40_< zD(R7xmf!V&N~7g0;yLL{P7d`uXOGQXF00BCgZcFSWI@hH##IW0To%Nv^xi7MU$z}T0l{z&0 zmG>(n?R)hz4F(0P?2k?j{q$yyF*e}m%-`P4D-Ra?w633CK|Tc&nagQm%k{@a-Plhh zlKfk&FK8wM((XqP2*$q{K&)B4f2-xVEC-?*4i#3W~&jIrsP(p!- zQy6{%)@0&h{;D8QyKmknmHO@8%_yfefz(R9zOzg~RYd-enryOKy0ryRkB1Jyxojn=|o;QWW6ZQ9!@ zp>2L8YR~5N*u*@gC!G1+mk+-z>n{Rk@p%gV;mPj@YRX*W08}`~O>PpL!zRvr`vJ~* z`@av)dK-_FiBIl>l^aP&Qc)f9=vB|!@!OBG+W*f@^PUXT9>fRL6g&2Yy7j;(Zlr)K z3L)!i1FNexb7Lfncz8@D%C0fo*Op+9_I=Z5Ix~$=bM@!gnE`p3md~OO%@EyX=unqH zj1JWCgC)n=<7;O&tLkeN#AgOZQb8eZ4#hzJ)0er9)I;*39~mZ!)C^X+evGFgCj7EU zT;oR8vR_|iEx^CA#7@)Qj1>P~<|C*Qh#^too2!2h`~uC{CsZ-h;(Kyf#aCwQiJI2k zeLIfmWw=URQJn?1D(A9m#lj%mDN!?a8!zfS8Z7J`1V`WSZZL3U?I-Z{Ztfub8^@+>x zb{vBxI7Hm+A1XZUtC+pC^VW66x^?^Fs%v2YQMAR$scwMvB%Z5)8DXK&3j;9ZJabpO zdSsi>rT91459>B(egNEOAk>--)dyxVc9)I)0981ii4X<;USaJ`_>L;YRjcnDd}^Nn z`eZxAvrGwfjKY5}r~L`BF3@!24HwI!+8e0?W=v0Qs^!j(Tj)NNL`eYXOFdD$+R&^) zhU~3f((R~$GKI$TR-Lgd$XQ14xrq16POanFvj`uk?OcgiFI6MTzvPrSsT-K^cCKV< zcyV`<4og!#KF)l^=hiX0qfu9}n{L3#Cgh>!oA$Y4hh0QqUt;ESQ8vfdzH{}Vdv7{K z;O2%R`6;;?Za%p?^hIWW$D1IFQg*XXRaApK?~lDFphvp>%0|AnidEyaC*?^yPczc| zS%NTIu``D5KeiU&a&N|1M{R_kW$oDcsZ=ZVQTQ-T3+xJ@g+9vH$h=d5MEV|bo#*rq zGEeh1m}3{S4y9m1o>_}jk77l>NkO^e8xCK${jQQkEkNowZ6jLxw!Z?=WyGbkvfQ6% zZuyVjI9TmQ1^h;vyO?7wO_@a&eKZd2OSoFVf%al7aET#|{PZ6MrtCVOAdR zZ?i*jc*juSFtCsi=Mtpjn2_QR zWbcO~ZF|Pr7sr+{rzmeckv<_Gdm*W^QlA81%*@yW?>FLg;TU?K+!d06td^`(oe7Mn zH{ZS>8e{DJVLviwbE+&WKu>6*u|DX4hmz*cbxObbx662R{XF?#6}Ak^w;gyY)m2CJ z-A`Zr+uzahF}TOh%dT3is|IS07vC*@1MR1vB%hN%qlFq2MZr#81jIr_5grk;El3k? zu;?!3-e%Qaia12$=dxgYF`qEuMFCOvIbAMm@`$On~b$%O~?KO8jYbD-~gfpYsx*AF2luum(qCT}yb3 z$LU?jG(OS0h*5mz1}~Ps=ru~k*ZuqnxYs{O*oNGixxl#sxG#Hz^+vUNsrbUfpx8xr zcoqs_xk%3*hwC7Jgm121gHC1Dps{bWzt%Knv&$OvY4d9b;-`o%8i29coIJe97vc95 zd7Nc&+BC9xlbN9lU{4onh-$S2e(Ax0zv*aQrE3Vpuk$4_X2DWN{bkqU&Jwb6hLo#v zZPMnEwyu7EeE(`qjVE`pZ1B6`N{gA^DPa7ydLG0kqUjv1{W3Clb|?>A68{Y9c(apM zR@Up^AY5M2Z=wlD`_=k6>vxgayDv~?=9`Shhv`E4wBA0^-43_Kb+O*@dy<1*cHmoP zFR5~}UwtMiM&B+ou!n)(q3}yCW~tvJqNtVs25{`%;)``GJkA7-I|#Qp_toa#w0P zW~`?&AK5;fpn)fzU~{8DT!w0rc$uShrFB|!CYqLuf<1#{AIL*n4jH80?!&zBzM=_|xz2Gu@1`a5X%%xhXE4n-XbfxsJjXYe9D0zP7&w#AAww zJ%?ZXf&3{T6IiD4EkxlsKTG>kzY8-lft!AVu^JYeW1CTO+?99oP+#k+fYH-8B2uM} z_FCmx?;97Ur(?&}*h|snv>E;HvpS`x!=e_*a$?K~>zjx-_z=Gn)RofAv`}O=o~<|3 zfAm^EA?*e>bp5l3&$Fr+UU{-Ny`e!#Ab#t#fVAQ{fG)@4a}xc2{$o4|jg`}^9a>oS zy39juwgp1<*;BsCYdJ>)UXFJddNMbMzX~;IeXcO{bKqQQ1Ge)`$nedh_+;%^BdU)TcY~y3A@Y?G27g+Dq_r6GaYJ! z6hiQ8NOZBtB9{+5^Ag@yqYfD;$_um_(l~%x*EBY?^sSK83tnaLb|~#AH)Wb;7NPC4 z#^!80nFvm|vvjhNE}58~R3s+M6lN?R?`?HSJz6X!xRTz#qD5U8qHk*T;;zh_v-}ZbYI*h^&OJL-@Xz0fb$tj3K+NNud$Oj zCBjloW)WcN2@WYkawSLl8-%7i$nCeqDaHhES*EkzZN{mj@sT~M^Vj0(`we#QjU9cH z+379fTXo8NnXln@iu;?o_{7tE|5SqvP!fsBtVp{x`z>a7J?;jM8QT^^VK+u41jvu4 zT!Y_EkPN~ZX6ahfa_o}&G+kik+uGyawDV)XL?qdMXC3qYfreYkkoY5|^3j>w4@A$y z(W>#Po`-av@mdl+l^y*O%L=6$C2z*~KW&Qifo96ET4m$4&anZ6qpgN7GQ=`$A9K92 za~0wD$+c>A*}#4xc9T$ma|^4xWGQ*a@ClfPw?|~oD--3)LiGl&q7p2UBT5lXVjMcp zusjE)z2xd_xf^k`pU_hRhomSiURPx{@609f>o@1WyZLa_uLcmta?bIMuW|13fm`2- z-nLLr;H$Gf7MLS-TUgGn(45;_*Fy$4%j5y?pkGVtRLM; zHUHv938A(h`C)o7(B5^*u;aEue|EIMLC*T^XrI}3D4$QpoZVLFigANCS=I=39?bOc zJid-+fT?@OX7wsF*DJ&CsnLvc-*3-1mJSEQ^4cdhT^@Y zJC@MU;_c)uADc#~cX5#9i~jL+9>=t&wywRU&E3d26dT|4%gD)G&x<|Fy#|yw7O_9I z>!0a2YN23@;TmDc7$N_Vg}yC2KFiq}#Yja#tt`rc<-|VOo04PZbG8?0mggRSkTlpb zC(?cHN`|pRfW+~l+hu&YRH-T2r>`ZUL&RW$WQ0YLj_xYVcLrSc*&NIGRISR6WZQUK z&^?7kWQ7 z9uRatzew0p5|Mdml2|<_jnm`|dLZy)Tew`j8O>Bii0ovjh@ZA)p9|28-N-Df+_sgE z5^9g88LY(0zH67Tq=~;~cG}H+Ofsa>wnMLIwQxcG%Fvd_pDZy(Ho#W2G2o-wzjac*7OM@#iPtk@jqU6l4o z1ZQ&_^uZt>*$lF1Mr_74an-Vt6o)=L_^WXQZLy?q?*|n+N~a*8of9u(#x!zpS|goq z_ryzE*DQ+tOhneuV5ee~B6VQTU6H^&VJ>>Ui?n^U*@cU=WZT+K%1tf2seC5(L?bz0 zMBh{H=z%-iXqDgtlqfh!Q3}F#szUmA8t>=Qb$y-N&k?CD_S~~aHwFM<*U(5O^Nk-q zzHuQwA8(HHa+NH7ZPoixpARJRxiWM+>P^%$|8(pGvU%Yc>Kq-mryrJ&pJnb!m4bP% zf5=U@+~ogwW;f!8tBIM#N~Epx8fg3IOoiJzn(y8H!&`5$nt6UkRa^<8*hi`C@kRs-sXsXAv)^XEVq;X?CX@f^?!IpGJDF4dn<~*8XH1**VO}Ac9rK5 z6*4*$bbEx6#w|2k>;K;Z8CKRo!B)xCdsYW}Er ztVDNabC>UXY@Tag`r1dV%&vN{;6J=-neFk5LjbvT)eq5=NHT^uy0P$_h`b0Yr z)~C?~3OM6#4zLn5n0~BvbW?e$M_4vE_3s5RC3~Z##1C2zL2%t>nZ#it&_2*XmNy>! zCrQxd1G`-&Fr#y4FAMI3$jzZs1?^^HN>~5(C4CY zES?kl@S_)16mf2~^iCl+L>{44&ujQav-%=e3{Ilp4Xg%_ci8iqgOV@yw-5#20CN|s z6I09xIuRe3D@O}y;%KDNhiLlJoC_>Z2%A}{^6|Rz+@b(27u6A5yOv>RFevBpxqXA2 z;qF1gx*9#$J0AqToo6U7(KtwZ=xv}mSUUNd4`?mkuk0WU%F96IUI>kxWy{#+FXgqw z#gemh4y>*AWzfGjEXFMwm(&N@{G2GyKtNr*kDrNY-03Xzx_rw zaGAQ(HduKj3X_l6bz?Qns>JOwXZbH*t1LYOmNOMuQ0`5_kD?waqlLT9b3T%|hova7 zj%0q=VN*REJk1==H#2a%#LVBPmf_ppcpnoTy{08W;%Aw-=w4?qp&9ck*1TGw)2`V` zT3pi%uk@9Pfr>o6eE=EC^8~4gw#7Q*#^VA(Q=>F%k9*&EPTH{;*IM&@MVXq*=3cIC z76%%9mb%W6AxZI=2I|>YDYk`qbeZ;r+^E&!{o;WO*uO)%kTU-Ob2HLGKDQj(-ml1) z5zW(xs--n4x(7j`@9Xa`VJEEzMBy`28*jNyZ0`d~35PBN<_Qy7mV%!^Yl=6h)HMpl za^e;d*Fy6bYBJRY@HW{TnZWA1$9R>>b2V2e)N&LR&~KTtiq{)-`Gr+c!sxw*RbymY zVyKraAX+2VxuOxFm|6_M^6OIQN)F+GfRikgXZnSwZ-)5#)Lj=?x21kiQa08=sE<+u zg@(Sh5ap$3OV`RUsakH@s{QdD>!EF6)MBWWEmvo5DgzCaZlR!uJw?*FS#~hYo4!F> zsg{6_M*$%gk(<06ccJ)%L=uCZSFK8b9SiaM-UpIi!d-X#O4hZ^TyEabRH_C40Dq(o zDg4y~w&pbX1(+?{(UnY?JB!oWRFwhCmDkBRLKT;Q;Llfi0Wn0E$K9?%<#*^!{%q1xu#*%_n1mx_K62; zuSzgIUW6-g%PHsk`W(*EJZ99_$Awj~WNF&q;8FzMmc!N7w z@hgg3G6bap;0Uwbhh#nsCJgpTLA{cIdn2RR2I0^(XZt2I?o1^W_SrWWw0Pr-$C{Xe zP1g@J8ixCW^p#D@*u`5aSSauuN?DQlCr$7x2#tCl>Vz|@(s3^?gE#5k7EH{!a^D!kRn0W(> zhrXvEJ58~;Zw-)P!XmyfS435y9tPia+ukor7N|{AVy|*oMVq&5)Lg{OnWTG&VVhZ4 zCYS^--uRp3g^#>`l7}QMG)mNX^gpqnPb!Z4Coz|XN5~@~99vL6 z09M}PhB%@%RCfZei}Sq7?#;W??Ycl(mv(%kIcG*9{&I_raNkL zHLprPN#PlNC8lSYlZYp2#Nw(L;?9w~I!Y4t7#Qj{02F&%;(nh#kE_Z_lX>6bpd2&HV5Rlr_ zI>VuZ4x;?a7fq;e=s0FpG)E5Kxfa%HI7q!iJ!ux@Vz<0UM4<4^%mXgF2Q1)Bf%O`d z9E=TnF>PT=^58jOJWZT-X4eYgC>jA9_Kn~s6Y^9Q6*pQ8VUF-9fW|OhgxAF4?r&%< zHjU!=_^6|_XlK$LCG^C;e$wh*aR#_&G0DUn>Rb#?%)rjcHB)nmne?C36!tVG$Q_{D z!NjKC_H1V1pOBm{V@+U{{U(?Y8=C?%&CKHD`e8yXlFlI9wL^h_tPzNy5*8*YC%)vL)b5tDt}=(8LYYiGk+3>My?*Va_91@HRc=T+ze~ z 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 %`g1c3 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 aQH|xu4M@6d!9^z@7;KzJGlxH@&;QwcXlr@^ literal 0 HcmV?d00001 diff --git a/bsp/raspberry-pi/raspi3-32/figures/raspi3_f.jpg b/bsp/raspberry-pi/raspi3-32/figures/raspi3_f.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd2f25133280c0fc00ac742b4afde45a2ec7f120 GIT binary patch literal 225139 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�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

&prsBezk~>!&~QI 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 rtt.asm\n' +POST_ACTION = OBJCPY + ' -O binary $TARGET kernel7.img\n' + SIZE + ' $TARGET \n' diff --git a/bsp/raspberry-pi/raspi3-64/.config b/bsp/raspberry-pi/raspi3-64/.config new file mode 100644 index 0000000000..d51c923bf9 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/.config @@ -0,0 +1,418 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Project Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=2048 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048 +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_MEMHEAP=y +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +CONFIG_RT_USING_MEMTRACE=y +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +CONFIG_RT_USING_DEVICE_OPS=y +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +CONFIG_RT_VER_NUM=0x40002 +CONFIG_ARCH_CPU_64BIT=y +CONFIG_ARCH_ARM=y +# CONFIG_RT_USING_CPU_FFS is not set +CONFIG_ARCH_ARM_CORTEX_AARCH64=y +CONFIG_ARCH_ARM_CORTEX_A53=y +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# C++ features +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Command shell +# +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_CMD_SIZE=80 +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_USING_MSH_DEFAULT=y +CONFIG_FINSH_USING_MSH_ONLY=y +CONFIG_FINSH_ARG_MAX=10 + +# +# Device virtual file system +# +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FILESYSTEMS_MAX=2 +CONFIG_DFS_FILESYSTEM_TYPES_MAX=2 +CONFIG_DFS_FD_MAX=16 +# CONFIG_RT_USING_DFS_MNTTABLE is not set +# CONFIG_RT_USING_DFS_ELMFAT is not set +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +# CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS_UFFS is not set +# CONFIG_RT_USING_DFS_JFFS2 is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_PIPE_BUFSZ=512 +# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SERIAL=y +# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_WIFI is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# POSIX layer and C standard library +# +CONFIG_RT_USING_LIBC=y +# CONFIG_RT_USING_PTHREADS is not set +CONFIG_RT_USING_POSIX=y +# CONFIG_RT_USING_POSIX_MMAP is not set +# CONFIG_RT_USING_POSIX_TERMIOS is not set +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# Network interface device +# +# CONFIG_RT_USING_NETDEV is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT is not set + +# +# VBUS(Virtual Software BUS) +# +# CONFIG_RT_USING_VBUS is not set + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOTHUB is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set + +# +# system packages +# +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_CMSIS is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_LCD_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_UKAL is not set +CONFIG_BCM2836_SOC=y +# CONFIG_BSP_SUPPORT_FPU is not set + +# +# Hardware Drivers Config +# + +# +# BCM Peripheral Drivers +# +CONFIG_BSP_USING_UART=y +# CONFIG_RT_USING_UART0 is not set +CONFIG_RT_USING_UART1=y +CONFIG_BSP_USING_PIN=y +# CONFIG_BSP_USING_SYSTIMER is not set +# CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_WDT is not set +# CONFIG_BSP_USING_RTC is not set +# CONFIG_BSP_USING_SDIO is not set + +# +# Board Peripheral Drivers +# +# CONFIG_BSP_USING_HDMI is not set diff --git a/bsp/raspberry-pi/raspi3-64/.cproject b/bsp/raspberry-pi/raspi3-64/.cproject new file mode 100644 index 0000000000..403db1205c --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/.cproject @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/raspberry-pi/raspi3-64/.project b/bsp/raspberry-pi/raspi3-64/.project new file mode 100644 index 0000000000..16586966cc --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/.project @@ -0,0 +1,54 @@ + + + raspi2 + + + + + + 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.core.rttnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + rt-thread + 2 + virtual:/virtual + + + rt-thread/components + 2 + $%7BPARENT-2-PROJECT_LOC%7D/components + + + rt-thread/include + 2 + $%7BPARENT-2-PROJECT_LOC%7D/include + + + rt-thread/libcpu + 2 + $%7BPARENT-2-PROJECT_LOC%7D/libcpu + + + rt-thread/src + 2 + $%7BPARENT-2-PROJECT_LOC%7D/src + + + diff --git a/bsp/raspberry-pi/raspi3-64/Kconfig b/bsp/raspberry-pi/raspi3-64/Kconfig new file mode 100644 index 0000000000..2122b45395 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/Kconfig @@ -0,0 +1,29 @@ +mainmenu "RT-Thread Project Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" + +config BCM2836_SOC + bool + select ARCH_ARM_CORTEX_A53 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + select ARCH_CPU_64BIT + default y + +source "driver/Kconfig" diff --git a/bsp/raspberry-pi/raspi3-64/README.md b/bsp/raspberry-pi/raspi3-64/README.md new file mode 100644 index 0000000000..28e00f96c0 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/README.md @@ -0,0 +1,100 @@ +# Raspberry PI 3-64板级支持包说明 + +## 1. 简介 + +树莓派由注册于英国的慈善组织“Raspberry Pi 基金会”开发,莓派3有三个发行版本: + +* B : 4核 Broadcom BCM2837 (ARMv8-A) 1.2GHz,双核VideoCore IV GPU,1GB内存,100 Base-T Ethernet +* B+: 4核 Broadcom BCM2837B0 Cortex-A53 (ARMv8) 1.4GHz, 1GB LPDDR2 SDRAM, GigaE over USB 2.0 +* A+: 4核 Broadcom BCM2837B0 Cortex-A53 (ARMv8) 1.4GHz, 512MB LPDDR2 SDRAM + +这份RT-Thread BSP是针对 Raspberry Pi 3 64位模式的一份移植,树莓派价格便宜, 使用者甚众,是研究和运行RT-Thread的可选平台之一。 + + +## 2. 编译说明 + +### 2.1 Window上的环境搭建 + +Windows环境下推荐使用[env工具][1]进行编译。 + +首先下载Linux上的gcc工具,版本为gcc-arm-8.3选择aarch64-elf就可以。 + +将推荐将gcc解压到`\env\tools\gnu_gcc\arm_gcc`目录下。 + +接着修改`bsp\raspberry-pi\raspi3-64\rtconfig.py` + +修改路径: + +``` +EXEC_PATH = r'E:/env_released_1.1.2/env/tools/gnu_gcc/arm_gcc/gcc-arm-8.3-2019.03-i686-mingw32-aarch64-elf/bin' +``` + +然后在`bsp\raspberry-pi\raspi3-64\`下输入scons编译即可。 + +### 2.2 Linux上的环境搭建 + +Linux下推荐使用[gcc工具][2]。Linux版本下gcc版本可采用`gcc-arm-8.3-2019.03-x86_64-aarch64-elf`。 + +直接进入`bsp\raspberry-pi\raspi3-64`,输入scons编译即可。 + + +## 3. 执行 + +### 3.1 下载[raspbian镜像][3],生成可以运行的raspbian SD卡 + +Windows下,去[etcher.io][4]下载etcher,这是个可以烧写img的工具 + +解开下载的镜像文件, linux下使用如下的命令 + +``` +unzip 2018-06-27-raspbian-stretch-lite.zip +``` + +准备一张空SD卡,linux环境下,插入电脑并执行 + +``` +sudo dd if=2018-06-27-raspbian-stretch-lite.img of=/dev/xxx bs=32M conv=fsync +``` + +**注意: /dev/xxx 要换成真实环境中的SD卡所在设置,千万不要弄错。** + +Windows环境下,执行etcher选择解压后的2018-06-27-raspbian-stretch-lite.img文件和SD卡就可以开始烧写了。 + +最后把kernel8.img放入SD boot分区,删除其它 kernel*.img。 + +### 3.2 准备好串口线 + +目前版本是使用raspi3的 GPIO 14, GPIO 15来作路口输出,连线情况如下图所示(图片中的板子是pi2,GPIO引脚是一样的): + +![raspi2](figures/raspi_uart.png) + +串口参数: 115200 8N1 ,硬件和软件流控为关。 + +按上面的方法做好SD卡后,插入树莓派,通电可以在串口上看到如下所示的输出信息: + +```text + heap: 0x00020b20 - 0x00400000 + + \ | / +- RT - Thread Operating System + / | \ 3.1.0 build Aug 23 2019 + 2006 - 2019 Copyright by rt-thread team +Hello RT-Thread! +msh > +``` + +## 4. 支持情况 + +| 驱动 | 支持情况 | 备注 | +| ------ | ---- | :------: | +| UART | 支持 | UART0| + +## 5. 联系人信息 + +维护人:[bernard][5] + +[1]: https://www.rt-thread.org/page/download.html +[2]: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads +[3]: https://downloads.raspberrypi.org/raspbian_lite_latest +[4]: https://etcher.io +[5]: https://github.com/BernardXiong diff --git a/bsp/raspberry-pi/raspi3-64/SConscript b/bsp/raspberry-pi/raspi3-64/SConscript new file mode 100644 index 0000000000..c7ef7659ec --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/SConscript @@ -0,0 +1,14 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/raspberry-pi/raspi3-64/SConstruct b/bsp/raspberry-pi/raspi3-64/SConstruct new file mode 100644 index 0000000000..93f349aab8 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/SConstruct @@ -0,0 +1,30 @@ +import os +import sys +import rtconfig + +from rtconfig import RTT_ROOT + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) +env['ASCOM'] = env['ASPPCOM'] + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False) + +# make a building +DoBuilding(TARGET, objs) + diff --git a/bsp/raspberry-pi/raspi3-64/applications/SConscript b/bsp/raspberry-pi/raspi3-64/applications/SConscript new file mode 100644 index 0000000000..fdf93d4235 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/applications/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('test/*.c') +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/raspberry-pi/raspi3-64/applications/main.c b/bsp/raspberry-pi/raspi3-64/applications/main.c new file mode 100644 index 0000000000..bcccbecc00 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/applications/main.c @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 bernard the first version + */ + +#include + +int main(int argc, char** argv) +{ + rt_kprintf("Hi, this is RT-Thread!!\n"); + + return 0; +} + diff --git a/bsp/raspberry-pi/raspi3-64/applications/mnt.c b/bsp/raspberry-pi/raspi3-64/applications/mnt.c new file mode 100644 index 0000000000..8ec394eb8c --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/applications/mnt.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 bernard the first version + */ + +#include + +int mnt_init(void) +{ + return 0; +} diff --git a/bsp/raspberry-pi/raspi3-64/applications/test/gpio.h b/bsp/raspberry-pi/raspi3-64/applications/test/gpio.h new file mode 100644 index 0000000000..52fa671d0f --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/applications/test/gpio.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * 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. + * + */ + +#define MMIO_BASE 0x3F000000 + +#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000)) +#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004)) +#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008)) +#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C)) +#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010)) +#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014)) +#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C)) +#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020)) +#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028)) +#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034)) +#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038)) +#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040)) +#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044)) +#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064)) +#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068)) +#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094)) +#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098)) +#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C)) diff --git a/bsp/raspberry-pi/raspi3-64/applications/test/uart.c b/bsp/raspberry-pi/raspi3-64/applications/test/uart.c new file mode 100644 index 0000000000..b3dd4da7ea --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/applications/test/uart.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * 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. + * + */ + +#include "gpio.h" + +/* Auxilary mini UART registers */ +#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004)) +#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040)) +#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044)) +#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048)) +#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C)) +#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050)) +#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054)) +#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058)) +#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C)) +#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060)) +#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064)) +#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068)) + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *AUX_ENABLE |=1; // enable UART1, AUX mini uart + *AUX_MU_CNTL = 0; + *AUX_MU_LCR = 3; // 8 bits + *AUX_MU_MCR = 0; + *AUX_MU_IER = 0; + *AUX_MU_IIR = 0xc6; // disable interrupts + *AUX_MU_BAUD = 270; // 115200 baud + /* map UART1 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(2<<12)|(2<<15); // alt5 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + *AUX_MU_CNTL = 3; // enable Tx, Rx +} + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* wait until we can send */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); + /* write the character to the buffer */ + *AUX_MU_IO=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01)); + /* read it and return */ + r=(char)(*AUX_MU_IO); + /* convert carrige return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void uart_puts(char *s) { + while(*s) { + /* convert newline to carrige return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} diff --git a/bsp/raspberry-pi/raspi3-64/applications/test/uart.h b/bsp/raspberry-pi/raspi3-64/applications/test/uart.h new file mode 100644 index 0000000000..72f8e3151f --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/applications/test/uart.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * 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. + * + */ + +void uart_init(); +void uart_send(unsigned int c); +char uart_getc(); +void uart_puts(char *s); diff --git a/bsp/raspberry-pi/raspi3-64/driver/Kconfig b/bsp/raspberry-pi/raspi3-64/driver/Kconfig new file mode 100644 index 0000000000..2deffef99c --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/Kconfig @@ -0,0 +1,112 @@ + +config BSP_SUPPORT_FPU + bool "Using Float" + default n + +menu "Hardware Drivers Config" + menu "BCM Peripheral Drivers" + menuconfig BSP_USING_UART + bool "Using UART" + select RT_USING_SERIAL + default y + + if BSP_USING_UART + config RT_USING_UART0 + bool "Enabel UART 0" + default y + + config RT_USING_UART1 + bool "Enabel UART 1" + default n + endif + + config BSP_USING_PIN + bool "Using PIN" + select RT_USING_PIN + default y + + menuconfig BSP_USING_SYSTIMER + bool "Enable SYSTIMER" + select BSP_USING_SYSTIMER + default n + + if BSP_USING_SYSTIMER + config RT_USING_SYSTIMER1 + bool "Enable sys timer1" + default n + config RT_USING_SYSTIMER3 + bool "Enable sys timer3" + default n + endif + + menuconfig BSP_USING_I2C + bool "Enable I2C" + select RT_USING_I2C + default n + + if BSP_USING_I2C + config BSP_USING_I2C0 + bool "Enable I2C0" + default n + config BSP_USING_I2C1 + bool "Enable I2C1" + default n + endif + + menuconfig BSP_USING_SPI + bool "Enable SPI" + select RT_USING_SPI + default n + + if BSP_USING_SPI + config BSP_USING_SPI0 + bool "Enable SPI0" + default n + config BSP_USING_SPI1 + bool "Enable SPI1" + default n + endif + + config BSP_USING_WDT + bool "Enable WDT" + select RT_USING_WDT + default n + + menuconfig BSP_USING_RTC + bool "Enable RTC" + select RT_USING_RTC + default n + + if BSP_USING_RTC + config BSP_USING_ALARM + bool "Enable Alarm" + select RT_USING_ALARM + default n + endif + + menuconfig BSP_USING_SDIO + bool "Enable SDIO" + select RT_USING_SDIO + default n + + if BSP_USING_SDIO + config BSP_USING_SDIO0 + bool "Enable SDIO0" + select RT_USING_SDIO + default n + endif + endmenu + + menu "Board Peripheral Drivers" + menuconfig BSP_USING_HDMI + bool "Enable HDMI" + select BSP_USING_SPI + default n + + if BSP_USING_HDMI + config BSP_USING_HDMI_DISPLAY + bool "HDMI DISPLAY" + default n + endif + endmenu +endmenu diff --git a/bsp/raspberry-pi/raspi3-64/driver/SConscript b/bsp/raspberry-pi/raspi3-64/driver/SConscript new file mode 100644 index 0000000000..2c19b9436d --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/SConscript @@ -0,0 +1,32 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Split(''' +board.c +bcm283x.c +drv_uart.c +mbox.c +''') +CPPPATH = [cwd] + +if GetDepend('BSP_USING_SYSTIMER'): + src += ['drv_timer.c'] +if GetDepend('BSP_USING_PIN'): + src += ['drv_gpio.c'] +if GetDepend('BSP_USING_I2C'): + src += ['drv_i2c.c'] +if GetDepend('BSP_USING_WDT'): + src += ['drv_wdt.c'] +if GetDepend('BSP_USING_SPI'): + src += ['drv_spi.c'] +if GetDepend('BSP_USING_SDIO'): + src += ['drv_sdio.c'] +if GetDepend('BSP_USING_RTC'): + src += ['drv_rtc.c'] +if GetDepend('BSP_USING_HDMI'): + src += ['drv_fb.c'] +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/raspberry-pi/raspi3-64/driver/bcm283x.c b/bsp/raspberry-pi/raspi3-64/driver/bcm283x.c new file mode 100644 index 0000000000..ea92c33a0f --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/bcm283x.c @@ -0,0 +1,575 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include "bcm283x.h" + +rt_uint32_t bcm283x_peri_read(volatile rt_ubase_t addr) +{ + rt_uint32_t ret; + __sync_synchronize(); + ret = HWREG32(addr); + __sync_synchronize(); + return ret; +} + +rt_uint32_t bcm283x_peri_read_nb(volatile rt_ubase_t addr) +{ + return HWREG32(addr); +} + +void bcm283x_peri_write(volatile rt_ubase_t addr, rt_uint32_t value) +{ + __sync_synchronize(); + HWREG32(addr) = value; + __sync_synchronize(); +} + +void bcm283x_peri_write_nb(volatile rt_ubase_t addr, rt_uint32_t value) +{ + HWREG32(addr) = value; +} + +void bcm283x_peri_set_bits(volatile rt_ubase_t addr, rt_uint32_t value, rt_uint32_t mask) +{ + rt_uint32_t v = bcm283x_peri_read(addr); + v = (v & ~mask) | (value & mask); + bcm283x_peri_write(addr, v); +} + +void bcm283x_gpio_fsel(rt_uint8_t pin, rt_uint8_t mode) +{ + volatile rt_ubase_t addr = (BCM283X_GPIO_BASE + BCM283X_GPIO_GPFSEL0 + (pin / 10) * 4); + rt_uint8_t shift = (pin % 10) * 3; + rt_uint32_t mask = BCM283X_GPIO_FSEL_MASK << shift; + rt_uint32_t value = mode << shift; + + bcm283x_peri_set_bits(addr, value, mask); +} + +void bcm283x_gpio_set(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPSET0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + bcm283x_peri_write(addr, 1 << shift); +} + +void bcm283x_gpio_clr(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPCLR0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + bcm283x_peri_write(addr, 1 << shift); +} + +rt_uint8_t bcm283x_gpio_lev(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM2835_GPIO_GPLEV0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = bcm283x_peri_read(addr); + return (value & (1 << shift)) ? HIGH : LOW; +} + +rt_uint8_t bcm283x_gpio_eds(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = bcm283x_peri_read(addr); + return (value & (1 << shift)) ? HIGH : LOW; +} + +/* Write a 1 to clear the bit in EDS */ +void bcm283x_gpio_set_eds(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_write(addr, value); +} + +/* Rising edge detect enable */ +void bcm283x_gpio_ren(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPREN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, value, value); +} + +void bcm283x_gpio_clr_ren(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPREN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, 0, value); +} + +/* Falling edge detect enable */ +void bcm283x_gpio_fen(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPFEN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, value, value); +} +void bcm283x_gpio_clr_fen(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPFEN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, 0, value); +} + +/* High detect enable */ +void bcm283x_gpio_hen(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, value, value); +} + +void bcm283x_gpio_clr_hen(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, 0, value); +} + +/* Low detect enable */ +void bcm283x_gpio_len(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPLEN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, value, value); +} + +void bcm283x_gpio_clr_len(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPLEN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, 0, value); +} + +/* Async rising edge detect enable */ +void bcm283x_gpio_aren(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAREN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, value, value); +} +void bcm283x_gpio_clr_aren(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAREN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, 0, value); +} + +/* Async falling edge detect enable */ +void bcm283x_gpio_afen(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAFEN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, value, value); +} +void bcm283x_gpio_clr_afen(rt_uint8_t pin) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAFEN0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + rt_uint32_t value = 1 << shift; + bcm283x_peri_set_bits(addr, 0, value); +} + +/* Set pullup/down */ +void bcm283x_gpio_pud(rt_uint8_t pud) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPPUD; + bcm283x_peri_write(addr, pud); +} + +/* Pullup/down clock +// Clocks the value of pud into the GPIO pin +*/ +void bcm283x_gpio_pudclk(rt_uint8_t pin, rt_uint8_t on) +{ + volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPPUDCLK0 + (pin / 32) * 4; + rt_uint8_t shift = pin % 32; + bcm283x_peri_write(addr, (on? 1 : 0) << shift); +} + +void bcm283x_gpio_set_pud(rt_uint8_t pin, rt_uint8_t pud) +{ + bcm283x_gpio_pud(pud); + bcm283x_clo_delayMicros(10); + + bcm283x_gpio_pudclk(pin, 1); + bcm283x_clo_delayMicros(10); + + bcm283x_gpio_pud(BCM283X_GPIO_PUD_OFF); + bcm283x_gpio_pudclk(pin, 0); +} + + +void bcm283x_gpio_write(rt_uint8_t pin, rt_uint8_t val) +{ + if (val) + bcm283x_gpio_set(pin); + else + bcm283x_gpio_clr(pin); +} + +rt_uint64_t bcm283x_st_read(void) +{ + volatile rt_ubase_t addr; + rt_uint32_t hi, lo; + rt_uint64_t st; + + addr = BCM283X_ST_BASE + BCM283X_ST_CHI; + hi = bcm283x_peri_read(addr); + + addr = BCM283X_ST_BASE + BCM283X_ST_CLO; + lo = bcm283x_peri_read(addr); + + addr = BCM283X_ST_BASE + BCM283X_ST_CHI; + st = bcm283x_peri_read(addr); + + /* Test for overflow */ + if (st == hi) + { + rt_kprintf(">> 1crash???\n"); + st <<= 32; + st += lo; + rt_kprintf(">> 2crash!!!\n"); + } + else + { + st <<= 32; + addr = BCM283X_ST_BASE + BCM283X_ST_CLO; + st += bcm283x_peri_read(addr); + } + return st; +} + +/* microseconds */ +void bcm283x_delayMicroseconds(rt_uint64_t micros) +{ + rt_uint64_t start; + + start = bcm283x_st_read(); + rt_kprintf("bcm283x_st_read result: %d\n", start); + + /* Not allowed to access timer registers (result is not as precise)*/ + if (start==0) + return; + + bcm283x_st_delay(start, micros); +} + +void bcm283x_clo_delayMicros(rt_uint32_t micros) +{ + volatile rt_uint32_t addr; + rt_uint32_t compare; + + addr = BCM283X_ST_BASE + BCM283X_ST_CLO; + compare = bcm283x_peri_read(addr) + micros; + while(bcm283x_peri_read(addr) < compare); +} + +void bcm283x_st_delay(rt_uint64_t offset_micros, rt_uint64_t micros) +{ + rt_uint64_t compare = offset_micros + micros; + while(bcm283x_st_read() < compare); +} + + +/* Read an number of bytes from I2C */ +rt_uint8_t bcm283x_i2c_read(rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len) +{ + volatile rt_uint32_t dlen = base + BCM283X_BSC_DLEN; + volatile rt_uint32_t fifo = base + BCM283X_BSC_FIFO; + volatile rt_uint32_t status = base + BCM283X_BSC_S; + volatile rt_uint32_t control = base + BCM283X_BSC_C; + + rt_uint32_t remaining = len; + rt_uint32_t i = 0; + rt_uint8_t reason = BCM283X_I2C_REASON_OK; + + /* Clear FIFO */ + bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1); + /* Clear Status */ + bcm283x_peri_write_nb(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE); + /* Set Data Length */ + bcm283x_peri_write_nb(dlen, len); + /* Start read */ + bcm283x_peri_write_nb(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST | BCM283X_BSC_C_READ); + + /* wait for transfer to complete */ + while (!(bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE)) + { + /* we must empty the FIFO as it is populated and not use any delay */ + while (remaining && bcm283x_peri_read_nb(status) & BCM283X_BSC_S_RXD) + { + /* Read from FIFO, no barrier */ + buf[i] = bcm283x_peri_read_nb(fifo); + i++; + remaining--; + } + } + + /* transfer has finished - grab any remaining stuff in FIFO */ + while (remaining && (bcm283x_peri_read_nb(status) & BCM283X_BSC_S_RXD)) + { + /* Read from FIFO, no barrier */ + buf[i] = bcm283x_peri_read_nb(fifo); + i++; + remaining--; + } + + /* Received a NACK */ + if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR) + { + reason = BCM283X_I2C_REASON_ERROR_NACK; + } + + /* Received Clock Stretch Timeout */ + else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT) + { + reason = BCM283X_I2C_REASON_ERROR_CLKT; + } + + /* Not all data is received */ + else if (remaining) + { + reason = BCM283X_I2C_REASON_ERROR_DATA; + } + + bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE); + + return reason; +} + +int bcm283x_i2c_begin(int no) +{ + if (0 == no) + { + bcm283x_gpio_fsel(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_ALT0); /* SDA */ + bcm283x_gpio_fsel(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_ALT0); /* SCL */ + } + else + { + bcm283x_gpio_fsel(BCM_GPIO_PIN_2, BCM283X_GPIO_FSEL_ALT0); /* SDA */ + bcm283x_gpio_fsel(BCM_GPIO_PIN_3, BCM283X_GPIO_FSEL_ALT0); /* SCL */ + } + return 0; +} + +void bcm283x_i2c_end(int no) +{ + if (0 == no) + { + bcm283x_gpio_fsel(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_INPT); /* SDA */ + bcm283x_gpio_fsel(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_INPT); /* SCL */ + } + else + { + bcm283x_gpio_fsel(BCM_GPIO_PIN_2, BCM283X_GPIO_FSEL_INPT); /* SDA */ + bcm283x_gpio_fsel(BCM_GPIO_PIN_3, BCM283X_GPIO_FSEL_INPT); /* SCL */ + } +} + +void bcm283x_i2c_setSlaveAddress(int no, rt_uint8_t saddr) +{ + volatile rt_uint32_t addr; + if (0 == no) + addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_A; + else + addr = PER_BASE + BCM283X_BSC1_BASE + BCM283X_BSC_A; + + bcm283x_peri_write(addr, saddr); +} + +void bcm283x_i2c_setClockDivider(int no, rt_uint16_t divider) +{ + volatile rt_uint32_t addr; + if (0 == no) + addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DIV; + else + addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DIV; + bcm283x_peri_write(addr, divider); +} + +void bcm283x_i2c_set_baudrate(int no, rt_uint32_t baudrate) +{ + rt_uint32_t divider; + divider = (BCM283X_CORE_CLK_HZ / baudrate) & 0xFFFE; + bcm283x_i2c_setClockDivider(no, (rt_uint16_t)divider); +} + +/* Writes an number of bytes to I2C */ +rt_uint8_t bcm283x_i2c_write(rt_uint32_t base, const rt_uint8_t * buf, rt_uint32_t len) +{ + volatile rt_uint32_t dlen = base + BCM283X_BSC_DLEN; + volatile rt_uint32_t fifo = base + BCM283X_BSC_FIFO; + volatile rt_uint32_t status = base + BCM283X_BSC_S; + volatile rt_uint32_t control = base + BCM283X_BSC_C; + + rt_uint32_t remaining = len; + rt_uint32_t i = 0; + rt_uint8_t reason = BCM283X_I2C_REASON_OK; + + /* Clear FIFO */ + bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1); + /* Clear Status */ + bcm283x_peri_write(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE); + /* Set Data Length */ + bcm283x_peri_write(dlen, len); + /* pre populate FIFO with max buffer */ + while(remaining && (i < BCM283X_BSC_FIFO_SIZE)) + { + bcm283x_peri_write_nb(fifo, buf[i]); + i++; + remaining--; + } + + /* Enable device and start transfer */ + bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST); + + /* Transfer is over when BCM2835_BSC_S_DONE */ + while(!(bcm283x_peri_read(status) & BCM283X_BSC_S_DONE)) + { + while (remaining && (bcm283x_peri_read(status) & BCM283X_BSC_S_TXD)) + { + /* Write to FIFO */ + bcm283x_peri_write(fifo, buf[i]); + i++; + remaining--; + } + } + + /* Received a NACK */ + if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR) + { + reason = BCM283X_I2C_REASON_ERROR_NACK; + } + + /* Received Clock Stretch Timeout */ + else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT) + { + reason = BCM283X_I2C_REASON_ERROR_CLKT; + } + + /* Not all data is sent */ + else if (remaining) + { + reason = BCM283X_I2C_REASON_ERROR_DATA; + } + + bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE); + + return reason; +} + +rt_uint8_t bcm283x_i2c_write_read_rs(char* cmds, rt_uint32_t cmds_len, char* buf, rt_uint32_t buf_len) +{ + volatile rt_uint32_t dlen = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DLEN; + volatile rt_uint32_t fifo = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_FIFO; + volatile rt_uint32_t status = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_S; + volatile rt_uint32_t control = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_C; + + rt_uint32_t remaining = cmds_len; + rt_uint32_t i = 0; + rt_uint8_t reason = BCM283X_I2C_REASON_OK; + + /* Clear FIFO */ + bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1); + + /* Clear Status */ + bcm283x_peri_write(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE); + + /* Set Data Length */ + bcm283x_peri_write(dlen, cmds_len); + + /* pre populate FIFO with max buffer */ + while(remaining && (i < BCM283X_BSC_FIFO_SIZE)) + { + bcm283x_peri_write_nb(fifo, cmds[i]); + i++; + remaining--; + } + + /* Enable device and start transfer */ + bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST); + + /* poll for transfer has started (way to do repeated start, from BCM2835 datasheet) */ + while (!(bcm283x_peri_read(status) & BCM283X_BSC_S_TA)) + { + /* Linux may cause us to miss entire transfer stage */ + if (bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE) + break; + } + + remaining = buf_len; + i = 0; + + /* Send a repeated start with read bit set in address */ + bcm283x_peri_write(dlen, buf_len); + bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST | BCM283X_BSC_C_READ); + + /* Wait for write to complete and first byte back. */ + bcm283x_clo_delayMicros(100); + + /* wait for transfer to complete */ + while (!(bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE)) + { + /* we must empty the FIFO as it is populated and not use any delay */ + while (remaining && bcm283x_peri_read(status) & BCM283X_BSC_S_RXD) + { + /* Read from FIFO, no barrier */ + buf[i] = bcm283x_peri_read_nb(fifo); + i++; + remaining--; + } + } + + /* transfer has finished - grab any remaining stuff in FIFO */ + while (remaining && (bcm283x_peri_read(status) & BCM283X_BSC_S_RXD)) + { + /* Read from FIFO */ + buf[i] = bcm283x_peri_read(fifo); + i++; + remaining--; + } + + /* Received a NACK */ + if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR) + { + reason = BCM283X_I2C_REASON_ERROR_NACK; + } + + /* Received Clock Stretch Timeout */ + else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT) + { + reason = BCM283X_I2C_REASON_ERROR_CLKT; + } + + /* Not all data is sent */ + else if (remaining) + { + reason = BCM283X_I2C_REASON_ERROR_DATA; + } + + bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE); + + return reason; +} diff --git a/bsp/raspberry-pi/raspi3-64/driver/bcm283x.h b/bsp/raspberry-pi/raspi3-64/driver/bcm283x.h new file mode 100644 index 0000000000..fc9ed1feab --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/bcm283x.h @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-15 RT-Thread the first version + * 2019-07-29 zdzn add macro definition + */ + +#ifndef __BCM283X_H__ +#define __BCM283X_H__ + +#include +#include + +#define PER_BASE (0x3F000000) +#define PER_BASE_40000000 (0x40000000) + + +#define HIGH 0x1 +#define LOW 0x0 + +#define BCM283X_CORE_CLK_HZ 250000000 /* 50 MHz */ + +/*! Offsets for the bases of various peripherals within the peripherals block + * Base Address of the System Timer registers + */ +/*! Base Address of the Pads registers */ +#define BCM283X_GPIO_PADS 0x100000 +/*! Base Address of the Clock/timer registers */ +#define BCM283X_CLOCK_BASE 0x101000 +/*! Base Address of the GPIO registers */ +//#define BCM283X_GPIO_BASE 0x200000 +/*! Base Address of the SPI0 registers */ +#define BCM283X_SPI0_BASE 0x204000 +/*! Base Address of the PWM registers */ +#define BCM283X_GPIO_PWM 0x20C000 +/*! Base Address of the AUX registers */ +#define BCM283X_AUX_BASE 0x215000 +/*! Base Address of the AUX_SPI1 registers */ +#define BCM283X_SPI1_BASE 0x215080 +/*! Base Address of the AUX_SPI2 registers */ +#define BCM283X_SPI2_BASE 0x2150C0 + +/*! Base Address of the BSC0 registers */ +#define BCM283X_BSC0_BASE 0x205000 //for i2c0 +/*! Base Address of the BSC1 registers */ +#define BCM283X_BSC1_BASE 0x804000 //for i2c1 +/*! Base Address of the BSC1 registers */ +#define BCM283X_BSC2_BASE 0x805000 //for hdmi i2c not use + +/* + * GPIO + */ +#define GPIO_BASE (PER_BASE + 0x200000) +#define GPIO_GPFSEL0 HWREG32(GPIO_BASE + 0x0000) /* GPIO Function Select 0 32bit R/W */ +#define GPIO_GPFSEL1 HWREG32(GPIO_BASE + 0x0004) /* GPIO Function Select 1 32bit R/W */ +#define GPIO_GPFSEL2 HWREG32(GPIO_BASE + 0x0008) /* GPIO Function Select 2 32bit R/W */ +#define GPIO_GPFSEL4 HWREG32(GPIO_BASE + 0x0010) /* GPIO Function Select 4 32bit R/W */ +#define GPIO_GPFSEL5 HWREG32(GPIO_BASE + 0x0014) /* GPIO Function Select 5 32bit R/W */ +#define GPIO_GPSET0 HWREG32(GPIO_BASE + 0x001C) +#define GPIO_GPSET1 HWREG32(GPIO_BASE + 0x0020) +#define GPIO_GPCLR0 HWREG32(GPIO_BASE + 0x0028) +#define GPIO_GPCLR1 HWREG32(GPIO_BASE + 0x002C) +#define GPIO_GPEDS0 HWREG32(GPIO_BASE + 0x0040) /* GPIO Pin Event Detect Status */ +#define GPIO_GPEDS1 HWREG32(GPIO_BASE + 0x0044) +#define GPIO_GPREN0 HWREG32(GPIO_BASE + 0x004c) /* GPIO Pin Rising Edge Detect Enable */ +#define GPIO_GPREN1 HWREG32(GPIO_BASE + 0x0050) +#define GPIO_GPFEN0 HWREG32(GPIO_BASE + 0x0058) /* GPIO Pin Falling Edge Detect Enable */ +#define GPIO_GPFEN1 HWREG32(GPIO_BASE + 0x005C) +#define GPIO_GPHEN0 HWREG32(GPIO_BASE + 0x0064) /* GPIO Pin High Detect Enable */ +#define GPIO_GPHEN1 HWREG32(GPIO_BASE + 0x0068) +#define GPIO_GPLEN0 HWREG32(GPIO_BASE + 0x0070) /* GPIO Pin Low Detect Enable 0 */ +#define GPIO_GPLEN1 HWREG32(GPIO_BASE + 0x0074) +#define GPIO_GPAREN0 HWREG32(GPIO_BASE + 0x007C) /* GPIO Pin Async. Rising Edge Detect */ +#define GPIO_GPAREN1 HWREG32(GPIO_BASE + 0x0080) +#define GPIO_GPAFEN0 HWREG32(GPIO_BASE + 0x0088) /* GPIO Pin Async. Falling Edge Detect */ +#define GPIO_GPAFEN1 HWREG32(GPIO_BASE + 0x008C) +#define GPIO_GPPUD HWREG32(GPIO_BASE + 0x0094) /* GPIO Pin Pull-up/down Enable */ +#define GPIO_GPPUDCLK0 HWREG32(GPIO_BASE + 0x0098) /* GPIO Pin Pull-up/down Enable Clock 0 */ +#define GPIO_GPPUDCLK1 HWREG32(GPIO_BASE + 0x009C) /* GPIO Pin Pull-up/down Enable Clock 1 */ + +#define BCM283X_GPIO_BASE (PER_BASE + 0x200000) +#define BCM283X_GPIO_GPFSEL0 (0x0000) /* GPIO Function Select 0 32bit R/W */ +#define BCM283X_GPIO_GPFSEL1 (0x0004) /* GPIO Function Select 1 32bit R/W */ +#define BCM283X_GPIO_GPFSEL2 (0x0008) /* GPIO Function Select 2 32bit R/W */ +#define BCM283X_GPIO_GPFSEL4 (0x0010) /* GPIO Function Select 4 32bit R/W */ +#define BCM283X_GPIO_GPFSEL5 (0x0014) /* GPIO Function Select 5 32bit R/W */ +#define BCM283X_GPIO_GPSET0 (0x001C) +#define BCM283X_GPIO_GPSET1 (0x0020) +#define BCM283X_GPIO_GPCLR0 (0x0028) +#define BCM283X_GPIO_GPCLR1 (0x002C) +#define BCM2835_GPIO_GPLEV0 (0x0034) /*!< GPIO Pin Level 0 */ +#define BCM2835_GPIO_GPLEV1 (0x0038) /*!< GPIO Pin Level 1 */ +#define BCM283X_GPIO_GPEDS0 (0x0040) /* GPIO Pin Event Detect Status */ +#define BCM283X_GPIO_GPEDS1 (0x0044) +#define BCM283X_GPIO_GPREN0 (0x004c) /* GPIO Pin Rising Edge Detect Enable */ +#define BCM283X_GPIO_GPREN1 (0x0050) +#define BCM283X_GPIO_GPFEN0 (0x0058) /* GPIO Pin Falling Edge Detect Enable */ +#define BCM283X_GPIO_GPFEN1 (0x005C) +#define BCM283X_GPIO_GPHEN0 (0x0064) /* GPIO Pin High Detect Enable */ +#define BCM283X_GPIO_GPHEN1 (0x0068) +#define BCM283X_GPIO_GPLEN0 (0x0070) /* GPIO Pin Low Detect Enable 0 */ +#define BCM283X_GPIO_GPLEN1 (0x0074) +#define BCM283X_GPIO_GPAREN0 (0x007C) /* GPIO Pin Async. Rising Edge Detect */ +#define BCM283X_GPIO_GPAREN1 (0x0080) +#define BCM283X_GPIO_GPAFEN0 (0x0088) /* GPIO Pin Async. Falling Edge Detect */ +#define BCM283X_GPIO_GPAFEN1 (0x008C) +#define BCM283X_GPIO_GPPUD (0x0094) /* GPIO Pin Pull-up/down Enable */ +#define BCM283X_GPIO_GPPUDCLK0 (0x0098) /* GPIO Pin Pull-up/down Enable Clock 0 */ +#define BCM283X_GPIO_GPPUDCLK1 (0x009C) /* GPIO Pin Pull-up/down Enable Clock 1 */ + +enum gpio_function_select +{ + BCM283X_GPIO_FSEL_INPT = 0x00, /*!< Input 0b000 */ + BCM283X_GPIO_FSEL_OUTP = 0x01, /*!< Output 0b001 */ + BCM283X_GPIO_FSEL_ALT0 = 0x04, /*!< Alternate function 0 0b100 */ + BCM283X_GPIO_FSEL_ALT1 = 0x05, /*!< Alternate function 1 0b101 */ + BCM283X_GPIO_FSEL_ALT2 = 0x06, /*!< Alternate function 2 0b110, */ + BCM283X_GPIO_FSEL_ALT3 = 0x07, /*!< Alternate function 3 0b111 */ + BCM283X_GPIO_FSEL_ALT4 = 0x03, /*!< Alternate function 4 0b011 */ + BCM283X_GPIO_FSEL_ALT5 = 0x02, /*!< Alternate function 5 0b010 */ + BCM283X_GPIO_FSEL_MASK = 0x07 /*!< Function select bits mask 0b111 */ +}; + +enum gpio_pud_mode +{ + BCM283X_GPIO_PUD_OFF = 0x00, /*!< Off ? disable pull-up/down 0b00 */ + BCM283X_GPIO_PUD_DOWN = 0x01, /*!< Enable Pull Down control 0b01 */ + BCM283X_GPIO_PUD_UP = 0x02 /*!< Enable Pull Up control 0b10 */ +}; + +/* Defines for BSC I2C + * GPIO register offsets from BCM283X_BSC*_BASE. + * Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map + */ +/* I2C Address Map offset address */ +#define BCM283X_BSC_C 0x0000 /*!< BSC Master Control */ +#define BCM283X_BSC_S 0x0004 /*!< BSC Master Status */ +#define BCM283X_BSC_DLEN 0x0008 /*!< BSC Master Data Length */ +#define BCM283X_BSC_A 0x000c /*!< BSC Master Slave Address */ +#define BCM283X_BSC_FIFO 0x0010 /*!< BSC Master Data FIFO */ +#define BCM283X_BSC_DIV 0x0014 /*!< BSC Master Clock Divider */ +#define BCM283X_BSC_DEL 0x0018 /*!< BSC Master Data Delay */ +#define BCM283X_BSC_CLKT 0x001c /*!< BSC Master Clock Stretch Timeout */ + +/* Register masks for C Register */ +#define BCM283X_BSC_C_I2CEN 0x00008000 /*!< I2C Enable, 0 = disabled, 1 = enabled */ +#define BCM283X_BSC_C_INTR 0x00000400 /*!< Interrupt on RX */ +#define BCM283X_BSC_C_INTT 0x00000200 /*!< Interrupt on TX */ +#define BCM283X_BSC_C_INTD 0x00000100 /*!< Interrupt on DONE */ +#define BCM283X_BSC_C_ST 0x00000080 /*!< Start transfer, 1 = Start a new transfer */ +#define BCM283X_BSC_C_CLEAR_1 0x00000020 /*!< Clear FIFO Clear */ +#define BCM283X_BSC_C_CLEAR_2 0x00000010 /*!< Clear FIFO Clear */ +#define BCM283X_BSC_C_READ 0x00000001 /*!< Read transfer */ + +/* Register masks for S Register */ +#define BCM283X_BSC_S_CLKT 0x00000200 /*!< Clock stretch timeout */ +#define BCM283X_BSC_S_ERR 0x00000100 /*!< ACK error */ +#define BCM283X_BSC_S_RXF 0x00000080 /*!< RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full */ +#define BCM283X_BSC_S_TXE 0x00000040 /*!< TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full */ +#define BCM283X_BSC_S_RXD 0x00000020 /*!< RXD FIFO contains data */ +#define BCM283X_BSC_S_TXD 0x00000010 /*!< TXD FIFO can accept data */ +#define BCM283X_BSC_S_RXR 0x00000008 /*!< RXR FIFO needs reading (full) */ +#define BCM283X_BSC_S_TXW 0x00000004 /*!< TXW FIFO needs writing (full) */ +#define BCM283X_BSC_S_DONE 0x00000002 /*!< Transfer DONE */ +#define BCM283X_BSC_S_TA 0x00000001 /*!< Transfer Active */ + +#define BCM283X_BSC_FIFO_SIZE 16 /*!< BSC FIFO size */ + +enum i2c_clock_divider +{ + BCM283X_I2C_CLOCK_DIVIDER_2500 = 2500, /*!< 2500 = 10us = 100 kHz */ + BCM283X_I2C_CLOCK_DIVIDER_626 = 626, /*!< 622 = 2.504us = 399.3610 kHz */ + BCM283X_I2C_CLOCK_DIVIDER_150 = 150, /*!< 150 = 60ns = 1.666 MHz (default at reset) */ + BCM283X_I2C_CLOCK_DIVIDER_148 = 148 /*!< 148 = 59ns = 1.689 MHz */ +}; + +enum i2c_reason_codes +{ + BCM283X_I2C_REASON_OK = 0x00, /*!< Success */ + BCM283X_I2C_REASON_ERROR_NACK = 0x01, /*!< Received a NACK */ + BCM283X_I2C_REASON_ERROR_CLKT = 0x02, /*!< Received Clock Stretch Timeout */ + BCM283X_I2C_REASON_ERROR_DATA = 0x04 /*!< Not all data is sent / received */ +}; + +/* + * Interrupt Controler + */ +#define IRQ_BASE (PER_BASE + 0xB200) +#define IRQ_PEND_BASIC HWREG32(IRQ_BASE + 0x00) +#define IRQ_PEND1 HWREG32(IRQ_BASE + 0x04) +#define IRQ_PEND2 HWREG32(IRQ_BASE + 0x08) +#define IRQ_FIQ_CONTROL HWREG32(IRQ_BASE + 0x0C) +#define IRQ_ENABLE1 HWREG32(IRQ_BASE + 0x10) +#define IRQ_ENABLE2 HWREG32(IRQ_BASE + 0x14) +#define IRQ_ENABLE_BASIC HWREG32(IRQ_BASE + 0x18) +#define IRQ_DISABLE1 HWREG32(IRQ_BASE + 0x1C) +#define IRQ_DISABLE2 HWREG32(IRQ_BASE + 0x20) +#define IRQ_DISABLE_BASIC HWREG32(IRQ_BASE + 0x24) + +/* + * System Timer + */ +#define STIMER_BASE (PER_BASE + 0x3000) +#define STIMER_CS HWREG32(STIMER_BASE + 0x00) +#define STIMER_CLO HWREG32(STIMER_BASE + 0x04) +#define STIMER_CHI HWREG32(STIMER_BASE + 0x08) +#define STIMER_C0 HWREG32(STIMER_BASE + 0x0C) +#define STIMER_C1 HWREG32(STIMER_BASE + 0x10) +#define STIMER_C2 HWREG32(STIMER_BASE + 0x14) +#define STIMER_C3 HWREG32(STIMER_BASE + 0x18) + +/* Defines for ST */ +#define BCM283X_ST_BASE (PER_BASE + 0x3000) +#define BCM283X_ST_CS 0x0000 /*!< System Timer Control/Status */ +#define BCM283X_ST_CLO 0x0004 /*!< System Timer Counter Lower 32 bits */ +#define BCM283X_ST_CHI 0x0008 /*!< System Timer Counter Upper 32 bits */ +#define BCM283X_ST_C0 0x000C +#define BCM283X_ST_C1 0x0010 +#define BCM283X_ST_C2 0x0014 +#define BCM283X_ST_C3 0x0018 + +/* + * ARM Timer + */ +#define ARM_TIMER_BASE (PER_BASE + 0xB000) +#define ARM_TIMER_LOAD HWREG32(ARM_TIMER_BASE + 0x400) +#define ARM_TIMER_VALUE HWREG32(ARM_TIMER_BASE + 0x404) +#define ARM_TIMER_CTRL HWREG32(ARM_TIMER_BASE + 0x408) +#define ARM_TIMER_IRQCLR HWREG32(ARM_TIMER_BASE + 0x40C) +#define ARM_TIMER_RAWIRQ HWREG32(ARM_TIMER_BASE + 0x410) +#define ARM_TIMER_MASKIRQ HWREG32(ARM_TIMER_BASE + 0x414) +#define ARM_TIMER_RELOAD HWREG32(ARM_TIMER_BASE + 0x418) +#define ARM_TIMER_PREDIV HWREG32(ARM_TIMER_BASE + 0x41C) +#define ARM_TIMER_CNTR HWREG32(ARM_TIMER_BASE + 0x420) + +/* + * Core Timer + */ +#define CTIMER_CTL HWREG32(PER_BASE_40000000 + 0x00) /* Control register */ +#define CTIMER_PRE HWREG32(PER_BASE_40000000 + 0x08) /* Core timer prescaler */ +#define CTIMER_LS32B HWREG32(PER_BASE_40000000 + 0x1C) /* Core timer access LS 32 bits */ +#define CTIMER_MS32B HWREG32(PER_BASE_40000000 + 0x20) /* Core timer access MS 32 bits */ + +/* + * ARM Core Timer + */ +#define C0TIMER_INTCTL HWREG32(PER_BASE_40000000 + 0x40) /* Core0 timers Interrupt control */ +#define C1TIMER_INTCTL HWREG32(PER_BASE_40000000 + 0x44) /* Core1 timers Interrupt control */ +#define C2TIMER_INTCTL HWREG32(PER_BASE_40000000 + 0x48) /* Core2 timers Interrupt control */ +#define C3TIMER_INTCTL HWREG32(PER_BASE_40000000 + 0x4C) /* Core3 timers Interrupt control */ +#define CORETIMER_INTCTL(n) HWREG32(PER_BASE_40000000 + 0x40 + n*4) /* Core3 timers Interrupt control */ +/* + * ARM Core Mailbox interrupt + */ +#define C0MB_INTCTL HWREG32(PER_BASE_40000000 + 0x50) /* Core0 Mailboxes Interrupt control */ +#define C1MB_INTCTL HWREG32(PER_BASE_40000000 + 0x54) /* Core1 Mailboxes Interrupt control */ +#define C2MB_INTCTL HWREG32(PER_BASE_40000000 + 0x58) /* Core2 Mailboxes Interrupt control */ +#define C3MB_INTCTL HWREG32(PER_BASE_40000000 + 0x5C) /* Core3 Mailboxes Interrupt control */ +#define COREMB_INTCTL(n) HWREG32(PER_BASE_40000000 + 0x50 + 4*n) /* Core3 Mailboxes Interrupt control */ +/* + * ARM Core IRQ/FIQ status + */ +#define C0_IRQSOURCE HWREG32(PER_BASE_40000000 + 0x60) /* Core0 IRQ Source */ +#define C1_IRQSOURCE HWREG32(PER_BASE_40000000 + 0x64) /* Core1 IRQ Source */ +#define C2_IRQSOURCE HWREG32(PER_BASE_40000000 + 0x68) /* Core2 IRQ Source */ +#define C3_IRQSOURCE HWREG32(PER_BASE_40000000 + 0x6C) /* Core3 IRQ Source */ +#define C0_FIQSOURCE HWREG32(PER_BASE_40000000 + 0x70) /* Core0 FIQ Source */ +#define C1_FIQSOURCE HWREG32(PER_BASE_40000000 + 0x74) /* Core1 FIQ Source */ +#define C2_FIQSOURCE HWREG32(PER_BASE_40000000 + 0x78) /* Core2 FIQ Source */ +#define C3_FIQSOURCE HWREG32(PER_BASE_40000000 + 0x7C) /* Core3 FIQ Source */ +#define CORE_IRQSOURCE(n) HWREG32(PER_BASE_40000000 + 0x60+ n*0x4) +#define CORE_FIQSOURCE(n) HWREG32(PER_BASE_40000000 + 0x70+ n*0x4) + +#define CORE_MAILBOX3_SET(n) HWREG32(PER_BASE_40000000 + 0x8C + n*0x10) +#define CORE_MAILBOX3_CLEAR(n) HWREG32(PER_BASE_40000000 + 0xCC + n*0x10) +#define CORE_MAILBOX2_SET(n) HWREG32(PER_BASE_40000000 + 0x88 + n*0x10) +#define CORE_MAILBOX2_CLEAR(n) HWREG32(PER_BASE_40000000 + 0xC8 + n*0x10) +#define CORE_MAILBOX1_SET(n) HWREG32(PER_BASE_40000000 + 0x84 + n*0x10) +#define CORE_MAILBOX1_CLEAR(n) HWREG32(PER_BASE_40000000 + 0xC4 + n*0x10) +#define CORE_MAILBOX0_SET(n) HWREG32(PER_BASE_40000000 + 0x80 + n*0x10) +#define CORE_MAILBOX0_CLEAR(n) HWREG32(PER_BASE_40000000 + 0xC0 + n*0x10) + +/* for smp ipi using mailbox0 */ +#define IPI_MAILBOX_SET CORE_MAILBOX0_SET + +#define IPI_MAILBOX_CLEAR CORE_MAILBOX0_CLEAR +#define IPI_MAILBOX_INT_MASK (0x01) + +#define IRQ_ARM_TIMER 64 +#define IRQ_ARM_MAILBOX 65 +#define IRQ_ARM_DB0 66 +#define IRQ_ARM_DB1 67 +#define IRQ_ARM_GPU0_HALT 68 +#define IRQ_ARM_GPU1_HALT 69 +#define IRQ_ARM_ILLEGAL_ACC1 70 +#define IRQ_ARM_ILLEGAL_ACC0 71 + +#define IRQ_SYSTIMER_MATCH_1 1 +#define IRQ_SYSTIMER_MATCH_3 3 + +#define IRQ_AUX 29 +#define IRQ_IIC_SPI_SLV 43 +#define IRQ_PWA0 45 +#define IRQ_PWA1 46 +#define IRQ_SMI 48 +#define IRQ_GPIO0 49 +#define IRQ_GPIO1 50 +#define IRQ_GPIO2 51 +#define IRQ_GPIO3 52 +#define IRQ_IIC 53 +#define IRQ_SPI 54 +#define IRQ_PCM 55 +#define IRQ_UART 57 + +/* CLOCK */ +#define BCM283X_PLLA 0 +#define BCM283X_PLLB 1 +#define BCM283X_PLLC 2 +#define BCM283X_PLLD 3 +#define BCM283X_PLLH 4 + +#define BCM283X_PLLA_CORE 5 +#define BCM283X_PLLA_PER 6 +#define BCM283X_PLLB_ARM 7 +#define BCM283X_PLLC_CORE0 8 +#define BCM283X_PLLC_CORE1 9 +#define BCM283X_PLLC_CORE2 10 +#define BCM283X_PLLC_PER 11 +#define BCM283X_PLLD_CORE 12 +#define BCM283X_PLLD_PER 13 +#define BCM283X_PLLH_RCAL 14 +#define BCM283X_PLLH_AUX 15 +#define BCM283X_PLLH_PIX 16 + +#define BCM283X_CLOCK_TIMER 17 +#define BCM283X_CLOCK_OTP 18 +#define BCM283X_CLOCK_UART 19 +#define BCM283X_CLOCK_VPU 20 +#define BCM283X_CLOCK_V3D 21 +#define BCM283X_CLOCK_ISP 22 +#define BCM283X_CLOCK_H264 23 +#define BCM283X_CLOCK_VEC 24 +#define BCM283X_CLOCK_HSM 25 +#define BCM283X_CLOCK_SDRAM 26 +#define BCM283X_CLOCK_TSENS 27 +#define BCM283X_CLOCK_EMMC 28 +#define BCM283X_CLOCK_PERI_IMAGE 29 +#define BCM283X_CLOCK_COUNT 30 + +#define CM_PASSWORD 0x5a000000 + +#define CM_GNRICCTL 0x000 +#define CM_GNRICDIV 0x004 +#define CM_VPUCTL 0x008 +#define CM_VPUDIV 0x00c +#define CM_SYSCTL 0x010 +#define CM_SYSDIV 0x014 +#define CM_PERIACTL 0x018 +#define CM_PERIADIV 0x01c +#define CM_PERIICTL 0x020 +#define CM_PERIIDIV 0x024 +#define CM_H264CTL 0x028 +#define CM_H264DIV 0x02c +#define CM_ISPCTL 0x030 +#define CM_ISPDIV 0x034 +#define CM_V3DCTL 0x038 +#define CM_V3DDIV 0x03c +#define CM_CAM0CTL 0x040 +#define CM_CAM0DIV 0x044 +#define CM_CAM1CTL 0x048 +#define CM_CAM1DIV 0x04c +#define CM_CCP2CTL 0x050 +#define CM_CCP2DIV 0x054 +#define CM_DSI0ECTL 0x058 +#define CM_DSI0EDIV 0x05c +#define CM_DSI0PCTL 0x060 +#define CM_DSI0PDIV 0x064 +#define CM_DPICTL 0x068 +#define CM_DPIDIV 0x06c +#define CM_GP0CTL 0x070 +#define CM_GP0DIV 0x074 +#define CM_GP1CTL 0x078 +#define CM_GP1DIV 0x07c +#define CM_GP2CTL 0x080 +#define CM_GP2DIV 0x084 +#define CM_HSMCTL 0x088 +#define CM_HSMDIV 0x08c +#define CM_OTPCTL 0x090 +#define CM_OTPDIV 0x094 +#define CM_PWMCTL 0x0a0 +#define CM_PWMDIV 0x0a4 +#define CM_SMICTL 0x0b0 +#define CM_SMIDIV 0x0b4 +#define CM_TSENSCTL 0x0e0 +#define CM_TSENSDIV 0x0e4 +#define CM_TIMERCTL 0x0e8 +#define CM_TIMERDIV 0x0ec +#define CM_UARTCTL 0x0f0 +#define CM_UARTDIV 0x0f4 +#define CM_VECCTL 0x0f8 +#define CM_VECDIV 0x0fc +#define CM_PULSECTL 0x190 +#define CM_PULSEDIV 0x194 +#define CM_SDCCTL 0x1a8 +#define CM_SDCDIV 0x1ac +#define CM_ARMCTL 0x1b0 +#define CM_EMMCCTL 0x1c0 +#define CM_EMMCDIV 0x1c4 + +#define BCM283X_AUX_IRQ 0x0000 /*!< xxx */ +#define BCM283X_AUX_ENABLE 0x0004 /*!< */ +#define BCM283X_AUX_ENABLE_UART1 0x01 /*!< */ +#define BCM283X_AUX_ENABLE_SPI0 0x02 /*!< SPI0 (SPI1 in the device) */ +#define BCM283X_AUX_ENABLE_SPI1 0x04 /*!< SPI1 (SPI2 in the device) */ +#define BCM283X_AUX_SPI_CNTL0 0x0000 /*!< */ +#define BCM283X_AUX_SPI_CNTL1 0x0004 /*!< */ +#define BCM283X_AUX_SPI_STAT 0x0008 /*!< */ +#define BCM283X_AUX_SPI_PEEK 0x000C /*!< Read but do not take from FF */ +#define BCM283X_AUX_SPI_IO 0x0020 /*!< Write = TX, read=RX */ +#define BCM283X_AUX_SPI_TXHOLD 0x0030 /*!< Write = TX keep CS, read=RX */ +#define BCM283X_AUX_SPI_CLOCK_MIN 30500 /*!< 30,5kHz */ +#define BCM283X_AUX_SPI_CLOCK_MAX 125000000 /*!< 125Mhz */ +#define BCM283X_AUX_SPI_CNTL0_SPEED 0xFFF00000 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_SPEED_MAX 0xFFF /*!< */ +#define BCM283X_AUX_SPI_CNTL0_SPEED_SHIFT 20 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_CS0_N 0x000C0000 /*!< CS 0 low */ +#define BCM283X_AUX_SPI_CNTL0_CS1_N 0x000A0000 /*!< CS 1 low */ +#define BCM283X_AUX_SPI_CNTL0_CS2_N 0x00060000 /*!< CS 2 low */ +#define BCM283X_AUX_SPI_CNTL0_POSTINPUT 0x00010000 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_VAR_CS 0x00008000 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_VAR_WIDTH 0x00004000 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_DOUTHOLD 0x00003000 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_ENABLE 0x00000800 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_CPHA_IN 0x00000400 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_CLEARFIFO 0x00000200 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_CPHA_OUT 0x00000100 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_CPOL 0x00000080 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_MSBF_OUT 0x00000040 /*!< */ +#define BCM283X_AUX_SPI_CNTL0_SHIFTLEN 0x0000003F /*!< */ +#define BCM283X_AUX_SPI_CNTL1_CSHIGH 0x00000700 /*!< */ +#define BCM283X_AUX_SPI_CNTL1_IDLE 0x00000080 /*!< */ +#define BCM283X_AUX_SPI_CNTL1_TXEMPTY 0x00000040 /*!< */ +#define BCM283X_AUX_SPI_CNTL1_MSBF_IN 0x00000002 /*!< */ +#define BCM283X_AUX_SPI_CNTL1_KEEP_IN 0x00000001 /*!< */ +#define BCM283X_AUX_SPI_STAT_TX_LVL 0xFF000000 /*!< */ +#define BCM283X_AUX_SPI_STAT_RX_LVL 0x00FF0000 /*!< */ +#define BCM283X_AUX_SPI_STAT_TX_FULL 0x00000400 /*!< */ +#define BCM283X_AUX_SPI_STAT_TX_EMPTY 0x00000200 /*!< */ +#define BCM283X_AUX_SPI_STAT_RX_FULL 0x00000100 /*!< */ +#define BCM283X_AUX_SPI_STAT_RX_EMPTY 0x00000080 /*!< */ +#define BCM283X_AUX_SPI_STAT_BUSY 0x00000040 /*!< */ +#define BCM283X_AUX_SPI_STAT_BITCOUNT 0x0000003F /*!< */ + +/* Defines for SPI */ +#define BCM283X_SPI0_CS 0x0000 /*!< SPI Master Control and Status */ +#define BCM283X_SPI0_FIFO 0x0004 /*!< SPI Master TX and RX FIFOs */ +#define BCM283X_SPI0_CLK 0x0008 /*!< SPI Master Clock Divider */ +#define BCM283X_SPI0_DLEN 0x000c /*!< SPI Master Data Length */ +#define BCM283X_SPI0_LTOH 0x0010 /*!< SPI LOSSI mode TOH */ +#define BCM283X_SPI0_DC 0x0014 /*!< SPI DMA DREQ Controls */ + +/* Register masks for SPI0_CS */ +#define BCM283X_SPI0_CS_LEN_LONG 0x02000000 /*!< Enable Long data word in Lossi mode if DMA_LEN is set */ +#define BCM283X_SPI0_CS_DMA_LEN 0x01000000 /*!< Enable DMA mode in Lossi mode */ +#define BCM283X_SPI0_CS_CSPOL2 0x00800000 /*!< Chip Select 2 Polarity */ +#define BCM283X_SPI0_CS_CSPOL1 0x00400000 /*!< Chip Select 1 Polarity */ +#define BCM283X_SPI0_CS_CSPOL0 0x00200000 /*!< Chip Select 0 Polarity */ +#define BCM283X_SPI0_CS_RXF 0x00100000 /*!< RXF - RX FIFO Full */ +#define BCM283X_SPI0_CS_RXR 0x00080000 /*!< RXR RX FIFO needs Reading (full) */ +#define BCM283X_SPI0_CS_TXD 0x00040000 /*!< TXD TX FIFO can accept Data */ +#define BCM283X_SPI0_CS_RXD 0x00020000 /*!< RXD RX FIFO contains Data */ +#define BCM283X_SPI0_CS_DONE 0x00010000 /*!< Done transfer Done */ +#define BCM283X_SPI0_CS_TE_EN 0x00008000 /*!< Unused */ +#define BCM283X_SPI0_CS_LMONO 0x00004000 /*!< Unused */ +#define BCM283X_SPI0_CS_LEN 0x00002000 /*!< LEN LoSSI enable */ +#define BCM283X_SPI0_CS_REN 0x00001000 /*!< REN Read Enable */ +#define BCM283X_SPI0_CS_ADCS 0x00000800 /*!< ADCS Automatically Deassert Chip Select */ +#define BCM283X_SPI0_CS_INTR 0x00000400 /*!< INTR Interrupt on RXR */ +#define BCM283X_SPI0_CS_INTD 0x00000200 /*!< INTD Interrupt on Done */ +#define BCM283X_SPI0_CS_DMAEN 0x00000100 /*!< DMAEN DMA Enable */ +#define BCM283X_SPI0_CS_TA 0x00000080 /*!< Transfer Active */ +#define BCM283X_SPI0_CS_CSPOL 0x00000040 /*!< Chip Select Polarity */ +#define BCM283X_SPI0_CS_CLEAR 0x00000030 /*!< Clear FIFO Clear RX and TX */ +#define BCM283X_SPI0_CS_CLEAR_RX 0x00000020 /*!< Clear FIFO Clear RX */ +#define BCM283X_SPI0_CS_CLEAR_TX 0x00000010 /*!< Clear FIFO Clear TX */ +#define BCM283X_SPI0_CS_CPOL 0x00000008 /*!< Clock Polarity */ +#define BCM283X_SPI0_CS_CPHA 0x00000004 /*!< Clock Phase */ +#define BCM283X_SPI0_CS_CS 0x00000003 /*!< Chip Select */ + +enum spi_bit_order +{ + BCM283X_SPI_BIT_ORDER_LSBFIRST = 0, /*!< LSB First */ + BCM283X_SPI_BIT_ORDER_MSBFIRST = 1 /*!< MSB First */ +}; + +enum spi_mode +{ + BCM283X_SPI_MODE0 = 0, /*!< CPOL = 0, CPHA = 0 */ + BCM283X_SPI_MODE1 = 1, /*!< CPOL = 0, CPHA = 1 */ + BCM283X_SPI_MODE2 = 2, /*!< CPOL = 1, CPHA = 0 */ + BCM283X_SPI_MODE3 = 3 /*!< CPOL = 1, CPHA = 1 */ +}; + +enum spi_chip_select +{ + BCM283X_SPI_CS0 = 0, /*!< Chip Select 0 */ + BCM283X_SPI_CS1 = 1, /*!< Chip Select 1 */ + BCM283X_SPI_CS2 = 2, /*!< Chip Select 2 (ie pins CS1 and CS2 are asserted) */ + BCM283X_SPI_CS_NONE = 3 /*!< No CS, control it yourself */ +}; + +enum spi_clock_divider +{ + BCM283X_SPI_CLOCK_DIVIDER_65536 = 0, /*!< 65536 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_32768 = 32768, /*!< 32768 = 7.629394531kHz on Rpi2, 12.20703125kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_16384 = 16384, /*!< 16384 = 15.25878906kHz on Rpi2, 24.4140625kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_8192 = 8192, /*!< 8192 = 30.51757813kHz on Rpi2, 48.828125kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_4096 = 4096, /*!< 4096 = 61.03515625kHz on Rpi2, 97.65625kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_2048 = 2048, /*!< 2048 = 122.0703125kHz on Rpi2, 195.3125kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_1024 = 1024, /*!< 1024 = 244.140625kHz on Rpi2, 390.625kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_512 = 512, /*!< 512 = 488.28125kHz on Rpi2, 781.25kHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_256 = 256, /*!< 256 = 976.5625kHz on Rpi2, 1.5625MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_128 = 128, /*!< 128 = 1.953125MHz on Rpi2, 3.125MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_64 = 64, /*!< 64 = 3.90625MHz on Rpi2, 6.250MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_32 = 32, /*!< 32 = 7.8125MHz on Rpi2, 12.5MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_16 = 16, /*!< 16 = 15.625MHz on Rpi2, 25MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_8 = 8, /*!< 8 = 31.25MHz on Rpi2, 50MHz on RPI3 */ + BCM283X_SPI_CLOCK_DIVIDER_4 = 4, /*!< 4 = 62.5MHz on Rpi2, 100MHz on RPI3. Dont expect this speed to work reliably. */ + BCM283X_SPI_CLOCK_DIVIDER_2 = 2, /*!< 2 = 125MHz on Rpi2, 200MHz on RPI3, fastest you can get. Dont expect this speed to work reliably.*/ + BCM283X_SPI_CLOCK_DIVIDER_1 = 1 /*!< 1 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3, same as 0/65536 */ +}; + +/* BCM IO pin */ +enum bcm_gpio_pin +{ + BCM_GPIO_PIN_0 = 0, + BCM_GPIO_PIN_1, + BCM_GPIO_PIN_2, + BCM_GPIO_PIN_3, + BCM_GPIO_PIN_4, + BCM_GPIO_PIN_5, + BCM_GPIO_PIN_6, + BCM_GPIO_PIN_7, + BCM_GPIO_PIN_8, + BCM_GPIO_PIN_9, + BCM_GPIO_PIN_10, + BCM_GPIO_PIN_11, + BCM_GPIO_PIN_12, + BCM_GPIO_PIN_13, + BCM_GPIO_PIN_14, + BCM_GPIO_PIN_15, + BCM_GPIO_PIN_16, + BCM_GPIO_PIN_17, + BCM_GPIO_PIN_18, + BCM_GPIO_PIN_19, + BCM_GPIO_PIN_20, + BCM_GPIO_PIN_21, + BCM_GPIO_PIN_22, + BCM_GPIO_PIN_23, + BCM_GPIO_PIN_24, + BCM_GPIO_PIN_25, + BCM_GPIO_PIN_26, + BCM_GPIO_PIN_27, + BCM_GPIO_PIN_28, + BCM_GPIO_PIN_29, + BCM_GPIO_PIN_30, + BCM_GPIO_PIN_31, + BCM_GPIO_PIN_32, + BCM_GPIO_PIN_33, + BCM_GPIO_PIN_34, + BCM_GPIO_PIN_35, + BCM_GPIO_PIN_36, + BCM_GPIO_PIN_37, + BCM_GPIO_PIN_38, + BCM_GPIO_PIN_39, + BCM_GPIO_PIN_40, + BCM_GPIO_PIN_41, + BCM_GPIO_PIN_42, + BCM_GPIO_PIN_43, + BCM_GPIO_PIN_44, + BCM_GPIO_PIN_45, + BCM_GPIO_PIN_46, + BCM_GPIO_PIN_47, + BCM_GPIO_PIN_48, + BCM_GPIO_PIN_49, + BCM_GPIO_PIN_50, + BCM_GPIO_PIN_51, + BCM_GPIO_PIN_52, + BCM_GPIO_PIN_53, + BCM_GPIO_PIN_NUM, +}; + +rt_uint32_t bcm283x_peri_read(volatile rt_ubase_t addr); +rt_uint32_t bcm283x_peri_read_nb(volatile rt_ubase_t addr); +void bcm283x_peri_write(volatile rt_ubase_t addr, rt_uint32_t value); +void bcm283x_peri_write_nb(volatile rt_ubase_t addr, rt_uint32_t value); +void bcm283x_peri_set_bits(volatile rt_ubase_t addr, rt_uint32_t value, rt_uint32_t mask); + +void bcm283x_gpio_fsel(rt_uint8_t pin, rt_uint8_t mode); +void bcm283x_gpio_set(rt_uint8_t pin); +void bcm283x_gpio_clr(rt_uint8_t pin); + +rt_uint8_t bcm283x_gpio_lev(rt_uint8_t pin); +rt_uint8_t bcm283x_gpio_eds(rt_uint8_t pin); +void bcm283x_gpio_set_eds(rt_uint8_t pin); +void bcm283x_gpio_ren(rt_uint8_t pin); +void bcm283x_gpio_clr_ren(rt_uint8_t pin); +void bcm283x_gpio_fen(rt_uint8_t pin); +void bcm283x_gpio_clr_fen(rt_uint8_t pin); +void bcm283x_gpio_hen(rt_uint8_t pin); +void bcm283x_gpio_clr_hen(rt_uint8_t pin); +void bcm283x_gpio_len(rt_uint8_t pin); +void bcm283x_gpio_clr_len(rt_uint8_t pin); +void bcm283x_gpio_aren(rt_uint8_t pin); +void bcm283x_gpio_clr_aren(rt_uint8_t pin); +void bcm283x_gpio_afen(rt_uint8_t pin); +void bcm283x_gpio_clr_afen(rt_uint8_t pin); +void bcm283x_gpio_pud(rt_uint8_t pud); +void bcm283x_gpio_pudclk(rt_uint8_t pin, rt_uint8_t on); +void bcm283x_gpio_set_pud(rt_uint8_t pin, rt_uint8_t pud); +void bcm283x_gpio_write(rt_uint8_t pin, rt_uint8_t val); +void bcm283x_st_delay(rt_uint64_t offset_micros, rt_uint64_t micros); +rt_uint64_t bcm283x_st_read(void); +void bcm283x_delayMicroseconds(rt_uint64_t micros); +void bcm283x_clo_delayMicros(rt_uint32_t micros); + +int bcm283x_i2c_begin(int no); +void bcm283x_i2c_end(int no); +void bcm283x_i2c_setSlaveAddress(int no, rt_uint8_t saddr); +void bcm283x_i2c_setClockDivider(int no, rt_uint16_t divider); +void bcm283x_i2c_set_baudrate(int no, rt_uint32_t baudrate); +rt_uint8_t bcm283x_i2c_read(rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len); +rt_uint8_t bcm283x_i2c_write(rt_uint32_t base, const rt_uint8_t * buf, rt_uint32_t len); +rt_uint8_t bcm283x_i2c_write_read_rs(char* cmds, rt_uint32_t cmds_len, char* buf, rt_uint32_t buf_len); + +#endif + diff --git a/bsp/raspberry-pi/raspi3-64/driver/board.c b/bsp/raspberry-pi/raspi3-64/driver/board.c new file mode 100644 index 0000000000..3c218d09a7 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/board.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include +#include + +#include "board.h" +#include "drv_uart.h" +#include "drv_timer.h" + +#include "cp15.h" + +#ifdef RT_USING_SMP +extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler); + +void ipi_handler(){ + rt_scheduler_ipi_handler(0,RT_NULL); +} +#endif + +void rt_hw_timer_isr(int vector, void *parameter) +{ + ARM_TIMER_IRQCLR = 0; + rt_tick_increase(); +} + +int rt_hw_timer_init() +{ + __DSB(); + rt_hw_interrupt_install(IRQ_ARM_TIMER, rt_hw_timer_isr, RT_NULL, "tick"); + rt_hw_interrupt_umask(IRQ_ARM_TIMER); + /* timer_clock = apb_clock/(pre_divider + 1) */ + ARM_TIMER_PREDIV = (250 - 1); + + ARM_TIMER_RELOAD = 0; + ARM_TIMER_LOAD = 0; + ARM_TIMER_IRQCLR = 0; + ARM_TIMER_CTRL = 0; + + ARM_TIMER_RELOAD = 10000; + ARM_TIMER_LOAD = 10000; + + /* 23-bit counter, enable interrupt, enable timer */ + ARM_TIMER_CTRL = (1 << 1) | (1 << 5) | (1 << 7); + return 0; +} + +void idle_wfi(void) +{ + asm volatile ("wfi"); +} + +#define MMU_LEVEL_MASK 0x1ffUL +#define MMU_MAP_ERROR_VANOTALIGN -1 +#define MMU_MAP_ERROR_PANOTALIGN -2 +#define MMU_MAP_ERROR_NOPAGE -3 +#define MMU_MAP_ERROR_CONFLICT -4 + +unsigned char main_tbl[4096] __attribute__((aligned (4096))); +unsigned char __page_start[4096*100] __attribute__((aligned (4096))); +unsigned long __page_off = 0; +unsigned long get_free_page(void) { + __page_off += 4096; + return (unsigned long)(__page_start + __page_off - 4096); +} + +#define MEM_ATTR_MEM ((0x1UL << 10) | (0x2UL << 8) | (0x0UL << 6) | (0x1UL << 2)) +#define MEM_ATTR_IO ((0x1UL << 10) | (0x2UL << 8) | (0x0UL << 6) | (0x2UL << 2)) + +static int map_single_page_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr) { + int level; + unsigned long* cur_lv_tbl = lv0_tbl; + unsigned long page; + unsigned long off; + int level_shift = 39; + + if (va & (0x200000UL - 1)) { + return MMU_MAP_ERROR_VANOTALIGN; + } + if (pa & (0x200000UL - 1)) { + return MMU_MAP_ERROR_PANOTALIGN; + } + for (level = 0; level < 2; level++) { + off = (va >> level_shift); + off &= MMU_LEVEL_MASK; + if ((cur_lv_tbl[off] & 1) == 0) { + page = get_free_page(); + if (!page) { + return MMU_MAP_ERROR_NOPAGE; + } + rt_memset((void *)page, 0, 4096); + cur_lv_tbl[off] = page | 0x3UL; + } + page = cur_lv_tbl[off]; + if (!(page & 0x2)) { + //is block! error! + return MMU_MAP_ERROR_CONFLICT; + } + cur_lv_tbl = (unsigned long*)(page & 0x0000fffffffff000UL); + level_shift -= 9; + } + attr &= 0xfff0000000000ffcUL; + pa |= (attr | 0x1UL); //block + off = (va >> 21); + off &= MMU_LEVEL_MASK; + cur_lv_tbl[off] = pa; + return 0; +} + +int armv8_map_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, int count, unsigned long attr) +{ + int i; + int ret; + + if (va & (0x200000 - 1)) + { + return -1; + } + if (pa & (0x200000 - 1)) + { + return -1; + } + for (i = 0; i < count; i++) + { + ret = map_single_page_2M(lv0_tbl, va, pa, attr); + va += 0x200000; + pa += 0x200000; + if (ret != 0) + { + return ret; + } + } + return 0; +} + +/** + * Initialize the Hardware related stuffs. Called from rtthread_startup() + * after interrupt disabled. + */ +void rt_hw_board_init(void) +{ + /* mmu set */ + unsigned long val64; + unsigned long val32; //val32不是uint32_t,val32只是表示相关的那个寄存器是32位的 + int ret; + + val64 = 0x007f6eUL; + asm volatile("msr MAIR_EL1, %0\n dsb sy\n"::"r"(val64)); + asm volatile("mrs %0, MAIR_EL1\n dsb sy\n":"=r"(val64)); + + //TCR_EL1 + val32 = (16UL << 0) + | (0x0UL << 6) + | (0x0UL << 7) + | (0x3UL << 8) + | (0x3UL << 10) + | (0x2UL << 12) + | (0x0UL << 14) + | (0x0UL << 16) + | (0x0UL << 22) + | (0x1UL << 23) + | (0x2UL << 30) + | (0x1UL << 32) + | (0x0UL << 35) + | (0x0UL << 36) + | (0x0UL << 37) + | (0x0UL << 38); + asm volatile("msr TCR_EL1, %0\n"::"r"(val32)); + asm volatile("mrs %0, TCR_EL1\n":"=r"(val32)); + + asm volatile("msr TTBR0_EL1, %0\n dsb sy\n"::"r"(main_tbl)); + asm volatile("mrs %0, TTBR0_EL1\n dsb sy\n":"=r"(val64)); + + rt_memset(main_tbl, 0, 4096); + + ret = armv8_map_2M((unsigned long *)main_tbl, 0x0, 0x0, 32, MEM_ATTR_MEM); //32*2M = 64M + if (ret) + { + goto skip_mmu; + } + ret = armv8_map_2M((unsigned long *)main_tbl, 0x3f000000, 0x3f000000, 8, MEM_ATTR_IO); //8*2M = 16M + if (ret) + { + goto skip_mmu; + } + + //关闭指令cache + __asm__ volatile("mrs %0, SCTLR_EL1\n":"=r"(val64)); + val64 &= ~0x1000; //disable I + __asm__ volatile("dmb sy\n msr SCTLR_EL1, %0\n isb sy\n"::"r"(val64)); + + //清除指令cache + __asm__ volatile("IC IALLUIS\n dsb sy\n isb sy\n"); + //清除tlb + __asm__ volatile("tlbi vmalle1\n dsb sy\n isb sy\n"); + + //SCTLR_EL1, turn on mmu + asm volatile("mrs %0, SCTLR_EL1\n":"=r"(val32)); + val32 |= 0x1005; //enable mmu, I C M + asm volatile("dmb sy\n msr SCTLR_EL1, %0\nisb sy\n"::"r"(val32)); + +skip_mmu: + + /* initialize hardware interrupt */ + rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device + rt_hw_vector_init(); // in libcpu/interrupt.c. == rt_cpu_vector_set_base((rt_ubase_t)&system_vectors); + + /* initialize uart */ + rt_hw_uart_init(); // driver/drv_uart.c + /* initialize timer for os tick */ + rt_hw_timer_init(); + rt_thread_idle_sethook(idle_wfi); + +#ifdef RT_USING_CONSOLE + /* set console device */ + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif /* RT_USING_CONSOLE */ + +#ifdef RT_USING_HEAP + /* initialize memory system */ + rt_kprintf("heap: 0x%08x - 0x%08x\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); + rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + rt_kprintf("__page_off = %x\n", __page_off); +} + +#ifdef RT_USING_SMP +void _reset(void); +void secondary_cpu_start(void); + +void rt_hw_secondary_cpu_up(void) +{ + int i; + int retry,val; + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); + /*TODO maybe, there is some bug */ + for(i=RT_CPUS_NR-1; i>0; i-- ) + { + rt_kprintf("boot cpu:%d\n", i); + setup_bootstrap_addr(i, (int)_reset); + __SEV(); + __DSB(); + __ISB(); + retry = 10; + rt_thread_delay(RT_TICK_PER_SECOND/1000); + do + { + val = CORE_MAILBOX3_CLEAR(i); + if (val == 0) + { + rt_kprintf("start OK: CPU %d \n",i); + break; + } + rt_thread_delay(RT_TICK_PER_SECOND); + + retry --; + if (retry <= 0) + { + rt_kprintf("can't start for CPU %d \n",i); + break; + } + }while (1); + } + __DSB(); + __SEV(); +} + +void secondary_cpu_c_start(void) +{ + uint32_t id; + id = rt_hw_cpu_id(); + rt_kprintf("cpu = 0x%08x\n",id); + rt_hw_timer_init(); + rt_kprintf("cpu %d startup.\n",id); + rt_hw_vector_init(); + enable_cpu_ipi_intr(id); + rt_hw_spin_lock(&_cpus_lock); + rt_system_scheduler_start(); +} + +void rt_hw_secondary_cpu_idle_exec(void) +{ + __WFE(); +} + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/board.h b/bsp/raspberry-pi/raspi3-64/driver/board.h new file mode 100644 index 0000000000..40fbfd9d84 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/board.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 Bernard the first version + */ + +#ifndef BOARD_H__ +#define BOARD_H__ + +#include + +#include +#include + +#define __REG32 HWREG32 +extern unsigned char __bss_start; +extern unsigned char __bss_end; + +#define RT_HW_HEAP_BEGIN (void*)&__bss_end +#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 4 * 1024 * 1024) + +void rt_hw_board_init(void); + +#endif + diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_fb.c b/bsp/raspberry-pi/raspi3-64/driver/drv_fb.c new file mode 100644 index 0000000000..485f7b587b --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_fb.c @@ -0,0 +1,523 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-29 zdzn first version + */ + +#include +#include +#include "mbox.h" +#include "drv_fb.h" +#include "mmu.h" + +#define CHAR_W 8 +#define CHAR_H 12 + +#define COLOR_DELTA 0.05 +static struct rt_hdmi_fb_device _hdmi; + +// https://github.com/xinu-os/xinu/blob/1789b7a50b5b73c2ea76ebd764c54a034097d04d/device/framebuffer_rpi/font.c +unsigned char FONT[] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/ +0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'!'*/ +0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'"'*/ +0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14, 0x00, 0x00, 0x00, /*'#'*/ +0x00, 0x00, 0x08, 0x3c, 0x0a, 0x1c, 0x28, 0x1e, 0x08, 0x00, 0x00, 0x00, /*'$'*/ +0x00, 0x00, 0x06, 0x26, 0x10, 0x08, 0x04, 0x32, 0x30, 0x00, 0x00, 0x00, /*'%'*/ +0x00, 0x00, 0x1c, 0x02, 0x02, 0x04, 0x2a, 0x12, 0x2c, 0x00, 0x00, 0x00, /*'&'*/ +0x00, 0x18, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'''*/ +0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, /*'('*/ +0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x00, /*')'*/ +0x00, 0x00, 0x00, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x00, 0x00, /*'*'*/ +0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /*'+'*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*','*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'-'*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*'.'*/ +0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, /*'/'*/ +0x00, 0x1c, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'0'*/ +0x00, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'1'*/ +0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'2'*/ +0x00, 0x1c, 0x22, 0x20, 0x18, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'3'*/ +0x00, 0x10, 0x18, 0x18, 0x14, 0x14, 0x3e, 0x10, 0x38, 0x00, 0x00, 0x00, /*'4'*/ +0x00, 0x3e, 0x02, 0x02, 0x1e, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'5'*/ +0x00, 0x18, 0x04, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'6'*/ +0x00, 0x3e, 0x22, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00, /*'7'*/ +0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'8'*/ +0x00, 0x1c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00, /*'9'*/ +0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*':'*/ +0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*';'*/ +0x00, 0x00, 0x00, 0x30, 0x0c, 0x03, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, /*'<'*/ +0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, /*'='*/ +0x00, 0x00, 0x00, 0x03, 0x0c, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, /*'>'*/ +0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'?'*/ +0x00, 0x00, 0x1c, 0x22, 0x3a, 0x3a, 0x1a, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'@'*/ +0x00, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00, 0x00, 0x00, /*'A'*/ +0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'B'*/ +0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'C'*/ +0x00, 0x00, 0x0e, 0x12, 0x22, 0x22, 0x22, 0x12, 0x0e, 0x00, 0x00, 0x00, /*'D'*/ +0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'E'*/ +0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'F'*/ +0x00, 0x00, 0x1c, 0x22, 0x02, 0x32, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'G'*/ +0x00, 0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'H'*/ +0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, /*'I'*/ +0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'J'*/ +0x00, 0x00, 0x22, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'K'*/ +0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'L'*/ +0x00, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'M'*/ +0x00, 0x00, 0x22, 0x26, 0x26, 0x2a, 0x32, 0x32, 0x22, 0x00, 0x00, 0x00, /*'N'*/ +0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'O'*/ +0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'P'*/ +0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x30, 0x00, 0x00, /*'Q'*/ +0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'R'*/ +0x00, 0x00, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'S'*/ +0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'T'*/ +0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'U'*/ +0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'V'*/ +0x00, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00, 0x00, 0x00, /*'W'*/ +0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00, 0x00, /*'X'*/ +0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'Y'*/ +0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'Z'*/ +0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, /*'['*/ +0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, /*'\'*/ +0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, /*']'*/ +0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'^'*/ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, /*'_'*/ +0x00, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'`'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'a'*/ +0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'b'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x02, 0x02, 0x3c, 0x00, 0x00, 0x00, /*'c'*/ +0x00, 0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'d'*/ +0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'e'*/ +0x00, 0x38, 0x04, 0x04, 0x1e, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, /*'f'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'g'*/ +0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'h'*/ +0x00, 0x08, 0x08, 0x00, 0x0c, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'i'*/ +0x00, 0x10, 0x10, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, /*'j'*/ +0x00, 0x02, 0x02, 0x02, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x00, 0x00, 0x00, /*'k'*/ +0x00, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'l'*/ +0x00, 0x00, 0x00, 0x00, 0x16, 0x2a, 0x2a, 0x2a, 0x22, 0x00, 0x00, 0x00, /*'m'*/ +0x00, 0x00, 0x00, 0x00, 0x1a, 0x26, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'n'*/ +0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'o'*/ +0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, /*'p'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, /*'q'*/ +0x00, 0x00, 0x00, 0x00, 0x1a, 0x06, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'r'*/ +0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x1c, 0x20, 0x1e, 0x00, 0x00, 0x00, /*'s'*/ +0x00, 0x08, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, /*'t'*/ +0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'u'*/ +0x00, 0x00, 0x00, 0x00, 0x36, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'v'*/ +0x00, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x2a, 0x14, 0x00, 0x00, 0x00, /*'w'*/ +0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, /*'x'*/ +0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'y'*/ +0x00, 0x00, 0x00, 0x00, 0x3e, 0x10, 0x08, 0x04, 0x3e, 0x00, 0x00, 0x00, /*'z'*/ +0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00, /*'{'*/ +0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, /*'|'*/ +0x02, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x00, /*'}'*/ +0x00, 0x04, 0x2a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'~'*/ +0x00, 0x00, 0x00, 0x08, 0x08, 0x14, 0x14, 0x22, 0x3e, 0x00, 0x00, 0x00, /*DEL*/ +}; + +void newline(fb_t* fb) +{ + uint8_t* to; + uint8_t* from; + int i; + fb->y++; + fb->x = 0; + + if (fb->y == (fb->height / CHAR_H)) + { + + to = (uint8_t*) fb->addr; + from = to + (CHAR_H * fb->pitch); + + for (i = 0; i < ((fb->height - CHAR_H) * fb->pitch); i++) + { + *to++ = *from++; + } + + uint32_t *addr = (uint32_t*) (fb->addr) + (fb->height - CHAR_H) * fb->width; + + for (i = 0; i < (CHAR_H * fb->width); i++) + { + *addr++ = fb->back; + } + + fb->y--; + } +} + +void clear_line(fb_t *fb, const int line) +{ + int i; + uint32_t* addr; + if (line > fb->height / CHAR_H) + { + fb->y = 0; + } + else + { + fb->y = line; + } + + fb->x = 0; + + addr = (uint32_t*) (fb->addr + (line * CHAR_H * fb->depth * fb->width)); + for (i = 0; i < (CHAR_H * fb->width); i++) + { + *addr++ = fb->back; + } + +} + +void clear(fb_t *fb, const uint32_t color) +{ + + uint32_t *addr = (uint32_t*) fb->addr; + uint32_t i; + for (i = 0; i < (fb->height * fb->width); i++) + { + *addr++ = color; + } + fb->x = 0; + fb->y = 0; + +} + +void fb_draw_char(fb_t *fb, char s) +{ + unsigned char* addr = (unsigned char*) fb->addr; + unsigned char *glyph = (unsigned char*) FONT + (s) * 12; + // calculate the offset on screen + int offs = (fb->y * CHAR_H * fb->pitch) + (fb->x * (CHAR_W + 1) * 4); + // variables + int i, j, line, mask, bytesperline = (CHAR_W + 7) / 8; + // display a character + for (j = 0; j < CHAR_H; j++) + { + // display one row + line = offs; + mask = 1; + for (i = 0; i < CHAR_W; i++) + { + // if bit set, we use white color, otherwise black + *((unsigned int*) (addr + line)) = ((int) *glyph) & mask ? fb->fore : fb->back; + mask <<= 1; + line += 4; + } + // adjust to next line + glyph += bytesperline; + offs += fb->pitch; + } +} + +void fb_print(fb_t *fb, char *s) +{ + + // draw next character if it's not zero + while (*s) + { + // handle carrige return + if (*s == '\r') + { + fb->x = 0; + } + else if (*s == '\n') + { + newline(fb); + } + else if (*s == '\t') + { + fb->x = ((fb->x + 4) >> 2) << 2; + } + else if (*s == '\b') + { + if (fb->x) + { + fb->x--; + fb_draw_char(fb, ' '); + } + } + else + { + fb_draw_char(fb, *s); + fb->x++; + } + // next character + if (fb->x == fb->width / CHAR_W) + { + newline(fb); + } + s++; + } +} + +rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +rt_err_t hdmi_fb_close(rt_device_t dev) +{ + return RT_EOK; +} + +rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size) +{ +#ifdef BSP_USING_USPI + char* buffer = (char *) buf; + if(keyboard_available()) + { + int i = 0; + int j = 0; + while (i != size) + { + int ch = keyboard_getchar(); + if(ch != -1) + buffer[j++] = ch; + i++; + } + return j; + + } +#endif + return 0; +} + +rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + fb_print(&_hdmi.fb, (char *) buffer); +#ifdef BSP_USING_HDMI_DISPLAY + rt_device_t uart = rt_device_find("uart1"); + int old_flag = uart->open_flag; + uart->open_flag |= RT_DEVICE_FLAG_STREAM; + rt_device_write(uart, 0, buffer, size); + uart->open_flag = old_flag; +#endif + return size; + +} + +rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args) +{ + return RT_EOK; +} + +const static struct rt_device_ops hdmi_fb_ops = { + RT_NULL, + hdmi_fb_open, + hdmi_fb_close, + hdmi_fb_read, + hdmi_fb_write, + hdmi_fb_control +}; + +static struct rt_device_graphic_info _hdmi_info; + +static void hdmi_draw_rect(const char* pixel, int x1, int y1, int x2, int y2) +{ + int i, j; + int line; + for (j = y1; j <= y2; j++) + { + line = (j * _hdmi.fb.pitch) + (x1 * 4); + for (i = x1; i <= x2; i++) + { + // if bit set, we use white color, otherwise black + *((unsigned int*) (_hdmi_info.framebuffer + line)) = *(unsigned int*) pixel; + line += 4; + } + } + +} + +static void hdmi_set_pixel(const char* pixel, int x, int y) +{ + *(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) = *(uint32_t *) pixel; +} + +static void hdmi_get_pixel(char* pixel, int x, int y) +{ + uint32_t ret = 0; + ret = (*(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) & 0x00FFFFFF); + *pixel = ret; +} + +static void hdmi_draw_hline(const char* pixel, int x1, int x2, int y) +{ + hdmi_draw_rect(pixel, x1, y, x2, y); +} + +static void hdmi_draw_vline(const char* pixel, int x, int y1, int y2) +{ + hdmi_draw_rect(pixel, x, y1, x, y2); +} + +static void hdmi_blit_line(const char* pixels, int x, int y, rt_size_t size) +{ + int i = 0; + uint32_t *pixel_base = (uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)); + uint32_t *colors = (uint32_t *) pixels; + for (i = 0; i < size; i++) + { + pixel_base[i] = colors[i]; + } +} + +static struct rt_device_graphic_ops hdmi_ops = { + hdmi_set_pixel, + hdmi_get_pixel, + hdmi_draw_hline, + hdmi_draw_vline, + hdmi_blit_line +}; + +rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name) +{ + struct rt_device *device; + RT_ASSERT(hdmi_fb != RT_NULL); + + device = &hdmi_fb->parent; + device->user_data = &hdmi_ops; + + /* set device type */ + device->type = RT_Device_Class_Graphic; + /* initialize device interface */ +#ifdef RT_USING_DEVICE_OPS + device->ops = &hdmi_fb_ops; +#else + device->init = RT_NULL; + device->open = hdmi_fb_open; + device->close = hdmi_fb_close; + device->read = hdmi_fb_read; + device->write = hdmi_fb_write; + device->control = hdmi_fb_control; +#endif + + /* register to device manager */ + rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); + + return RT_EOK; +} + +/** + * Show a picture + */ +void print_fb_info() +{ + rt_kprintf("FrameBuffer Info: \n \t width %x\t height %x\t depth %x\t addr %x\t size %x\t \n", fb_info.width, + fb_info.height, fb_info.depth, fb_info.addr, fb_info.size); + rt_kprintf("call mbox:%x,%x,%x,%x,%x\n", mbox[0], mbox[1], mbox[2], mbox[3], mbox[4]); +} + +void hdmi_fb_init() +{ + unsigned int *mbox = (unsigned int*) MBOX_ADDR; + mbox[0] = 35 * 4; + mbox[1] = MBOX_REQUEST; + + mbox[2] = 0x48003; //set phy wh + mbox[3] = 8; + mbox[4] = 8; + mbox[5] = 640; //FrameBufferInfo.width + mbox[6] = 480; //FrameBufferInfo.height + + mbox[7] = 0x48004; //set virt wh + mbox[8] = 8; + mbox[9] = 8; + mbox[10] = 640; //FrameBufferInfo.virtual_width + mbox[11] = 480; //FrameBufferInfo.virtual_height + + mbox[12] = 0x48009; //set virt offset + mbox[13] = 8; + mbox[14] = 8; + mbox[15] = 0; //FrameBufferInfo.x_offset + mbox[16] = 0; //FrameBufferInfo.y.offset + + mbox[17] = 0x48005; //set depth + mbox[18] = 4; + mbox[19] = 4; + mbox[20] = 32; //FrameBufferInfo.depth + + mbox[21] = 0x48006; //set pixel order + mbox[22] = 4; + mbox[23] = 4; + mbox[24] = 1; //RGB, not BGR preferably + + mbox[25] = 0x40001; //get framebuffer, gets alignment on request + mbox[26] = 8; + mbox[27] = 8; + mbox[28] = 4096; //FrameBufferInfo.pointer + mbox[29] = 0; //FrameBufferInfo.size + + mbox[30] = 0x40008; //get pitch + mbox[31] = 4; + mbox[32] = 4; + mbox[33] = 0; //FrameBufferInfo.pitch + + mbox[34] = MBOX_TAG_LAST; + if (mbox_call(MBOX_CH_PROP, MMU_DISABLE) && mbox[20] == 32 && mbox[28] != 0) + { + mbox[28] &= 0x3FFFFFFF; + _hdmi.fb.width = mbox[5]; + _hdmi.fb.height = mbox[6]; + _hdmi.fb.pitch = mbox[33]; + //_hdmi.fb.addr = (void*)((unsigned long)mbox[28]); + _hdmi.fb.addr = (rt_uint32_t) mbox[28]; + _hdmi.fb.size = mbox[29]; + _hdmi.fb.depth = 32; + _hdmi.fb.x = 0; + _hdmi.fb.y = 0; + _hdmi.fb.fore = CONSOLE_WHITE; + _hdmi.fb.back = CONSOLE_BLACK; + rt_hdmi_fb_device_init(&_hdmi, "hdmi"); + rt_hw_change_mmu_table(_hdmi.fb.addr, _hdmi.fb.size, _hdmi.fb.addr, DEVICE_MEM); + fb_info.width = _hdmi.fb.width; + fb_info.height = _hdmi.fb.height; + fb_info.addr = _hdmi.fb.addr; + fb_info.size = _hdmi.fb.size; + fb_info.pitch = _hdmi.fb.pitch; + fb_info.depth = _hdmi.fb.depth; + _hdmi_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888; + _hdmi_info.bits_per_pixel = _hdmi.fb.depth; + _hdmi_info.width = _hdmi.fb.width; + _hdmi_info.height = _hdmi.fb.height; + _hdmi_info.framebuffer = (rt_uint8_t *) _hdmi.fb.addr; + } +} + diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_fb.h b/bsp/raspberry-pi/raspi3-64/driver/drv_fb.h new file mode 100644 index 0000000000..1b733f8d0f --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_fb.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-29 zdzn first version + */ +#ifndef __DRV_FB_H__ +#define __DRV_FB_H__ + +#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b))) + +#define COLOR_BLACK RGB(0, 0, 0) + +#define COLOR_GREEN RGB(0, 255, 0) + +#define COLOR_CYAN RGB(0, 255, 255) + +#define COLOR_RED RGB(255, 0, 0) + +#define COLOR_YELLOW RGB(255, 255, 0) + +#define COLOR_WHITE RGB(255, 255, 255) + +#define CONSOLE_WHITE COLOR_WHITE +#define CONSOLE_BLACK COLOR_BLACK +#define CONSOLE_GREEN COLOR_GREEN +#define CONSOLE_CYAN COLOR_CYAN +#define CONSOLE_RED COLOR_RED +#define CONSOLE_YELLOW COLOR_YELLOW + +typedef struct +{ + rt_uint32_t width; + rt_uint32_t height; + rt_uint32_t vwidth; + rt_uint32_t vheight; + rt_uint32_t pitch; + rt_uint32_t depth; + rt_uint32_t fore; + rt_uint32_t back; + rt_uint32_t x; + rt_uint32_t y; + rt_uint32_t addr; + rt_uint32_t size; +}fb_t; + +struct rt_hdmi_fb_device +{ + struct rt_device parent; + fb_t fb; +}; + +fb_t fb_info; +void print_fb_info(); +void hdmi_fb_init(); + +#endif/* __DRV_FB_H__ */ diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_gpio.c b/bsp/raspberry-pi/raspi3-64/driver/drv_gpio.c new file mode 100644 index 0000000000..ce1883cce7 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_gpio.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ +#include "raspi.h" +#include "drv_gpio.h" + +#ifdef BSP_USING_PIN + +struct rpi_pin_index +{ + rt_uint8_t phy_id; + rt_uint8_t bcm_id; + rt_uint8_t signal_name; + rt_uint8_t magic; +}; + +//raspi phy id and bcm id +static struct rpi_pin_index phypin_index[] = +{ + {0, 0, 0, 0}, + {1, 0, 0, 0}, + {2, 0, 0, 0}, + {3, BCM_GPIO_PIN_2, RPI_SDA1, PIN_MAGIC}, + {4, 0, 0, 0}, + {5, BCM_GPIO_PIN_3, RPI_SCL1, PIN_MAGIC}, + {6, 0, 0, 0}, + {7, BCM_GPIO_PIN_4, RPI_GPIO_GCLK, PIN_MAGIC}, + {8, BCM_GPIO_PIN_14, RPI_TXD0, PIN_MAGIC}, + {9, 0, 0, 0}, + {10, BCM_GPIO_PIN_15, RPI_RXD0, PIN_MAGIC}, + {11, BCM_GPIO_PIN_17, RPI_GPIO_GEN0, PIN_MAGIC}, + {12, BCM_GPIO_PIN_18, RPI_GPIO_GEN1, PIN_MAGIC}, + {13, BCM_GPIO_PIN_27, RPI_GPIO_GEN2, PIN_MAGIC}, + {14, 0, 0, 0}, + {15, BCM_GPIO_PIN_22, RPI_GPIO_GEN3, PIN_MAGIC}, + {16, BCM_GPIO_PIN_23, RPI_GPIO_GEN4, PIN_MAGIC}, + {17, 0, 0, 0}, + {18, BCM_GPIO_PIN_24, RPI_GPIO_GEN5, PIN_MAGIC}, + {19, BCM_GPIO_PIN_10, RPI_SPI_MOSI, PIN_MAGIC}, + {20, 0, 0, 0}, + {21, BCM_GPIO_PIN_9, RPI_SPI_MISO, PIN_MAGIC}, + {22, BCM_GPIO_PIN_25, RPI_GPIO_GEN6, PIN_MAGIC}, + {23, BCM_GPIO_PIN_11, RPI_SPI_SCLK, PIN_MAGIC}, + {24, BCM_GPIO_PIN_8, RPI_SPI_CE0_N, PIN_MAGIC}, + {25, 0, 0, 0}, + {26, BCM_GPIO_PIN_7, RPI_SPI_CE1_N, PIN_MAGIC}, + {27, BCM_GPIO_PIN_0, RPI_SDA0, PIN_MAGIC}, + {28, BCM_GPIO_PIN_1, RPI_SCL0, PIN_MAGIC}, + {29, BCM_GPIO_PIN_5, RPI_CAM_CLK, PIN_MAGIC}, + {30, 0, 0, 0}, + {31, BCM_GPIO_PIN_6, RPI_LAN_RUN, PIN_MAGIC}, + {32, BCM_GPIO_PIN_12, 0, PIN_MAGIC}, + {33, BCM_GPIO_PIN_13, 0, PIN_MAGIC}, + {34, 0, 0, 0}, + {35, BCM_GPIO_PIN_19, 0, PIN_MAGIC}, + {36, BCM_GPIO_PIN_16, RPI_STATUS_LED_N, PIN_MAGIC}, + {37, BCM_GPIO_PIN_26, 0, PIN_MAGIC}, + {38, BCM_GPIO_PIN_20, 0, PIN_MAGIC}, + {39, 0, 0, 0}, + {40, BCM_GPIO_PIN_21, RPI_CAM_GPIO, PIN_MAGIC}, +}; + +/* + * gpio_int[0] for BANK0 (pins 0-27) + * gpio_int[1] for BANK1 (pins 28-45) + * gpio_int[2] for BANK2 (pins 46-53) + */ +static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM]; + +int gpio_set_func(enum gpio_code code, enum bcm_gpio_pin pin, rt_uint8_t func) +{ + RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM)); + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53)); + + if (func & 0x8) + { + rt_kprintf("[line]:%d There is a warning with parameter input", __LINE__); + return RT_EINVAL; + } + + switch(func) + { + case 0x00: + bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_OUTP); + break; + case 0x01: + bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT); + break; + case 0x02: + bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP); + bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT); + break; + case 0x03: + bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_DOWN); + bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT); + break; + case 0x04: + bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_OFF); + bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_OUTP); + break; + } + + return RT_EOK; +} + +int gpio_set_value(enum gpio_code code, enum bcm_gpio_pin pin, rt_uint8_t value) +{ + + RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM)); + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53)); + + if (value & 0xE) + { + rt_kprintf("[line]:%d There is a warning with parameter input", __LINE__); + return RT_EINVAL; + } + + bcm283x_gpio_write(pin, value); + return RT_EOK; +} + +int gpio_get_value(enum gpio_code code, enum bcm_gpio_pin pin) +{ + rt_uint8_t data; + + RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM)); + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53)); + + data = bcm283x_gpio_lev(pin); + return data; +} + +void gpio_set_irq_callback(enum gpio_code port, enum bcm_gpio_pin pin, void (*irq_cb)(void *), void *irq_arg) +{ + RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM)); + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53)); + + rt_uint8_t index; + if (pin <= 27) + { + index = 0; + } + else if (pin <= 45) + { + index = 1; + } + else{ + index = 2; + } + _g_gpio_irq_tbl[index].irq_cb[pin] = irq_cb; + _g_gpio_irq_tbl[index].irq_arg[pin] = irq_arg; +} + +void gpio_set_irq_type(enum gpio_code port, enum bcm_gpio_pin pin, rt_uint8_t irq_type) +{ + + RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM)); + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53)); + + rt_uint8_t index; + if (pin <= 27) + { + index = 0; + } + else if (pin <= 45) + { + index = 1; + } + else{ + index = 2; + } + _g_gpio_irq_tbl[index].irq_type[pin] = irq_type; + + switch(irq_type) + { + case 0x00: + bcm283x_gpio_ren(pin); + break; + case 0x01: + bcm283x_gpio_fen(pin); + break; + case 0x02: + bcm283x_gpio_aren(pin); + bcm283x_gpio_afen(pin); + break; + case 0x03: + bcm283x_gpio_hen(pin); + break; + case 0x04: + bcm283x_gpio_len(pin); + break; + } +} + +static void gpio_ack_irq(int irq, enum bcm_gpio_pin pin) +{ + rt_uint32_t data; + data = IRQ_PEND2; + data &= (0x0 << (irq - 32)); + IRQ_PEND2 = data; + + data = IRQ_DISABLE2; + data |= (0x1 << (irq - 32)); + IRQ_DISABLE2 = data; +} + +void gpio_irq_disable(enum gpio_code port, enum bcm_gpio_pin pin) +{ + rt_uint8_t index; + int irq = 0; + RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM)); + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53)); + + if (pin <= 27) + { + index = 0; + irq = IRQ_GPIO0; + }else if (pin <= 45){ + index = 1; + irq = IRQ_GPIO1; + }else{ + index = 2; + irq = IRQ_GPIO2; + } + + gpio_ack_irq(irq, pin); + + rt_uint8_t irq_type = _g_gpio_irq_tbl[index].irq_type[pin]; + + switch(irq_type) + { + case 0x00: + bcm283x_gpio_clr_ren(pin); + break; + case 0x01: + bcm283x_gpio_clr_fen(pin); + break; + case 0x02: + bcm283x_gpio_clr_aren(pin); + bcm283x_gpio_clr_afen(pin); + break; + case 0x03: + bcm283x_gpio_clr_hen(pin); + break; + case 0x04: + bcm283x_gpio_clr_len(pin); + break; + } +} + +void gpio_clear_irq_callback(enum gpio_code port, enum bcm_gpio_pin pin) +{ + rt_uint8_t index; + gpio_irq_disable(port, pin); + + if (pin <= 27) + { + index = 0; + } + else if (pin <= 45) + { + index = 1; + } + else + { + index = 2; + } + + _g_gpio_irq_tbl[index].irq_cb[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_arg[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_type[pin] = RT_NULL; + +} + + +void gpio_irq_enable(enum gpio_code port, enum bcm_gpio_pin pin) +{ + + rt_uint32_t offset; + rt_uint32_t data; + + RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM)); + RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53)); + + offset = pin; + if (pin <= 27) + { + offset = IRQ_GPIO0 - 32; + } + else if (pin <= 45) + { + offset = IRQ_GPIO1 - 32; + } + else + { + offset = IRQ_GPIO2 - 32; + } + + data = IRQ_ENABLE2; + data |= 0x1 << offset; + IRQ_ENABLE2 = data; + +} + +//gpio_int[0] for BANK0 (pins 0-27) +//gpio_int[1] for BANK1 (pins 28-45) +//gpio_int[2] for BANK2 (pins 46-53) +static void gpio_irq_handler(int irq, void *param) +{ + struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param; + rt_uint32_t pin; + rt_uint32_t addr; + rt_uint32_t value; + rt_uint32_t tmpvalue; + + if (irq == IRQ_GPIO0) + { + /* 0~27 */ + addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0; // 0~31 + value = bcm283x_peri_read(addr); + value &= 0x0fffffff; + pin = 0; + } + else if (irq == IRQ_GPIO1) + { + /* 28-45 */ + addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0; + tmpvalue = bcm283x_peri_read(addr); + tmpvalue &= (~0x0fffffff); + + addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS1; + value = bcm283x_peri_read(addr); + value &= 0x3fff; + value = (value<<4) | tmpvalue; + + pin = 28; + } + else if (irq == IRQ_GPIO2) + { + /* 46-53 */ + addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS1; + value = bcm283x_peri_read(addr); + value &= (~0x3fff); + value &= 0xff600000; + pin = 46; + } + + bcm283x_peri_write(addr,0); + + while (value) + { + if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL)) + { + irq_def->irq_cb[pin](irq_def->irq_arg[pin]); + gpio_ack_irq(irq,pin); + } + pin++; + value = value >> 1; + } +} + +static void pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode) +{ + if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC)) + { + rt_kprintf("pin:%d value wrongful", pin); + return; + } + + gpio_set_func(GPIO_CODE_BCM, phypin_index[pin].bcm_id, mode); +} + +static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value) +{ + if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC)) + { + rt_kprintf("pin:%d value wrongful", pin); + return; + } + + gpio_set_value(GPIO_CODE_BCM, phypin_index[pin].bcm_id, value); +} + +static int pin_read(struct rt_device *device, rt_base_t pin) +{ + if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC)) + { + rt_kprintf("pin:%d value wrongful", pin); + return 0; + } + + return gpio_get_value(GPIO_CODE_BCM, phypin_index[pin].bcm_id); +} + +static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) +{ + if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC)) + { + rt_kprintf("pin:%d value wrongful", pin); + return RT_ERROR; + } + + gpio_set_irq_callback(GPIO_CODE_BCM , phypin_index[pin].bcm_id, hdr, args); + gpio_set_irq_type(GPIO_CODE_BCM, phypin_index[pin].bcm_id, mode); + + return RT_EOK; +} + +static rt_err_t pin_detach_irq(struct rt_device *device, rt_int32_t pin) +{ + if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC)) + { + rt_kprintf("pin:%d value wrongful", pin); + return RT_ERROR; + } + + gpio_clear_irq_callback(GPIO_CODE_BCM, phypin_index[pin].bcm_id); + + return RT_EOK; +} + +rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) +{ + if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC)) + { + rt_kprintf("pin:%d value wrongful", pin); + return RT_ERROR; + } + + if (enabled) + gpio_irq_enable(GPIO_CODE_BCM, phypin_index[pin].bcm_id); + else + gpio_irq_disable(GPIO_CODE_BCM, phypin_index[pin].bcm_id); + + return RT_EOK; +} + +static const struct rt_pin_ops ops = +{ + pin_mode, + pin_write, + pin_read, + pin_attach_irq, + pin_detach_irq, + pin_irq_enable, +}; +#endif + +int rt_hw_gpio_init(void) +{ +#ifdef BSP_USING_PIN + rt_device_pin_register("gpio", &ops, RT_NULL); +#endif + + /* install ISR */ + rt_hw_interrupt_install(IRQ_GPIO0, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq"); + rt_hw_interrupt_umask(IRQ_GPIO0); + + rt_hw_interrupt_install(IRQ_GPIO1, gpio_irq_handler, &_g_gpio_irq_tbl[1], "gpio1_irq"); + rt_hw_interrupt_umask(IRQ_GPIO1); + + rt_hw_interrupt_install(IRQ_GPIO2, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq"); + rt_hw_interrupt_umask(IRQ_GPIO2); + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_gpio_init); diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_gpio.h b/bsp/raspberry-pi/raspi3-64/driver/drv_gpio.h new file mode 100644 index 0000000000..b0a67870ab --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_gpio.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_GPIO_H__ +#define __DRV_GPIO_H__ + +#include +#include +#include +#include +#include + +#include "interrupt.h" +#include "bcm283x.h" +#include "raspi.h" +#include "board.h" + +#define GPIO_IRQ_NUM 3 + +struct gpio_irq_def +{ + void *irq_arg[32]; + void (*irq_cb[32])(void *param); + rt_uint8_t irq_type[32]; +}; + +enum gpio_irq_clock +{ + GPIO_IRQ_LOSC_32KHZ = 0, + GPIO_IRQ_HOSC_24MHZ +}; + +int rt_hw_gpio_init(void); + +#endif /* __DRV_GPIO_H__ */ diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c b/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c new file mode 100644 index 0000000000..5163af60ee --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include "drv_i2c.h" + +#if defined (BSP_USING_I2C0) +#define I2C1BUS_NAME "i2c0" +#endif /*BSP_USING_I2C0*/ + +#if defined (BSP_USING_I2C1) +#define I2C2BUS_NAME "i2c1" +#endif /*BSP_USING_I2C1*/ + +static int i2c_byte_wait_us = 0; + +#ifdef BSP_USING_I2C0 + +static struct raspi_i2c_bus raspi_i2c0 = +{ + .device_name = I2C1BUS_NAME, +}; + +static struct raspi_master_config_t raspi_i2c0_cfg = +{ + .sdl_pin = BCM_GPIO_PIN_0, + .scl_pin = BCM_GPIO_PIN_1, + .sdl_pin_mode = BCM283X_GPIO_FSEL_ALT0, + .scl_pin_mode = BCM283X_GPIO_FSEL_ALT0, + .slave_address = 8, + .bsc_base = (PER_BASE + BCM283X_BSC0_BASE), + .clk_div = BCM283X_I2C_CLOCK_DIVIDER_148, +}; + +#endif /* RT_USING_HW_I2C1 */ + +#ifdef BSP_USING_I2C1 +static struct raspi_i2c_bus raspi_i2c1 = +{ + .device_name = I2C2BUS_NAME, +}; + +static struct raspi_master_config_t raspi_i2c1_cfg = +{ + .sdl_pin = BCM_GPIO_PIN_2, + .scl_pin = BCM_GPIO_PIN_3, + .sdl_pin_mode = BCM283X_GPIO_FSEL_ALT0, + .scl_pin_mode = BCM283X_GPIO_FSEL_ALT0, + .slave_address = 9, + .bsc_base = (PER_BASE + BCM283X_BSC1_BASE), + .clk_div = BCM283X_I2C_CLOCK_DIVIDER_148, +}; +#endif /* RT_USING_HW_I2C2 */ + +#if (defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1)) + +static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num); +static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num); +static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus, + rt_uint32_t, + rt_uint32_t); + +void i2c_master_init(struct raspi_master_config_t *cfg) +{ + volatile rt_uint32_t addr; + rt_uint32_t data; + + bcm283x_gpio_fsel(cfg->sdl_pin, cfg->sdl_pin_mode); /* SDA */ + bcm283x_gpio_fsel(cfg->scl_pin, cfg->scl_pin_mode); /* SCL */ + + addr = cfg->bsc_base + BCM283X_BSC_DIV; + data = bcm283x_peri_read(addr); + i2c_byte_wait_us = ( data * 1000000 / BCM283X_CORE_CLK_HZ) * 9; + + addr = cfg->bsc_base + BCM283X_BSC_DIV; + bcm283x_peri_write(addr, cfg->clk_div); + + //update + i2c_byte_wait_us = (cfg->clk_div * 1000000 * 9 / BCM283X_CORE_CLK_HZ); +} + +static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + volatile rt_uint32_t addr; + struct raspi_i2c_bus *raspi_i2c; + rt_size_t i; + RT_ASSERT(bus != RT_NULL); + raspi_i2c = (struct raspi_i2c_bus *) bus; + raspi_i2c->msg = msgs; + raspi_i2c->msg_ptr = 0; + raspi_i2c->msg_cnt = num; + raspi_i2c->dptr = 0; + + addr = raspi_i2c->cfg->bsc_base + BCM283X_BSC_A; + bcm283x_peri_write(addr, msgs->addr); + + for (i = 0; i < num; i++) + { + if ( raspi_i2c->msg[i].flags & RT_I2C_RD ) + { + bcm283x_i2c_read(raspi_i2c->cfg->bsc_base, raspi_i2c->msg->buf, num); + } + else + { + bcm283x_i2c_write(raspi_i2c->cfg->bsc_base, raspi_i2c->msg->buf, num); + } + } + raspi_i2c->msg = RT_NULL; + raspi_i2c->msg_ptr = 0; + raspi_i2c->msg_cnt = 0; + raspi_i2c->dptr = 0; + return i; +} + +static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + return 0; +} +static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus, + rt_uint32_t cmd, + rt_uint32_t arg) +{ + return RT_ERROR; +} + +static const struct rt_i2c_bus_device_ops raspi_i2c_ops = +{ + .master_xfer = raspi_i2c_mst_xfer, + .slave_xfer = raspi_i2c_slv_xfer, + .i2c_bus_control = raspi_i2c_bus_control, +}; + +static rt_err_t raspi_i2c_configure(struct raspi_i2c_bus *bus, struct raspi_master_config_t *cfg) +{ + RT_ASSERT(bus != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + bus->device.ops = &raspi_i2c_ops; + bus->cfg = cfg; + + i2c_master_init(cfg); + return RT_EOK; +} +#endif + +int rt_hw_i2c_init(void) +{ + +#if defined(BSP_USING_I2C0) + raspi_i2c_configure(&raspi_i2c0 , &raspi_i2c0_cfg); + rt_i2c_bus_device_register(&raspi_i2c0.device, raspi_i2c0.device_name); +#endif /* BSP_USING_I2C1 */ + +#if defined(BSP_USING_I2C1) + + raspi_i2c_configure(&raspi_i2c1 , &raspi_i2c1_cfg); + rt_i2c_bus_device_register(&raspi_i2c1.device, raspi_i2c1.device_name); + +#endif /* BSP_USING_I2C2 */ + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_i2c_init); diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h b/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h new file mode 100644 index 0000000000..041d6b00db --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_I2C_H__ +#define __DRV_I2C_H__ + +#include +#include +#include +#include "bcm283x.h" + +struct raspi_master_config_t +{ + rt_uint8_t sdl_pin; + rt_uint8_t scl_pin; + rt_uint8_t sdl_pin_mode; + rt_uint8_t scl_pin_mode; + rt_uint8_t slave_address; + rt_uint32_t bsc_base; + rt_uint16_t clk_div; +}; + +struct raspi_i2c_bus +{ + struct rt_i2c_bus_device device; + struct rt_i2c_msg *msg; + rt_uint32_t msg_cnt; + volatile rt_uint32_t msg_ptr; + volatile rt_uint32_t dptr; + char *device_name; + struct raspi_master_config_t *cfg; +}; + +int rt_hw_i2c_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_rtc.c b/bsp/raspberry-pi/raspi3-64/driver/drv_rtc.c new file mode 100644 index 0000000000..e38393bbd0 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_rtc.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + + +#include "drv_rtc.h" + +#ifdef BSP_USING_RTC + +static struct rt_rtc_device rtc_device; + +rt_uint8_t buf[]= +{ + 0x00, 0x00, 0x43, 0x15, 0x05, 0x01, 0x03, 0x19 +}; + +static time_t raspi_get_timestamp(void) +{ + struct tm tm_new = {0}; + buf[0] = 0; + bcm283x_i2c_write_read_rs((char*)buf, 1, (char*)buf, 7); + + tm_new.tm_year = ((buf[6] / 16) + 0x30) * 10 + (buf[6] % 16) + 0x30; + tm_new.tm_mon = ((buf[5] & 0x1F) / 16 + 0x30) + (buf[5] & 0x1F) % 16+ 0x30; + tm_new.tm_mday = ((buf[4] & 0x3F) / 16 + 0x30) + (buf[4] & 0x3F) % 16+ 0x30; + tm_new.tm_hour = ((buf[2] & 0x3F) / 16 + 0x30) + (buf[2] & 0x3F) % 16+ 0x30; + tm_new.tm_min = ((buf[1] & 0x7F) / 16 + 0x30) + (buf[1] & 0x7F) % 16+ 0x30; + tm_new.tm_sec = ((buf[0] & 0x7F) / 16 + 0x30) + (buf[0] & 0x7F) % 16+ 0x30; + + return mktime(&tm_new); +} + +static int raspi_set_timestamp(time_t timestamp) +{ + struct tm *tblock; + tblock = localtime(×tamp); + buf[0] = 0; + buf[1] = tblock->tm_sec; + buf[2] = tblock->tm_min; + buf[3] = tblock->tm_hour; + buf[4] = tblock->tm_wday; + buf[5] = tblock->tm_mday; + buf[6] = tblock->tm_mon; + buf[7] = tblock->tm_year; + bcm283x_i2c_write((PER_BASE + BCM283X_BSC0_BASE) ,buf, 8); + return RT_EOK; +} + +static rt_err_t raspi_rtc_init(rt_device_t dev) +{ + bcm283x_i2c_setSlaveAddress(0, 0x68); + bcm283x_i2c_set_baudrate(0, 10000); + raspi_set_timestamp(0); + return RT_EOK; +} + +static rt_err_t raspi_rtc_open(rt_device_t dev, rt_uint16_t oflag) +{ + bcm283x_i2c_begin(0); + return RT_EOK; +} + +static rt_err_t raspi_rtc_close(rt_device_t dev) +{ + bcm283x_i2c_end(0); + return RT_EOK; +} + +static rt_err_t raspi_rtc_control(rt_device_t dev, int cmd, void *args) +{ + + RT_ASSERT(dev != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + *(rt_uint32_t *)args = raspi_get_timestamp(); + break; + case RT_DEVICE_CTRL_RTC_SET_TIME: + raspi_set_timestamp(*(time_t *)args); + break; + default: + return RT_EINVAL; + } + return RT_EOK; +} + +static rt_size_t raspi_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + raspi_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer); + return size; +} + +static rt_size_t raspi_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + raspi_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer); + return size; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops raspi_rtc_ops = +{ + .init = raspi_rtc_init, + .open = raspi_rtc_open, + .close = raspi_rtc_close, + .read = raspi_rtc_read, + .write = raspi_rtc_write, + .control = raspi_rtc_control +}; +#endif + +int rt_hw_rtc_init(void) +{ + rt_memset(&rtc_device, 0, sizeof(rtc_device)); + + rtc_device.device.type = RT_Device_Class_RTC; + rtc_device.device.rx_indicate = RT_NULL; + rtc_device.device.tx_complete = RT_NULL; + rtc_device.device.ops = &raspi_rtc_ops; + rtc_device.device.user_data = RT_NULL; + + /* register a rtc device */ + rt_device_register(&rtc_device.device, "rtc", RT_DEVICE_FLAG_RDWR); + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_rtc_init); +#endif /* BSP_USING_RTC */ + diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_rtc.h b/bsp/raspberry-pi/raspi3-64/driver/drv_rtc.h new file mode 100644 index 0000000000..82306068ca --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_rtc.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_RTC_H__ +#define __DRV_RTC_H__ + +#include +#include +#include +#include "bcm283x.h" + +struct rt_rtc_device +{ + struct rt_device device; +}; + +int rt_hw_rtc_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_sdio.c b/bsp/raspberry-pi/raspi3-64/driver/drv_sdio.c new file mode 100644 index 0000000000..4f3018c0ef --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_sdio.c @@ -0,0 +1,532 @@ +/* + * File : drv_sdio.c + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include +#include +#include +#include + +#include "drv_sdio.h" +#include "interrupt.h" +#include "drv_gpio.h" + +#include "bcm283x.h" +#include +#include "bcm283x.h" + + +#include + +#ifdef RT_USING_SDIO +#define CONFIG_MMC_USE_DMA +#define DMA_ALIGN (32U) + +typedef struct EMMCCommand +{ + const char* name; + unsigned int code; + unsigned char resp; + unsigned char rca; + int delay; +} EMMCCommand; + +static EMMCCommand sdCommandTable[] = +{ + {"GO_IDLE_STATE", 0x00000000 | CMD_RSPNS_NO , RESP_NO , RCA_NO ,0}, + {"ALL_SEND_CID" , 0x02000000 | CMD_RSPNS_136 , RESP_R2I, RCA_NO ,0}, + {"SEND_REL_ADDR", 0x03000000 | CMD_RSPNS_48 , RESP_R6 , RCA_NO ,0}, + {"SET_DSR" , 0x04000000 | CMD_RSPNS_NO , RESP_NO , RCA_NO ,0}, + {"SWITCH_FUNC" , 0x06000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"CARD_SELECT" , 0x07000000 | CMD_RSPNS_48B , RESP_R1b, RCA_YES ,0}, + {"SEND_IF_COND" , 0x08000000 | CMD_RSPNS_48 , RESP_R7 , RCA_NO ,100}, + {"SEND_CSD" , 0x09000000 | CMD_RSPNS_136 , RESP_R2S, RCA_YES ,0}, + {"SEND_CID" , 0x0A000000 | CMD_RSPNS_136 , RESP_R2I, RCA_YES ,0}, + {"VOLT_SWITCH" , 0x0B000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"STOP_TRANS" , 0x0C000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0}, + {"SEND_STATUS" , 0x0D000000 | CMD_RSPNS_48 , RESP_R1 , RCA_YES ,0}, + {"GO_INACTIVE" , 0x0F000000 | CMD_RSPNS_NO , RESP_NO , RCA_YES ,0}, + {"SET_BLOCKLEN" , 0x10000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"READ_SINGLE" , 0x11000000 | CMD_RSPNS_48 | CMD_IS_DATA | TM_DAT_DIR_CH, RESP_R1 , RCA_NO ,0}, + {"READ_MULTI" , 0x12000000 | CMD_RSPNS_48 | TM_MULTI_DATA | TM_DAT_DIR_CH, RESP_R1 , RCA_NO ,0}, + {"SEND_TUNING" , 0x13000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"SPEED_CLASS" , 0x14000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0}, + {"SET_BLOCKCNT" , 0x17000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"WRITE_SINGLE" , 0x18000000 | CMD_RSPNS_48 | CMD_IS_DATA | TM_DAT_DIR_HC, RESP_R1 , RCA_NO ,0}, + {"WRITE_MULTI" , 0x19000000 | CMD_RSPNS_48 | TM_MULTI_DATA | TM_DAT_DIR_HC, RESP_R1 , RCA_NO ,0}, + {"PROGRAM_CSD" , 0x1B000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"SET_WRITE_PR" , 0x1C000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0}, + {"CLR_WRITE_PR" , 0x1D000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0}, + {"SND_WRITE_PR" , 0x1E000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"ERASE_WR_ST" , 0x20000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"ERASE_WR_END" , 0x21000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"ERASE" , 0x26000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0}, + {"LOCK_UNLOCK" , 0x2A000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"APP_CMD" , 0x37000000 | CMD_RSPNS_NO , RESP_NO , RCA_NO ,100}, + {"APP_CMD" , 0x37000000 | CMD_RSPNS_48 , RESP_R1 , RCA_YES ,0}, + {"GEN_CMD" , 0x38000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + + // APP commands must be prefixed by an APP_CMD. + {"SET_BUS_WIDTH", 0x06000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"SD_STATUS" , 0x0D000000 | CMD_RSPNS_48 , RESP_R1 , RCA_YES ,0}, // RCA??? + {"SEND_NUM_WRBL", 0x16000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"SEND_NUM_ERS" , 0x17000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"SD_SENDOPCOND", 0x29000000 | CMD_RSPNS_48 , RESP_R3 , RCA_NO ,1000}, + {"SET_CLR_DET" , 0x2A000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0}, + {"SEND_SCR" , 0x33000000 | CMD_RSPNS_48 | CMD_IS_DATA | TM_DAT_DIR_CH , RESP_R1 , RCA_NO ,0}, +}; + +static rt_err_t sdhci_setwidth(struct sdhci_t * sdhci, rt_uint32_t width); +static rt_err_t sdhci_setclock(struct sdhci_t * sdhci, rt_uint32_t clock); +static rt_err_t sdhci_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat); + +static inline rt_uint32_t read32(rt_uint32_t addr) +{ + return( *((volatile rt_uint32_t *)(addr)) ); +} + +static inline void write32(rt_uint32_t addr, rt_uint32_t value) +{ + *((volatile rt_uint32_t *)(addr)) = value; +} + +static rt_err_t raspi_transfer_command(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd) +{ + rt_uint32_t cmdidx; + rt_uint32_t status; + rt_err_t ret = RT_EOK; + + if(read32(pdat->virt + EMMC_STATUS) & SR_CMD_INHIBIT) + write32(pdat->virt + EMMC_CMDTM, 0x0); + + EMMCCommand* cmdtab = &sdCommandTable[cmd->cmdidx]; + + cmdidx = cmdtab->code; + + write32(pdat->virt + EMMC_ARG1, cmd->cmdarg); + write32(pdat->virt + EMMC_CMDTM, cmdidx); + + do { + status = read32(pdat->virt + EMMC_STATUS); + } while(!(status & SR_CMD_INHIBIT)); + + if(cmd->resptype & RESP_MASK) + { + cmd->response[0] = read32(pdat->virt + EMMC_RESP0); + if(cmd->resptype & RESP_R2) + { + cmd->response[1] = read32(pdat->virt + EMMC_RESP1); + cmd->response[2] = read32(pdat->virt + EMMC_RESP2); + cmd->response[3] = read32(pdat->virt + EMMC_RESP3); + } + } + + return ret; +} + +static rt_err_t read_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize) +{ + rt_uint32_t * tmp = buf; + rt_uint32_t count = blkcount * blksize; + rt_uint32_t status, err; + +// status = read32(pdat->virt + PL180_STATUS); +// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN); +// while((!err) && (count >= sizeof(rt_uint32_t))) +// { +// if(status & PL180_STAT_RX_FIFO_AVL) +// { +// *(tmp) = read32(pdat->virt + PL180_FIFO); +// tmp++; +// count -= sizeof(rt_uint32_t); +// } +// status = read32(pdat->virt + PL180_STATUS); +// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN); +// } +// +// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN); +// while(!err) +// { +// status = read32(pdat->virt + PL180_STATUS); +// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN); +// } +// +// if(status & PL180_STAT_DAT_TIME_OUT) +// return -RT_ERROR; +// else if (status & PL180_STAT_DAT_CRC_FAIL) +// return -RT_ERROR; +// else if (status & PL180_STAT_RX_OVERRUN) +// return -RT_ERROR; +// write32(pdat->virt + PL180_CLEAR, 0x1DC007FF); +// +// if(count) +// return -RT_ERROR; + + return RT_EOK; +} + +static rt_err_t write_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize) +{ + rt_uint32_t * tmp = buf; + rt_uint32_t count = blkcount * blksize; + rt_uint32_t status, err; + int i; + +// status = read32(pdat->virt + PL180_STATUS); +// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT); +// while(!err && count) +// { +// if(status & PL180_STAT_TX_FIFO_HALF) +// { +// if(count >= 8 * sizeof(rt_uint32_t)) +// { +// for(i = 0; i < 8; i++) +// write32(pdat->virt + PL180_FIFO, *(tmp + i)); +// tmp += 8; +// count -= 8 * sizeof(rt_uint32_t); +// } +// else +// { +// while(count >= sizeof(rt_uint32_t)) +// { +// write32(pdat->virt + PL180_FIFO, *tmp); +// tmp++; +// count -= sizeof(rt_uint32_t); +// } +// } +// } +// status = read32(pdat->virt + PL180_STATUS); +// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT); +// } +// +// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END); +// while(!err) +// { +// status = read32(pdat->virt + PL180_STATUS); +// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END); +// } +// +// if(status & PL180_STAT_DAT_TIME_OUT) +// return -RT_ERROR; +// else if (status & PL180_STAT_DAT_CRC_FAIL) +// return -RT_ERROR; +// write32(pdat->virt + PL180_CLEAR, 0x1DC007FF); +// +// if(count) +// return -RT_ERROR; + return RT_EOK; +} + +static rt_err_t raspi_transfer_data(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat) +{ + rt_uint32_t dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz); + rt_uint32_t blksz_bits = dat->blksz - 1; + rt_err_t ret = -RT_ERROR; + + write32(pdat->virt + EMMC_BLKSIZECNT, dlen); + + if(dat->flag & DATA_DIR_READ) + { + write32(pdat->virt + EMMC_STATUS, SR_READ_TRANSFER); + ret = raspi_transfer_command(pdat, cmd); + if (ret < 0) return ret; + ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz); + } + else if(dat->flag & DATA_DIR_WRITE) + { + ret = raspi_transfer_command(pdat, cmd); + if (ret < 0) return ret; + write32(pdat->virt + EMMC_STATUS, SR_WRITE_TRANSFER); + ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz); + } + + return ret; +} + +static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req) +{ + struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data; + struct sdhci_cmd_t cmd; + struct sdhci_cmd_t stop; + struct sdhci_data_t dat; + + rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t)); + rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t)); + rt_memset(&dat, 0, sizeof(struct sdhci_data_t)); + + cmd.cmdidx = req->cmd->cmd_code; + EMMCCommand* cmdtab = &sdCommandTable[cmd.cmdidx]; + cmd.cmdarg = req->cmd->arg; + cmd.resptype = cmdtab->resp; + + if(req->data) + { + dat.buf = (rt_uint8_t *)req->data->buf; + dat.flag = req->data->flags; + dat.blksz = req->data->blksize; + dat.blkcnt = req->data->blks; + + req->cmd->err = sdhci_transfer(sdhci, &cmd, &dat); + } + else + { + req->cmd->err = sdhci_transfer(sdhci, &cmd, RT_NULL); + } + + req->cmd->resp[3] = cmd.response[3]; + req->cmd->resp[2] = cmd.response[2]; + req->cmd->resp[1] = cmd.response[1]; + req->cmd->resp[0] = cmd.response[0]; + + if (req->stop) + { + stop.cmdidx = req->stop->cmd_code; + cmdtab = &sdCommandTable[cmd.cmdidx]; + stop.cmdarg = req->stop->arg; + cmd.resptype = cmdtab->resp; + + req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL); + } + + mmcsd_req_complete(host); +} + + +static rt_err_t sdhci_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat) +{ + struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv; + + if(!dat) + return raspi_transfer_command(pdat, cmd); + + return raspi_transfer_data(pdat, cmd, dat); +} + + +//#ifdef CONFIG_MMC_USE_DMA +//#ifdef BSP_USING_SDIO0 +////ALIGN(32) static rt_uint8_t dma_buffer[64 * 1024]; +//static rt_uint8_t dma_buffer[64 * 1024]; +//#endif +//#endif + + +static void mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg) +{ + struct sdhci_t * sdhci = (struct sdhci_t *)host->private_data; + sdhci_setclock(sdhci, io_cfg->clock); + sdhci_setwidth(sdhci, io_cfg->bus_width); +} + +rt_int32_t mmc_card_status(struct rt_mmcsd_host *host) +{ + return 0; +} + +void mmc_enable_irq(struct rt_mmcsd_host *host, rt_int32_t en) +{ + +} + +static rt_err_t sdhci_detect(struct sdhci_t * sdhci) +{ + return RT_EOK; +} + +static rt_err_t sdhci_setwidth(struct sdhci_t * sdhci, rt_uint32_t width) +{ + rt_uint32_t temp = 0; + struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv; + temp = read32((pdat->virt + EMMC_CONTROL0)); + temp |= C0_HCTL_HS_EN; + temp |= C0_HCTL_DWITDH; // always use 4 data lines: + write32((pdat->virt + EMMC_CONTROL0), temp); + + return RT_EOK; +} + +static rt_uint32_t sdhci_getdivider( rt_uint32_t sdHostVer, rt_uint32_t freq ) +{ + rt_uint32_t divisor; + rt_uint32_t closest = 41666666 / freq; + rt_uint32_t shiftcount = __rt_fls(closest - 1); + + + if (shiftcount > 0) shiftcount--; + if (shiftcount > 7) shiftcount = 7; + if (sdHostVer > HOST_SPEC_V2) + divisor = closest; + else + divisor = (1 << shiftcount); + + if (divisor <= 2) { + divisor = 2; + shiftcount = 0; + } + + rt_uint32_t hi = 0; + if (sdHostVer > HOST_SPEC_V2) + hi = (divisor & 0x300) >> 2; + rt_uint32_t lo = (divisor & 0x0ff); + rt_uint32_t cdiv = (lo << 8) + hi; + return cdiv; +} + +static rt_err_t sdhci_setclock(struct sdhci_t * sdhci, rt_uint32_t clock) +{ + rt_uint32_t temp = 0; + rt_uint32_t sdHostVer = 0; + int count = 100000; + struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv; + + temp = read32(pdat->virt + EMMC_STATUS); + while((temp & (SR_CMD_INHIBIT | SR_DAT_INHIBIT))&&(--count)) + bcm283x_clo_delayMicros(1); + + if( count <= 0 ) + { + rt_kprintf("EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.\n", temp); + return RT_ERROR; + } + + // Switch clock off. + temp = read32((pdat->virt + EMMC_CONTROL1)); + temp |= ~C1_CLK_EN; + write32((pdat->virt + EMMC_CONTROL1),temp); + + bcm283x_clo_delayMicros(10); + + // Request the new clock setting and enable the clock + temp = read32(pdat->virt + EMMC_SLOTISR_VER); + sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT; + + int cdiv = sdhci_getdivider(sdHostVer, clock); + temp = read32((pdat->virt + EMMC_CONTROL1)); + temp = (temp & 0xffff003f) | cdiv; + write32((pdat->virt + EMMC_CONTROL1),temp); + bcm283x_clo_delayMicros(10); + + // Enable the clock. + temp = read32(pdat->virt + EMMC_CONTROL1); + temp |= C1_CLK_EN; + write32((pdat->virt + EMMC_CONTROL1),temp); + bcm283x_clo_delayMicros(10); + + // Wait for clock to be stable. + count = 10000; + temp = read32(pdat->virt + EMMC_CONTROL1); + while( !(temp & C1_CLK_STABLE) && count-- ) + bcm283x_clo_delayMicros(10); + + if( count <= 0 ) + { + rt_kprintf("EMMC: ERROR: failed to get stable clock.\n"); + return RT_ERROR; + } + + return RT_EOK; +} + +static const struct rt_mmcsd_host_ops ops = +{ + mmc_request_send, + mmc_set_iocfg, + RT_NULL, + RT_NULL, +}; + +static void sdmmc_gpio_init() +{ + int pin; + + for (pin = BCM_GPIO_PIN_48; pin <= BCM_GPIO_PIN_53; pin++) + { + bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP); + bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_ALT3); + } + bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP); + bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT); +} + +int raspi_sdmmc_init(void) +{ + rt_uint32_t virt; + rt_uint32_t id; + struct rt_mmcsd_host * host = RT_NULL; + struct sdhci_pdata_t * pdat = RT_NULL; + struct sdhci_t * sdhci = RT_NULL; + + rt_kprintf("raspi_sdmmc_init start\n"); + +#ifdef BSP_USING_SDIO0 + host = mmcsd_alloc_host(); + if (!host) + { + rt_kprintf("alloc host failed"); + goto err; + } + + sdhci = rt_malloc(sizeof(struct sdhci_t)); + if (!sdhci) + { + rt_kprintf("alloc sdhci failed"); + goto err; + } + rt_memset(sdhci, 0, sizeof(struct sdhci_t)); + + rt_kprintf(">> sdmmc_gpio_init\n"); + sdmmc_gpio_init(); + rt_kprintf("<< sdmmc_gpio_init\n"); + + virt = MMC0_BASE_ADDR; + + pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t)); + RT_ASSERT(pdat != RT_NULL); + + pdat->virt = (rt_uint32_t)virt; + + sdhci->name = "sd0"; + sdhci->voltages = VDD_33_34; + sdhci->width = MMCSD_BUSWIDTH_4; + sdhci->clock = 26 * 1000 * 1000; + sdhci->removeable = RT_TRUE; + + sdhci->detect = sdhci_detect; + sdhci->setwidth = sdhci_setwidth; + sdhci->setclock = sdhci_setclock; + sdhci->transfer = sdhci_transfer; + sdhci->priv = pdat; + //write32(pdat->virt + PL180_POWER, 0xbf); + + host->ops = &ops; + host->freq_min = 400000; + host->freq_max = 50000000; + host->valid_ocr = VDD_32_33 | VDD_33_34; + host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4; + host->max_seg_size = 2048; + host->max_dma_segs = 10; + host->max_blk_size = 512; + host->max_blk_count = 4096; + + host->private_data = sdhci; + + mmcsd_change(host); + + return RT_EOK; + +err: + if(host) rt_free(host); + if(sdhci) rt_free(sdhci); + + return -RT_EIO; +#endif +} +INIT_APP_EXPORT(raspi_sdmmc_init); +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_sdio.h b/bsp/raspberry-pi/raspi3-64/driver/drv_sdio.h new file mode 100644 index 0000000000..8ab10aebb6 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_sdio.h @@ -0,0 +1,345 @@ +/* + * File : drv_sdio.h + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_SDIO_H__ +#define __DRV_SDIO_H__ + +#include + +#define MMC0_BASE_ADDR 0x20300000 + +struct raspi_mmc +{ + volatile rt_uint32_t arg2_reg; /* (0x000) */ + volatile rt_uint32_t blksizecnt_reg; /* (0x004) */ + volatile rt_uint32_t arg1_reg; /* (0x008) */ + volatile rt_uint32_t cmdtm_reg; /* (0x00C) */ + volatile rt_uint32_t resp0_reg; /* (0x010) */ + volatile rt_uint32_t resp1_reg; /* (0x014) */ + volatile rt_uint32_t resp2_reg; /* (0x018) */ + volatile rt_uint32_t resp3_reg; /* (0x01C) */ + volatile rt_uint32_t data_reg; /* (0x020) */ + volatile rt_uint32_t status_reg; /* (0x024) */ + volatile rt_uint32_t control0_reg; /* (0x028) */ + volatile rt_uint32_t control1_reg; /* (0x02C) */ + volatile rt_uint32_t interrupt_reg; /* (0x030) */ + volatile rt_uint32_t irpt_mask_reg; /* (0x034) */ + volatile rt_uint32_t irpt_en_reg; /* (0x038) */ + volatile rt_uint32_t control2_reg; /* (0x03C) */ + volatile rt_uint32_t reserved1[4]; /* (0x040) */ + volatile rt_uint32_t force_irpt_reg; /* (0x050) */ + volatile rt_uint32_t reserved2[7]; /* (0x054) */ + volatile rt_uint32_t boot_timeout_reg; /* (0x070) */ + volatile rt_uint32_t deg_sel_reg; /* (0x074) */ + volatile rt_uint32_t reserved3[2]; /* (0x078) */ + volatile rt_uint32_t exrdfifo_cfg_reg; /* (0x080) */ + volatile rt_uint32_t exrdfifo_cn_reg; /* (0x084) */ + volatile rt_uint32_t tune_step_reg; /* (0x088) */ + volatile rt_uint32_t tune_step_std_reg; /* (0x08C) */ + volatile rt_uint32_t tune_step_ddr_reg; /* (0x090) */ + volatile rt_uint32_t reserved4[23]; /* (0x094) */ + volatile rt_uint32_t spi_int_reg; /* (0x0f0) */ + volatile rt_uint32_t reserved5[2]; /* (0x0f4) */ + volatile rt_uint32_t slotisr_ver_reg; /* (0x0fC) */ +}; + +typedef struct raspi_mmc *raspi_mmc_t; + +#define MMC0 ((tina_mmc_t)MMC0_BASE_ADDR) + + +#define BIT(x) (1<<(x)) + +/* Struct for Intrrrupt Information */ +#define SDXC_CmdDone BIT(0) +#define SDXC_DataDone BIT(1) +#define SDXC_BlockGap BIT(2) +#define SDXC_WriteRdy BIT(4) +#define SDXC_ReadRdy BIT(5) +#define SDXC_Card BIT(8) +#define SDXC_Retune BIT(12) +#define SDXC_BootAck BIT(13) +#define SDXC_EndBoot BIT(14) +#define SDXC_Err BIT(15) +#define SDXC_CTOErr BIT(16) +#define SDXC_CCRCErr BIT(17) +#define SDXC_CENDErr BIT(18) +#define SDXC_CBADErr BIT(19) +#define SDXC_DTOErr BIT(20) +#define SDXC_DCRCErr BIT(21) +#define SDXC_DENDErr BIT(22) +#define SDXC_ACMDErr BIT(24) + + +/* + SD CMD reg +REG[0-5] : Cmd ID +REG[6] : Has response +REG[7] : Long response +REG[8] : Check response CRC +REG[9] : Has data +REG[10] : Write +REG[11] : Steam mode +REG[12] : Auto stop +REG[13] : Wait previous over +REG[14] : About cmd +REG[15] : Send initialization +REG[21] : Update clock +REG[31] : Load cmd +*/ + + +#define SDXC_BLKCNT_EN BIT(1) +#define SDXC_AUTO_CMD12_EN BIT(2) +#define SDXC_AUTO_CMD23_EN BIT(3) +#define SDXC_DAT_DIR BIT(4) //from card to host +#define SDXC_MULTI_BLOCK BIT(5) +#define SDXC_CMD_RSPNS_136 BIT(16) +#define SDXC_CMD_RSPNS_48 BIT(17) +#define SDXC_CMD_RSPNS_48busy BIT(16)|BIT(17) +#define SDXC_CHECK_CRC_CMD BIT(19) +#define SDXC_CMD_IXCHK_EN BIT(20) +#define SDXC_CMD_ISDATA BIT(21) +#define SDXC_CMD_SUSPEND BIT(22) +#define SDXC_CMD_RESUME BIT(23) +#define SDXC_CMD_ABORT BIT(23)|BIT(22) + +//#define SDXC_CHECK_CRC_CMD BIT(19) +// +//#define SDXC_RESPONSE_CMD BIT(6) +//#define SDXC_LONG_RESPONSE_CMD BIT(7) +//#define SDXC_CHECK_CRC_CMD BIT(8) +//#define SDXC_HAS_DATA_CMD BIT(9) +//#define SDXC_WRITE_CMD BIT(10) +//#define SDXC_STEAM_CMD BIT(11) +//#define SDXC_AUTO_STOP_CMD BIT(12) +//#define SDXC_WAIT_OVER_CMD BIT(13) +//#define SDXC_ABOUT_CMD BIT(14) +//#define SDXC_SEND_INIT_CMD BIT(15) +//#define SDXC_UPDATE_CLOCK_CMD BIT(21) +//#define SDXC_LOAD_CMD BIT(31) + +/* + SD status reg +REG[0] : FIFO_RX_LEVEL +REG[1] : FIFO_TX_LEVEL +REG[2] : FIFO_EMPTY +REG[3] : FIFO_FULL +REG[4-7] : FSM_STA +REG[8] : CARD_PRESENT +REG[9] : CARD_BUSY +REG[10] : FSM_BUSY +REG[11-16]: RESP_IDX +REG[17-21]: FIFO_LEVEL +REG[31] : DMA_REQ +*/ + +#define SDXC_CMD_INHIBIT BIT(0) +#define SDXC_DAT_INHIBIT BIT(1) +#define SDXC_DAT_ACTIVE BIT(2) +#define SDXC_WRITE_TRANSFER BIT(8) +#define SDXC_READ_TRANSFER BIT(9) + +// +// +//#define SDXC_FIFO_RX_LEVEL BIT(0) +//#define SDXC_FIFO_TX_LEVEL BIT(1) +//#define SDXC_FIFO_EMPTY BIT(2) +//#define SDXC_FIFO_FULL BIT(3) +//#define SDXC_CARD_PRESENT BIT(8) +//#define SDXC_CARD_BUSY BIT(9) +//#define SDXC_FSM_BUSY BIT(10) +//#define SDXC_DMA_REQ BIT(31) + +struct mmc_des_v4p1 +{ + rt_uint32_t : 1, + dic : 1, /* disable interrupt on completion */ + last_des : 1, /* 1-this data buffer is the last buffer */ + first_des : 1, /* 1-data buffer is the first buffer,0-data buffer contained in the next descriptor is 1st buffer */ + des_chain : 1, /* 1-the 2nd address in the descriptor is the next descriptor address */ + end_of_ring : 1, /* 1-last descriptor flag when using dual data buffer in descriptor */ + : 24, + card_err_sum : 1, /* transfer error flag */ + own : 1; /* des owner:1-idma owns it, 0-host owns it */ + +#define SDXC_DES_NUM_SHIFT 12 /* smhc2!! */ +#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT) + rt_uint32_t data_buf1_sz : 16, + data_buf2_sz : 16; + rt_uint32_t buf_addr_ptr1; + rt_uint32_t buf_addr_ptr2; +}; + +struct sdhci_cmd_t +{ + rt_uint32_t cmdidx; + rt_uint32_t cmdarg; + //const char* name; + // rt_uint32_t code; + rt_uint32_t resptype; + // rt_uint8_t rca; + // rt_uint32_t delay; + rt_uint32_t response[4]; +}; + +struct sdhci_data_t +{ + rt_uint8_t * buf; + rt_uint32_t flag; + rt_uint32_t blksz; + rt_uint32_t blkcnt; +}; + +struct sdhci_t +{ + char * name; + rt_uint32_t voltages; + rt_uint32_t width; + rt_uint32_t clock; + rt_err_t removeable; + void * sdcard; + + rt_err_t (*detect)(struct sdhci_t * sdhci); + rt_err_t (*setwidth)(struct sdhci_t * sdhci, rt_uint32_t width); + rt_err_t (*setclock)(struct sdhci_t * sdhci, rt_uint32_t clock); + rt_err_t (*transfer)(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat); + void * priv; +}; + +struct sdhci_pdata_t +{ + rt_uint32_t virt; +}; + +// EMMC command flags +#define CMD_TYPE_NORMAL 0x00000000 +#define CMD_TYPE_SUSPEND 0x00400000 +#define CMD_TYPE_RESUME 0x00800000 +#define CMD_TYPE_ABORT 0x00c00000 +#define CMD_IS_DATA 0x00200000 +#define CMD_IXCHK_EN 0x00100000 +#define CMD_CRCCHK_EN 0x00080000 +#define CMD_RSPNS_NO 0x00000000 +#define CMD_RSPNS_136 0x00010000 +#define CMD_RSPNS_48 0x00020000 +#define CMD_RSPNS_48B 0x00030000 +#define TM_MULTI_BLOCK 0x00000020 +#define TM_DAT_DIR_HC 0x00000000 +#define TM_DAT_DIR_CH 0x00000010 +#define TM_AUTO_CMD23 0x00000008 +#define TM_AUTO_CMD12 0x00000004 +#define TM_BLKCNT_EN 0x00000002 +#define TM_MULTI_DATA (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN) + +// Response types. +// Note that on the PI, the index and CRC are dropped, leaving 32 bits in RESP0. +#define RESP_NO 0 // No response +//#define RESP_R1 1 // 48 RESP0 contains card status +#define RESP_R1b 11 // 48 RESP0 contains card status, data line indicates busy +#define RESP_R2I 2 // 136 RESP0..3 contains 128 bit CID shifted down by 8 bits as no CRC +#define RESP_R2S 12 // 136 RESP0..3 contains 128 bit CSD shifted down by 8 bits as no CRC +//#define RESP_R3 3 // 48 RESP0 contains OCR register +//#define RESP_R6 6 // 48 RESP0 contains RCA and status bits 23,22,19,12:0 +//#define RESP_R7 7 // 48 RESP0 contains voltage acceptance and check pattern + +#define RCA_NO 1 +#define RCA_YES 2 + +// INTERRUPT register settings +#define INT_AUTO_ERROR 0x01000000 +#define INT_DATA_END_ERR 0x00400000 +#define INT_DATA_CRC_ERR 0x00200000 +#define INT_DATA_TIMEOUT 0x00100000 +#define INT_INDEX_ERROR 0x00080000 +#define INT_END_ERROR 0x00040000 +#define INT_CRC_ERROR 0x00020000 +#define INT_CMD_TIMEOUT 0x00010000 +#define INT_ERR 0x00008000 +#define INT_ENDBOOT 0x00004000 +#define INT_BOOTACK 0x00002000 +#define INT_RETUNE 0x00001000 +#define INT_CARD 0x00000100 +#define INT_READ_RDY 0x00000020 +#define INT_WRITE_RDY 0x00000010 +#define INT_BLOCK_GAP 0x00000004 +#define INT_DATA_DONE 0x00000002 +#define INT_CMD_DONE 0x00000001 +#define INT_ERROR_MASK (INT_CRC_ERROR|INT_END_ERROR|INT_INDEX_ERROR| \ + INT_DATA_TIMEOUT|INT_DATA_CRC_ERR|INT_DATA_END_ERR| \ + INT_ERR|INT_AUTO_ERROR) +#define INT_ALL_MASK (INT_CMD_DONE|INT_DATA_DONE|INT_READ_RDY|INT_WRITE_RDY|INT_ERROR_MASK) + +#define EMMC_ARG2 (0x00) +#define EMMC_BLKSIZECNT (0x04) +#define EMMC_ARG1 (0x08) +#define EMMC_CMDTM (0x0c) +#define EMMC_RESP0 (0x10) +#define EMMC_RESP1 (0x14) +#define EMMC_RESP2 (0x18) +#define EMMC_RESP3 (0x1c) +#define EMMC_DATA (0x20) +#define EMMC_STATUS (0x24) +#define EMMC_CONTROL0 (0x28) +#define EMMC_CONTROL1 (0x2c) +#define EMMC_INTERRUPT (0x30) +#define EMMC_IRPT_MASK (0x34) +#define EMMC_IRPT_EN (0x38) +#define EMMC_CONTROL2 (0x3c) +#define EMMC_BOOT_TIMEOUT (0x70) +#define EMMC_EXRDFIFO_EN (0x84) +#define EMMC_SPI_INT_SPT (0xf0) +#define EMMC_SLOTISR_VER (0xfc) + +// CONTROL register settings +#define C0_SPI_MODE_EN 0x00100000 +#define C0_HCTL_HS_EN 0x00000004 +#define C0_HCTL_DWITDH 0x00000002 + +#define C1_SRST_DATA 0x04000000 +#define C1_SRST_CMD 0x02000000 +#define C1_SRST_HC 0x01000000 +#define C1_TOUNIT_DIS 0x000f0000 +#define C1_TOUNIT_MAX 0x000e0000 +#define C1_CLK_GENSEL 0x00000020 +#define C1_CLK_EN 0x00000004 +#define C1_CLK_STABLE 0x00000002 +#define C1_CLK_INTLEN 0x00000001 + +#define FREQ_SETUP 400000 // 400 Khz +#define FREQ_NORMAL 25000000 // 25 Mhz + +// SLOTISR_VER values +#define HOST_SPEC_NUM 0x00ff0000 +#define HOST_SPEC_NUM_SHIFT 16 +#define HOST_SPEC_V3 2 +#define HOST_SPEC_V2 1 +#define HOST_SPEC_V1 0 + +// STATUS register settings +#define SR_DAT_LEVEL1 0x1e000000 +#define SR_CMD_LEVEL 0x01000000 +#define SR_DAT_LEVEL0 0x00f00000 +#define SR_DAT3 0x00800000 +#define SR_DAT2 0x00400000 +#define SR_DAT1 0x00200000 +#define SR_DAT0 0x00100000 +#define SR_WRITE_PROT 0x00080000 // From SDHC spec v2, BCM says reserved +#define SR_READ_AVAILABLE 0x00000800 // ???? undocumented +#define SR_WRITE_AVAILABLE 0x00000400 // ???? undocumented +#define SR_READ_TRANSFER 0x00000200 +#define SR_WRITE_TRANSFER 0x00000100 +#define SR_DAT_ACTIVE 0x00000004 +#define SR_DAT_INHIBIT 0x00000002 +#define SR_CMD_INHIBIT 0x00000001 + + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_spi.c b/bsp/raspberry-pi/raspi3-64/driver/drv_spi.c new file mode 100644 index 0000000000..041a97b510 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_spi.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include "drv_spi.h" + +#if !defined(BSP_USING_SPI0) && !defined(BSP_USING_SPI1) +#ifdef RT_USING_SPI +#undef RT_USING_SPI +#endif +#endif + +#ifdef RT_USING_SPI + + +static rt_uint8_t bcm2835_spi_bit_order = BCM283X_SPI_BIT_ORDER_MSBFIRST; +static rt_uint8_t bcm2835_byte_reverse_table[] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +#define BSP_SPI_MAX_HZ (30* 1000 *1000) +#define SPITIMEOUT 0x0FFF + +struct rt_spi_hw_config +{ + rt_int8_t sclk_pin; + rt_int8_t sclk_mode; + rt_int8_t mosi_pin; + rt_int8_t mosi_mode; + rt_int8_t miso_pin; + rt_int8_t miso_mode; + rt_int8_t cs_pin; + rt_int8_t cs_mode; + rt_uint32_t spi_base; + rt_uint32_t clk_div; +}; + +struct rt_sw_spi_cs +{ + rt_uint32_t pin; +}; + +struct rt_spi +{ + char *device_name; + struct rt_spi_bus *spi_bus; + struct rt_spi_hw_config *hwcfg; + struct rt_spi_configuration *cfg; +}; + +static rt_err_t raspi_hostspi_init(struct rt_spi_configuration *cfg) +{ + + volatile rt_uint32_t addr = (PER_BASE + BCM283X_SPI0_BASE) + BCM283X_SPI0_CS; + //volatile rt_uint32_t fifo = (PER_BASE + BCM283X_SPI0_BASE) + BCM283X_SPI0_FIFO; + + // spi clear fifo + bcm283x_peri_set_bits(addr, BCM283X_SPI0_CS_CLEAR, BCM283X_SPI0_CS_CLEAR); + + // /* Set TA = 1 */ + // bcm2835_peri_set_bits(addr, BCM283X_SPI0_CS_TA, BCM283X_SPI0_CS_TA); + + /* Mask in the CPO and CPHA bits of CS */ + + bcm283x_peri_set_bits(addr, (rt_uint32_t)(cfg->mode << 2), BCM283X_SPI0_CS_CPOL | BCM283X_SPI0_CS_CPHA); + + //chipSelect + bcm283x_peri_set_bits(addr, BCM283X_SPI_CS0, BCM283X_SPI0_CS_CS); + + rt_uint8_t shift = 21 + BCM283X_SPI_CS0; + /* Mask in the appropriate CSPOLn bit */ + bcm283x_peri_set_bits(addr, LOW << shift, 1 << shift); + + + if(cfg->max_hz > BSP_SPI_MAX_HZ) + { + cfg->max_hz = BSP_SPI_MAX_HZ; + } + + volatile rt_uint32_t clk_addr = (PER_BASE + BCM283X_SPI0_BASE) + BCM283X_SPI0_CLK; + bcm283x_peri_write(clk_addr, cfg->max_hz); + + return RT_EOK; +} + +static rt_err_t raspi_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg) +{ + RT_ASSERT(cfg != RT_NULL); + RT_ASSERT(device != RT_NULL); + + struct rt_spi *hspi = (struct rt_spi *)&device->bus->parent; + hspi->cfg = cfg; + + raspi_hostspi_init(cfg); + + return RT_EOK; +} + + +rt_uint8_t correct_order(rt_uint8_t b) +{ + if (bcm2835_spi_bit_order == BCM283X_SPI_BIT_ORDER_LSBFIRST) + return bcm2835_byte_reverse_table[b]; + else + return b; +} + +static rt_err_t spi_transfernb(rt_uint8_t* tbuf, rt_uint8_t* rbuf, rt_uint32_t len) +{ + volatile rt_uint32_t paddr = SPI0_BASE_ADDR + BCM283X_SPI0_CS; + volatile rt_uint32_t fifo = SPI0_BASE_ADDR + BCM283X_SPI0_FIFO; + rt_uint32_t TXCnt=0; + rt_uint32_t RXCnt=0; + + /* Clear TX and RX fifos */ + bcm283x_peri_set_bits(paddr, BCM283X_SPI0_CS_CLEAR, BCM283X_SPI0_CS_CLEAR); + + /* Set TA = 1 */ + bcm283x_peri_set_bits(paddr, BCM283X_SPI0_CS_TA, BCM283X_SPI0_CS_TA); + + /* Use the FIFO's to reduce the interbyte times */ + while ((TXCnt < len) || (RXCnt < len)) + { + /* TX fifo not full, so add some more bytes */ + while (((bcm283x_peri_read(paddr) & BCM283X_SPI0_CS_TXD)) && (TXCnt < len)) + { + bcm283x_peri_write_nb(fifo, correct_order(tbuf[TXCnt])); + TXCnt++; + } + /* Rx fifo not empty, so get the next received bytes */ + while (((bcm283x_peri_read(paddr) & BCM283X_SPI0_CS_RXD)) && (RXCnt < len)) + { + rbuf[RXCnt] = correct_order(bcm283x_peri_read_nb(fifo)); + RXCnt++; + } + } + /* Wait for DONE to be set */ + while (!(bcm283x_peri_read_nb(paddr) & BCM283X_SPI0_CS_DONE)); + + /* Set TA = 0, and also set the barrier */ + bcm283x_peri_set_bits(paddr, 0, BCM283X_SPI0_CS_TA); + return RT_EOK; + +} + +static rt_uint32_t raspi_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + rt_err_t res; + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->bus != RT_NULL); + RT_ASSERT(device->bus->parent.user_data != RT_NULL); + RT_ASSERT(message->send_buf != RT_NULL || message->recv_buf != RT_NULL); + + struct rt_spi *hspi = (struct rt_spi *)&device->bus->parent; + /* only send data */ + if (message->recv_buf == RT_NULL) + { + if (message->cs_take) + { + bcm283x_gpio_write(hspi->hwcfg->cs_pin, 0); + } + res = spi_transfernb((rt_uint8_t *)message->send_buf, RT_NULL,(rt_int32_t)message->length); + if (message->cs_release) + { + bcm283x_gpio_write(hspi->hwcfg->cs_pin, 1); + + } + if (res != RT_EOK) + return RT_ERROR; + } + + /* only receive data */ + if (message->send_buf == RT_NULL) + { + if (message->cs_take) + { + bcm283x_gpio_write(hspi->hwcfg->cs_pin, 0); + } + res = spi_transfernb(RT_NULL,(rt_uint8_t *)message->recv_buf, (rt_int32_t)message->length); + if (message->cs_release) + { + bcm283x_gpio_write(hspi->hwcfg->cs_pin, 1); + } + if (res != RT_EOK) + return RT_ERROR; + } + /* send & receive */ + else + { + if (message->cs_take) + { + bcm283x_gpio_write(hspi->hwcfg->cs_pin, 0); + } + res = spi_transfernb((rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, + (rt_int32_t)message->length); + if (message->cs_release) + { + bcm283x_gpio_write(hspi->hwcfg->cs_pin, 1); + } + if (res != RT_EOK) + return RT_ERROR; + } + + return message->length; +} + +rt_err_t raspi_spi_bus_attach_device(const char *bus_name, const char *device_name, rt_uint32_t pin) +{ + rt_err_t ret; + rt_int16_t gpio_pin; + struct rt_spi_device *spi_device; + struct rt_sw_spi_cs *cs_pin; + + gpio_pin = phypin_index[pin].bcm_id; + + spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device)); + RT_ASSERT(spi_device != RT_NULL); + + cs_pin = (struct rt_sw_spi_cs *)rt_malloc(sizeof(struct rt_sw_spi_cs)); + RT_ASSERT(cs_pin != RT_NULL); + + cs_pin->pin = gpio_pin; + + ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin); + + return ret; +} + +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +rt_uint16_t spi_clockdivider(rt_uint32_t speed_hz) +{ + rt_uint16_t divider; + + if (speed_hz < (rt_uint32_t) BCM283X_AUX_SPI_CLOCK_MIN) + { + speed_hz = (rt_uint32_t) BCM283X_AUX_SPI_CLOCK_MIN; + } + else if (speed_hz > (rt_uint32_t) BCM283X_AUX_SPI_CLOCK_MAX) + { + speed_hz = (rt_uint32_t) BCM283X_AUX_SPI_CLOCK_MAX; + } + + divider = (rt_uint16_t) DIV_ROUND_UP(BCM283X_CORE_CLK_HZ, 2 * speed_hz) - 1; + + if (divider > (rt_uint16_t) BCM283X_AUX_SPI_CNTL0_SPEED_MAX) + { + return (rt_uint16_t) BCM283X_AUX_SPI_CNTL0_SPEED_MAX; + } + + return divider; +} + +rt_err_t raspi_spi_hw_init(struct rt_spi_hw_config *hwcfg) +{ + volatile rt_uint32_t enable = PER_BASE + BCM283X_AUX_BASE + BCM283X_AUX_ENABLE; + volatile rt_uint32_t cntl0 = PER_BASE + BCM283X_SPI1_BASE + BCM283X_AUX_SPI_CNTL0; + volatile rt_uint32_t cntl1 = PER_BASE + BCM283X_SPI1_BASE + BCM283X_AUX_SPI_CNTL1; + + bcm283x_gpio_fsel(hwcfg->sclk_pin, hwcfg->sclk_mode); + bcm283x_gpio_fsel(hwcfg->miso_pin, hwcfg->miso_mode); + bcm283x_gpio_fsel(hwcfg->mosi_pin, hwcfg->mosi_mode); + bcm283x_gpio_fsel(hwcfg->cs_pin, hwcfg->cs_mode); + + hwcfg->clk_div = spi_clockdivider(1000000); // Default 1MHz SPI + + bcm283x_peri_write(enable, BCM283X_AUX_ENABLE_SPI0); + bcm283x_peri_write(cntl1, 0); + bcm283x_peri_write(cntl0, BCM283X_AUX_SPI_CNTL0_CLEARFIFO); + + return RT_EOK; +} + +const static struct rt_spi_ops raspi_spi_ops = +{ + .configure = raspi_spi_configure, + .xfer = raspi_spi_xfer +}; + +#if defined (BSP_USING_SPI0) +#define SPI0BUS_NAME "spi0.0" + +struct rt_spi_bus raspi_spi0_bus = +{ + .ops = &raspi_spi_ops, + .parent.user_data = spi0 +}; + +struct rt_spi_hw_config raspi_spi0_hw = +{ + .sclk_pin = BCM_GPIO_PIN_11, + .sclk_mode = BCM283X_GPIO_FSEL_ALT0, + .mosi_pin = BCM_GPIO_PIN_10, + .mosi_mode = BCM283X_GPIO_FSEL_ALT0, + .miso_pin = BCM_GPIO_PIN_9, + .miso_mode = BCM283X_GPIO_FSEL_ALT0, + .cs_pin = BCM_GPIO_PIN_8, + .cs_mode = BCM283X_GPIO_FSEL_ALT0, + .spi_base = (PER_BASE + BCM283X_SPI0_BASE), + .clk_div = 0, +}; + +struct rt_spi spi0 = +{ + .device_name = SPI0BUS_NAME, + .spi_bus = &raspi_spi0_bus, + .hwcfg = &raspi_spi0_hw, +}; + +#endif + +#if defined (BSP_USING_SPI1) +#define SPI1BUS_NAME "spi0.1" + +struct rt_spi_bus raspi_spi1_bus = +{ + .ops = &raspi_spi_ops, + .parent.user_data = spi1 +}; + +struct rt_spi_hw_config raspi_spi1_hw = +{ + .sclk_pin = BCM_GPIO_PIN_11, + .sclk_mode = BCM283X_GPIO_FSEL_ALT0, + .mosi_pin = BCM_GPIO_PIN_10, + .mosi_mode = BCM283X_GPIO_FSEL_ALT0, + .miso_pin = BCM_GPIO_PIN_9, + .miso_mode = BCM283X_GPIO_FSEL_ALT0, + .cs_pin = BCM_GPIO_PIN_7, + .cs_mode = BCM283X_GPIO_FSEL_ALT0, + .spi_base = (PER_BASE + BCM283X_SPI0_BASE), + .clk_div = 0, +}; + +struct rt_spi spi1 = +{ + .device_name = SPI1BUS_NAME, + .spi_bus = &raspi_spi1_bus, + .hwcfg = &raspi_spi1_hw, +}; +#endif + +int rt_hw_spi_bus_init(void) +{ +#if defined (BSP_USING_SPI0) + raspi_spi_hw_init(spi0.hwcfg); + rt_spi_bus_register(spi0.spi_bus, spi0.device_name, spi0.spi_bus->ops); +#endif + +#if defined (BSP_USING_SPI1) + raspi_spi_hw_init(spi1.hwcfg); + rt_spi_bus_register(spi1.spi_bus, spi1.device_name, spi1.spi_bus->ops); +#endif + + return RT_EOK; +} +INIT_PREV_EXPORT(rt_hw_spi_bus_init); + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_spi.h b/bsp/raspberry-pi/raspi3-64/driver/drv_spi.h new file mode 100644 index 0000000000..c4883758e5 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_spi.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_SPI_H__ +#define __DRV_SPI_H__ + +#include +#include + +#include "bcm283x.h" +#include +#include +#include "raspi.h" + +#define SPI0_BASE_ADDR (PER_BASE + BCM283X_SPI0_BASE) + +#define SPI_CORE_CLK 250000000U +#define SPI_CS 0x00 +#define SPI_CS_LEN_LONG (1 << 25) +#define SPI_CS_DMA_LEN (1 << 24) +#define SPI_CS_CSPOL2 (1 << 23) +#define SPI_CS_CSPOL1 (1 << 22) +#define SPI_CS_CSPOL0 (1 << 21) +#define SPI_CS_RXF (1 << 20) +#define SPI_CS_RXR (1 << 19) +#define SPI_CS_TXD (1 << 18) +#define SPI_CS_RXD (1 << 17) +#define SPI_CS_DONE (1 << 16) +#define SPI_CS_LEN (1 << 13) +#define SPI_CS_REN (1 << 12) +#define SPI_CS_ADCS (1 << 11) +#define SPI_CS_INTR (1 << 10) +#define SPI_CS_INTD (1 << 9) +#define SPI_CS_DMAEN (1 << 8) +#define SPI_CS_TA (1 << 7) +#define SPI_CS_CSPOL (1 << 6) +#define SPI_CS_CLEAR_RXFIFO (1 << 5) +#define SPI_CS_CLEAR_TXFIFO (1 << 4) +#define SPI_CS_CPOL (1 << 3) +#define SPI_CS_CPHA (1 << 2) +#define SPI_CS_MASK 0x3 +#define SPI_FIFO 0x04 +#define SPI_CLK 0x08 +#define SPI_CLK_MASK 0xffff +#define SPI_DLEN 0x0c +#define SPI_DLEN_MASK 0xffff +#define SPI_LTOH 0x10 +#define SPI_LTOH_MASK 0xf +#define SPI_DC 0x14 +#define SPI_DC_RPANIC_SHIFT 24 +#define SPI_DC_RPANIC_MASK (0xff << SPI_DC_RPANIC_SHIFT) +#define SPI_DC_RDREQ_SHIFT 16 +#define SPI_DC_RDREQ_MASK (0xff << SPI_DC_RDREQ_SHIFT) +#define SPI_DC_TPANIC_SHIFT 8 +#define SPI_DC_TPANIC_MASK (0xff << SPI_DC_TPANIC_SHIFT) +#define SPI_DC_TDREQ_SHIFT 0 +#define SPI_DC_TDREQ_MASK 0xff + +int rt_hw_spi_bus_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_timer.c b/bsp/raspberry-pi/raspi3-64/driver/drv_timer.c new file mode 100644 index 0000000000..0ead0fdf74 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_timer.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#include +#include +#include "bcm283x.h" +#include "drv_timer.h" +#include +#include "cp15.h" + +static void rt_systimer_init(rt_hwtimer_t *hwtimer, rt_uint32_t state) +{ + if (state == 0) + hwtimer->ops->stop(hwtimer); +} + +static rt_err_t rt_systimer_start(rt_hwtimer_t *hwtimer, rt_uint32_t cnt, rt_hwtimer_mode_t mode) +{ + rt_err_t result = RT_EOK; + rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; + int timer_id = timer->timer_id; + if (mode == HWTIMER_MODE_PERIOD) + timer->cnt = cnt; + else + timer->cnt = 0; + __DSB(); + if (timer_id == 1) + { + rt_hw_interrupt_umask(IRQ_SYSTIMER_MATCH_1); + STIMER_C1 = STIMER_CLO + cnt; + } + else if (timer_id == 3) + { + rt_hw_interrupt_umask(IRQ_SYSTIMER_MATCH_3); + STIMER_C3 = STIMER_CLO + cnt; + } + else + result = -RT_ERROR; + __DSB(); + + return result; +} + +static void rt_systimer_stop(rt_hwtimer_t *hwtimer) +{ + rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; + int timer_id = timer->timer_id; + if (timer_id == 1) + rt_hw_interrupt_mask(IRQ_SYSTIMER_MATCH_1); + else if (timer_id == 3) + rt_hw_interrupt_mask(IRQ_SYSTIMER_MATCH_3); + +} + +static rt_err_t rt_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) +{ + /* The frequency value is an immutable value. */ + if (cmd == HWTIMER_CTRL_FREQ_SET) + { + return RT_EOK; + } + else + { + return -RT_ENOSYS; + } +} + +const static struct rt_hwtimer_ops systimer_ops = +{ + rt_systimer_init, + rt_systimer_start, + rt_systimer_stop, + RT_NULL, + rt_systimer_ctrl +}; + +void rt_device_systimer_isr(int vector, void *param) +{ + rt_hwtimer_t *hwtimer = (rt_hwtimer_t *) param; + rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; + RT_ASSERT(timer != RT_NULL); + int timer_id = timer->timer_id; + + __DSB(); + if (timer_id == 1) + { + STIMER_CS = 0x2; + STIMER_C1 = STIMER_CLO + timer->cnt; + } + else if (timer_id == 3) + { + STIMER_CS = 0x8; + STIMER_C3 = STIMER_CLO + timer->cnt; + } + + __DSB(); + rt_device_hwtimer_isr(hwtimer); +} + +static struct rt_hwtimer_device _hwtimer1; +static struct rt_hwtimer_device _hwtimer3; +static struct rt_systimer_device _systimer1; +static struct rt_systimer_device _systimer3; + +static const struct rt_hwtimer_info _info = +{ + 1000000, /* the maxinum count frequency can be set */ + 1000000, /* the maxinum count frequency can be set */ + 0xFFFFFFFF, /* the maximum counter value */ + HWTIMER_CNTMODE_UP /* count mode (inc/dec) */ +}; + +int rt_hw_systimer_init(void) +{ +#ifdef RT_USING_SYSTIMER1 + _systimer1.timer_id =1; + _hwtimer1.ops = &systimer_ops; + _hwtimer1.info = &_info; + rt_device_hwtimer_register(&_hwtimer1, "timer1",&_systimer1); + rt_hw_interrupt_install(IRQ_SYSTIMER_MATCH_1, rt_device_systimer_isr, &_hwtimer1, "systimer1"); + rt_hw_interrupt_umask(IRQ_SYSTIMER_MATCH_1); +#endif + +#ifdef RT_USING_SYSTIMER3 + _systimer3.timer_id =3; + _hwtimer3.ops = &systimer_ops; + _hwtimer3.info = &_info; + rt_device_hwtimer_register(&_hwtimer3, "timer3",&_systimer3); + rt_hw_interrupt_install(IRQ_SYSTIMER_MATCH_3, rt_device_systimer_isr, &_hwtimer3, "systimer3"); + +#endif + + return 0; +} diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_timer.h b/bsp/raspberry-pi/raspi3-64/driver/drv_timer.h new file mode 100644 index 0000000000..c18e3d893c --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_timer.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ +#ifndef __DRV_TIMER_H__ +#define __DRV_TIMER_H__ + +#include +#include + +typedef struct rt_systimer_device +{ + int timer_id; + rt_uint32_t cnt; +} rt_systimer_t; + +int rt_hw_systimer_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_uart.c b/bsp/raspberry-pi/raspi3-64/driver/drv_uart.c new file mode 100644 index 0000000000..fd8ec66af9 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_uart.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/5/5 Bernard The first version + */ + +#include +#include +#include + +#include "board.h" +#include "drv_uart.h" + +#include + +#define AUX_BASE (0x3F000000 + 0x215000) + +struct hw_uart_device +{ + rt_ubase_t hw_base; + rt_uint32_t irqno; +}; + +static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + if (uart->hw_base == AUX_BASE) + { + rt_uint32_t value; + + /* GPIO function set */ + value = GPIO_GPFSEL1; + value &= ~(7<<12); /* GPIO14 */ + value |= 2<<12 ; /* ALT5 */ + value &= ~(7<<15); /* GPIO15 */ + value |= 2<<15 ; /* ALT5 */ + GPIO_GPFSEL1 = value; + + /* PullUD disable */ + GPIO_GPPUD = 0; + GPIO_GPPUDCLK0 = (1 << 14) | (1 << 15); + GPIO_GPPUDCLK0 = 0; + + AUX_ENABLES(uart->hw_base) = 1; /* Enable UART1 */ + AUX_MU_IER_REG(uart->hw_base) = 0; /* Disable interrupt */ + AUX_MU_CNTL_REG(uart->hw_base) = 0; /* Disable Transmitter and Receiver */ + AUX_MU_LCR_REG(uart->hw_base) = 3; /* Works in 8-bit mode */ + AUX_MU_MCR_REG(uart->hw_base) = 0; /* Disable RTS */ + AUX_MU_IIR_REG(uart->hw_base) = 0xC6; /* Enable FIFO, Clear FIFO */ + AUX_MU_BAUD_REG(uart->hw_base) = 270; /* 115200 = system clock 250MHz / (8 * (baud + 1)), baud = 270 */ + AUX_MU_CNTL_REG(uart->hw_base) = 3; /* Enable Transmitter and Receiver */ + } + + return RT_EOK; +} + +static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + AUX_MU_IER_REG(uart->hw_base) = 0x0; + rt_hw_interrupt_mask(uart->irqno); + break; + + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + AUX_MU_IER_REG(uart->hw_base) = 0x1; + rt_hw_interrupt_umask(uart->irqno); + break; + } + + return RT_EOK; +} + +static int uart_putc(struct rt_serial_device *serial, char c) +{ + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + while (!(AUX_MU_LSR_REG(uart->hw_base) & 0x20)); + AUX_MU_IO_REG(uart->hw_base) = c; + + return 1; +} + +static int uart_getc(struct rt_serial_device *serial) +{ + int ch = -1; + struct hw_uart_device *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct hw_uart_device *)serial->parent.user_data; + + if ((AUX_MU_LSR_REG(uart->hw_base) & 0x01)) + { + ch = AUX_MU_IO_REG(uart->hw_base) & 0xff; + } + + return ch; +} + +static const struct rt_uart_ops _uart_ops = +{ + uart_configure, + uart_control, + uart_putc, + uart_getc, +}; + +static void rt_hw_uart_isr(int irqno, void *param) +{ + struct rt_serial_device *serial = (struct rt_serial_device*)param; + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); +} + +#ifdef RT_USING_UART0 +/* UART device driver structure */ +static struct hw_uart_device _uart0_device = +{ + RPI_UART0_BASE, + IRQ_PBA8_UART0, +}; +static struct rt_serial_device _serial0; +#endif + +#ifdef RT_USING_UART1 +/* UART1 device driver structure */ +static struct hw_uart_device _uart1_device = +{ + AUX_BASE, + IRQ_AUX, +}; +static struct rt_serial_device _serial1; +#endif + +int rt_hw_uart_init(void) +{ + struct hw_uart_device *uart; + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + +#ifdef RT_USING_UART0 + uart = &_uart0_device; + + _serial0.ops = &_uart_ops; + _serial0.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&_serial0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + uart); + rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart0"); +#endif + +#ifdef RT_USING_UART1 + uart = &_uart1_device; + _serial1.ops = &_uart_ops; + _serial1.config = config; + + /* register UART1 device */ + rt_hw_serial_register(&_serial1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); + /* enable Rx and Tx of UART */ + rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial1, "uart1"); +#endif + + return 0; +} diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_uart.h b/bsp/raspberry-pi/raspi3-64/driver/drv_uart.h new file mode 100644 index 0000000000..894c6098db --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_uart.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 Bernard the first version + */ + + +#ifndef DRV_UART_H__ +#define DRV_UART_H__ + +/* + * Auxiliary + */ +#define AUX_IRQ(BASE) HWREG32(BASE + 0x00) /* Auxiliary Interrupt status 3 */ +#define AUX_ENABLES(BASE) HWREG32(BASE + 0x04) /* Auxiliary enables 3bit */ +#define AUX_MU_IO_REG(BASE) HWREG32(BASE + 0x40) /* Mini Uart I/O Data 8bit */ +#define AUX_MU_IER_REG(BASE) HWREG32(BASE + 0x44) /* Mini Uart Interrupt Enable 8bit */ +#define AUX_MU_IIR_REG(BASE) HWREG32(BASE + 0x48) /* Mini Uart Interrupt Identify 8bit */ +#define AUX_MU_LCR_REG(BASE) HWREG32(BASE + 0x4C) /* Mini Uart Line Control 8bit */ +#define AUX_MU_MCR_REG(BASE) HWREG32(BASE + 0x50) /* Mini Uart Modem Control 8bit */ +#define AUX_MU_LSR_REG(BASE) HWREG32(BASE + 0x54) /* Mini Uart Line Status 8bit */ +#define AUX_MU_MSR_REG(BASE) HWREG32(BASE + 0x58) /* Mini Uart Modem Status 8bit */ +#define AUX_MU_SCRATCH(BASE) HWREG32(BASE + 0x5C) /* Mini Uart Scratch 8bit */ +#define AUX_MU_CNTL_REG(BASE) HWREG32(BASE + 0x60) /* Mini Uart Extra Control 8bit */ +#define AUX_MU_STAT_REG(BASE) HWREG32(BASE + 0x64) /* Mini Uart Extra Status 32bit */ +#define AUX_MU_BAUD_REG(BASE) HWREG32(BASE + 0x68) /* Mini Uart Baudrate 16bit */ +#define AUX_SPI0_CNTL0_REG(BASE) HWREG32(BASE + 0x80) /* SPI 1 Control register 0 32bit */ +#define AUX_SPI0_CNTL1_REG(BASE) HWREG32(BASE + 0x84) /* SPI 1 Control register 1 8bit */ +#define AUX_SPI0_STAT_REG(BASE) HWREG32(BASE + 0x88) /* SPI 1 Status 32bit */ +#define AUX_SPI0_IO_REG(BASE) HWREG32(BASE + 0x90) /* SPI 1 Data 32bit */ +#define AUX_SPI0_PEEK_REG(BASE) HWREG32(BASE + 0x94) /* SPI 1 Peek 16bit */ +#define AUX_SPI1_CNTL0_REG(BASE) HWREG32(BASE + 0xC0) /* SPI 2 Control register 0 32bit */ +#define AUX_SPI1_CNTL1_REG(BASE) HWREG32(BASE + 0xC4) /* SPI 2 Control register 1 8bit */ + +int rt_hw_uart_init(void); + +#endif /* DRV_UART_H__ */ + diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_wdt.c b/bsp/raspberry-pi/raspi3-64/driver/drv_wdt.c new file mode 100644 index 0000000000..a1baee96aa --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_wdt.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ +#include "drv_wdt.h" + +#ifdef BSP_USING_WDT + +#define PM_RSTC 0x1c +#define PM_RSTS 0x20 +#define PM_WDOG 0x24 + +#define PM_PASSWORD 0x5a000000 + +#define PM_WDOG_TIME_SET 0x000fffff +#define PM_RSTC_WRCFG_CLR 0xffffffcf +#define PM_RSTS_HADWRH_SET 0x00000040 +#define PM_RSTC_WRCFG_SET 0x00000030 +#define PM_RSTC_WRCFG_FULL_RESET 0x00000020 +#define PM_RSTC_RESET 0x00000102 +#define PM_RSTS_PARTITION_CLR 0xfffffaaa + +#define SECS_TO_WDOG_TICKS(x) ((x) << 16) +#define WDOG_TICKS_TO_SECS(x) ((x) >> 16) + +static struct raspi_wdt_driver bcm_wdt = +{ + .base = PER_BASE, +}; + +void raspi_watchdog_init(rt_uint32_t time_init) +{ + bcm_wdt.timeout = time_init; +} + +void raspi_watchdog_start() +{ + volatile rt_uint32_t cur; + bcm283x_peri_write(bcm_wdt.base + PM_WDOG, PM_PASSWORD + | (SECS_TO_WDOG_TICKS(bcm_wdt.timeout) & PM_WDOG_TIME_SET)); + bcm283x_peri_write(bcm_wdt.base + PM_WDOG, PM_PASSWORD + | (SECS_TO_WDOG_TICKS(bcm_wdt.timeout) & PM_WDOG_TIME_SET)); + + cur = bcm283x_peri_read(bcm_wdt.base + PM_RSTC); + + bcm283x_peri_write(bcm_wdt.base + PM_RSTC, PM_PASSWORD + | (cur & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET); + +} + +void raspi_watchdog_stop() +{ + bcm283x_peri_write(bcm_wdt.base + PM_RSTC, PM_PASSWORD | PM_RSTC_RESET); +} + +void raspi_watchdog_clr() +{ + bcm_wdt.timeout = 0; +} + +void raspi_watchdog_set_timeout( rt_uint32_t timeout_us) +{ + bcm_wdt.timeout = timeout_us; +} + +rt_uint64_t raspi_watchdog_get_timeout() +{ + return bcm_wdt.timeout; +} + +rt_uint64_t raspi_watchdog_get_timeleft() +{ + rt_uint32_t ret = bcm283x_peri_read(bcm_wdt.base + PM_WDOG); + return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET); +} + +static rt_err_t raspi_wdg_init(rt_watchdog_t *wdt) +{ + /*init for 10S*/ + raspi_watchdog_init(1000000); + raspi_watchdog_start(); + raspi_watchdog_stop(); + return RT_EOK; +} + +static rt_err_t raspi_wdg_control(rt_watchdog_t *wdt, int cmd, void *arg) +{ + rt_uint64_t timeout_us = 0; + switch (cmd) + { + case RT_DEVICE_CTRL_WDT_SET_TIMEOUT: + timeout_us = *((rt_uint32_t *)arg) * 1000000; + if (timeout_us >= 0xFFFFFFFF) + timeout_us = 0xFFFFFFFF; + raspi_watchdog_set_timeout((rt_uint32_t)timeout_us); + break; + case RT_DEVICE_CTRL_WDT_GET_TIMEOUT: + timeout_us = raspi_watchdog_get_timeout(); + *((rt_uint32_t *)arg) = timeout_us / 1000000; + break; + case RT_DEVICE_CTRL_WDT_GET_TIMELEFT: + timeout_us = raspi_watchdog_get_timeleft(); + *((rt_uint32_t *)arg) = timeout_us / 1000000; + break; + case RT_DEVICE_CTRL_WDT_KEEPALIVE: + raspi_watchdog_clr(); + break; + case RT_DEVICE_CTRL_WDT_START: + raspi_watchdog_start(); + break; + case RT_DEVICE_CTRL_WDT_STOP: + raspi_watchdog_stop(); + break; + default: + return RT_EIO; + } + return RT_EOK; +} + +static const struct rt_watchdog_ops raspi_wdg_pos = +{ + raspi_wdg_init, + raspi_wdg_control, +}; + +static rt_watchdog_t raspi_wdg; + +int rt_hw_wdt_init(void) +{ + raspi_wdg.ops = &raspi_wdg_pos; + rt_hw_watchdog_register(&raspi_wdg, "wdg", 0, RT_NULL); + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_wdt_init); +#endif /*BSP_USING_WDT */ diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_wdt.h b/bsp/raspberry-pi/raspi3-64/driver/drv_wdt.h new file mode 100644 index 0000000000..a690becfd1 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_wdt.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __DRV_WDT_H__ +#define __DRV_WDT_H__ + +#include +#include +#include +#include + +#include "bcm283x.h" + +struct raspi_wdt_driver +{ + volatile rt_uint32_t base; + rt_uint32_t timeout; +}; + +int rt_hw_wdt_init(void); + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/mbox.c b/bsp/raspberry-pi/raspi3-64/driver/mbox.c new file mode 100644 index 0000000000..36ed95b429 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/mbox.c @@ -0,0 +1,53 @@ +/* + * File : mbox.c + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-29 zdzn first version + */ + +/* mailbox message buffer */ +#include "mbox.h" +#include "mmu.h" +//volatile unsigned int __attribute__((aligned(16))) mbox[36]; +volatile unsigned int *mbox = (volatile unsigned int *) MBOX_ADDR; +/** + * Make a mailbox call. Returns 0 on failure, non-zero on success + */ +void init_mbox_mmu_map(){ + rt_hw_change_mmu_table(MBOX_ADDR, 96, MBOX_ADDR, STRONG_ORDER_MEM); +} + +int mbox_call(unsigned char ch, int mmu_enable) +{ + unsigned int r = (((MBOX_ADDR)&~0xF) | (ch&0xF)); + if(mmu_enable) + r = BUS_ADDRESS(r); + /* wait until we can write to the mailbox */ + do + { + asm volatile("nop"); + } while (*MBOX_STATUS & MBOX_FULL); + /* write the address of our message to the mailbox with channel identifier */ + *MBOX_WRITE = r; + /* now wait for the response */ + // rt_kprintf("mailbox request %x\n",r); + while(1) + { + /* is there a response? */ + do + { + asm volatile("nop"); + } while (*MBOX_STATUS & MBOX_EMPTY); + /* is it a response to our message? */ + if (r == *MBOX_READ){ + /* is it a valid successful response? */ + // rt_kprintf("mbox: %x, %x, %x, %x, %x, %x, %x, %x\n", mbox[0], mbox[1], mbox[2], mbox[3], mbox[4], mbox[5], mbox[6], mbox[7]); + return mbox[1] == MBOX_RESPONSE; + } + } + return 0; +} diff --git a/bsp/raspberry-pi/raspi3-64/driver/mbox.h b/bsp/raspberry-pi/raspi3-64/driver/mbox.h new file mode 100644 index 0000000000..eb7eb0318c --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/mbox.h @@ -0,0 +1,62 @@ +/* + * File : mbox.h + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-08-29 zdzn first version + */ + +#ifndef __MBOX_H__ +#define __MBOX_H__ + + +/* a properly aligned buffer */ +extern volatile unsigned int* mbox; + +#define MBOX_REQUEST 0 + +/* channels */ +#define MBOX_CH_POWER 0 +#define MBOX_CH_FB 1 +#define MBOX_CH_VUART 2 +#define MBOX_CH_VCHIQ 3 +#define MBOX_CH_LEDS 4 +#define MBOX_CH_BTNS 5 +#define MBOX_CH_TOUCH 6 +#define MBOX_CH_COUNT 7 +#define MBOX_CH_PROP 8 + +/* tags */ +#define MBOX_TAG_SETPOWER 0x28001 +#define MBOX_TAG_SETCLKRATE 0x38002 +#define MBOX_GET_MAC_ADDRESS 0x10003 +#define MBOX_TAG_LAST 0 + +#define MMIO_BASE 0x3F000000 +#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880) +#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0)) +#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10)) +#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14)) +#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18)) +#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C)) +#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20)) +#define MBOX_RESPONSE 0x80000000 +#define MBOX_FULL 0x80000000 +#define MBOX_EMPTY 0x40000000 + +#define DEVICE_ID_SD_CARD 0 +#define DEVICE_ID_USB_HCD 3 +#define POWER_STATE_OFF (0 << 0) +#define POWER_STATE_ON (1 << 0) +#define POWER_STATE_WAIT (1 << 1) +#define POWER_STATE_NO_DEVICE (1 << 1) // in response +#define MMU_ENABLE 1 +#define MMU_DISABLE 0 + +#define MBOX_ADDR 0xc00000 + +int mbox_call(unsigned char ch, int mmu_enable); +#endif diff --git a/bsp/raspberry-pi/raspi3-64/driver/raspi.h b/bsp/raspberry-pi/raspi3-64/driver/raspi.h new file mode 100644 index 0000000000..0d55df2a11 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/driver/raspi.h @@ -0,0 +1,70 @@ +/* + * File : rsapi.h + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-07-29 zdzn first version + */ + +#ifndef __RASPI_H__ +#define __RASPI_H__ + +#include "bcm283x.h" + +#define PIN_MAGIC (0x5A) +#define PIN_NUM(_N) (sizeof(_N) / sizeof(_N[0])) + +enum gpio_code +{ + GPIO_CODE_PHY = 0, + GPIO_CODE_BCM, + GPIO_CODE_WIRING, + GPIO_CODE_NUM, +}; + +enum rpi_pin_name +{ + RPI_SDA0 = 0, + RPI_SCL0, + RPI_SDA1, + RPI_SCL1, + RPI_GPIO_GCLK, + RPI_CAM_CLK, + RPI_LAN_RUN, + RPI_SPI_CE1_N, + RPI_SPI_CE0_N, + RPI_SPI_MISO, + RPI_SPI_MOSI, + RPI_SPI_SCLK, + RPI_TXD0, + RPI_RXD0, + RPI_STATUS_LED_N, + RPI_GPIO_GEN0, + RPI_GPIO_GEN1, + RPI_CAM_GPIO, + RPI_GPIO_GEN3, + RPI_GPIO_GEN4, + RPI_GPIO_GEN5, + RPI_GPIO_GEN6, + RPI_GPIO_GEN2, + RPI_GPIO_GEN7, + RPI_GPIO_GEN8, + RPI_GPIO_GEN9, + RPI_GPIO_GEN10, + RPI_PWM0_OUT, + RPI_PWM1_OUT, + RPI_HDMI_HPD_P, + RPI_SD_CARD_DET, + RPI_SD_CLK_R, + RPI_SD_CMD_R, + RPI_SD_DATA0_R, + RPI_SD_DATA1_R, + RPI_SD_DATA2_R, + RPI_SD_DATA3_R, + RPI_GPIO_PIN_NUM, +}; + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/figures/raspi_uart.png b/bsp/raspberry-pi/raspi3-64/figures/raspi_uart.png new file mode 100644 index 0000000000000000000000000000000000000000..c6ae382182e3f218c61338dbf0ed5c3066d9550f GIT binary patch literal 1067143 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

&l?!DZ9_U+y5 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≧D&ukr9*>hxR`QEt; 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

@3MH43z7cSQ^lk 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

    Y~HpsmWvJti$}Q> zFxOaQa1#geU^)C%&~Z8seOC~5{Tsjn`pX>t1+X4^t^T?u2;`uvhkymQd#xVoFLdQ_ zVgaL^1i8K{sfbD%vV!hZLUApjx))Mhk}+_V{{}sNcN%kzHVh&0bJK+GNMo!wfZr|t z2t&9_0m-F=hA4ybI6w}k8k#-n0~rQ+u*h&|tq?F44b;N{W7W`|D(Pz~n8<7#EFolf zK0mNrxiOLAtcq~c;CyrCsH*r4iIfe=RNor)E|bE&j18}(+Z}r}cs1DxbgyRZu8|e3 zb{>A_(*8#tIehx;qfcEu^!TZPLld>f`>CUu8=EAXD_Nm+8cK5#rQSd&kEK@Vnbk%@ zNt|D%%t?boMiD@{K|}J+QU(;odZsCNYq_COLSarqTtmL1A;UkJ7m^|tS+fbH`rzzH zPrZ0&BzsRRZ;wu}PD4Q`F)$4j80sX$Z`bm~)p^;2P4e>8APqA-PRK7#Hg;5CQbewT zK!i8|E)Rx*&mwU!OcVqYffBMe$C8MJDqdwYp;YQw%-K@L^{AGoFSSlQex%seR5jW^ zcj1x#g9kFZ8U*Il;7ZwsLZW*y)+GO{|peJ!igRnz^Q`==^q zIsDawZzm?Uf);W*;(7#S=-iI-`Q>L2R1&qq3PIN)% z4E9@X0I(WM&2xPdM`!m>bPi2*4yXJ2~ixfgCc{~82X|FamZ|0`hG(==SZd+Xw} z0I;rJdhVY9%U~_N{=%)le|!JuZ@>HQUjggu2ccIF^$@V2G!0*T`sw=su! znTFt0Jw7X$nV%AA%GZ=9aZ=@?Jgu@qCn}HUm&bF;Vz_0{5z#=xDjg87B8FccBdClM zRmKS`7s&tVp1h#t{ot8d|JW5s*rnvx@1Ntl?P-wC&~LX;S}W0j4}Qur$)ID#p7q*1ICc zzbrnaB*8aJyG_sc%~cUii7ac9u+fOi7gI`<njlrhiqz3uU81Nwj_#bN%TzTIB8HYbp%X{g=@eJ(U3G4h=!x^ zFhEplEc{`O7QZ%%iY+&?EV-<@{O}Uvx_F*XhLU4R#pWqVxeDJDo>MfzC7uyd5Fg)T z;&vA7ZHPkDa-gK0wM;0byM2k!ky+}$vqXq6GoVCSj)RRI2gv*`J7C#a>fg|ny|Rvl zsHVGCvR$&tP6jM84uv%05ZM&xN-okOfYrgt9u3gy zPs@T(#`cGF^)Q(IukI^2K&w(R4ANhS>R&{Hl@eiPBv?5aa$l8GktG!OV(QugdsMr^ zdn2H$4AvS=2vY0~%B@D?8XX$0@k1n`oeL?>fW|855X^xmg84vlKotd1Lv^a5L5?vX z@CKT}TMF7xTx*#wl{A-pf^$NIXMqq^9kW$WcTu8UHF&Qa8LBpZYZ7y#f#zAE+*6}m zTgii#dM!*uH4SNkLhIJl@EL6>dGoENm43@YuW6;XYF~Hxsx9YO7j7VJi%BBr%d(!G z=)SP8<>XAkbX(qZYxU7l%Z0h9@mkktJVFz($H+6-Ol>DuhAy3LI=U}sz*aUjXgjmN ze7;9go2shM)HM{@PAvDGJJfypK>f;O!BA(-@_62SZ*Wc|QVCu=3a*UU9L3RfHx8aZ zIe+Pq?t`<%-PXF9p{d7DwI7|NWXacxgPbG*Flhix77P;y!9_qJ2uT=B8io*uZdKtZ zc{08!3R5NVDdUCKDl-+Rc5+*lo7ZmMXkD>AoMH1^lqy3JkV?W1Gu z!~NE7d-ep|!r;Vg-^iiqg?*#b2PYQJEFV6-bO_KDC?`7l0dg%3PJ+v;ryhOm$mvH9 zpPC;S-#;-oX&daWYiX}(0G9xU=K9CFOwH}pjZ-%0AZJi-$}jD%Yg!(eJUX{D(>u5_ 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 SZz7s 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

    b1rzWbq=X|hP->F-m2ilyr7 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%0DZLM(| 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 Vw0jH7i%Uw(ZpTQ!=y_z5{|{psBvt?b literal 0 HcmV?d00001 diff --git a/bsp/raspberry-pi/raspi3-64/link.lds b/bsp/raspberry-pi/raspi3-64/link.lds new file mode 100644 index 0000000000..604a45c110 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/link.lds @@ -0,0 +1,151 @@ +/* + * File : link.lds + * COPYRIGHT (C) 2017, RT-Thread Development Team + * + * 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; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * 2017-5-30 bernard first version + */ + +/* _EL1_STACK_SIZE = DEFINED(_EL1_STACK_SIZE) ? _EL1_STACK_SIZE : 0x20000; */ + +SECTIONS +{ + . = 0x80000; + . = ALIGN(4096); + .text : + { + KEEP(*(.text.entrypoint)) /* The entry point */ + *(.vectors) + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(16); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(16); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(16); + + /* section information for initial. */ + . = ALIGN(16); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(16); + + . = ALIGN(16); + _etext = .; + } + + .eh_frame_hdr : + { + *(.eh_frame_hdr) + *(.eh_frame_entry) + } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + + . = ALIGN(16); + .data : + { + *(.data) + *(.data.*) + + *(.data1) + *(.data1.*) + + . = ALIGN(16); + _gp = ABSOLUTE(.); /* Base of small data */ + + *(.sdata) + *(.sdata.*) + } + + . = ALIGN(16); + .ctors : + { + PROVIDE(__ctors_start__ = .); + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + } + + .dtors : + { + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } + + . = ALIGN(16); + .bss : + { + PROVIDE(__bss_start = .); + *(.bss) + *(.bss.*) + *(.dynbss) + *(COMMON) + PROVIDE(__bss_end = .); + } + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} + +__bss_size = (__bss_end - __bss_start)>>3; diff --git a/bsp/raspberry-pi/raspi3-64/qemu-64.bat b/bsp/raspberry-pi/raspi3-64/qemu-64.bat new file mode 100644 index 0000000000..c009905e23 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/qemu-64.bat @@ -0,0 +1 @@ +qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial stdio \ No newline at end of file diff --git a/bsp/raspberry-pi/raspi3-64/rtconfig.h b/bsp/raspberry-pi/raspi3-64/rtconfig.h new file mode 100644 index 0000000000..4a8d8c42bc --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/rtconfig.h @@ -0,0 +1,382 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Project Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +/* RT_USING_ARCH_DATA_TYPE is not set */ +/* RT_USING_SMP is not set */ +#define RT_ALIGN_SIZE 4 +/* RT_THREAD_PRIORITY_8 is not set */ +#define RT_THREAD_PRIORITY_32 +/* RT_THREAD_PRIORITY_256 is not set */ +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 2048 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 2048 +#define RT_DEBUG +#define RT_DEBUG_COLOR +/* RT_DEBUG_INIT_CONFIG is not set */ +/* RT_DEBUG_THREAD_CONFIG is not set */ +/* RT_DEBUG_SCHEDULER_CONFIG is not set */ +/* RT_DEBUG_IPC_CONFIG is not set */ +/* RT_DEBUG_TIMER_CONFIG is not set */ +/* RT_DEBUG_IRQ_CONFIG is not set */ +/* RT_DEBUG_MEM_CONFIG is not set */ +/* RT_DEBUG_SLAB_CONFIG is not set */ +/* RT_DEBUG_MEMHEAP_CONFIG is not set */ +/* RT_DEBUG_MODULE_CONFIG is not set */ + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE +/* RT_USING_SIGNALS is not set */ + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP +/* RT_USING_NOHEAP is not set */ +#define RT_USING_SMALL_MEM +/* RT_USING_SLAB is not set */ +/* RT_USING_MEMHEAP_AS_HEAP is not set */ +#define RT_USING_MEMTRACE +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_DEVICE_OPS +/* RT_USING_INTERRUPT_INFO is not set */ +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x40002 +#define ARCH_CPU_64BIT +#define ARCH_ARM +/* RT_USING_CPU_FFS is not set */ +#define ARCH_ARM_CORTEX_AARCH64 +#define ARCH_ARM_CORTEX_A53 +/* ARCH_CPU_STACK_GROWS_UPWARD is not set */ + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + +/* RT_USING_CPLUSPLUS is not set */ + +/* Command shell */ + +#define RT_USING_FINSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +/* FINSH_ECHO_DISABLE_DEFAULT is not set */ +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +/* FINSH_USING_AUTH is not set */ +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_USING_MSH_ONLY +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + +#define RT_USING_DFS +#define DFS_USING_WORKDIR +#define DFS_FILESYSTEMS_MAX 2 +#define DFS_FILESYSTEM_TYPES_MAX 2 +#define DFS_FD_MAX 16 +/* RT_USING_DFS_MNTTABLE is not set */ +/* RT_USING_DFS_ELMFAT is not set */ +#define RT_USING_DFS_DEVFS +/* RT_USING_DFS_ROMFS is not set */ +/* RT_USING_DFS_RAMFS is not set */ +/* RT_USING_DFS_UFFS is not set */ +/* RT_USING_DFS_JFFS2 is not set */ + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +/* RT_USING_SYSTEM_WORKQUEUE is not set */ +#define RT_USING_SERIAL +/* RT_SERIAL_USING_DMA is not set */ +#define RT_SERIAL_RB_BUFSZ 64 +/* RT_USING_CAN is not set */ +/* RT_USING_HWTIMER is not set */ +/* RT_USING_CPUTIME is not set */ +/* RT_USING_I2C is not set */ +#define RT_USING_PIN +/* RT_USING_ADC is not set */ +/* RT_USING_PWM is not set */ +/* RT_USING_MTD_NOR is not set */ +/* RT_USING_MTD_NAND is not set */ +/* RT_USING_PM is not set */ +/* RT_USING_RTC is not set */ +/* RT_USING_SDIO is not set */ +/* RT_USING_SPI is not set */ +/* RT_USING_WDT is not set */ +/* RT_USING_AUDIO is not set */ +/* RT_USING_SENSOR is not set */ +/* RT_USING_TOUCH is not set */ +/* RT_USING_HWCRYPTO is not set */ +/* RT_USING_WIFI is not set */ + +/* Using USB */ + +/* RT_USING_USB_HOST is not set */ +/* RT_USING_USB_DEVICE is not set */ + +/* POSIX layer and C standard library */ + +#define RT_USING_LIBC +/* RT_USING_PTHREADS is not set */ +#define RT_USING_POSIX +/* RT_USING_POSIX_MMAP is not set */ +/* RT_USING_POSIX_TERMIOS is not set */ +/* RT_USING_POSIX_AIO is not set */ +/* RT_USING_MODULE is not set */ + +/* Network */ + +/* Socket abstraction layer */ + +/* RT_USING_SAL is not set */ + +/* Network interface device */ + +/* RT_USING_NETDEV is not set */ + +/* light weight TCP/IP stack */ + +/* RT_USING_LWIP is not set */ + +/* AT commands */ + +/* RT_USING_AT is not set */ + +/* VBUS(Virtual Software BUS) */ + +/* RT_USING_VBUS is not set */ + +/* Utilities */ + +/* RT_USING_RYM is not set */ +/* RT_USING_ULOG is not set */ +/* RT_USING_UTEST is not set */ + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + +/* PKG_USING_PAHOMQTT is not set */ +/* PKG_USING_WEBCLIENT is not set */ +/* PKG_USING_WEBNET is not set */ +/* PKG_USING_MONGOOSE is not set */ +/* PKG_USING_WEBTERMINAL is not set */ +/* PKG_USING_CJSON is not set */ +/* PKG_USING_JSMN is not set */ +/* PKG_USING_LIBMODBUS is not set */ +/* PKG_USING_FREEMODBUS is not set */ +/* PKG_USING_LJSON is not set */ +/* PKG_USING_EZXML is not set */ +/* PKG_USING_NANOPB is not set */ + +/* Wi-Fi */ + +/* Marvell WiFi */ + +/* PKG_USING_WLANMARVELL is not set */ + +/* Wiced WiFi */ + +/* PKG_USING_WLAN_WICED is not set */ +/* PKG_USING_RW007 is not set */ +/* PKG_USING_COAP is not set */ +/* PKG_USING_NOPOLL is not set */ +/* PKG_USING_NETUTILS is not set */ +/* PKG_USING_PPP_DEVICE is not set */ +/* PKG_USING_AT_DEVICE is not set */ +/* PKG_USING_ATSRV_SOCKET is not set */ +/* PKG_USING_WIZNET is not set */ + +/* IoT Cloud */ + +/* PKG_USING_ONENET is not set */ +/* PKG_USING_GAGENT_CLOUD is not set */ +/* PKG_USING_ALI_IOTKIT is not set */ +/* PKG_USING_AZURE is not set */ +/* PKG_USING_TENCENT_IOTHUB is not set */ +/* PKG_USING_JIOT-C-SDK is not set */ +/* PKG_USING_NIMBLE is not set */ +/* PKG_USING_OTA_DOWNLOADER is not set */ +/* PKG_USING_IPMSG is not set */ +/* PKG_USING_LSSDP is not set */ +/* PKG_USING_AIRKISS_OPEN is not set */ +/* PKG_USING_LIBRWS is not set */ +/* PKG_USING_TCPSERVER is not set */ +/* PKG_USING_PROTOBUF_C is not set */ +/* PKG_USING_ONNX_PARSER is not set */ +/* PKG_USING_ONNX_BACKEND is not set */ +/* PKG_USING_DLT645 is not set */ +/* PKG_USING_QXWZ is not set */ +/* PKG_USING_SMTP_CLIENT is not set */ + +/* security packages */ + +/* PKG_USING_MBEDTLS is not set */ +/* PKG_USING_libsodium is not set */ +/* PKG_USING_TINYCRYPT is not set */ + +/* language packages */ + +/* PKG_USING_LUA is not set */ +/* PKG_USING_JERRYSCRIPT is not set */ +/* PKG_USING_MICROPYTHON is not set */ + +/* multimedia packages */ + +/* PKG_USING_OPENMV is not set */ +/* PKG_USING_MUPDF is not set */ +/* PKG_USING_STEMWIN is not set */ +/* PKG_USING_WAVPLAYER is not set */ +/* PKG_USING_TJPGD is not set */ + +/* tools packages */ + +/* PKG_USING_CMBACKTRACE is not set */ +/* PKG_USING_EASYFLASH is not set */ +/* PKG_USING_EASYLOGGER is not set */ +/* PKG_USING_SYSTEMVIEW is not set */ +/* PKG_USING_RDB is not set */ +/* PKG_USING_QRCODE is not set */ +/* PKG_USING_ULOG_EASYFLASH is not set */ +/* PKG_USING_ADBD is not set */ +/* PKG_USING_COREMARK is not set */ +/* PKG_USING_DHRYSTONE is not set */ + +/* system packages */ + +/* PKG_USING_GUIENGINE is not set */ +/* PKG_USING_CAIRO is not set */ +/* PKG_USING_PIXMAN is not set */ +/* PKG_USING_LWEXT4 is not set */ +/* PKG_USING_PARTITION is not set */ +/* PKG_USING_FAL is not set */ +/* PKG_USING_SQLITE is not set */ +/* PKG_USING_RTI is not set */ +/* PKG_USING_LITTLEVGL2RTT is not set */ +/* PKG_USING_CMSIS is not set */ +/* PKG_USING_DFS_YAFFS is not set */ +/* PKG_USING_LITTLEFS is not set */ +/* PKG_USING_THREAD_POOL is not set */ +/* PKG_USING_ROBOTS is not set */ + +/* peripheral libraries and drivers */ + +/* PKG_USING_SENSORS_DRIVERS is not set */ +/* PKG_USING_REALTEK_AMEBA is not set */ +/* PKG_USING_SHT2X is not set */ +/* PKG_USING_STM32_SDIO is not set */ +/* PKG_USING_ICM20608 is not set */ +/* PKG_USING_U8G2 is not set */ +/* PKG_USING_BUTTON is not set */ +/* PKG_USING_PCF8574 is not set */ +/* PKG_USING_SX12XX is not set */ +/* PKG_USING_SIGNAL_LED is not set */ +/* PKG_USING_LEDBLINK is not set */ +/* PKG_USING_WM_LIBRARIES is not set */ +/* PKG_USING_KENDRYTE_SDK is not set */ +/* PKG_USING_INFRARED is not set */ +/* PKG_USING_ROSSERIAL is not set */ +/* PKG_USING_AGILE_BUTTON is not set */ +/* PKG_USING_AGILE_LED is not set */ +/* PKG_USING_AT24CXX is not set */ +/* PKG_USING_MOTIONDRIVER2RTT is not set */ +/* PKG_USING_AD7746 is not set */ +/* PKG_USING_PCA9685 is not set */ +/* PKG_USING_I2C_TOOLS is not set */ +/* PKG_USING_NRF24L01 is not set */ +/* PKG_USING_TOUCH_DRIVERS is not set */ +/* PKG_USING_LCD_DRIVERS is not set */ +/* PKG_USING_MAX17048 is not set */ +/* PKG_USING_RPLIDAR is not set */ + +/* miscellaneous packages */ + +/* PKG_USING_LIBCSV is not set */ +/* PKG_USING_OPTPARSE is not set */ +/* PKG_USING_FASTLZ is not set */ +/* PKG_USING_MINILZO is not set */ +/* PKG_USING_QUICKLZ is not set */ +/* PKG_USING_MULTIBUTTON is not set */ +/* PKG_USING_FLEXIBLE_BUTTON is not set */ +/* PKG_USING_CANFESTIVAL is not set */ +/* PKG_USING_ZLIB is not set */ +/* PKG_USING_DSTR is not set */ +/* PKG_USING_TINYFRAME is not set */ +/* PKG_USING_KENDRYTE_DEMO is not set */ +/* PKG_USING_DIGITALCTRL is not set */ +/* PKG_USING_UPACKER is not set */ +/* PKG_USING_UPARAM is not set */ + +/* samples: kernel and components samples */ + +/* PKG_USING_KERNEL_SAMPLES is not set */ +/* PKG_USING_FILESYSTEM_SAMPLES is not set */ +/* PKG_USING_NETWORK_SAMPLES is not set */ +/* PKG_USING_PERIPHERAL_SAMPLES is not set */ +/* PKG_USING_HELLO is not set */ +/* PKG_USING_VI is not set */ +/* PKG_USING_NNOM is not set */ +/* PKG_USING_LIBANN is not set */ +/* PKG_USING_ELAPACK is not set */ +/* PKG_USING_ARMv7M_DWT is not set */ +/* PKG_USING_VT100 is not set */ +/* PKG_USING_ULAPACK is not set */ +/* PKG_USING_UKAL is not set */ +#define BCM2836_SOC +/* BSP_SUPPORT_FPU is not set */ + +/* Hardware Drivers Config */ + +/* BCM Peripheral Drivers */ + +#define BSP_USING_UART +/* RT_USING_UART0 is not set */ +#define RT_USING_UART1 +#define BSP_USING_PIN +/* BSP_USING_SYSTIMER is not set */ +/* BSP_USING_I2C is not set */ +/* BSP_USING_SPI is not set */ +/* BSP_USING_WDT is not set */ +/* BSP_USING_RTC is not set */ +/* BSP_USING_SDIO is not set */ + +/* Board Peripheral Drivers */ + +/* BSP_USING_HDMI is not set */ + +#endif diff --git a/bsp/raspberry-pi/raspi3-64/rtconfig.py b/bsp/raspberry-pi/raspi3-64/rtconfig.py new file mode 100644 index 0000000000..54d5988b64 --- /dev/null +++ b/bsp/raspberry-pi/raspi3-64/rtconfig.py @@ -0,0 +1,54 @@ +import os + +# toolchains options +ARCH ='aarch64' +CPU ='cortex-a53' +CROSS_TOOL ='gcc' + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = r'../../..' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +PLATFORM = 'gcc' +EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + # PREFIX = 'arm-none-eabi-' + PREFIX = 'aarch64-elf-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -march=armv8-a -mtune=cortex-a53' + CFLAGS = DEVICE + ' -Wall' + AFLAGS = ' -c' + ' -x assembler-with-cpp -D__ASSEMBLY__' + LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + +DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' +POST_ACTION = OBJCPY + ' -O binary $TARGET kernel8.img\n' + SIZE + ' $TARGET \n' diff --git a/libcpu/aarch64/SConscript b/libcpu/aarch64/SConscript new file mode 100644 index 0000000000..453afe4b3e --- /dev/null +++ b/libcpu/aarch64/SConscript @@ -0,0 +1,16 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +group = [] +list = os.listdir(cwd) + +# cpu porting code files +if rtconfig.CPU != 'common': + group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/aarch64/cortex-a53/SConscript b/libcpu/aarch64/cortex-a53/SConscript new file mode 100644 index 0000000000..57a5accc5c --- /dev/null +++ b/libcpu/aarch64/cortex-a53/SConscript @@ -0,0 +1,15 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +asm_src = Split(''' +context_gcc.S +vector_gcc.S +entry_point.S +cpu_gcc.S +''') +CPPPATH = [cwd] + +group = DefineGroup('cpu', src + asm_src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/aarch64/cortex-a53/armv8.h b/libcpu/aarch64/cortex-a53/armv8.h new file mode 100644 index 0000000000..28ed50e1ac --- /dev/null +++ b/libcpu/aarch64/cortex-a53/armv8.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ + +#ifndef __ARMV7_H__ +#define __ARMV7_H__ + +/* the exception stack without VFP registers */ +struct rt_hw_exp_stack +{ + unsigned long long pc; + unsigned long long spsr; + unsigned long long x30; + unsigned long long xz; + unsigned long long x28; + unsigned long long x29; + unsigned long long x26; + unsigned long long x27; + unsigned long long x24; + unsigned long long x25; + unsigned long long x22; + unsigned long long x23; + unsigned long long x20; + unsigned long long x21; + unsigned long long x18; + unsigned long long x19; + unsigned long long x16; + unsigned long long x17; + unsigned long long x14; + unsigned long long x15; + unsigned long long x12; + unsigned long long x13; + unsigned long long x10; + unsigned long long x11; + unsigned long long x8; + unsigned long long x9; + unsigned long long x6; + unsigned long long x7; + unsigned long long x4; + unsigned long long x5; + unsigned long long x2; + unsigned long long x3; + unsigned long long x0; + unsigned long long x1; +}; + +#define SP_ELx ( ( unsigned long long ) 0x01 ) +#define SP_EL0 ( ( unsigned long long ) 0x00 ) +#define PSTATE_EL1 ( ( unsigned long long ) 0x04 ) +#define PSTATE_EL2 ( ( unsigned long long ) 0x08 ) +#define PSTATE_EL3 ( ( unsigned long long ) 0x0c ) + +rt_ubase_t rt_hw_get_current_el(void); +void rt_hw_set_elx_env(void); +void rt_hw_set_current_vbar(rt_ubase_t addr); + +#endif diff --git a/libcpu/aarch64/cortex-a53/context_gcc.S b/libcpu/aarch64/cortex-a53/context_gcc.S new file mode 100644 index 0000000000..3812eb4b1a --- /dev/null +++ b/libcpu/aarch64/cortex-a53/context_gcc.S @@ -0,0 +1,307 @@ +/* + * Date Author Notes + * 2018-10-06 ZhaoXiaowei the first version + */ + +.macro SAVE_CONTEXT + + /* Switch to use the EL0 stack pointer. */ + MSR SPSEL, #0 + + /* Save the entire context. */ + STP X0, X1, [SP, #-0x10]! + STP X2, X3, [SP, #-0x10]! + STP X4, X5, [SP, #-0x10]! + STP X6, X7, [SP, #-0x10]! + STP X8, X9, [SP, #-0x10]! + STP X10, X11, [SP, #-0x10]! + STP X12, X13, [SP, #-0x10]! + STP X14, X15, [SP, #-0x10]! + STP X16, X17, [SP, #-0x10]! + STP X18, X19, [SP, #-0x10]! + STP X20, X21, [SP, #-0x10]! + STP X22, X23, [SP, #-0x10]! + STP X24, X25, [SP, #-0x10]! + STP X26, X27, [SP, #-0x10]! + STP X28, X29, [SP, #-0x10]! + STP X30, XZR, [SP, #-0x10]! + + MRS X0, CurrentEL + CMP X0, 0xc + B.EQ 3f + CMP X0, 0x8 + B.EQ 2f + CMP X0, 0x4 + B.EQ 1f + B . +3: + MRS X3, SPSR_EL3 + /* Save the ELR. */ + MRS X2, ELR_EL3 + B 0f +2: + MRS X3, SPSR_EL2 + /* Save the ELR. */ + MRS X2, ELR_EL2 + B 0f +1: + MRS X3, SPSR_EL1 + MRS X2, ELR_EL1 + B 0f +0: + + STP X2, X3, [SP, #-0x10]! + + MOV X0, SP /* Move SP into X0 for saving. */ + + /* Switch to use the ELx stack pointer. */ + MSR SPSEL, #1 + + .endm + +.macro SAVE_CONTEXT_T + + /* Switch to use the EL0 stack pointer. */ + MSR SPSEL, #0 + + /* Save the entire context. */ + STP X0, X1, [SP, #-0x10]! + STP X2, X3, [SP, #-0x10]! + STP X4, X5, [SP, #-0x10]! + STP X6, X7, [SP, #-0x10]! + STP X8, X9, [SP, #-0x10]! + STP X10, X11, [SP, #-0x10]! + STP X12, X13, [SP, #-0x10]! + STP X14, X15, [SP, #-0x10]! + STP X16, X17, [SP, #-0x10]! + STP X18, X19, [SP, #-0x10]! + STP X20, X21, [SP, #-0x10]! + STP X22, X23, [SP, #-0x10]! + STP X24, X25, [SP, #-0x10]! + STP X26, X27, [SP, #-0x10]! + STP X28, X29, [SP, #-0x10]! + STP X30, XZR, [SP, #-0x10]! + + MRS X0, CurrentEL + CMP X0, 0xc + B.EQ 3f + CMP X0, 0x8 + B.EQ 2f + CMP X0, 0x4 + B.EQ 1f + B . +3: + MRS X3, SPSR_EL3 + MOV X2, X30 + B 0f +2: + MRS X3, SPSR_EL2 + MOV X2, X30 + B 0f +1: + MRS X3, SPSR_EL1 + MOV X2, X30 + B 0f +0: + + STP X2, X3, [SP, #-0x10]! + + MOV X0, SP /* Move SP into X0 for saving. */ + + /* Switch to use the ELx stack pointer. */ + MSR SPSEL, #1 + + .endm + +.macro RESTORE_CONTEXT + + /* Switch to use the EL0 stack pointer. */ + MSR SPSEL, #0 + + /* Set the SP to point to the stack of the task being restored. */ + MOV SP, X0 + + LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */ + + MRS X0, CurrentEL + CMP X0, 0xc + B.EQ 3f + CMP X0, 0x8 + B.EQ 2f + CMP X0, 0x4 + B.EQ 1f + B . +3: + MSR SPSR_EL3, X3 + MSR ELR_EL3, X2 + B 0f +2: + MSR SPSR_EL2, X3 + MSR ELR_EL2, X2 + B 0f +1: + MSR SPSR_EL1, X3 + MSR ELR_EL1, X2 + B 0f +0: + + LDP X30, XZR, [SP], #0x10 + LDP X28, X29, [SP], #0x10 + LDP X26, X27, [SP], #0x10 + LDP X24, X25, [SP], #0x10 + LDP X22, X23, [SP], #0x10 + LDP X20, X21, [SP], #0x10 + LDP X18, X19, [SP], #0x10 + LDP X16, X17, [SP], #0x10 + LDP X14, X15, [SP], #0x10 + LDP X12, X13, [SP], #0x10 + LDP X10, X11, [SP], #0x10 + LDP X8, X9, [SP], #0x10 + LDP X6, X7, [SP], #0x10 + LDP X4, X5, [SP], #0x10 + LDP X2, X3, [SP], #0x10 + LDP X0, X1, [SP], #0x10 + + /* Switch to use the ELx stack pointer. _RB_ Might not be required. */ + MSR SPSEL, #1 + + ERET + + .endm + +.text +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + MRS X0, DAIF + MSR DAIFSet, #3 + DSB SY + RET + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + DSB SY + MOV X1, #0xC0 + ANDS X0, X0, X1 + B.NE rt_hw_interrupt_enable_exit + MSR DAIFClr, #3 +rt_hw_interrupt_enable_exit: + RET + +/* + * void rt_hw_context_switch_to(rt_ubase_t to); + * r0 --> to + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + LDR X0, [X0] + RESTORE_CONTEXT + +.text +/* + * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); + * r0 --> from + * r1 --> to + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + + MOV X8,X0 + MOV X9,X1 + + SAVE_CONTEXT_T + + STR X0, [X8] // store sp in preempted tasks TCB + LDR X0, [X9] // get new task stack pointer + + RESTORE_CONTEXT + +/* + * void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to); + */ +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + ADR X2, rt_thread_switch_interrupt_flag + LDR X3, [X2] + CMP X3, #1 + B.EQ _reswitch + ADR X4, rt_interrupt_from_thread // set rt_interrupt_from_thread + MOV X3, #1 // set rt_thread_switch_interrupt_flag to 1 + STR X0, [X4] + STR X3, [X2] +_reswitch: + ADR X2, rt_interrupt_to_thread // set rt_interrupt_to_thread + STR X1, [X2] + RET + +.text + +// -- Exception handlers ---------------------------------- + + .align 8 +.globl vector_fiq +vector_fiq: + SAVE_CONTEXT + STP X0, X1, [SP, #-0x10]! + BL rt_hw_trap_fiq + LDP X0, X1, [SP], #0x10 + RESTORE_CONTEXT + +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread + + +// ------------------------------------------------------------------- + + .align 8 +.globl vector_irq +vector_irq: + SAVE_CONTEXT + STP X0, X1, [SP, #-0x10]! + + BL rt_interrupt_enter + BL rt_hw_trap_irq + BL rt_interrupt_leave + + LDP X0, X1, [SP], #0x10 + + // if rt_thread_switch_interrupt_flag set, jump to + // rt_hw_context_switch_interrupt_do and don't return + ADR X1, rt_thread_switch_interrupt_flag + LDR X2, [X1] + CMP X2, #1 + B.NE vector_irq_exit + + MOV X2, #0 // clear flag + STR X2, [X1] + + ADR X3, rt_interrupt_from_thread + LDR X4, [X3] + STR x0, [X4] // store sp in preempted tasks's TCB + + ADR x3, rt_interrupt_to_thread + LDR X4, [X3] + LDR x0, [X4] // get new task's stack pointer + +vector_irq_exit: + RESTORE_CONTEXT + +// ------------------------------------------------- + + .align 8 + .globl vector_error +vector_error: + SAVE_CONTEXT + BL rt_hw_trap_error + B . diff --git a/libcpu/aarch64/cortex-a53/cp15.h b/libcpu/aarch64/cortex-a53/cp15.h new file mode 100644 index 0000000000..26f6ef1a31 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/cp15.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ + +#ifndef __CP15_H__ +#define __CP15_H__ + +#include "bcm283x.h" +#ifndef __STATIC_FORCEINLINE +#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif + +#define __WFI() __asm__ volatile ("wfi":::"memory") + +#define __WFE() __asm__ volatile ("wfe":::"memory") + +#define __SEV() __asm__ volatile ("sev") + +__STATIC_FORCEINLINE void __ISB(void) +{ + __asm__ volatile ("isb 0xF":::"memory"); +} + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __asm__ volatile ("dsb 0xF":::"memory"); +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ + +__STATIC_FORCEINLINE void __DMB(void) +{ + __asm__ volatile ("dmb 0xF":::"memory"); +} + +#ifdef RT_USING_SMP +static inline void send_ipi_msg(int cpu, int ipi_vector) +{ + IPI_MAILBOX_SET(cpu) = 1 << ipi_vector; +} + +static inline void setup_bootstrap_addr(int cpu, int addr) +{ + CORE_MAILBOX3_SET(cpu) = addr; +} + +static inline void enable_cpu_ipi_intr(int cpu) +{ + COREMB_INTCTL(cpu) = IPI_MAILBOX_INT_MASK; +} + +static inline void enable_cpu_timer_intr(int cpu) +{ + CORETIMER_INTCTL(cpu) = 0x8; +} + +static inline void enable_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 1; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL +} + +static inline void disable_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 0; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL +} + +static inline void mask_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 2; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL +} + +static inline void unmask_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 1; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl) ); // write CNTV_CTL +} + +static inline rt_uint64_t read_cntvct(void) +{ + rt_uint32_t val,val1; + asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (val),"=r" (val1)); + return (val); +} + +static inline rt_uint64_t read_cntvoff(void) +{ + + rt_uint64_t val; + asm volatile("mrrc p15, 4, %Q0, %R0, c14" : "=r" (val)); + return (val); +} + +static inline rt_uint32_t read_cntv_tval(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c3, 0" : "=r"(val) ); + return val; +} + + +static inline void write_cntv_tval(rt_uint32_t val) +{ + asm volatile ("mcr p15, 0, %0, c14, c3, 0" :: "r"(val) ); + return; +} + +static inline rt_uint32_t read_cntfrq(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val) ); + return val; +} + + +static inline rt_uint32_t read_cntctrl(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c1, 0" : "=r"(val) ); + return val; +} + +static inline uint32_t write_cntctrl(uint32_t val) +{ + + asm volatile ("mcr p15, 0, %0, c14, c1, 0" : :"r"(val) ); + return val; +} +#endif + +unsigned long rt_cpu_get_smp_id(void); + +void rt_cpu_mmu_disable(void); +void rt_cpu_mmu_enable(void); +void rt_cpu_tlb_set(volatile unsigned long*); + +void rt_cpu_dcache_clean_flush(void); +void rt_cpu_icache_flush(void); + +void rt_cpu_vector_set_base(rt_ubase_t addr); +void rt_hw_mmu_init(void); +void rt_hw_vector_init(void); + +void set_timer_counter(unsigned int counter); +void set_timer_control(unsigned int control); +#endif diff --git a/libcpu/aarch64/cortex-a53/cpu.c b/libcpu/aarch64/cortex-a53/cpu.c new file mode 100644 index 0000000000..962a53a071 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/cpu.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + * 2019-07-28 zdzn add smp support + */ + +#include +#include +#include +#include "cp15.h" + +int rt_hw_cpu_id(void) +{ + int cpu_id; + rt_base_t value; + + __asm__ volatile ( + "mrs %0, mpidr_el1" + :"=r"(value) + ); + cpu_id = value & 0xf; + return cpu_id; +}; + +#ifdef RT_USING_SMP +void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock) +{ + lock->slock = 0; +} + +void rt_hw_spin_lock(rt_hw_spinlock_t *lock) +{ + unsigned long tmp; + unsigned long newval; + rt_hw_spinlock_t lockval; + __asm__ __volatile__( + "pld [%0]" + ::"r"(&lock->slock) + ); + + __asm__ __volatile__( + "1: ldrex %0, [%3]\n" + " add %1, %0, %4\n" + " strex %2, %1, [%3]\n" + " teq %2, #0\n" + " bne 1b" + : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) + : "r" (&lock->slock), "I" (1 << 16) + : "cc"); + + while (lockval.tickets.next != lockval.tickets.owner) { + __WFE(); + lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner); + } + + __DMB(); +} + +void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) +{ + __DMB(); + lock->tickets.owner++; + __DSB(); + __SEV(); +} +#endif /*RT_USING_SMP*/ + +/** + * @addtogroup ARM CPU + */ +/*@{*/ + +/** shutdown CPU */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} + +/*@}*/ diff --git a/libcpu/aarch64/cortex-a53/cpu_gcc.S b/libcpu/aarch64/cortex-a53/cpu_gcc.S new file mode 100644 index 0000000000..ab9a5706ae --- /dev/null +++ b/libcpu/aarch64/cortex-a53/cpu_gcc.S @@ -0,0 +1,78 @@ +/* + * Date Author Notes + * 2018-10-06 ZhaoXiaowei the first version + */ + +.text +.globl rt_hw_get_current_el +rt_hw_get_current_el: + MRS X0, CurrentEL + CMP X0, 0xc + B.EQ 3f + CMP X0, 0x8 + B.EQ 2f + CMP X0, 0x4 + B.EQ 1f + + LDR X0, =0 + B 0f +3: + LDR X0, =3 + B 0f +2: + LDR X0, =2 + B 0f +1: + LDR X0, =1 + B 0f +0: + RET + + +.globl rt_hw_set_current_vbar +rt_hw_set_current_vbar: + MRS X1, CurrentEL + CMP X1, 0xc + B.EQ 3f + CMP X1, 0x8 + B.EQ 2f + CMP X1, 0x4 + B.EQ 1f + B 0f +3: + MSR VBAR_EL3,X0 + B 0f +2: + MSR VBAR_EL2,X0 + B 0f +1: + MSR VBAR_EL1,X0 + B 0f +0: + RET + + +.globl rt_hw_set_elx_env +rt_hw_set_elx_env: + MRS X1, CurrentEL + CMP X1, 0xc + B.EQ 3f + CMP X1, 0x8 + B.EQ 2f + CMP X1, 0x4 + B.EQ 1f + B 0f +3: + MRS X0, SCR_EL3 + ORR X0, X0, #0xF /* SCR_EL3.NS|IRQ|FIQ|EA */ + MSR SCR_EL3, X0 + B 0f +2: + MRS X0, HCR_EL2 + ORR X0, X0, #0x38 + MSR HCR_EL2, X0 + B 0f +1: + B 0f +0: + RET diff --git a/libcpu/aarch64/cortex-a53/entry_point.S b/libcpu/aarch64/cortex-a53/entry_point.S new file mode 100644 index 0000000000..098cd9a840 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/entry_point.S @@ -0,0 +1,102 @@ +.section ".text.entrypoint" + +.set EL1_stack, __el1_stack + +.global _start + +// This symbol is set to 0x80000 in ld script. That is the address that raspi3's firmware +// loads 'kernel8.img' file in. +_start: + // read cpu id, stop slave cores + mrs x1, mpidr_el1 // MPIDR_EL1: Multi-Processor Affinity Register + and x1, x1, #3 + cbz x1, .L__cpu_0 // .L prefix is the local label in ELF + + // cpu id > 0, stop + // cpu id == 0 will also goto here after returned from entry() if possible +.L__current_cpu_idle: + wfe + b .L__current_cpu_idle + +.L__cpu_0: // cpu id == 0 + + // set stack before our code + + /* Define stack pointer for current exception level */ + // ldr x2, =EL1_stack + // mov sp, x2 + + ldr x1, =_start + + // set up EL1 + mrs x0, CurrentEL // CurrentEL Register. bit 2, 3. Others reserved + and x0, x0, #12 // clear reserved bits + + // running at EL3? + cmp x0, #12 // 1100b. So, EL3 + bne .L__not_in_el3 // 11? !EL3 -> 5: + + // should never be executed, just for completeness. (EL3) + mov x2, #0x5b1 + msr scr_el3, x2 // SCR_ELn Secure Configuration Register + mov x2, #0x3c9 + msr spsr_el3, x2 // SPSR_ELn. Saved Program Status Register. 1111001001 + adr x2, .L__not_in_el3 + msr elr_el3, x2 + eret // Exception Return: from EL3, continue from .L__not_in_el3 + + // running at EL2 or EL1 +.L__not_in_el3: + cmp x0, #4 // 0x04 0100 EL1 + beq .L__in_el1 // EL1 -> 5: + + // in EL2 + msr sp_el1, x1 // Set sp of EL1 to _start + + // enable CNTP for EL1 + mrs x0, cnthctl_el2 // Counter-timer Hypervisor Control register + orr x0, x0, #3 + msr cnthctl_el2, x0 + msr cntvoff_el2, xzr + + // enable AArch64 in EL1 + mov x0, #(1 << 31) // AArch64 + orr x0, x0, #(1 << 1) // SWIO hardwired on Pi3 + msr hcr_el2, x0 + mrs x0, hcr_el2 + + // change execution level to EL1 + mov x2, #0x3c4 + msr spsr_el2, x2 // 1111000100 + adr x2, .L__in_el1 + msr elr_el2, x2 + eret // exception return. from EL2. continue from .L__in_el1 + +.L__in_el1: + mov sp, x1 // in EL1. Set sp to _start + + // Set CPACR_EL1 (Architecture Feature Access Control Register) to avoid trap from SIMD or float point instruction + mov x1, #0x00300000 // Don't trap any SIMD/FP instructions in both EL0 and EL1 + msr cpacr_el1, x1 + + mrs x1, sctlr_el1 + orr x1, x1, #(1 << 12) + bic x1, x1, #(3 << 3) + bic x1, x1, #(1 << 1) + msr sctlr_el1, x1 + + // clear bss + ldr x1, =__bss_start + ldr w2, =__bss_size + +.L__clean_bss_loop: + cbz w2, .L__jump_to_entry + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, .L__clean_bss_loop + + // jump to C code, should not return +.L__jump_to_entry: + bl entry + // for failsafe, halt this core too + b .L__current_cpu_idle diff --git a/libcpu/aarch64/cortex-a53/interrupt.c b/libcpu/aarch64/cortex-a53/interrupt.c new file mode 100644 index 0000000000..8ad60c6de2 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/interrupt.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/5/3 Bernard first version + * 2019-07-28 zdzn add smp support + * 2019-08-09 zhangjun fixup the problem of smp startup and scheduling issues, + * write addr to mailbox3 to startup smp, and we use mailbox0 for ipi + */ + +#include +#include + +#include "cp15.h" +#include "armv8.h" + +#include + +#define MAX_HANDLERS 72 + +#ifdef RT_USING_SMP +#define rt_interrupt_nest rt_cpu_self()->irq_nest +#else +extern volatile rt_uint8_t rt_interrupt_nest; +#endif + +extern int system_vectors; + +/* exception and interrupt handler table */ +struct rt_irq_desc isr_table[MAX_HANDLERS]; + +rt_ubase_t rt_interrupt_from_thread; +rt_ubase_t rt_interrupt_to_thread; +rt_ubase_t rt_thread_switch_interrupt_flag; + +void rt_hw_vector_init(void) +{ + rt_hw_set_current_vbar((rt_ubase_t)&system_vectors); // cpu_gcc.S +} + +static void default_isr_handler(int vector, void *param) +{ +#ifdef RT_USING_SMP + rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(),vector); +#else + rt_kprintf("unhandled irq: %d\n",vector); +#endif +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + rt_uint32_t index; + + /* mask all of interrupts */ + IRQ_DISABLE_BASIC = 0x000000ff; + IRQ_DISABLE1 = 0xffffffff; + IRQ_DISABLE2 = 0xffffffff; + for (index = 0; index < MAX_HANDLERS; index ++) + { + isr_table[index].handler = default_isr_handler; + isr_table[index].param = NULL; +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX); + isr_table[index].counter = 0; +#endif + } + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + if (vector < 32) + { + IRQ_DISABLE1 = (1 << vector); + } + else if (vector<64) + { + vector = vector % 32; + IRQ_DISABLE2 = (1 << vector); + } + else + { + vector = vector - 64; + IRQ_DISABLE_BASIC = (1 << vector); + } +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + if (vector < 32) + { + IRQ_ENABLE1 = (1 << vector); + } + else if (vector < 64) + { + vector = vector % 32; + IRQ_ENABLE2 = (1 << vector); + } + else + { + vector = vector - 64; + IRQ_ENABLE_BASIC = (1 << vector); + } +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} + +#ifdef RT_USING_SMP +void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) +{ + __DSB(); + if(cpu_mask & 0x1) + { + send_ipi_msg(0, ipi_vector); + } + if(cpu_mask & 0x2) + { + send_ipi_msg(1, ipi_vector); + } + if(cpu_mask & 0x4) + { + send_ipi_msg(2, ipi_vector); + } + if(cpu_mask & 0x8) + { + send_ipi_msg(3, ipi_vector); + } + __DSB(); +} +#endif + +#ifdef RT_USING_SMP +void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) +{ + /* note: ipi_vector maybe different with irq_vector */ + rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER"); +} +#endif diff --git a/libcpu/aarch64/cortex-a53/interrupt.h b/libcpu/aarch64/cortex-a53/interrupt.h new file mode 100644 index 0000000000..6e86516045 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/interrupt.h @@ -0,0 +1,20 @@ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include +#include + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + +//void rt_hw_vector_init(void); + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(int vector); + +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +#endif diff --git a/libcpu/aarch64/cortex-a53/mmu.c b/libcpu/aarch64/cortex-a53/mmu.c new file mode 100644 index 0000000000..17b40c3b47 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/mmu.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2012-01-10 bernard porting to AM1808 + * 2019-07-28 zdzn add smp support + */ + +#include "mmu.h" + +/* dump 2nd level page table */ +void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + for (i = 0; i < 256; i++) + { + rt_uint32_t pte2 = ptb[i]; + if ((pte2 & 0x3) == 0) + { + if (fcnt == 0) + rt_kprintf(" "); + rt_kprintf("%04x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf(" %04x: %x: ", i, pte2); + if ((pte2 & 0x3) == 0x1) + { + rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, + (pte2 >> 15) & 0x1, + ((pte2 >> 10) | (pte2 >> 2)) & 0x1f); + } + else + { + rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1, + ((pte2 >> 4) | (pte2 >> 2)) & 0x1f); + } + } +} + +void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + rt_kprintf("page table@%p\n", ptb); + for (i = 0; i < 1024*4; i++) + { + rt_uint32_t pte1 = ptb[i]; + if ((pte1 & 0x3) == 0) + { + rt_kprintf("%03x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf("%03x: %08x: ", i, pte1); + if ((pte1 & 0x3) == 0x3) + { + rt_kprintf("LPAE\n"); + } + else if ((pte1 & 0x3) == 0x1) + { + rt_kprintf("pte,ns:%d,domain:%d\n", + (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf); + /* + *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000) + * - 0x80000000 + 0xC0000000)); + */ + } + else if (pte1 & (1 << 18)) + { + rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + ((pte1 >> 10) | (pte1 >> 2)) & 0x1f); + } + else + { + rt_kprintf("section,ns:%d,ap:%x," + "xn:%d,texcb:%02x,domain:%d\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + (((pte1 & (0x7 << 12)) >> 10) | + ((pte1 & 0x0c) >> 2)) & 0x1f, + (pte1 >> 5) & 0xf); + } + } +} + +/* level1 page table, each entry for 1MB memory. */ +volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024))); +void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, + rt_uint32_t vaddrEnd, + rt_uint32_t paddrStart, + rt_uint32_t attr) +{ + volatile rt_uint32_t *pTT; + volatile int i, nSec; + pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20); + nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); + for(i = 0; i <= nSec; i++) + { + *pTT = attr | (((paddrStart >> 20) + i) << 20); + pTT++; + } +} + +unsigned long rt_hw_set_domain_register(unsigned long domain_val) +{ +#if 0 + unsigned long old_domain; + + asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain)); + asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory"); + + return old_domain; +#else + return 0; +#endif +} + +void rt_hw_init_mmu_table() +{ + /* set page table */ + /* 4G 1:1 memory */ + rt_hw_mmu_setmtt(0x00000000, 0x3effffff, 0x00000000, NORMAL_MEM); + /* IO memory region */ + rt_hw_mmu_setmtt(0x3f000000, 0x40010000, 0x3f000000, DEVICE_MEM); +} + +void rt_hw_change_mmu_table(rt_uint32_t vaddrStart, + rt_uint32_t size, + rt_uint32_t paddrStart, rt_uint32_t attr) +{ + rt_hw_mmu_setmtt(vaddrStart, vaddrStart+size-1, paddrStart, attr); +} + +void rt_hw_mmu_init(void) +{ + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); + rt_hw_cpu_dcache_disable(); + rt_hw_cpu_icache_disable(); + rt_cpu_mmu_disable(); + + /*rt_hw_cpu_dump_page_table(MMUTable);*/ + rt_hw_set_domain_register(0x55555555); + + rt_cpu_tlb_set(MMUTable); + + rt_cpu_mmu_enable(); + + rt_hw_cpu_icache_enable(); + rt_hw_cpu_dcache_enable(); +} diff --git a/libcpu/aarch64/cortex-a53/mmu.h b/libcpu/aarch64/cortex-a53/mmu.h new file mode 100644 index 0000000000..022d200f96 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/mmu.h @@ -0,0 +1,51 @@ +#ifndef MMU_H__ +#define MMU_H__ +#include +#include +#include +#include "cp15.h" + +#define DESC_SEC (0x2) +#define CB (3<<2) //cache_on, write_back +#define CNB (2<<2) //cache_on, write_through +#define NCB (1<<2) //cache_off,WR_BUF on +#define NCNB (0<<2) //cache_off,WR_BUF off +#define AP_RW (3<<10) //supervisor=RW, user=RW +#define AP_RO (2<<10) //supervisor=RW, user=RO +#define XN (1<<4) // eXecute Never +#define SHARED (1<<16) /* shareable */ +#define SHAREDEVICE (1<<2) /* shared device */ +#define STRONGORDER (0<<2) /* strong ordered */ +#define MEMWBWA ((1<<12)|(3<<2)) /* write back, write allocate */ + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) + +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) + +/* Read/Write, cache, write back */ +#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) +/* Read/Write, cache, write through */ +#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) +/* Read/Write without cache and write buffer */ +#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) +/* Read/Write without cache and write buffer, no execute */ +#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN) +/* Read/Write without cache and write buffer */ +#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) + +/* device mapping type */ +#define DEVICE_MEM (SHARED|SHAREDEVICE|RW_NCNBXN) +/* normal memory mapping type */ +#define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWBWA|DESC_SEC) +#define STRONG_ORDER_MEM (SHARED|AP_RO|XN|DESC_SEC) +#define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000) + +void rt_hw_change_mmu_table(rt_uint32_t vaddrStart, + rt_uint32_t size, + rt_uint32_t paddrStart, rt_uint32_t attr); +#endif diff --git a/libcpu/aarch64/cortex-a53/stack.c b/libcpu/aarch64/cortex-a53/stack.c new file mode 100644 index 0000000000..68222c2c67 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/stack.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-23 Bernard the first version + * 2011-10-05 Bernard add thumb mode + */ +#include +#include + +#include + +#define INITIAL_SPSR_EL3 (PSTATE_EL3 | SP_EL0) +#define INITIAL_SPSR_EL2 (PSTATE_EL2 | SP_EL0) +#define INITIAL_SPSR_EL1 (PSTATE_EL1 | SP_EL0) + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_ubase_t *stk; + rt_ubase_t current_el; + + stk = (rt_ubase_t*)stack_addr; + + *(--stk) = ( rt_ubase_t ) 11; /* X1 */ + *(--stk) = ( rt_ubase_t ) parameter; /* X0 */ + *(--stk) = ( rt_ubase_t ) 33; /* X3 */ + *(--stk) = ( rt_ubase_t ) 22; /* X2 */ + *(--stk) = ( rt_ubase_t ) 55; /* X5 */ + *(--stk) = ( rt_ubase_t ) 44; /* X4 */ + *(--stk) = ( rt_ubase_t ) 77; /* X7 */ + *(--stk) = ( rt_ubase_t ) 66; /* X6 */ + *(--stk) = ( rt_ubase_t ) 99; /* X9 */ + *(--stk) = ( rt_ubase_t ) 88; /* X8 */ + *(--stk) = ( rt_ubase_t ) 11; /* X11 */ + *(--stk) = ( rt_ubase_t ) 10; /* X10 */ + *(--stk) = ( rt_ubase_t ) 13; /* X13 */ + *(--stk) = ( rt_ubase_t ) 12; /* X12 */ + *(--stk) = ( rt_ubase_t ) 15; /* X15 */ + *(--stk) = ( rt_ubase_t ) 14; /* X14 */ + *(--stk) = ( rt_ubase_t ) 17; /* X17 */ + *(--stk) = ( rt_ubase_t ) 16; /* X16 */ + *(--stk) = ( rt_ubase_t ) 19; /* X19 */ + *(--stk) = ( rt_ubase_t ) 18; /* X18 */ + *(--stk) = ( rt_ubase_t ) 21; /* X21 */ + *(--stk) = ( rt_ubase_t ) 20; /* X20 */ + *(--stk) = ( rt_ubase_t ) 23; /* X23 */ + *(--stk) = ( rt_ubase_t ) 22; /* X22 */ + *(--stk) = ( rt_ubase_t ) 25; /* X25 */ + *(--stk) = ( rt_ubase_t ) 24; /* X24 */ + *(--stk) = ( rt_ubase_t ) 27; /* X27 */ + *(--stk) = ( rt_ubase_t ) 26; /* X26 */ + *(--stk) = ( rt_ubase_t ) 29; /* X29 */ + *(--stk) = ( rt_ubase_t ) 28; /* X28 */ + *(--stk) = ( rt_ubase_t ) 0; /* XZR - has no effect, used so there are an even number of registers. */ + *(--stk) = ( rt_ubase_t ) texit; /* X30 - procedure call link register. */ + + current_el = rt_hw_get_current_el(); + + if(current_el == 3) + { + *(--stk) = INITIAL_SPSR_EL3; + } + else if(current_el == 2) + { + *(--stk) = INITIAL_SPSR_EL2; + } + else + { + *(--stk) = INITIAL_SPSR_EL1; + } + + *(--stk) = ( rt_ubase_t ) tentry; /* Exception return address. */ + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} diff --git a/libcpu/aarch64/cortex-a53/startup_gcc.S b/libcpu/aarch64/cortex-a53/startup_gcc.S new file mode 100644 index 0000000000..ea4268148c --- /dev/null +++ b/libcpu/aarch64/cortex-a53/startup_gcc.S @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + + .global Reset_Handler + .section ".start", "ax" +Reset_Handler: + nop diff --git a/libcpu/aarch64/cortex-a53/trap.c b/libcpu/aarch64/cortex-a53/trap.c new file mode 100644 index 0000000000..aa639ea596 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/trap.c @@ -0,0 +1,221 @@ +/* + * Date Author Notes + * 2018-10-06 ZhaoXiaowei the first version + */ + +#include +#include + +#include "interrupt.h" +#include "armv8.h" + +extern struct rt_thread *rt_current_thread; +#ifdef RT_USING_FINSH +extern long list_thread(void); +#endif + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ +void rt_hw_show_register(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%16.16llx r01:0x%16.16llx r02:0x%16.16llx r03:0x%16.16llx\n", regs->x0, regs->x1, regs->x2, regs->x3); + rt_kprintf("r04:0x%16.16llx r05:0x%16.16llx r06:0x%16.16llx r07:0x%16.16llx\n", regs->x4, regs->x5, regs->x6, regs->x7); + rt_kprintf("r08:0x%16.16llx r09:0x%16.16llx r10:0x%16.16llx r11:0x%16.16llx\n", regs->x8, regs->x9, regs->x10, regs->x11); + rt_kprintf("r12:0x%16.16llx r13:0x%16.16llx r14:0x%16.16llx r15:0x%16.16llx\n", regs->x12, regs->x13, regs->x14, regs->x15); + rt_kprintf("r16:0x%16.16llx r17:0x%16.16llx r18:0x%16.16llx r19:0x%16.16llx\n", regs->x16, regs->x17, regs->x18, regs->x19); + rt_kprintf("r20:0x%16.16llx r21:0x%16.16llx r22:0x%16.16llx r23:0x%16.16llx\n", regs->x20, regs->x21, regs->x22, regs->x23); + rt_kprintf("r24:0x%16.16llx r25:0x%16.16llx r26:0x%16.16llx r27:0x%16.16llx\n", regs->x24, regs->x25, regs->x26, regs->x27); + rt_kprintf("r28:0x%16.16llx r29:0x%16.16llx r30:0x%16.16llx", regs->x28, regs->x29, regs->x30); + rt_kprintf("spsr:0x%16.16llx", regs->spsr); + rt_kprintf("return pc:0x%16.16llx", regs->pc); +} + +/** + * When comes across an instruction which it cannot handle, + * it takes the undefined instruction trap. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_error(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("error exception:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +#define GIC_ACK_INTID_MASK 0x000003ff + +void rt_hw_trap_irq(void) +{ + void *param; + uint32_t irq; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + uint32_t value = 0; + value = IRQ_PEND_BASIC & 0x3ff; +#ifdef RT_USING_SMP + uint32_t mailbox_data; + uint32_t cpu_id = rt_hw_cpu_id(); + uint32_t int_source = CORE_IRQSOURCE(cpu_id); + mailbox_data = IPI_MAILBOX_CLEAR(cpu_id); + if (int_source & 0x0f) + { + if (int_source & 0x08){ + isr_func = isr_table[IRQ_ARM_TIMER].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[IRQ_ARM_TIMER].counter++; +#endif + if (isr_func) + { + param = isr_table[IRQ_ARM_TIMER].param; + isr_func(IRQ_ARM_TIMER, param); + } + } + } + if (int_source & 0xf0) + { + /*it's a ipi interrupt*/ + if (mailbox_data & 0x1){ + /* clear mailbox */ + IPI_MAILBOX_CLEAR(cpu_id) = mailbox_data; + isr_func = isr_table[IRQ_ARM_MAILBOX].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[IRQ_ARM_MAILBOX].counter++; +#endif + if (isr_func) + { + param = isr_table[IRQ_ARM_MAILBOX].param; + isr_func(IRQ_ARM_MAILBOX, param); + } + } + else + CORE_MAILBOX3_CLEAR(cpu_id) = mailbox_data; + } +#endif + /* local interrupt*/ + if (value) + { + if (value & (1 << 8)) + { + value = IRQ_PEND1; + irq = __rt_ffs(value) - 1; + } + else if (value & (1 << 9)) + { + value = IRQ_PEND2; + irq = __rt_ffs(value) + 31; + } + else + { + value &= 0x0f; + irq = __rt_ffs(value) + 63; + } + + /* get interrupt service routine */ + isr_func = isr_table[irq].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[irq].counter++; +#endif + if (isr_func) + { + /* Interrupt for myself. */ + param = isr_table[irq].param; + /* turn to interrupt service routine */ + isr_func(irq, param); + } + } +} + +void rt_hw_trap_fiq(void) +{ + void *param; + uint32_t irq; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + uint32_t value = 0; + value = IRQ_PEND_BASIC & 0x3ff; +#ifdef RT_USING_SMP + uint32_t mailbox_data; + uint32_t cpu_id = rt_hw_cpu_id(); + uint32_t int_source = CORE_IRQSOURCE(cpu_id); + mailbox_data = IPI_MAILBOX_CLEAR(cpu_id); + if (int_source & 0x0f) + { + if (int_source & 0x08) + { + isr_func = isr_table[IRQ_ARM_TIMER].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[IRQ_ARM_TIMER].counter++; +#endif + if (isr_func) + { + param = isr_table[IRQ_ARM_TIMER].param; + isr_func(IRQ_ARM_TIMER, param); + } + } + } + if (int_source & 0xf0) + { + /*it's a ipi interrupt*/ + if (mailbox_data & 0x1) + { + /* clear mailbox */ + IPI_MAILBOX_CLEAR(cpu_id) = mailbox_data; + isr_func = isr_table[IRQ_ARM_MAILBOX].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[IRQ_ARM_MAILBOX].counter++; +#endif + if (isr_func) + { + param = isr_table[IRQ_ARM_MAILBOX].param; + isr_func(IRQ_ARM_MAILBOX, param); + } + } + else + CORE_MAILBOX3_CLEAR(cpu_id) = mailbox_data; + } +#endif + /* local interrupt*/ + if (value) + { + if (value & (1 << 8)) + { + value = IRQ_PEND1; + irq = __rt_ffs(value) - 1; + } + else if (value & (1 << 9)) + { + value = IRQ_PEND2; + irq = __rt_ffs(value) + 31; + } + else + { + value &= 0x0f; + irq = __rt_ffs(value) + 63; + } + + /* get interrupt service routine */ + isr_func = isr_table[irq].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[irq].counter++; +#endif + if (irq > 1) + rt_kprintf("interrupt fiq %d\n", irq); + if (isr_func) + { + /* Interrupt for myself. */ + param = isr_table[irq].param; + /* turn to interrupt service routine */ + isr_func(irq, param); + } + } +} diff --git a/libcpu/aarch64/cortex-a53/vector_gcc.S b/libcpu/aarch64/cortex-a53/vector_gcc.S new file mode 100644 index 0000000000..0efbf4e540 --- /dev/null +++ b/libcpu/aarch64/cortex-a53/vector_gcc.S @@ -0,0 +1,57 @@ +/* + * Date Author Notes + * 2018-10-06 ZhaoXiaowei the first version + */ + +.text + +.globl system_vectors +.globl vector_error +.globl vector_irq +.globl vector_fiq + +system_vectors: +.align 11 + .set VBAR, system_vectors + .org VBAR + // Exception from CurrentEL (EL1) with SP_EL0 (SPSEL=1) + .org (VBAR + 0x00 + 0) + B vector_error // Synchronous + .org (VBAR + 0x80 + 0) + B vector_irq // IRQ/vIRQ + .org (VBAR + 0x100 + 0) + B vector_fiq // FIQ/vFIQ + .org (VBAR + 0x180 + 0) + B vector_error // Error/vError + + // Exception from CurrentEL (EL1) with SP_ELn + .org (VBAR + 0x200 + 0) + B vector_error // Synchronous + .org (VBAR + 0x280 + 0) + B vector_irq // IRQ/vIRQ + .org (VBAR + 0x300 + 0) + B vector_fiq // FIQ/vFIQ + .org (VBAR + 0x380 + 0) + B vector_error + + // Exception from lower EL, aarch64 + .org (VBAR + 0x400 + 0) + B vector_error + .org (VBAR + 0x480 + 0) + B vector_error + .org (VBAR + 0x500 + 0) + B vector_error + .org (VBAR + 0x580 + 0) + B vector_error + + // Exception from lower EL, aarch32 + .org (VBAR + 0x600 + 0) + B vector_error + .org (VBAR + 0x680 + 0) + B vector_error + .org (VBAR + 0x700 + 0) + B vector_error + .org (VBAR + 0x780 + 0) + B vector_error + .org (VBAR + 0x800 + 0) + B vector_error diff --git a/libcpu/arm/cortex-a53/SConscript b/libcpu/arm/cortex-a53/SConscript new file mode 100644 index 0000000000..eb4ee7a585 --- /dev/null +++ b/libcpu/arm/cortex-a53/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-a53/armv7.h b/libcpu/arm/cortex-a53/armv7.h new file mode 100644 index 0000000000..859b0371b7 --- /dev/null +++ b/libcpu/arm/cortex-a53/armv7.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ + +#ifndef __ARMV7_H__ +#define __ARMV7_H__ + +/* the exception stack without VFP registers */ +struct rt_hw_exp_stack +{ + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long sp; + unsigned long lr; + unsigned long pc; + unsigned long cpsr; +}; + +struct rt_hw_stack +{ + unsigned long cpsr; + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long lr; + unsigned long pc; +}; + +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define MONITORMODE 0x16 +#define ABORTMODE 0x17 +#define HYPMODE 0x1b +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 + +#define T_Bit (1<<5) +#define F_Bit (1<<6) +#define I_Bit (1<<7) +#define A_Bit (1<<8) +#define E_Bit (1<<9) +#define J_Bit (1<<24) + +#endif diff --git a/libcpu/arm/cortex-a53/context_gcc.S b/libcpu/arm/cortex-a53/context_gcc.S new file mode 100644 index 0000000000..cb95558f7a --- /dev/null +++ b/libcpu/arm/cortex-a53/context_gcc.S @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + * 2019-07-28 zdzn add smp support + */ + +#include "../rtconfig.h" +.section .text, "ax" + +#ifdef RT_USING_SMP +#define rt_hw_interrupt_disable rt_hw_local_irq_disable +#define rt_hw_interrupt_enable rt_hw_local_irq_enable +#endif + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mrs r0, cpsr + cpsid i + bx lr + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + msr cpsr, r0 + bx lr + +/* + * void rt_hw_context_switch_to(rt_uint32 to, struct rt_thread *to_thread); + * r0 --> to (thread stack) + * r1 --> to_thread + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + ldr sp, [r0] @ get new task stack pointer + +#ifdef RT_USING_SMP + mov r0, r1 + bl rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + b rt_hw_context_switch_exit + +.section .bss.share.isr +_guest_switch_lvl: + .word 0 + +.globl vmm_virq_update + +.section .text.isr, "ax" +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to, struct rt_thread *to_thread); + * r0 --> from (from_thread stack) + * r1 --> to (to_thread stack) + * r2 --> to_thread + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) + stmfd sp!, {r0-r12, lr} @ push lr & register file + + mrs r4, cpsr + tst lr, #0x01 + orrne r4, r4, #0x20 @ it's thumb code + + stmfd sp!, {r4} @ push cpsr + +#ifdef RT_USING_LWP + stmfd sp, {r13, r14}^ @ push usr_sp usr_lr + sub sp, #8 +#endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb sp!, {d0-d15} + vstmdb sp!, {d16-d31} + vmrs r5, fpscr + stmfd sp!, {r5} +1: + stmfd sp!, {r6} +#endif + + str sp, [r0] @ store sp in preempted tasks TCB + ldr sp, [r1] @ get new task stack pointer + +#ifdef RT_USING_SMP + mov r0, r2 + bl rt_cpus_lock_status_restore +#endif /*RT_USING_SMP*/ + b rt_hw_context_switch_exit + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: +#ifdef RT_USING_SMP + /* r0 :svc_mod context + * r1 :addr of from_thread's sp + * r2 :addr of to_thread's sp + * r3 :to_thread's tcb + */ + + str r0, [r1] + + ldr sp, [r2] + mov r0, r3 + bl rt_cpus_lock_status_restore + + b rt_hw_context_switch_exit + +#else /*RT_USING_SMP*/ + ldr r2, =rt_thread_switch_interrupt_flag + ldr r3, [r2] + cmp r3, #1 + beq _reswitch + ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 + str r0, [ip] + str r3, [r2] +_reswitch: + ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread + str r1, [r2] + bx lr +#endif /*RT_USING_SMP*/ + +.global rt_hw_context_switch_exit +rt_hw_context_switch_exit: + +#ifdef RT_USING_SMP +#ifdef RT_USING_SIGNALS + mov r0, sp + cps #Mode_IRQ + bl rt_signal_check + cps #Mode_SVC + mov sp, r0 +#endif +#endif +#ifdef RT_USING_FPU +/* fpu context */ + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq 1f + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d16-d31} + vldmia sp!, {d0-d15} + +#endif + +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ /* usr_sp, usr_lr */ + add sp, #8 +#endif + ldmfd sp!, {r4} + msr spsr_cxsf, r4 /* original mode */ + ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ + diff --git a/libcpu/arm/cortex-a53/cp15.h b/libcpu/arm/cortex-a53/cp15.h new file mode 100644 index 0000000000..14b85b7e64 --- /dev/null +++ b/libcpu/arm/cortex-a53/cp15.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ +#include "raspi.h" +#ifndef __CP15_H__ +#define __CP15_H__ + +#ifndef __STATIC_FORCEINLINE +#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif + +#define __WFI() __asm__ volatile ("wfi":::"memory") + +#define __WFE() __asm__ volatile ("wfe":::"memory") + +#define __SEV() __asm__ volatile ("sev") + +__STATIC_FORCEINLINE void __ISB(void) +{ + __asm__ volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __asm__ volatile ("dsb 0xF":::"memory"); +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ + +__STATIC_FORCEINLINE void __DMB(void) +{ + __asm__ volatile ("dmb 0xF":::"memory"); +} + + +#ifdef RT_USING_SMP +static inline void send_ipi_msg(int cpu, int ipi_vector) +{ + IPI_MAILBOX_SET(cpu) = 1 << ipi_vector; +} + +static inline void setup_bootstrap_addr(int cpu, int addr) +{ + CORE_MAILBOX3_SET(cpu) = addr; +} + +static inline void enable_cpu_ipi_intr(int cpu) +{ + COREMB_INTCTL(cpu) = IPI_MAILBOX_INT_MASK; +} + +static inline void enable_cpu_timer_intr(int cpu) +{ + CORETIMER_INTCTL(cpu) = 0x8; +} + +static inline void enable_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 1; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL +} + +static inline void disable_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 0; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL +} + +static inline void mask_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 2; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL +} + +static inline void unmask_cntv(void) +{ + rt_uint32_t cntv_ctl; + cntv_ctl = 1; + asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL +} + +static inline rt_uint64_t read_cntvct(void) +{ + rt_uint32_t val,val1; + asm volatile ("mrrc p15, 1, %0, %1, c14" : "=r" (val),"=r" (val1)); + return (val); +} + +static inline rt_uint64_t read_cntvoff(void) +{ + + rt_uint64_t val; + asm volatile ("mrrc p15, 4, %Q0, %R0, c14" : "=r" (val)); + return (val); +} + +static inline rt_uint32_t read_cntv_tval(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c3, 0" : "=r"(val)); + return val; +} + + +static inline void write_cntv_tval(rt_uint32_t val) +{ + asm volatile ("mcr p15, 0, %0, c14, c3, 0" :: "r"(val)); + return; +} + +static inline rt_uint32_t read_cntfrq(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val)); + return val; +} + + +static inline rt_uint32_t read_cntctrl(void) +{ + rt_uint32_t val; + asm volatile ("mrc p15, 0, %0, c14, c1, 0" : "=r"(val)); + return val; +} + +static inline uint32_t write_cntctrl(uint32_t val) +{ + + asm volatile ("mcr p15, 0, %0, c14, c1, 0" : :"r"(val)); + return val; +} +#endif + +unsigned long rt_cpu_get_smp_id(void); + +void rt_cpu_mmu_disable(void); +void rt_cpu_mmu_enable(void); +void rt_cpu_tlb_set(volatile unsigned long*); + +void rt_cpu_dcache_clean_flush(void); +void rt_cpu_icache_flush(void); + +void rt_cpu_vector_set_base(unsigned int addr); +void rt_hw_mmu_init(void); +void rt_hw_vector_init(void); + +void set_timer_counter(unsigned int counter); +void set_timer_control(unsigned int control); +#endif diff --git a/libcpu/arm/cortex-a53/cp15_gcc.S b/libcpu/arm/cortex-a53/cp15_gcc.S new file mode 100644 index 0000000000..db2e6143ae --- /dev/null +++ b/libcpu/arm/cortex-a53/cp15_gcc.S @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.globl rt_cpu_get_smp_id +rt_cpu_get_smp_id: + mrc p15, #0, r0, c0, c0, #5 + bx lr + +.globl rt_cpu_vector_set_base +rt_cpu_vector_set_base: + /* clear SCTRL.V to customize the vector address */ + mrc p15, #0, r1, c1, c0, #0 + bic r1, #(1 << 13) + mcr p15, #0, r1, c1, c0, #0 + /* set up the vector address */ + mcr p15, #0, r0, c12, c0, #0 + dsb + bx lr + +.globl rt_hw_cpu_dcache_enable +rt_hw_cpu_dcache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_hw_cpu_icache_enable +rt_hw_cpu_icache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +_FLD_MAX_WAY: + .word 0x3ff +_FLD_MAX_IDX: + .word 0x7ff + +.globl set_timer_counter +set_timer_counter: + mcr p15, #0, r0, c14, c3, #0 @ write virtual timer timerval register + bx lr +.globl set_timer_control +set_timer_control: + mcr p15, #0, r0, c14, c3, #1 @ write virtual timer control register + bx lr + +.globl rt_cpu_dcache_clean_flush +rt_cpu_dcache_clean_flush: + push {r4-r11} + dmb + mrc p15, #1, r0, c0, c0, #1 @ read clid register + ands r3, r0, #0x7000000 @ get level of coherency + mov r3, r3, lsr #23 + beq finished + mov r10, #0 +loop1: + add r2, r10, r10, lsr #1 + mov r1, r0, lsr r2 + and r1, r1, #7 + cmp r1, #2 + blt skip + mcr p15, #2, r10, c0, c0, #0 + isb + mrc p15, #1, r1, c0, c0, #0 + and r2, r1, #7 + add r2, r2, #4 + ldr r4, _FLD_MAX_WAY + ands r4, r4, r1, lsr #3 + clz r5, r4 + ldr r7, _FLD_MAX_IDX + ands r7, r7, r1, lsr #13 +loop2: + mov r9, r4 +loop3: + orr r11, r10, r9, lsl r5 + orr r11, r11, r7, lsl r2 + mcr p15, #0, r11, c7, c14, #2 + subs r9, r9, #1 + bge loop3 + subs r7, r7, #1 + bge loop2 +skip: + add r10, r10, #2 + cmp r3, r10 + bgt loop1 + +finished: + dsb + isb + pop {r4-r11} + bx lr + +.globl rt_cpu_icache_flush +rt_cpu_icache_flush: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate + dsb + isb + bx lr + +.globl rt_hw_cpu_dcache_disable +rt_hw_cpu_dcache_disable: + push {r4-r11, lr} + bl rt_cpu_dcache_clean_flush + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + pop {r4-r11, lr} + bx lr + +.globl rt_hw_cpu_icache_disable +rt_hw_cpu_icache_disable: + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_cpu_mmu_disable +rt_cpu_mmu_disable: + mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #1 + mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit + dsb + bx lr + +.globl rt_cpu_mmu_enable +rt_cpu_mmu_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x001 + mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit + dsb + bx lr + +.globl rt_cpu_tlb_set +rt_cpu_tlb_set: + mcr p15, #0, r0, c2, c0, #0 + dmb + bx lr diff --git a/libcpu/arm/cortex-a53/cpu.c b/libcpu/arm/cortex-a53/cpu.c new file mode 100644 index 0000000000..4d02ca35e1 --- /dev/null +++ b/libcpu/arm/cortex-a53/cpu.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + * 2019-07-28 zdzn add smp support + */ + +#include +#include +#include +#include "cp15.h" + +int rt_hw_cpu_id(void) +{ + int cpu_id; + __asm__ volatile ( + "mrc p15, 0, %0, c0, c0, 5" + :"=r"(cpu_id) + ); + cpu_id &= 0xf; + return cpu_id; +}; + + +#ifdef RT_USING_SMP +void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock) +{ + lock->slock = 0; +} + +void rt_hw_spin_lock(rt_hw_spinlock_t *lock) +{ + unsigned long tmp; + unsigned long newval; + rt_hw_spinlock_t lockval; + __asm__ __volatile__( + "pld [%0]" + ::"r"(&lock->slock) + ); + + __asm__ __volatile__( + "1: ldrex %0, [%3]\n" + " add %1, %0, %4\n" + " strex %2, %1, [%3]\n" + " teq %2, #0\n" + " bne 1b" + : "=&r" (lockval), "=&r" (newval), "=&r" (tmp) + : "r" (&lock->slock), "I" (1 << 16) + : "cc"); + + while (lockval.tickets.next != lockval.tickets.owner) + { + __WFE(); + lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner); + } + + __DMB(); +} + +void rt_hw_spin_unlock(rt_hw_spinlock_t *lock) +{ + __DMB(); + lock->tickets.owner++; + __DSB(); + __SEV(); +} +#endif /*RT_USING_SMP*/ + +/** + * @addtogroup ARM CPU + */ +/*@{*/ + +/** shutdown CPU */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} + +/*@}*/ diff --git a/libcpu/arm/cortex-a53/interrupt.c b/libcpu/arm/cortex-a53/interrupt.c new file mode 100644 index 0000000000..c9e7c17f8f --- /dev/null +++ b/libcpu/arm/cortex-a53/interrupt.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018/5/3 Bernard first version + * 2019-07-28 zdzn add smp support + * 2019-08-09 zhangjun fixup the problem of smp startup and scheduling issues, + * write addr to mailbox3 to startup smp, and we use mailbox0 for ipi + */ + +#include +#include + +#include "cp15.h" +#include + +#define MAX_HANDLERS 72 + +#ifdef RT_USING_SMP +#define rt_interrupt_nest rt_cpu_self()->irq_nest +#else +extern volatile rt_uint8_t rt_interrupt_nest; +#endif + +const unsigned int VECTOR_BASE = 0x00; +extern void rt_cpu_vector_set_base(unsigned int addr); +extern int system_vectors; + +void rt_hw_vector_init(void) +{ + rt_cpu_vector_set_base((unsigned int)&system_vectors); +} + +/* exception and interrupt handler table */ +struct rt_irq_desc isr_table[MAX_HANDLERS]; + +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +extern int system_vectors; + +static void default_isr_handler(int vector, void *param) +{ +#ifdef RT_USING_SMP + rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(),vector); +#else + rt_kprintf("unhandled irq: %d\n",vector); +#endif +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + rt_uint32_t index; + + /* mask all of interrupts */ + IRQ_DISABLE_BASIC = 0x000000ff; + IRQ_DISABLE1 = 0xffffffff; + IRQ_DISABLE2 = 0xffffffff; + for (index = 0; index < MAX_HANDLERS; index ++) + { + isr_table[index].handler = default_isr_handler; + isr_table[index].param = NULL; +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX); + isr_table[index].counter = 0; +#endif + } + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + + if (vector < 32) + { + IRQ_DISABLE1 = (1 << vector); + } + else if (vector < 64) + { + vector = vector % 32; + IRQ_DISABLE2 = (1 << vector); + } + else + { + vector = vector - 64; + IRQ_DISABLE_BASIC = (1 << vector); + } +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + if (vector < 32) + { + IRQ_ENABLE1 = (1 << vector); + } + else if (vector < 64) + { + vector = vector % 32; + IRQ_ENABLE2 = (1 << vector); + } + else + { + vector = vector - 64; + IRQ_ENABLE_BASIC = (1 << vector); + } +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} + +#ifdef RT_USING_SMP +void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) +{ + __DSB(); + if (cpu_mask & 0x1) + { + send_ipi_msg(0, ipi_vector); + } + if (cpu_mask & 0x2) + { + send_ipi_msg(1, ipi_vector); + } + if (cpu_mask & 0x4) + { + send_ipi_msg(2, ipi_vector); + } + if (cpu_mask & 0x8) + { + send_ipi_msg(3, ipi_vector); + } + __DSB(); +} +#endif + +#ifdef RT_USING_SMP +void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) +{ + /* note: ipi_vector maybe different with irq_vector */ + rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER"); +} +#endif diff --git a/libcpu/arm/cortex-a53/interrupt.h b/libcpu/arm/cortex-a53/interrupt.h new file mode 100644 index 0000000000..9aae0f556a --- /dev/null +++ b/libcpu/arm/cortex-a53/interrupt.h @@ -0,0 +1,18 @@ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +#include +#include + +#define INT_IRQ 0x00 +#define INT_FIQ 0x01 + +void rt_hw_interrupt_init(void); +void rt_hw_interrupt_mask(int vector); +void rt_hw_interrupt_umask(int vector); + +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name); + +#endif diff --git a/libcpu/arm/cortex-a53/mmu.c b/libcpu/arm/cortex-a53/mmu.c new file mode 100644 index 0000000000..b3541d2ad4 --- /dev/null +++ b/libcpu/arm/cortex-a53/mmu.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2012-01-10 bernard porting to AM1808 + * 2019-07-28 zdzn add smp support + */ + +#include "mmu.h" + +/* dump 2nd level page table */ +void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + for (i = 0; i < 256; i++) + { + rt_uint32_t pte2 = ptb[i]; + if ((pte2 & 0x3) == 0) + { + if (fcnt == 0) + rt_kprintf(" "); + rt_kprintf("%04x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf(" %04x: %x: ", i, pte2); + if ((pte2 & 0x3) == 0x1) + { + rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, + (pte2 >> 15) & 0x1, + ((pte2 >> 10) | (pte2 >> 2)) & 0x1f); + } + else + { + rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1, + ((pte2 >> 4) | (pte2 >> 2)) & 0x1f); + } + } +} + +void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + rt_kprintf("page table@%p\n", ptb); + for (i = 0; i < 1024*4; i++) + { + rt_uint32_t pte1 = ptb[i]; + if ((pte1 & 0x3) == 0) + { + rt_kprintf("%03x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf("%03x: %08x: ", i, pte1); + if ((pte1 & 0x3) == 0x3) + { + rt_kprintf("LPAE\n"); + } + else if ((pte1 & 0x3) == 0x1) + { + rt_kprintf("pte,ns:%d,domain:%d\n", + (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf); + /* + *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000) + * - 0x80000000 + 0xC0000000)); + */ + } + else if (pte1 & (1 << 18)) + { + rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + ((pte1 >> 10) | (pte1 >> 2)) & 0x1f); + } + else + { + rt_kprintf("section,ns:%d,ap:%x," + "xn:%d,texcb:%02x,domain:%d\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + (((pte1 & (0x7 << 12)) >> 10) | + ((pte1 & 0x0c) >> 2)) & 0x1f, + (pte1 >> 5) & 0xf); + } + } +} + +/* level1 page table, each entry for 1MB memory. */ +volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024))); +void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, + rt_uint32_t vaddrEnd, + rt_uint32_t paddrStart, + rt_uint32_t attr) +{ + volatile rt_uint32_t *pTT; + volatile int i, nSec; + pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20); + nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); + for (i = 0; i <= nSec; i++) + { + *pTT = attr | (((paddrStart >> 20) + i) << 20); + pTT++; + } +} + +unsigned long rt_hw_set_domain_register(unsigned long domain_val) +{ + unsigned long old_domain; + + asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain)); + asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory"); + + return old_domain; +} + +void rt_hw_init_mmu_table() +{ + /* set page table */ + /* 4G 1:1 memory */ + rt_hw_mmu_setmtt(0x00000000, 0x3effffff, 0x00000000, NORMAL_MEM); + /* IO memory region */ + rt_hw_mmu_setmtt(0x3f000000, 0x40010000, 0x3f000000, DEVICE_MEM); +} + +void rt_hw_change_mmu_table(rt_uint32_t vaddrStart, + rt_uint32_t size, + rt_uint32_t paddrStart, rt_uint32_t attr) +{ + rt_hw_mmu_setmtt(vaddrStart, vaddrStart+size-1, paddrStart, attr); +#ifndef RT_USING_SMP + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); +#endif +} + + +void rt_hw_mmu_init(void) +{ + rt_cpu_dcache_clean_flush(); + rt_cpu_icache_flush(); + rt_hw_cpu_dcache_disable(); + rt_hw_cpu_icache_disable(); + rt_cpu_mmu_disable(); + + /*rt_hw_cpu_dump_page_table(MMUTable);*/ + rt_hw_set_domain_register(0x55555555); + + rt_cpu_tlb_set(MMUTable); + + rt_cpu_mmu_enable(); + + rt_hw_cpu_icache_enable(); + rt_hw_cpu_dcache_enable(); +} + diff --git a/libcpu/arm/cortex-a53/mmu.h b/libcpu/arm/cortex-a53/mmu.h new file mode 100644 index 0000000000..6b0c25e990 --- /dev/null +++ b/libcpu/arm/cortex-a53/mmu.h @@ -0,0 +1,51 @@ +#ifndef MMU_H__ +#define MMU_H__ +#include +#include +#include +#include "cp15.h" + +#define DESC_SEC (0x2) +#define CB (3 << 2) //cache_on, write_back +#define CNB (2 << 2) //cache_on, write_through +#define NCB (1 << 2) //cache_off,WR_BUF on +#define NCNB (0 << 2) //cache_off,WR_BUF off +#define AP_RW (3 << 10) //supervisor=RW, user=RW +#define AP_RO (2 << 10) //supervisor=RW, user=RO +#define XN (1 << 4) // eXecute Never +#define SHARED (1 << 16) /* shareable */ +#define SHAREDEVICE (1 << 2) /* shared device */ +#define STRONGORDER (0 << 2) /* strong ordered */ +#define MEMWBWA ((1 << 12) | (3 << 2)) /* write back, write allocate */ + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0 << 5) +#define DOMAIN1 (0x1 << 5) + +#define DOMAIN0_ATTR (DOMAIN_CHK << 0) +#define DOMAIN1_ATTR (DOMAIN_FAULT << 2) + +/* Read/Write, cache, write back */ +#define RW_CB (AP_RW | DOMAIN0 | CB | DESC_SEC) +/* Read/Write, cache, write through */ +#define RW_CNB (AP_RW | DOMAIN0 | CNB | DESC_SEC) +/* Read/Write without cache and write buffer */ +#define RW_NCNB (AP_RW | DOMAIN0 | NCNB | DESC_SEC) +/* Read/Write without cache and write buffer, no execute */ +#define RW_NCNBXN (AP_RW | DOMAIN0 | NCNB | DESC_SEC | XN) +/* Read/Write without cache and write buffer */ +#define RW_FAULT (AP_RW | DOMAIN1 | NCNB | DESC_SEC) + +/* device mapping type */ +#define DEVICE_MEM (SHARED | SHAREDEVICE | RW_NCNBXN) +/* normal memory mapping type */ +#define NORMAL_MEM (SHARED | AP_RW | DOMAIN0 | MEMWBWA | DESC_SEC) +#define STRONG_ORDER_MEM (SHARED | AP_RO | XN | DESC_SEC) +#define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000) + +void rt_hw_change_mmu_table(rt_uint32_t vaddrStart, + rt_uint32_t size, + rt_uint32_t paddrStart, rt_uint32_t attr); +#endif diff --git a/libcpu/arm/cortex-a53/stack.c b/libcpu/arm/cortex-a53/stack.c new file mode 100644 index 0000000000..c2c60fbf49 --- /dev/null +++ b/libcpu/arm/cortex-a53/stack.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2011-09-23 Bernard the first version + * 2011-10-05 Bernard add thumb mode + */ +#include +#include +#include + +/** + * @addtogroup AM33xx + */ +/*@{*/ + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_uint32_t *stk; + + stack_addr += sizeof(rt_uint32_t); + stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); + stk = (rt_uint32_t *)stack_addr; + *(--stk) = (rt_uint32_t)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0xdeadbeef; /* r12 */ + *(--stk) = 0xdeadbeef; /* r11 */ + *(--stk) = 0xdeadbeef; /* r10 */ + *(--stk) = 0xdeadbeef; /* r9 */ + *(--stk) = 0xdeadbeef; /* r8 */ + *(--stk) = 0xdeadbeef; /* r7 */ + *(--stk) = 0xdeadbeef; /* r6 */ + *(--stk) = 0xdeadbeef; /* r5 */ + *(--stk) = 0xdeadbeef; /* r4 */ + *(--stk) = 0xdeadbeef; /* r3 */ + *(--stk) = 0xdeadbeef; /* r2 */ + *(--stk) = 0xdeadbeef; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + + /* cpsr */ + if ((rt_uint32_t)tentry & 0x01) + *(--stk) = SVCMODE | 0x20; /* thumb mode */ + else + *(--stk) = SVCMODE; /* arm mode */ + +#ifdef RT_USING_LWP + *(--stk) = 0; /* user lr */ + *(--stk) = 0; /* user sp*/ +#endif +#ifdef RT_USING_FPU + *(--stk) = 0; /* not use fpu*/ +#endif + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} + +/*@}*/ diff --git a/libcpu/arm/cortex-a53/start_gcc.S b/libcpu/arm/cortex-a53/start_gcc.S new file mode 100644 index 0000000000..ec74213f07 --- /dev/null +++ b/libcpu/arm/cortex-a53/start_gcc.S @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + * 2019-07-28 zdzn add smp support + */ + +#include "../rtconfig.h" +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + +#ifdef RT_USING_FPU +.equ UND_Stack_Size, 0x00000400 +#else +.equ UND_Stack_Size, 0x00000000 +#endif +.equ SVC_Stack_Size, 0x00000400 +.equ ABT_Stack_Size, 0x00000000 +.equ RT_FIQ_STACK_PGSZ, 0x00000000 +.equ RT_IRQ_STACK_PGSZ, 0x00000800 +.equ USR_Stack_Size, 0x00000400 + +#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ + RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) + +.section .data.share.isr +/* stack */ + +#ifdef RT_USING_SMP +.globl stack_start0 +.globl stack_top0 +.globl stack_start1 +.globl stack_top1 +.globl stack_start2 +.globl stack_top2 +.globl stack_start3 +.globl stack_top3 +stack_start0: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top0: + +stack_start1: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top1: + +stack_start2: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top2: + +stack_start3: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top3: + +.globl boot_indicate +boot_indicate: +.rept 16 +.byte 0 +.endr + +#else +.globl stack_start +.globl stack_top +stack_start: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top: +#endif + + +.text +/* reset entry */ +.globl _reset +_reset: + + /* Disable IRQ & FIQ */ + cpsid if + + /* Check for HYP mode */ + mrs r0, cpsr_all + and r0, r0, #0x1F + mov r8, #0x1A + cmp r0, r8 + beq overHyped + b continue + +overHyped: /* Get out of HYP mode */ + ldr r1, =continue + msr ELR_hyp, r1 + mrs r1, cpsr_all + and r1, r1, #0x1f ;@ CPSR_MODE_MASK + orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR + msr SPSR_hyp, r1 + eret + +continue: + + /* disable mmu */ + bl rt_cpu_mmu_disable + /* set the cpu to SVC32 mode and disable interrupt */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0x13 + msr cpsr_c, r0 +#ifdef RT_USING_SMP + mrc p15, 0, r0, c0, c0, 5 + ubfx r0, r0, #0, #2 + cmp r0, #0 + beq 1f + /* write boot indicate */ + ldr r5, = boot_indicate + str r0, [r5, r0, lsl #2] + bl secondary_cpu_start + b . +1: +#endif + /* setup stack */ +#ifdef RT_USING_SMP + ldr r0, =stack_top0 +#else + ldr r0, =stack_top +#endif + bl stack_setup + + /* clear .bss */ + mov r0,#0 /* get a zero */ + ldr r1,=__bss_start /* bss start */ + ldr r2,=__bss_end /* bss end */ + +bss_loop: + cmp r1,r2 /* check if data to clear */ + strlo r0,[r1],#4 /* clear 4 bytes */ + blo bss_loop /* loop until done */ + bl rt_hw_init_mmu_table + bl init_mbox_mmu_map + bl rt_hw_mmu_init + + /* start RT-Thread Kernel */ + ldr pc, _rtthread_startup +_rtthread_startup: + .word rtthread_startup + +stack_setup: + + @ Set the startup stack for svc + mov sp, r0 + + @ Enter Undefined Instruction Mode and set its Stack Pointer + msr cpsr_c, #Mode_UND|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #UND_Stack_Size + + @ Enter Abort Mode and set its Stack Pointer + msr cpsr_c, #Mode_ABT|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #ABT_Stack_Size + + @ Enter FIQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #RT_FIQ_STACK_PGSZ + + @ Enter IRQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #RT_IRQ_STACK_PGSZ + + /* come back to SVC mode */ + msr cpsr_c, #Mode_SVC|I_Bit|F_Bit + bx lr + +.text + +/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ +.section .text.isr, "ax" + .align 5 +.globl vector_fiq +vector_fiq: + stmfd sp!,{r0-r7,lr} + bl rt_hw_trap_fiq + ldmfd sp!,{r0-r7,lr} + subs pc, lr, #4 + +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread + +.globl rt_current_thread +.globl vmm_thread +.globl vmm_virq_check + + .align 5 +.globl vector_irq +vector_irq: +#ifdef RT_USING_SMP + clrex + + stmfd sp!, {r0, r1} + cps #Mode_SVC + mov r0, sp /* svc_sp */ + mov r1, lr /* svc_lr */ + + cps #Mode_IRQ + sub lr, lr, #4 + stmfd r0!, {r1, lr} /* svc_lr, svc_pc */ + stmfd r0!, {r2 - r12} + ldmfd sp!, {r1, r2} /* original r0, r1 */ + stmfd r0!, {r1 - r2} + mrs r1, spsr /* original mode */ + stmfd r0!, {r1} + +#ifdef RT_USING_LWP + stmfd r0, {r13, r14}^ /* usr_sp, usr_lr */ + sub r0, #8 +#endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb r0!, {d0-d15} + vstmdb r0!, {d16-d31} + vmrs r5, fpscr + stmfd r0!, {r5} +1: + stmfd r0!, {r6} +#endif + mov r8, r0 + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + cps #Mode_SVC + mov sp, r8 + mov r0, r8 + + bl rt_scheduler_do_irq_switch + + b rt_hw_context_switch_exit + +#else + stmfd sp!, {r0-r12,lr} + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + @ if rt_thread_switch_interrupt_flag set, jump to + @ rt_hw_context_switch_interrupt_do and don't return + ldr r0, =rt_thread_switch_interrupt_flag + ldr r1, [r0] + cmp r1, #1 + beq rt_hw_context_switch_interrupt_do + + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + +rt_hw_context_switch_interrupt_do: + mov r1, #0 @ clear flag + str r1, [r0] + + mov r1, sp @ r1 point to {r0-r3} in stack + add sp, sp, #4*4 + ldmfd sp!, {r4-r12,lr}@ reload saved registers + mrs r0, spsr @ get cpsr of interrupt thread + sub r2, lr, #4 @ save old task's pc to r2 + + @ Switch to SVC mode with no interrupt. If the usr mode guest is + @ interrupted, this will just switch to the stack of kernel space. + @ save the registers in kernel space won't trigger data abort. + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + + stmfd sp!, {r2} @ push old task's pc + stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 + ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread + stmfd sp!, {r1-r4} @ push old task's r0-r3 + stmfd sp!, {r0} @ push old task's cpsr + +#ifdef RT_USING_LWP + stmfd sp, {r13, r14}^ @push usr_sp, usr_lr + sub sp, #8 +#endif +#ifdef RT_USING_FPU + /* fpu context */ + vmrs r6, fpexc + tst r6, #(1<<30) + beq 1f + vstmdb sp!, {d0-d15} + vstmdb sp!, {d16-d31} + vmrs r5, fpscr + stmfd sp!, {r5} +1: + stmfd sp!, {r6} +#endif + + ldr r4, =rt_interrupt_from_thread + ldr r5, [r4] + str sp, [r5] @ store sp in preempted tasks's TCB + + ldr r6, =rt_interrupt_to_thread + ldr r6, [r6] + ldr sp, [r6] @ get new task's stack pointer + +#ifdef RT_USING_FPU +/* fpu context */ + ldmfd sp!, {r6} + vmsr fpexc, r6 + tst r6, #(1<<30) + beq 1f + ldmfd sp!, {r5} + vmsr fpscr, r5 + vldmia sp!, {d16-d31} + vldmia sp!, {d0-d15} +1: +#endif + +#ifdef RT_USING_LWP + ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr + add sp, #8 +#endif + + ldmfd sp!, {r4} @ pop new task's cpsr to spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr + +#endif + +.macro push_svc_reg + sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + mov r0, sp + mrs r6, spsr @/* Save CPSR */ + str lr, [r0, #15*4] @/* Push PC */ + str r6, [r0, #16*4] @/* Push CPSR */ + cps #Mode_SVC + str sp, [r0, #13*4] @/* Save calling SP */ + str lr, [r0, #14*4] @/* Save calling PC */ +.endm + + .align 5 + .globl vector_swi +vector_swi: + push_svc_reg + bl rt_hw_trap_swi + b . + + .align 5 + .globl vector_undef +vector_undef: + push_svc_reg + cps #Mode_UND + bl rt_hw_trap_undef +#ifdef RT_USING_FPU + ldr lr, [sp, #15*4] + ldmia sp, {r0 - r12} + add sp, sp, #17 * 4 + movs pc, lr +#endif + b . + + .align 5 + .globl vector_pabt +vector_pabt: + push_svc_reg + bl rt_hw_trap_pabt + b . + + .align 5 + .globl vector_dabt +vector_dabt: + push_svc_reg + bl rt_hw_trap_dabt + b . + + .align 5 + .globl vector_resv +vector_resv: + push_svc_reg + bl rt_hw_trap_resv + b . + +#ifdef RT_USING_SMP + +.global secondary_cpu_start +secondary_cpu_start: + /* set vector base */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1<<13) + mcr p15, 0, r0, c1, c0, 0 + + /* setup stack */ + mrc p15, 0, r0, c0, c0, 5 + ubfx r0, r0, #0, #2 + ldr r1, =stack_top0 + ldr r2, =ISR_Stack_Size + mul r3, r2, r0 + add r0, r1, r3 + bl stack_setup + /* initialize the mmu table and enable mmu */ + bl rt_hw_mmu_init + b secondary_cpu_c_start + +#endif + +;@ void arm_smp_enable(void); +.globl arm_smp_enable +arm_smp_enable: + mrc p15, 0, r0, c1, c0, 1 ;@ set SMP bit in ACTLR + orr r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + bx lr +/* + mrrc p15, 1, r0, r1, c15 + orr r0, r0, #0x40 + mcrr p15, 1, r0, r1, c15 + dsb + isb + bx lr +*/ +.text +;@ void arm_smp_disable(void); +.globl arm_smp_disable + +arm_smp_disable: + mrc p15, 0, r0, c1, c0, 1 ;@ clear SMP bit in ACTLR + bic r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + bx lr +/* + mrrc p15, 1, r0, r1, c15 + bic r0, r0, #0x40 + mcrr p15, 1, r0, r1, c15 + bx lr +*/ + diff --git a/libcpu/arm/cortex-a53/trap.c b/libcpu/arm/cortex-a53/trap.c new file mode 100644 index 0000000000..f83f183695 --- /dev/null +++ b/libcpu/arm/cortex-a53/trap.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + * 2019-07-28 zdzn add smp support + * 2019-08-09 zhangjun fixup the problem of smp startup and scheduling issues, + * write addr to mailbox3 to startup smp, and we use mailbox0 for ipi + */ + +#include +#include +#include + +#include "armv7.h" + +extern struct rt_thread *rt_current_thread; +#ifdef RT_USING_FINSH +extern long list_thread(void); +#endif + + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ +void rt_hw_show_register(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); + rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); + rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); + rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); + rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); + rt_kprintf("cpsr:0x%08x\n", regs->cpsr); +} + + +/** + * When comes across an instruction which it cannot handle, + * it takes the undefined instruction trap. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("undefined instruction:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * The software interrupt instruction (SWI) is used for entering + * Supervisor mode, usually to request a particular supervisor + * function. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("software interrupt:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during an instruction prefetch. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("prefetch abort:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during a data access. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("data abort:"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * Normally, system will never reach here + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("reserved trap:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +void rt_hw_trap_irq(void) +{ + void *param; + uint32_t irq; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + uint32_t value = 0; + value = IRQ_PEND_BASIC & 0x3ff; +#ifdef RT_USING_SMP + uint32_t mailbox_data; + uint32_t cpu_id = rt_hw_cpu_id(); + uint32_t int_source = CORE_IRQSOURCE(cpu_id); + mailbox_data = IPI_MAILBOX_CLEAR(cpu_id); + if (int_source & 0x0f) + { + if (int_source & 0x08) + { + isr_func = isr_table[IRQ_ARM_TIMER].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[IRQ_ARM_TIMER].counter++; +#endif + if (isr_func) + { + param = isr_table[IRQ_ARM_TIMER].param; + isr_func(IRQ_ARM_TIMER, param); + } + } + } + if (int_source & 0xf0) + { + /*it's a ipi interrupt*/ + if (mailbox_data & 0x1) + { + /* clear mailbox */ + IPI_MAILBOX_CLEAR(cpu_id) = mailbox_data; + isr_func = isr_table[IRQ_ARM_MAILBOX].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[IRQ_ARM_MAILBOX].counter++; +#endif + if (isr_func) + { + param = isr_table[IRQ_ARM_MAILBOX].param; + isr_func(IRQ_ARM_MAILBOX, param); + } + } + else + CORE_MAILBOX3_CLEAR(cpu_id) = mailbox_data; + } +#endif + /* local interrupt*/ + if (value) + { + if (value & (1 << 8)) + { + value = IRQ_PEND1; + irq = __rt_ffs(value) - 1; + } + else if (value & (1 << 9)) + { + value = IRQ_PEND2; + irq = __rt_ffs(value) + 31; + } + else + { + value &= 0x0f; + irq = __rt_ffs(value) + 63; + } + + /* get interrupt service routine */ + isr_func = isr_table[irq].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[irq].counter++; +#endif + if (isr_func) + { + /* Interrupt for myself. */ + param = isr_table[irq].param; + /* turn to interrupt service routine */ + isr_func(irq, param); + } + } +} + +void rt_hw_trap_fiq(void) +{ + +} diff --git a/libcpu/arm/cortex-a53/vector_gcc.S b/libcpu/arm/cortex-a53/vector_gcc.S new file mode 100644 index 0000000000..eebfe9c13b --- /dev/null +++ b/libcpu/arm/cortex-a53/vector_gcc.S @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.section .vectors, "ax" +.code 32 + +.globl system_vectors +system_vectors: + ldr pc, _vector_reset + ldr pc, _vector_undef + ldr pc, _vector_swi + ldr pc, _vector_pabt + ldr pc, _vector_dabt + ldr pc, _vector_resv + ldr pc, _vector_irq + ldr pc, _vector_fiq + +.globl _reset +.globl vector_undef +.globl vector_swi +.globl vector_pabt +.globl vector_dabt +.globl vector_resv +.globl vector_irq +.globl vector_fiq + +_vector_reset: + .word _reset +_vector_undef: + .word vector_undef +_vector_swi: + .word vector_swi +_vector_pabt: + .word vector_pabt +_vector_dabt: + .word vector_dabt +_vector_resv: + .word vector_resv +_vector_irq: + .word vector_irq +_vector_fiq: + .word vector_fiq + +.balignl 16,0xdeadbeef diff --git a/libcpu/arm/cortex-a7/SConscript b/libcpu/arm/cortex-a7/SConscript new file mode 100644 index 0000000000..eb4ee7a585 --- /dev/null +++ b/libcpu/arm/cortex-a7/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/raspi2/cpu/armv7.h b/libcpu/arm/cortex-a7/armv7.h similarity index 100% rename from bsp/raspi2/cpu/armv7.h rename to libcpu/arm/cortex-a7/armv7.h diff --git a/bsp/raspi2/cpu/context_gcc.S b/libcpu/arm/cortex-a7/context_gcc.S similarity index 100% rename from bsp/raspi2/cpu/context_gcc.S rename to libcpu/arm/cortex-a7/context_gcc.S diff --git a/bsp/raspi2/cpu/cp15.h b/libcpu/arm/cortex-a7/cp15.h similarity index 100% rename from bsp/raspi2/cpu/cp15.h rename to libcpu/arm/cortex-a7/cp15.h diff --git a/bsp/raspi2/cpu/cp15_gcc.S b/libcpu/arm/cortex-a7/cp15_gcc.S similarity index 100% rename from bsp/raspi2/cpu/cp15_gcc.S rename to libcpu/arm/cortex-a7/cp15_gcc.S diff --git a/bsp/raspi2/cpu/cpu.c b/libcpu/arm/cortex-a7/cpu.c similarity index 100% rename from bsp/raspi2/cpu/cpu.c rename to libcpu/arm/cortex-a7/cpu.c diff --git a/bsp/raspi2/cpu/interrupt.c b/libcpu/arm/cortex-a7/interrupt.c similarity index 100% rename from bsp/raspi2/cpu/interrupt.c rename to libcpu/arm/cortex-a7/interrupt.c diff --git a/bsp/raspi2/cpu/mmu.c b/libcpu/arm/cortex-a7/mmu.c similarity index 100% rename from bsp/raspi2/cpu/mmu.c rename to libcpu/arm/cortex-a7/mmu.c diff --git a/bsp/raspi2/cpu/stack.c b/libcpu/arm/cortex-a7/stack.c similarity index 100% rename from bsp/raspi2/cpu/stack.c rename to libcpu/arm/cortex-a7/stack.c diff --git a/bsp/raspi2/cpu/start_gcc.S b/libcpu/arm/cortex-a7/start_gcc.S similarity index 100% rename from bsp/raspi2/cpu/start_gcc.S rename to libcpu/arm/cortex-a7/start_gcc.S diff --git a/bsp/raspi2/cpu/trap.c b/libcpu/arm/cortex-a7/trap.c similarity index 100% rename from bsp/raspi2/cpu/trap.c rename to libcpu/arm/cortex-a7/trap.c diff --git a/bsp/raspi2/cpu/vector_gcc.S b/libcpu/arm/cortex-a7/vector_gcc.S similarity index 100% rename from bsp/raspi2/cpu/vector_gcc.S rename to libcpu/arm/cortex-a7/vector_gcc.S -- Gitee From c8e4bca1fc2d7765b3ccb5b7cb95c8adc43e88d7 Mon Sep 17 00:00:00 2001 From: bigmagic Date: Fri, 10 Jan 2020 14:14:37 +0800 Subject: [PATCH 052/110] fix some bug --- bsp/raspberry-pi/raspi3-32/driver/drv_fb.c | 3 ++- bsp/raspberry-pi/raspi3-32/driver/drv_fb.h | 1 - bsp/raspberry-pi/raspi3-64/kernel8.img | Bin 163872 -> 163920 bytes bsp/raspberry-pi/raspi3-64/rtconfig.py | 3 --- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_fb.c b/bsp/raspberry-pi/raspi3-32/driver/drv_fb.c index a24ca63377..f15fa12fb4 100644 --- a/bsp/raspberry-pi/raspi3-32/driver/drv_fb.c +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_fb.c @@ -429,7 +429,7 @@ void print_fb_info() rt_kprintf("call mbox:%x,%x,%x,%x,%x\n", mbox[0], mbox[1], mbox[2], mbox[3], mbox[4]); } -void hdmi_fb_init() +int hdmi_fb_init() { unsigned int *mbox = (unsigned int*) MBOX_ADDR; mbox[0] = 35 * 4; @@ -503,6 +503,7 @@ void hdmi_fb_init() _hdmi_info.height = _hdmi.fb.height; _hdmi_info.framebuffer = (rt_uint8_t *) _hdmi.fb.addr; } + return 0; } INIT_DEVICE_EXPORT(hdmi_fb_init); diff --git a/bsp/raspberry-pi/raspi3-32/driver/drv_fb.h b/bsp/raspberry-pi/raspi3-32/driver/drv_fb.h index b11589e769..4926fa3ab1 100644 --- a/bsp/raspberry-pi/raspi3-32/driver/drv_fb.h +++ b/bsp/raspberry-pi/raspi3-32/driver/drv_fb.h @@ -55,6 +55,5 @@ struct rt_hdmi_fb_device fb_t fb_info; void print_fb_info(); -void hdmi_fb_init(); #endif/* __DRV_FB_H__ */ diff --git a/bsp/raspberry-pi/raspi3-64/kernel8.img b/bsp/raspberry-pi/raspi3-64/kernel8.img index d1e9d50822eab7049392ad0a707bc93d8176db52..86b1df4fbcf7d1733ec498fa4a928ae751f3ea35 100755 GIT binary patch delta 11540 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 LFJ!;glga-ByZ3{l diff --git a/bsp/raspberry-pi/raspi3-64/rtconfig.py b/bsp/raspberry-pi/raspi3-64/rtconfig.py index 54d5988b64..e376665083 100644 --- a/bsp/raspberry-pi/raspi3-64/rtconfig.py +++ b/bsp/raspberry-pi/raspi3-64/rtconfig.py @@ -16,9 +16,6 @@ if os.getenv('RTT_CC'): PLATFORM = 'gcc' EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/' -if os.getenv('RTT_EXEC_PATH'): - EXEC_PATH = os.getenv('RTT_EXEC_PATH') - BUILD = 'debug' if PLATFORM == 'gcc': -- Gitee From 464f1cf5faabb0bc9e84f10f6cc0cb85ba8c8075 Mon Sep 17 00:00:00 2001 From: bigmagic Date: Fri, 10 Jan 2020 14:40:27 +0800 Subject: [PATCH 053/110] fix compile warning --- bsp/raspberry-pi/raspi3-64/.cproject | 150 --------------------------- bsp/raspberry-pi/raspi3-64/.project | 54 ---------- 2 files changed, 204 deletions(-) delete mode 100644 bsp/raspberry-pi/raspi3-64/.cproject delete mode 100644 bsp/raspberry-pi/raspi3-64/.project diff --git a/bsp/raspberry-pi/raspi3-64/.cproject b/bsp/raspberry-pi/raspi3-64/.cproject deleted file mode 100644 index 403db1205c..0000000000 --- a/bsp/raspberry-pi/raspi3-64/.cproject +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bsp/raspberry-pi/raspi3-64/.project b/bsp/raspberry-pi/raspi3-64/.project deleted file mode 100644 index 16586966cc..0000000000 --- a/bsp/raspberry-pi/raspi3-64/.project +++ /dev/null @@ -1,54 +0,0 @@ - - - raspi2 - - - - - - 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.core.rttnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - - - rt-thread - 2 - virtual:/virtual - - - rt-thread/components - 2 - $%7BPARENT-2-PROJECT_LOC%7D/components - - - rt-thread/include - 2 - $%7BPARENT-2-PROJECT_LOC%7D/include - - - rt-thread/libcpu - 2 - $%7BPARENT-2-PROJECT_LOC%7D/libcpu - - - rt-thread/src - 2 - $%7BPARENT-2-PROJECT_LOC%7D/src - - - -- Gitee From 2fbe05d7fc7c8219e221fbc548d3712a979f0749 Mon Sep 17 00:00:00 2001 From: bigmagic Date: Fri, 10 Jan 2020 20:48:25 +0800 Subject: [PATCH 054/110] [bsp/raspi] remove "kernel8.img" from bsp --- bsp/raspberry-pi/raspi3-64/kernel8.img | Bin 163920 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 bsp/raspberry-pi/raspi3-64/kernel8.img diff --git a/bsp/raspberry-pi/raspi3-64/kernel8.img b/bsp/raspberry-pi/raspi3-64/kernel8.img deleted file mode 100755 index 86b1df4fbcf7d1733ec498fa4a928ae751f3ea35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163920 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%0Aqgx`D|`^A4ovxB_+H_@}v*{67^XXp~$ z`S3i6m_fgiwR|bSR5^=(+KHT3gHH2fczlp=Lf-@(@VQ)mBw04ZSLlMbe%@0u-@KD^ z^Y$J+ZNI7S=_8-|yXvX;XZ_hB$>=Wnw6oICI>0@@zy4S^a*|G_d)a=Ca+8nvk$ij{ zHMt^hmp#N!&P%{Gj#ME89@j{aSWuba3p<~WnZdHc&5Gl^Z=qqhD6uXlM~OR09(`F8vU zNxYXn^gRIjU7xex>n#jjxM%og8#kz1{gdW+zaYHyRnfNzbUl$P?>m?bk2C#sRN5l` z_$^g_BfF|Ix++iE?Iy|7mkH1L!kLCa2ko*il|idu6#D~=^{qPZAKiy~SUqEJ1B_*F zOu-u*wDfAs@;I#w*cvUqpF(KIbHG0kXyNxG4n#{;V|$>@)3QJ~krDALt|G50vWdvS z1ZQRNr@m@(qg`Ti$WXG-*erQ+-z{3wxO_gR{A*Nvw6pw6bjgP4FE4oElnk)3qj)xd z1h>J6PSb1R13CFN`hJM-UQ(8m#<Z$ybs%_+?wAHJRhI2d(Qcv%e}^>m68qZo-Id! z{(S|F36r6db3S@5^ZQ27YB>V&X+hG*3Gp%DH8{SDuDn3JsxB&@pxl|Wv?s)Kftjy< zg->u^CI;sg)ZnH8=g-9^aGdw3;mgwlkHhQMPFW85I?Pb zwS+gzmyOQ81@RN1+<*Js%F7GlpNDckz9AEjhn)WXG(b-bk?RuZ`6Z}R#7GR1|Y1-Q) zBg&rC`#6lV6~;Z)Z<0MyJ{y0@V>g!xj(DqaF`AUXInHxM{HdH=C&>x;jVhhvwzA_r zP5PD-FwCRuYB=)TgG)I0>v#Trk9Lh0Do2i0`qy`_L{Ee~O=gu7^>;kEryGB|a7U66^5V5aJ2RH|?Yq!5^sP2p41QbyYk#2pN`8fB+huUL{wC{O~V7S-XM6lzJiXY*ZJgBSZ z%BeHZnfJ4TEuI-<=Y6{?8O!?hjZX9`TkGe1klica4}2f%`^e)*nq z%_hWOou<_La-OC@kI7o?eJn15PqD&crOG7>-scj1g<#8)1!dAb-+Z&*h6%LQ<&S=(7!))K{1I^zb=wAfxpWaYkhY`8WNTA999_{-qsqs$o#7?KZ z$=lk(j6GJd5!r=vC&l|J=o_8cbK#`;7d$6*C&xeIUiw^$K4rg`czhxM8=xQ6yVQK5 zqOz1dtxoKGU$38|BA3<5#|F-}F`?h*X8rj?Zd~53m}a>eGT};omE?RgxYExF&;eh| z8~h}n$a+9_4@@4Iz}r^?FZq+>uY`Mda(svQ!ls~QhS8cCw=Gt9|7ZdKAhZOVSKO4H zn=N^m>A<9UUJTFHCgVq<@9DkGe8bOK{kM|jA9~-ObIe1-uA6C7Gi^w-N-lnSZ+K{O!!sapz*}UyWrdK zoAzxR?|hxc*b3jp5v{#1*|uDGjpvk)Z;}kbZ!wm7`@Ty<{_#)tEj-JCmbzM;X-|Ci zKCMf<^MAtMGU}Gq_3}FD1AHpawe~G%-Daq)HB|ESKC$)8(f@Y?;ye_e@Z)RGv%aMbo~Q5 zV_jQo+$OJzawOo5Z_4gXa^W7$=R>=at-G8O->dZw@)S2|#*$G&!PSruCoz|J*gwWPX`*ZM8K~zovYb&;OBP|^| zEkSEFv9@?&YHF(i+S(f13QTRsw&OVg(Mm6(BE&-T`+V2l>ztiKg3kP(|MUOndGegS z*Iw&g?|r@NU2CtcXCB||wskUR2Ro=UKs1w&5=>j3Jv;az5&4|}6$T?3t z3&)=vYyeJGxAl}K3Ub!kk?J}eeh~W1rHYRVFq$R@p9O}UFWzT@F}%MjzORMvIqnnO ziw_P4-{{$pTZz0@hVr6(f$9}_m75$~C)%Rt^}Gw}+MY_=qbq(I(O1M%aEHk^0}L!|E7@svo!wPlx?+sgy*i0 z7gg_i;_&NzTepUF2%as_y@j8f5}XcvJJ*U}J*Tri=u0u2gR_%s;g|)-BJVaAWNc%G z)$l~NiLB>Fv~`m)-|Rk-zCI@Y%}oZ*HY<^Fo_pDk%FY+gfALy#f2nP)B8L0|xr?qh z87uyROsJO_Xsq7bZx3>=$fLAZy_9kq@#p&1FV9=tbL9tl&O5oGor34Ld7nH7?A)8B zvYr}rFn6`_Y`hI}*`zkYV9kI}XIMS)3O?jF_UCNkNkd~U-kF(u26>V{u1t0K14c29pz#QYlabD z|46PvJpU-NI=bSe$R1*GAo(r%hF_ir-m!Irdf6J~S_4;%Ylx5B^J1J@^z+hW|0=jK|7gdQO`3O`sX5?SUA6aB_PziY+5DdfE-#JSd8+fV zMHr`+z<6H>BZOa^*W3H>I}uF<`JNm6Gx*tcldykVKdZTly${bE%E}g@QQy0;^nzEV zbS5@l2p=nFe9FbZlz(82)Q*S0{hR9go%fS((z?BTf#Cg$a;sCZzH(7t>tcN!(%AwR zp`RC(>hzT0EczM&OshjY*O^kRzgqYMq%&OKLBBSpS3hMTO$EIJmz8Q0;nW3Al83wh zEBD2*BbslYjQnee_gJH{=W`|TrR+bD&b*JdR)@&ZU<(KG(k;e3UEBOK`lYq4fw6k_ zd?fgxJdoutHvR~QbbH9f#vHn82O$%P6++OFV1;6In^=I=iHKAW_jOdY1^jQDf$JrO% z=l?MtL1#QKl&9@>#y$1n<<7T0&zR}KH<00zf@AqOin*`poG$)U$reN2rDF4H@v=$r zN%VXe{*d^&mE5Z;Gpq zXibItABt;=^ljHDd9K{4Vi?5>(jEO4e3NkG%qSbLt4*XUf}iZ{TJROojjWEzpGe2h zC!Lj4;0yDNO7UedFr&EEmtWAmbO$^IcbjCSGI%GQ>=)r=%Y+MX?0f$)TpEZcu2)~^ zQqkv?@Oc|5O*^m_Y{NS6NWP?o9b!I{WX{kS?ErFAmXgE6X8g)M$+^p(&y(HuU( zeoI$8wrgSHnO%=cEX|3Q!hLwYVHP|1wD_R%fvo+!#2Uy;;rdlQ_4VA2$>5r&96hbJ zb+H%0MaC2D{kZVn{L_dl)0)c)-sw@%R--WaoNEF5N9&*Gdo62EFi()b3W@ zgg+ycOJ+u}hc?s;eUq(o>295qmOB@jo{KDQ>31d1mu`;1F~IT0`RfEL$+xAg4N*75 zV@B``U`n^t-lM&K6XQ&!t=|^)-83Wk5%usT?0<6SYHtnWEX`r@5gq8LJttB+e>wm1 z_3%}6NuFJdGcKp~^B+Nb$++X=AOFn$Ci=%@7gX7Ck0&qnxsUHpmq5i1#1pC9t|d7VR$yV7(H7j0LD zIw#ulf^m5$H>*cH)BM)zi0Ub40A25l33=T}{U-WaNne*cSn^N6&Z})wXC8!O8acB9 zY>lI(&$mIB#<@=cOLQB?xzo@)jg9s`H8U8)y}f39tKxd9`UGF`!P+u%@z4>KvCeOQ z6~lOpbCX0n*P^pYJfx0vryjlDjZUgO2R(hMm$2ui5NlHBWN1}<;$+?}$If%*8^r$> z!HnR8V*&oOACq4>*d69OX|rCr6xozw);_`w8a{~ZWCKT6v`4XT_pw;xgLLXX>*t{l z-Ux5$pJe{NNapVc=CA29D$gTdA0GdR zy`9vt`gt39A;p>Y-pmSa=H6bTpEq$WSxOc+fQRDE!IDA5zkE%$)hw$&EZ9~SCFRzy zA@8b4E=KxA3}>{~3oKnL_95?3@MrehCQm05Hqd1nt=6B4?6xS*z|LC`{1J3E$qXsD;3u$ByTr2xQ+QmRks{bYaxHobuIIQg{C#+ z$N53WeJ0TPBbhS4*)KEA8T8zjkHNRvm=nBzuKCJU$mXgr)^5WtZTnnx@aBsl-RDaO z$i+r+YG>*e^EJLruDu!u_%``QbL5hH7}IS&dX(y(iw+z)`M?(>Pp)aV-;DFurTO>f zHNHsyE#|G;c55$}(H_%MSkR$%$CT4YPiK*S0YB|x-+i>pEksXs{w(y{b6U?N#|-{2 zGsoFW-{MIJ`G7p%G_th%=LJuMv=T2o6Zx@63Vh9TCU-{z@xmue=iVizlXImz_g!x~ zU%3f<250BwhiB(>jLOd0QdI6pTzlno2L);E3G*7ZB@(Jy;ipNn8=9-ww#uzhNM z^q1Z95mmsd@>?&{bK;-4FE-%x{RqxL!9g#_D-K|NTi46fMr+m)4Y>)~*6+morOvg~ zfhKt9bT}Fdph4>u9r!NMa<*XMn_ax6u|WNAjNoa$(SdH}2m7{8gYe*c8@ZWb|2A&G zuU{!RGqbIC#qps0gSI@rKHM`N1A4(@Suc3}rWZWUiSW3l1dlV1!6Wh;$U!#UF)EbD zYx+h=5Ayg>2yfktP_EW@S|2hBKCrJS6Y7JNiDD7!tC54&h2<|&n%mINiIF_*xtXzY zJIAKJ2cAug6X!+!+59o}WZ#z8)Hw`}s&h_MNB-3MB%W<|dJ^e}YqMW;p(o>_Hda5W z|FX(~U(}QC{?z%pxyr%B^k23keIFRY<8#SjJkk>!`Q%fCR}byYduSi`xh=iG`SY&O zhJ}ap`WQSSIm_mj_9EloM=;>^kZ3$#uHS7l?$&-7YkMZzyU-|k^NjmeZ`r^~UE4bL zm;E7bebkl1>%w<~RVLrhZHIjm#_&;ic9u#@; zT{rJ)W!}}=f#2MN-`u+bKe`e>x*9)v2l(JWIp=at2mW&p{&O$>^JVc0k^s6i*9bAA;gyb!e?E#JVijOrn~grA+yT>82^K2GC( ztHzmF|1M5gYwP=+pVu#bb9)5O?vtV2S<+8_8>4zF`3>oHIg_GamOuTm>c{$V{`lK5 zI=l0$NGE3kcb2IiH;%{X{P(c^E}NHUj6Y5Fkh@z4%i*iCqEWF(B)k2}HPmKzttW1a z#}eB#Mo|B4)#vvTV2R#U)b)r>6mwj3D!E&J^Yq0$+xi1veNyK35Y4tY_?_qJ7u~o% z!m&69DAFe0F!yOa{6=?NTwJp_YI~mKsJdl!cFfMnpXZ(uSsy-qbgnyAo-StO2`mWmbVAG?bK5gC%xp~@iCb;lQ zyh$6=UfNHNm{Ky{DVW5H#WAPYuk|H@L*I9o^xX*EiaU=yAHFAM?HPDqgg=bOOZP{7 zwKR)XXtXqo7u0(Ucs=!L@ua^Sdg(70^@l$05}fPaV}BdorN4hH>CfrkkLVA(EbP0S z>}-j?SJ^h$mwut~zcg=-Y|Pp>y8n38{@vm&cxH3LA3G54ukzT3lGUDxw%I}E*IgTy zQ7->*W~5g?#ty4Y*@0&GoWW;rjQY_!y=;NHyM|gj4CO5NqDghX6xAI;-46g)eB8^r znbiq&L3OuDew2R`nm!WtU1|4&@O%qnPa=g)@VrU;+`#o=yGHAGewF$kjBqW=_j}#u zgIe2H>>!@$Y^aOOdywlcDX4m=Iw=z4(BLnfnq== zO+s4b4UB90$dpVVQlVBbMWyRo1LoELG% zb+`7}Il+h29$x+`%8SU(EIhT3>40=+75lrowTI^St35ig`DuPj{Jq7U_aUUu(w!_e zQ9lj44@Wsn;4#k=KK7Zd$C^!^vKp;{>b)=3)w^iq zpFaH?V8!;_HYwjs9?J6>GxbZ3U%$Kuuw3oD*{0H#4>8MydmIm&zf|A8*=cRpwg(UO z7rh&tM_v}@d&IYqJZwMsBR=N^FOtb@C+mpMCq6};n9S?pozI>}yOx2B$?aKP%trZf zk9)zi@5l%?bp+eWlbpKvC*3928^tHWJ8Yx8tj7De&Y)Y?k5`Q_kJO^a(i`PE>iLz9 z-7WlLIu@_LO>JX1sI86fDdSuVa>vrW@IAAhzQTX0 z?OdZn;XIvdJ5RU2v3Yu|-0oxMUUPHdI8!o+`g-_>&=>R9In8%fx6o&_Pa64~R5-89 zM|4{p%;2f2FC6Tg$<>SACDSuoudGJ-la6 zY-^TyLAh_`CH2hNL>hT{TJM*h<7?ovy>3j|>*Xp}3@-ajaIX8&Um{Q7p-1+d3c(hx zHN@<7niE7gF`ikR=&Qf%Gd)D_33^M$@}9NDAG|Fb{D$fj{0IId!goISj&ko{+jxRF z0=S*}MvM9^#uMS$9a+U|*_xn(m{fXLJU`^vF@2Bb>BuXto6@@kXXgXwc`s8Yzxuo} z$zc1hpc$QTJd<2`X7gG2zXKVr>2H^vb4c%I!7J7)Ebn;t(9HJNfw%o8uhvT}t>U-d z86%b|jvwzG&kh$OH5Kvv>i+`Iq{a%#7(6}jwAYNg!Wq4?IA_4QS3G0!TPZI)_`ZeZ zCEo{jyu7vt9Hry%Z(W>!N%_?GfS34QgM$xf}K#e_VK` zcO6~5Msz6cCj;sh%49R%tk}K$(KOS!2px-Ja0_$751ih)HG~Ks@(#R<&AIO6zhXE^ zPn?ga3*(S2UaF6HwZ)jSU>v-1c&V=2|Imb;#moD!FJdn^?Ez2TM`+DYw%_KlI5kD< zb8VJS4zDPt$ByD~94?DavU1zv@!cbbi&u(EwC3!W;F6%+`n8Df(s%jJu>bDgTC($l z;XUJU@5vDkxgrj^|19B0w62;d!68X`$8h)nPaJ*H;p5_gKX7&9a!G`77H1WmP~gQ= zC3r|zH76?VulrhO_jy!LeRa6Lvc-M^xYO@@Io~Rajd{6>NT%h%2cUln=YH5&485UltBnnak$-A&$s^TN87w^ao1P_B4yui!-Ze316G zFOvxJSL&T1k1add`OCB)T{uvFrQWB<$GG`i@xF5_e}@$-0Gn0 zgcyF3`al;|R?rV(+3k^TY}TBLd-)*E&xgwHCRkc_x>zy6*lhO#puh5=vMo5PCg;bnUdcHh=7@>~6a)UK`#(LVGoo-1$a7aXBn>w`M0 z0h?%@+R86;6!=x}Ns94BbA1@&%|9C+eMq=qN64bpD1UiHDqPPaKPXvFgAY2Nk33j6 z-Ul{!{Wu*qwvCwkro4{blJ%NX(YT+hCvD1Vci>~~%jp4-tmQ}1=n^gF)~?4Oex zdOYgG*{kdvT(wuD^ASCxuLk;%-W2!NbRWm!h{RVoD!fiK@^-l0=& zIacQMr~}@rzHIe8`YYmg?EKE1KVkcUK9>&$Upp6T6WulFWKC#C_S=%+Z)ImH!?7B^ z`C6N&p4~$#--7P&eqtqX<{#18Le!q~4;JY9csPkaj_z*wK+jI_DYh-1NhiOq`~-W? zqcK!|3thx_IbFOre79kXXDSQ2xL-O$9qVUfI?0~(*4(8b&FGEx`r3U%=v3%)p-;9n zT0Q{0j1LU>XU}Gk4Zs8TOD?y5mRy5mRxcavq1=ngnP1r$tWo_b$D#MlLVwozFz?-~ z%;h7F$+syd0pA?0i$+FqQff#@Yv#mYi)bZpAvq0~-ipu6>paE?U8fiybY@D9vr)8` z?#thCZNDu|%;70d!!I^#-$@ZHuKyn1g>6pfTWG?aa`0H{A#3FeWou41^T=M$Q+!jm zD8~}LETN@ibVN(8NXxA;T6CV5#Y?$HaA*`iMcdzzM=&F;j#|7TdNsG$Os+|FKQPDhGp{ z*k|fj+chCqPVTLcFC*Vx=u7;)1)W%Y$!(lnrBEC0SeX@N218btvOY7@I$2|BD^Y@L|ecgnT zcBzws-_lNF)4S=A+nZwTAHNtJiG7Q_Cwq!$ti^_U)~zt-*kp4xQv+mVWx5UB4|VCJ zU>CVkd);(W@Jn~i`1c&wu3Z}cj9uIB`WEw*#XSIajFfLH9oNr{c#*Nb^lpO=epNh# zckKPQW2SUSI#wCl}4hs(jkuE2`#& zzcy!vJqd;{+~r4+;T2Y+kaJu)R2&Yu!Kfr0G z!%4b3S^h8lzNF$Q%kztiW!456=f5w0+qy%ouk2noEOT|gTc{g;>#}>@u*}u{W})t| z9^i&$uI|4T>W2P$o70h)56@6$D#94h;!Cc;`XOZC{T=?r#vPH&bVjtLDZ*3tdS0S) z#y7!y`P>ryUUg{+Z_)3Z)*htaw6VXMt8!n+6_>zP{#x-*E}3ju{L`?lU9Y5#^@sYE z{{ydl2sfN>Sei#nJ%%=PNBMH?z3|8IGY`FRY@P{)g|hKIzQ9Ah<4VGIKC|#-d)E9H>L+^=>cWZgCZUw zuL^i*EGyCPj)f(7Aj8um{eHmV5trYxp}pgQ{Ni}@$ZPs{`&r!Dm*dIyh6tCYBH#N6 z7vgKxk&h5eH_lpFU@xIwMfNTKMt%ACypsYG@c&g6AW`6P_vG zLXODJGn9jL*V@Nu=ZvxWWCovU^;`9slQ+qi=$dmF4ReDU>AvJ($COc_eanwsY?jx> zpDi01>Q40R{K#g6Z%*F}ki5uW0b6-a8$VjxJ(K&GPo=*l*8Wv4J0yn92q$!7f?!e( z4PhQ}Ht=HgnnbJaqw&}32=^Lyhtal+82bw4X=LY=KMmh=io3C`%Tx}IdE!_PpKpCq z1WW$7FyE%k+9C3A^BsID<9RQ8B$(%v+QOK-BH3jl*=0@)>YVI^oBTs6jG48DXzz8F z9p#P8A=0^lcI{C2`TpR`Iw9AsipQ;O;FtAm^j2t6jNsb&0|IXx_xPcrO~mHcT3;Zq zW|W`D|7GF3bb?&y0=?6WeTL@~!l%+XOP;#-1`%Dkh%Wrz0MVuT$i&V;xlYNCY3`%E z9dpnWI{2FMW^PX7<|o8(ZhoRUKw7bY=BJvY=vjP@qCG;A9p$#a5}hi{QR4Lk$HlLj z2S@ka;6`&A8$)XxS0A)FZXdK6B;A7VPe2#B=HZ20)QHgE8EoR=IL*R4hR;~}5ZzO5 zfPetsGg03qxOC*4tDymPJKsXR#Ox=>YYn#1C+~VtWTBfVq?n>c<0FJy=W@t zD#G02m8|b5cP==xed&;{Yl)G_^{warZsQLNzHv%)ogEf@jcas^{HM!3cGtzhPJ%Ff9wor;m;Wls$))`1UN_qFw%e{ndc zX=m|ho22<&CwShS25y>buguuK zqiwvM)&DE(I(j#{+u(Uqj29D!={r85uPEw9VIF(jwxhbWb>GAZ+b-js`{LX+mdB2K z)|U?Gd8j|7`+|9&)#~H6f#Ez@e$4IbDb$VDFxWfMDt+y-Zfs4u+w-~Mp5tz?v=;X+ zaHR8Yt*EeuR8Ifpp?uqAJGw@>Q8=l?r zk5L@5XDqPChWj2AC)@+yt>4Di6~~kwax;ui){ikZRcOyT`N`wvh&68NeK_6~%PVI? zyFIVJOFM@nd1AMJK{%cUjz)VXqp`JDJn>sLW}vV8L{|xp1sS1F$ZnUDT{k{4kLrlQ zdF)-_l*njZ5oR$@p}e=^-n#{BGJKm{e19;GQwglfBCMD^df`zQyzQAsAs$`Ol+jr? z{_x=M9|MorTthw}*ASlBY3HoOfJ2ErDj%gD{pFEC?!LR{XXdoT_8|7Tk~Q@C=9a{$ z6yuY0!*r~%`v<*?KesFIHN8Q3JLN4+@-LiKCx0mU@D5=Co?qD0*vFn*q&C#sS!jdr z4aX_B223B9{d-P_sc+^mmLx4*JOqVzh}+T!pX*RZ`6H~^#E6H{UW)wUq2Gc z#+D0L{C5X(a&(vCnb!VD`uE(}KpU-*cS@*(Eag29l?(SUYH+E&N`N11aH|%~RJ7Vt} zsax9EPdab6WMu1VY@(gprx5p%MVl+~-|6*!#SAfhYLq@fL!46oQr3oI{36L>~ZS|ePN5$v!>xe{j;on zpBw34Tcm$xL@-Bd=9;%eeqAt~P3yWXSv)&cX9G!gS!B0?YZrqt4zzgi(e{-Z5xk$i z#M@7@kAFP-RRmvpB3QN`#y_8YgX_nYA*)u^bLB@@6zOiVkb>=+zk>_;= zpX!>|{c2;XD((CRozFX1{<-$MDi$u+n%BnraD0uIB?gA?3%WKRCx&&`Q)z!I-y5Wz zJ%d2y3E*brUveYtd7)#-couJ;qW!jVYj4XPoN&K~<7pU&#rY|| zh=;4#>z5I2sZo|jy({)b^ekT2^1iHgw|IX{9EV-R>pHlLSj)9=IonFVg1amRS3VZs zgkGA;1aMQx*Edz?rd~JI-R&>L{Y2u+_u6-Y^*7shuGsfS-nDPjYu`Q5ckdX-x6uXq z{8%4Fo%MU>n;Vm}rvz9047;vC=a}o%NB;B6{muG0_;;JTzzuIHRyraZH5ZrL{Vop1G@f_2xuRdU_2^ z!M@igxQXc8W#!P9ofO(l?j+t%BGws!UFbZ2Lmj@``>T1!9lGsk>{IeDx2 z_s|vSnyx<;`u2Ex8>h`Ot#>30-`|am3A3n=&Ey$3!?vCs7vgnlB`?}83)^mS<4F}| zI9S0el#%DM^R>oPIFmhAuDTX}nYVN^`L6ggb4w_HpPW#<99b<-qX%htCmF_{CDAc= zFF)w6tQcX^o}W zck1G@ZaDoJxlAtQ5qM9e%+g)~Z#h3Z4qLR--^6ZZk^a|^3)Wc;@n;cF205M#D&;?I zr3+cVq#fmPIR9_*bwdw)<>NyCYrcLJzW$dN@o=EGv=%=Rr^Q?x`r1@A?|$o@h}kb#m?cB%?k0h6--1Ru@6C5=jC@1M?ya%{(U)~L8@DUDru6M$g@a}2% z=jFlK@U^t;Rs0t1-n0H+?{Gij*?hUx^A!7{827rv4rSCfse8ExZwqq4#^P;CW!CK( z?c(>+0mdy|pz%LBf_=Q!$rPKaoqTPHe}9ZMg6lb7U*nI*+Eq7v>|DhZ z<||k>3l)fF5)OpI8_lO6ick zow236KQGm{D#n#%N5gfu&qTjBM8BLzV%OvTHTvay4)*?2{Mvj6xqEn}^$*VWo*LxI zqkH5c?0p;e$?#rrtILNR(=J!i&Yat0JC{dMeiit4d#QopT#)nIe@}dC%UIjjuigpo*IY)gHKa33S+=(uQ`IABnv6sGB3se31s^=NbAx@UH+)eHieC7|p$GH6*ZRmjF zeBof{qvWp-vTu$43+sH2XUba(U-6kS?3j1#?79jvvF~J4M|jz_Nnom-?rk1Gew|!` zaEQaR=T49(aBDtCSA_WhOKWCy&=~S%S1~sbK2I=ifp4t5n8(weXWO25cq#4GzelW| zr+;W(n(pda(0z^_%fW9l)mkIiqq)l_zxrkJd@gTk^j?tG?8#dy2P>J{YwEElt=e8| zPFEI{V`ttF;835v0?{7NA4Pj)i)V!>*Q&E`t$e6wc{D`6AlmaGp84T^3&~4#&xJlwQqg01k4ktczD zALj+$R~96(E4_!9hA*qJRl|MmTCcU^N#I>u8~Mcd1$%WKHup=YWA!L?YVeZEfMLh& zXISsyS&n|X?(kY~6J2*SM(6e>?YX^{pO2Z&uLKQqs!n0H=_zKUg?dutNo5n(aso+aIvv`ezhNq)%tUnE&+I!7?PS*w7{$=gs0oHjxO#ctq zn1S&o9gJ4L+}}r?5Z5umaFqeW+Q&lPW#k#Yr?cyOrq%kY?`6B4Yi;f0a?`n6=L}s6 zUoMBvf_>;)@sWL8>UaKvI+MjKuG>|gx}1k%_guA=u5}&~6+}O=E&rbpE{BQJ0M?AzisKL7sB?t={1J$AfFe20I1! zdy&tB7rE8wH2278$&y3p47>vO1L?Ozoe96`_*|qnJ;=--+oQ}Hk=bS7(xc2WV}tJs z59rl5x~};=2w#0wwTO@Ou>#L z8N9~xUgeb?7pxHOQQgyH^16|7?JZ(_2=xG%-F&5!d2U>AjbQX5n=^U0#mOe$qih~4 z*waDw6?Apn+@%Lr7MbzEMG-E)piU^C(}Fsc z0mItVC;09=&vNv`_||%sc>7FbQ}m^?;;l`6*mV9)=YU;_ePFi*n;KhJw5coo&Q9u_ zA{bo1t@_l>VUKUhwq%Q(_lEtn*z4!~>VvW+m17@#hhoDk-0w>co%k}}EG=UUD%g~x zDSKK_Dg2*_bRV2^_n`aSOZU&zIY7`P-Os~o#T3&0gM&4m|2)$FUU-~4tw$bjhR6CY zWRE;H6M{c)2Osde(eb!xLhuKb#dy3i#^Xzm!{htk1CN`iGc)4x*JC_(e4IdEvVnT? z3kAO45cw_f`d|I!alVhI{yzBrGJNmm#~ja7rw3a_Pb8;B&eri`-=%yAxV)Es`oCL0 z+0%ossh?hCy99f2vP~cCO}0Jww%qAG`nGMzbvQWn=-X0f1j~dAcHPAs$J$QQ8Nu}` zi}|*3w0FMkc;nGz$?09jqlwgU=n?RcT)T}&%es$8k5Z>s|7IozbA^B8 z-(ClIOBZsSLwUFHs08l69}jM3VsMt=qA$cz57CwP{lpDyALJB~aM z`8xV4_&Q>M9h{>^+#LFP7eCw=iy!9toljB6#Hc2e03x#vgvo zB)>JZvm|zwD8|{2hRmekx6D7KbC!?bn7ba|#=U&oL-K9VAm3KcH|ylvir*M2;bD&N z38QcMx$tmqk%t~WRo~^bJp2+oB=*UFDdHjD_#9TTkz8QwE>HGbgDlTR96KmtCN4)NHa1Ua z?&EmkpB;Qg^a~gI7#p*hf2F(<-2WfJZ#z5q7r~Fqd`VH}d@rLQ^E}^GJ+938UUE-% zQwu%6=l!i7?ItrhxIq1*gFmKD7$Zyxs#O-Vo7eRIS7bL+<1#O?n}gbi^e%SuI(76; zsAT;o)i1RhKeCs3erxE`bz*;cJ$v}G*kTA}<6WghpI2br1Jzc*3e zx>DXJyby*-ir@tZwxx&ix%p5@)!JS&!y)47H(#Ca2s$F z(4={-eV)N*0^9aQ?l(S9zK=a4p&o>Lq*9DY;hwx`FATXr<=udNw`rOkd?Lh|d47cR zaMP*%Et-D|=j|cRMWB z`NY-WZE+&sTSq%+ASdhgUlenk!hN3f)joIoz`8$g2y>^jch5`CLx6X}UAa5Gf2Fg@ z?h(xs?ATSUU!(jC&skFmuc>Ftm8;1X-boYv)m5woD<8!Ag594gdhXMCBUQi~XAXP- zA0P62PS79P?Dv4x-zZ?~n^(v@rM(dFQe&8{o4Oz{)U|bl3%ScY^#xP#$Fdga`1SVF zT^scM#d!a#Si>sd`#EB5y@%WzUBHavk*A)g9IwjNH~i7NY6W=z>V;=rMDQ#R=pzpg zdhMgPzEv(B(!QyLhti2SO=I-V9`&)AUS*UPp6`JkJ6^vVPRKbWJ$E=F=TaQ^=$wR@ z-0P?xzi%KXrt@}XyYlt=E!Z-67T-rH?p4#-Rb9-jvo`-$w99d#4ZZEjE@!Zw3SVsO z?d;NEm-*q@R^@)BV`sTKk?mT4Gn|-ZM7W-r3U#nraJEU7ve^phbolO}^*<^*jvXie zir(9~th3$dd+6A`dkrAFbYd!dm3xcuIeQ;JC`I?T>I++WC zk<<}SZLB3d1+L8nUS6;#YpWT_g#J{oK%b^_JsTTJbcqAz7?)}`Ek9IE_(l4c_w07#jmurdm`0`_SxFHigl^4 z=X%%8_Ia|k#a8O!&z?OduPT3Nb(wnBR^{9J+v}Zn4NB#a&&uI5?D!G+tc>od8>3_X z1mSW|gg4Jr|4Y#9@WmEdZEVCdhu<%~Q1|LXp3S$uf_C!tRzA`h$%p$$H;X=0&xDV3 zPWW)ob+z=>>O%H{;Hjsqzpr%Tfm?f{|IS>waO{Bx$*51&aXg?8=|WD=qCRudbDm=h z)vmmTxeV`cFAxrbkIu9g*XhDD=CqGn^mNVSU*klG_kr9<^d^1^p6i01QrF^4**6MsxzBQFQ8Fa+n-@22Yye&uI6CTX&jV)D7Wo+eKw5?dRm$uEEi_`m?fj zeZ>2xk6Nv5L@@e-Z=SZP7%mB}J7|+e4xZ$1VTX3PS$Y9n(I+~8{WAQ5@41;FewH@M zH!zpJS-ilnI$WKcw@L2Q?^0XI3!g5zG`Vq7XMMY|H+MmhM(5sw4_d!dy8|WdvO2c{ z7=!gK9dNx7*;!jB$FBQb$O`yN)587Cu&-L-KpR7wPf}m&h3?+T^=KJ>BdQ}kxDeaZ zUX#N353Cw|)gt*>#RI_jjgwc@PfFt?ZLgpY3)hx=`xg<1h?cs2;ve5|E}_XsC*w4c zS?Wg9*W)xf9AiBD&mVSeaBG%Ue#1lC5$>GN+$nm*n;VkovBf>q^L$uut>jx68^Ldy z@T5%|xk|UtGT4lML{9gKVIWfL1^E!{mS@896;XK(-Y1Z)VkOldgiJ)YJ?{{j zUz4xo3_ugTbFi0w_kgcpCHU5X+8lUN`dWlx91NZfQ7%PiCj#qC{Gr}EdK;fE+e+}x zwY3kPUxiJ}K4cH7`!KfEb+T8j^C?dj-8ImNEr~|)ILEWx$>a#L(LPFD!(UJM)i#lWu^MCpvhxhZsWsOyj%N3$A6uMSJQ# z@5P4{&J}=9Tl8+yqTfYlG-DSgWo)kCpD6=gY<}DW9QH97X!5n+tgR;a=O5VI+uefk zQLb&w8o^B9w`|Pmhwv?J~1UYns12PdRdtj3nnvHAZs%Ey@+IT`S#) z#Rc0Uz15k)rvg)U@B!&Vgu`Ib99_$A-}pWFlVD#4e%Ou?_(ADQRV;o(mv`!Uyq)|d zICjhU&7~1@hW0Q#@?yuK1vbd6Y;^>!UZL??w8I%>k^g6V5g;L zy4M^}w8!XSyyz^~bAI7hc&=}(t)2^S@Uk((EOb>m)%`r??l~u?pJ^xSOd@y&Izrhc zf*)}$7?seK;#coNSv|w2+WbW1+r{tGeg|&o4m=&Cde+CH|KPM_ExZ(*qK|zSJW|Qv zeuqak8Ql9nz~g!G^gZLzgPk$XMLu$izAI;W!8b4(!C{c(3r*Umv`zjcX2U1#4d-OC z(RjIR&%#KR1^*h+QOtvN@1J_z`ds`j^_~3W>uev{vf#tC3H$34@Dln4I|jz^lz)E& zJqqRF@^Rhep%}ozFuZ>!pAgY3Jt?J4I@4G;IA$%x3}no(Q(+usHcA1gA!P>8t+aukasD=)H8#*5P{+Lkqlfd5`YAb~LG- zZIdbw{zhM;1hW)xpLg}Z`}+~zevA+DwQBEW!a9#cbv8S=+4A5G&MLO=yT|0PhrYVY zAl&rq zxyC;{p8u7m&wh{jt;+9$ugR+y9UjmBSo(_B0ha}JzB%xD^lD+&JMc5=mJjgP)tPc) zg>v@ZmA5PYO%B}l;P?^S9#q{-_QH3v=Kb$vm=CKT+4Y`e8S8r|wCKK;d&Zo#Y5tP~ z{pRr_{AQIm0y|!>VL;o9_w%o3xpKb$F)sU2<@wcL-9Yom4&gn|e_}lU)LEkOh4P(x zmgPD*#Gf^u|GF}88hGK&S@6l2K9>r{dth0&Dk+og90$IA_+JQ(eItHc3{OA6n0MM} zzxk78Q)b>ZZDn(_Ieo_I<7%7loOD}r#W=6IWzq%BCyX}D-=0>}?C@U*-}iw3Y3TYL z*@cI(#m)z^Rfpa4?PlN%p0(c5w(tp_wLZ{R^@N@!JoESmj@0hvS@j*SFPwGy)t{Wj z^XiJL&zSYV>s7N{d-XqYQeE?;X>*$!D{gCEGhn5~LHP8WlxQ9>E!n)e;)3RH4hV7T zi%gS$yk*^_X?}Cs^lh&*eb=5gx|VvT`Sfvhz?uuJA2rwci36WRejgw0HS77+;}Z7y zHItII&ZnlW3F{f}z^llhvEr6y)&1<~TW#IXjk~Q`b?=a;K6>YSJ2SM&m{kwgLH~p3Th?6A4aUpn{9oPvw+S=vA7Cn<#-}$z zLx#T8u3_)Z>oO)m`{cudS!c?2Hkd?Eg}#ryq5rQMjK>)XA>52H)DwQ);XgfuJX8#( zgV&H-zAg?kgqHwbBEoYvu;z4w_gVbRGpQese3^b1VuL$a8{CJke+=7)-r!!7+<(70 z?an6j7@EJGfmaT{J;^>Tt4tqgDBph{&%^%8*XsUW_#*$&kTpC1gS^hTEZ;s%Jb0aC zoOpG`y1NIIU4~zHqx`d5E^C68+NPKOZcj4VKK84r%f{c8`akpdeLueqqbFRphX4CV zPr2+T{4X7S|7Gh&f9tY_!z*{6^VHPK`f&cPe(xK%W8?S>DlWUvjJ@-|gxM;1rLbJv zb54EqvU8p~aM@Vu@AzBS$)`mudvQ0c&{YO+Xb@%`YXmivk{$dY2g1A<b?G-Q)hOT4KdAQ%%Jup|C+}v9@6;Wydm2jboe{Gq2o^B z-d5qilfwtTWXyq|47_8b!|~O$7yKn{g1-#<+{QZaZQy_2klUIU4+;I>7<|k;_)>A; z*4;Jz{5SrP-1OoZ@5D}rJ0X@KzgLmprnZ^`laO0tfZsgN zRJ31+oIcL)C-_}s#=rJsGvUrA=$4MHnR5F^!*?auAe%MFCU}uDu;Idg3_K{q=E||Ny{R8Amp%K-D>l8@2fNAj4R!4-@9=-rVaGZ2zYg3^0=HkJw}Z#ocdp_8esfaGGp0|A zY)by*kMKzRYDhh|aSi_s_?1jINwpLogI7fNW>cs&LgDJH|_!jp2hhkUdb-=?9W%5 z+kpeW)-5{J^|(oyooW6R3y{HzjU~#aSL78<;E@_KYzTjOXHTtFO6LdKNxq} z{XaO3-?99Tzw8>~8jWM};SX`$XZ((hmw4mvT*CirjA1K1bKw00KfCc0gYMYa<9H@` zz!hx4J?E)&EZm8VSAy3sHnyp6^{YO~*Y7;T>-X#uukULP{>$jd{dxzzjIT-I%gn%V zY+H4Ld3-!$cb{nNPBM1i&)D6UvHOyN{yM|>R?k>Fu94Wtlsz<7W49f*$3yq{%RWxO zKLNL&(C@g;mAij3?nfJcf*qYfyPrU#+A^*laP6AW>5q^8CT;fFHYYGXHUOs-)~nQ; z=k;B?1{~HfF7GWbYZqJ#pRrnTN9dE=Ud)uee{C+AjmGNiF3HvO@YkE|syxTu1GU=* zJ{sc^_=buB{u}kk|7>jK7f0vqp3D5`YQ{C$?VbFtv^ntXiT*nEDO**) zOBhEk@haAyF}{7{F9uy=?euo+wBh+pFRpq1_Kh#b{Cp3j+oC?kYgg=jZ?^88dpC3~ z_;H!W(!|=a{NK)){wd}?4L08E)Bf?%E1U0Pu5-1G^=~E4KhnI$K1&?xT2HIm|VD>dtOX3`sJt zN!WQ-ze&c8UnFPEtUsG| zKUN)q%Az?aK_A}Hm%NzS<@Wt=*RN#s=8*E zBfSxLUq){;33A!MtSR%~@TdnL+VwtJEqap6+qylqb`#&^dszMq z8u##?+2S$Uzc>`#2zjwSVJ@u#|8JwSz*tWIm1#3_s&FpFqy9SbKC1gxn8Pi7zUUIa z^ShEUJXsX+U{Q<*-r-No$XsGNpQ271yi2{+HLdCfv$RZn3-?CO7k{))eec^{(^dB| zt_^<$yaUM)Gww9cAg%_`rPi!p^HWkI21uFTK2hXTl--t+~qgS)0UeoJ~&4oYrP} z=W@G`fI}y68>v5rJ-y=b7-L!wQD*z$497b9F#KuFaWQnP=KpBY1k!)(w`Ft3kU)J? zg>{(IgU3$rI}bG^o7peBtCMvLbE))(sL1S?N6ou_b*4YyV&tAmvjP3y|?$e9Io6ynYqmfWR-^1K(s*e`3s#Eu<4>ngJjFbtdiF^jo*> zPUBPRE4{TzkIjqe5y=bW^3ylH|hoTbRS&C}$s)YrG^%k~3} z>>p>%by&-e86h5@{{wiG9iGXYcMJU4vc^;g4eWPMaE-lesWY>KG<%qDz(-|HGs~~9 zOg1<4D{HPtN7j4(%mTeuKf+uy-%;fZ_=pd&@^G9S+A3TR(q=VBk+aK%LQi# z*UCwV{s!#P?%{;i3}cvlo65m8vghJEWg5?*-;QYqlgWv)-^1`H6ZsGi{?y9{r{yEO zepRWmr72>u&oDN_>SS{4?0?NcaKFT}^!%chJweWaE5|zcnUtjpn(v z{jZoQS)`H0OXzHl@lfNk#$*TY9^f59-c2LT^ln-k> zj=kEr1D+(x8Y_htx%YkA$=lavK<$P za^#%!V@Qke0_QM37-GlO<+k4e17`@&MZ^Y&5{dSDjT^)Ux*m}nzV+2t5_t=9i3G9s zDf@p)oO9Ei#6{pIdJiRsUn)Ef-R9qOC~?Z29m(OAZpkC{25|uWSl-fyc%6sV(wOiU z*r;TaK{hk#&+t7L;oO97IQr|Mzv(ZG&e92Jq zlnl|i`R5`>$?dX87jGi2NWV3F=C-%0W-Ow8ExwbO>p(u?t(`e=!^S4n0}nr$A-?cC zot%c7MEf>;y_1t-3CY6AA%z^8UhA6PIn(bvC3(u)kq5h`|Cu_HafW`tXP5YF;P0V? zAt!9sHVXzk91EUtoe}S9iDAe?f=kj->Q!ZT&y=&T1YZv#z&zmED zHb6(59}V!e0ltbaf9eeRQUPpd?|ry#N{03?+xNIP{5gLtUpzEBbDm zSn|`F&om*M$D;A-)A$oNP7Pt4TL1QKyNM6mZ>SuyR{Vv=rGG%L7QsXL$c221CBwb7 znS_}bj$cFeZzh)93jd}b?b_PS9@+cj&h-`!dZsb_P^>(T_b}m&kIaJiA<0w3jYSAOONa35xIA5r2*!?8p-WmC;r|&6TD-*JnH}s&U%`Ik zChzdfJY!-at9_A;^R0iV@R#O?ZyLE78LvWzisN~>?_BbEnrFtFHN)fk%8k@9mRIim z^{^hkrPpV|-|>HJ$|r^maUJVb%t-yte)oC4{6U7eqkfEO6%J0G8rSyhW}h%Lh%Swn zns?^4-xpu=MQn|>kJn=x9h@DtXD087634E>hosFZQ#s?@`WoQkZ%yYS;4^=ko;E`# zs;o$F$ZOeHDsk~lbHk~X_5bY!oYOsZ4D`weX&zh;p7jwN<@D;U&JJmrD*iHW79M|~ zTy=k;=kPBLtTboFa#rYIaI|)W&A;yErygT^VIBf+>{t%1|I8Zsbm@fV>+oSS=VC9% zRt@xOt|?#PeB#0(X4aRZIk_uaq4A)HxwCsN*w^(^CxM*O#AzBAYsQ(S8SGJVS6ue9 zBgf9Cg)?=+JOX2i_^5F`Z?2wc%;2euzQZ0j?#0KtWtEkSh~+gF)b=}lW^Hod%yj?M zjLj7zX3DP^bLv#p%itqZ%uhc9tY2Ng`rrxv8;#g(edXL{$sV89s`=m|WRhk6E#I&B zSa|-Ncc0_~LR|`DZTWBIK1#=&bEHGeLDgPkPgBxNSKq=VMZD_xbve2h$EA(Edp_^} zrRh()gdFeIye`ezi2p$>@EOWd@Q_%lA2zh4mUpEctltq&OFw+}0&bO_Fy>0PgnJxk zSN}stkR|#hzFHnF8(qoV#?EUVw>p)r{4u|J-iS})Oth)MsuW)0gW^ZYvk_bNn1{P( zPf#AeS6#{FQ43Rc8@>Aw*{u9Z7+PC-u}6$P((Dhu9ox(- zsXpuz~Q zv+A!-%`(ir=y$sMS_`e>pN9?2$DT7b*A z&%PkWuDN&lhljJr?Y^$At!983l(^;AdzcSApIPuhzKKA5hYaMC)aRlFC$@eN`u++J zeQZT=j}U+T8~o}>p3?G_LtPuLy1cye-^-bou9$uJ(6y%ZJIGdTFQ=W)Gqug&Q(U`) zR`%Il8plOv{+c44KjB#-k=>d}yv zFJViv?R*dM_!Z#?xm+@jP>; ziSkEVnNxm`e~VL@nU-fir0lK64Be0J6y_&Fy}>YI2sF>c(*_>)PFm|@Dz zjC^wFrLtk>m#vb&9gE;s7`Ob`>dHa-(7bjH{FI%fl;dMeF^p}(Nx0yL(7z!qXW=6x z6J1Z_I?QpApP`SQV7r{@0p7U~9pZ_2;rP9aSQa&~{|(EUyDNU_%kBieXVXKOup(5`Zi)t7ALu7citv-x85<_|0UN3HIV zud6YA_vbFk&dFbzozro7cFvwFvvc--I6LR%tFm+UEzHh&rGc`0PHBGmYa^RqdC7DR zzJG4#gNzHwT5RWB)46AlScZw%CnTEpRVADEVplJ}VwUe+ZCXFVxJ^uZ4ttmv z)DL28z~|=A^}*LvhdILES=qXN_Rx1e>U$4;mC;u|>T6%sJm4pqg@^hJ`%N}?(cfPB z;~lluIX(0j??*U@r^4f%0zaQ>ZooG>Ub@)vGQA&U4u7v+b0g*@^_LJ6vZv7H9P1U& zEE{acm3X;}Uu4Gz<)6rlD$aYGalz#$(&NbAl1HhdJ#pCb9r&p*XFQ~3IsG~vb@^${ zgXW@hhG&bUpTt@RV)&Qh{kpVci!8IxsJ_?jWwoaCF{`I*X>ta^v=c1EfV>sTvWINBUYv;MF3BiU8G>9ck`>z(rN zD}lSxc>A|8z6oAea?H-t=^GtfcXWj*ocr~re6r0e>72ldmT=5B_~}H8#`zWCD0xZ# zf}4VdJ&CflW_)x+8H%*&(UCz>5FoCjsvb;s`lHlRs zy_`rE;N1_reZYIk^jY#r&Nvsma@JNHJXcrn8j#r<{#Tl^{YR3Cp!}RWHg248emkJZAWq> zx-h)u72Zu;a*+HTbN;3i&2(bxU4FUQ$vfIRhj1-F)07z5K2+D|o6g0_A!}1h7SGDA z$Q;h%e~1qc)F;Z@69X@LM|DzDvKyHruQkcR?Nw&T{#DSCN{(1tpSbZ+_0^0nGQTW5 zSHFvpId;D5=nCJ)z1AlyuTAWsF&No$Zu-I(7AA-8uO0j4jVqJh{tuvsS@Inn*VNA% zyCj1yB$jL@#?GE#f_;f0?TmeErH4DN&dl0Q9s8Wzp<+J|er$qgX?VdN-cG^IBZm+0 z&6IJ_*MWSpv|DJxZ|QytID05tMVWGx^$@j>Fh_3-ybc=9wl zn?Ij#xk1}BeA1KLXVEF?sm{ldKC-84Z3E>#<ZC#lhx&I9K?*p^rnww{(;r~M8ElI=QY+~5jeTiZ1 zj`#OQysxFc<9!wSES}YZUkVuCH)d-iv_Rv|8s$LAi|wIZ0$UNkeaQ(vDmR};UuM9| zom|Uy($F_Jc0EpY&}}D=X7EoT(|6OYqbr^$_zd|@`NuRi)L3q&tvbQ49&?hJmhI

    CrzE!(t!%EBL0s)9)k?oKF0wHA?v- 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 -- Gitee From 696b130afeeec09358d6777930805add2fbc0886 Mon Sep 17 00:00:00 2001 From: wangyq2018 Date: Mon, 4 Nov 2019 10:05:14 +0800 Subject: [PATCH 055/110] [bsp]1.update es32f0654 libraries. 2.adapt to the new power management interface. 3.rename es32f0654 folder to essemi_es32f0654 folder. 4.add can driver. --- bsp/es32f0654/drivers/drv_pm.c | 74 - .../CMSIS_END_USER_LICENCE_AGREEMENT.pdf | Bin 172641 -> 0 bytes .../CMSIS_END_USER_LICENCE_AGREEMENT.rtf | 793 -- .../EastSoft/ES32F065x/Include/es32f065x.h | 6665 ----------------- .../libraries/CMSIS/Include/core_cm3.h | 1763 ----- .../libraries/CMSIS/Include/core_cm4.h | 1937 ----- .../libraries/CMSIS/Include/core_cm7.h | 2512 ------- .../libraries/CMSIS/RTOS/Template/cmsis_os.h | 707 -- bsp/es32f0654/libraries/CMSIS/index.html | 14 - .../Include/ald_acmp.h | 374 - .../Include/ald_adc.h | 585 -- .../Include/ald_can.h | 485 -- .../Include/ald_cmu.h | 632 -- .../Include/ald_dma.h | 389 - .../Include/ald_gpio.h | 288 - .../Include/ald_i2c.h | 534 -- .../Include/ald_pis.h | 633 -- .../Include/ald_pmu.h | 241 - .../Include/ald_rmu.h | 265 - .../Include/ald_rtc.h | 699 -- .../Include/ald_spi.h | 377 - .../Include/ald_temp.h | 203 - .../Include/ald_timer.h | 1130 --- .../Include/ald_uart.h | 478 -- .../ReleaseNote.html | 14 - bsp/{ => essemi}/es32f0654/.config | 111 +- bsp/{ => essemi}/es32f0654/Kconfig | 2 +- bsp/{ => essemi}/es32f0654/README.md | 1 + bsp/{ => essemi}/es32f0654/SConscript | 0 bsp/{ => essemi}/es32f0654/SConstruct | 2 +- .../es32f0654/applications/SConscript | 0 .../es32f0654/applications/main.c | 0 bsp/{ => essemi}/es32f0654/drivers/Kconfig | 7 + bsp/{ => essemi}/es32f0654/drivers/SConscript | 4 + bsp/{ => essemi}/es32f0654/drivers/board.c | 11 +- bsp/{ => essemi}/es32f0654/drivers/board.h | 0 bsp/{ => essemi}/es32f0654/drivers/drv_adc.c | 56 +- bsp/{ => essemi}/es32f0654/drivers/drv_adc.h | 0 bsp/essemi/es32f0654/drivers/drv_can.c | 605 ++ bsp/essemi/es32f0654/drivers/drv_can.h | 37 + bsp/{ => essemi}/es32f0654/drivers/drv_gpio.c | 23 +- bsp/{ => essemi}/es32f0654/drivers/drv_gpio.h | 0 .../es32f0654/drivers/drv_hwtimer.c | 47 +- .../es32f0654/drivers/drv_hwtimer.h | 0 bsp/{ => essemi}/es32f0654/drivers/drv_i2c.c | 17 +- bsp/{ => essemi}/es32f0654/drivers/drv_i2c.h | 0 bsp/essemi/es32f0654/drivers/drv_pm.c | 226 + bsp/{ => essemi}/es32f0654/drivers/drv_pm.h | 0 bsp/{ => essemi}/es32f0654/drivers/drv_pwm.c | 45 +- bsp/{ => essemi}/es32f0654/drivers/drv_pwm.h | 0 bsp/{ => essemi}/es32f0654/drivers/drv_rtc.c | 11 +- bsp/{ => essemi}/es32f0654/drivers/drv_rtc.h | 0 bsp/{ => essemi}/es32f0654/drivers/drv_spi.c | 39 +- bsp/{ => essemi}/es32f0654/drivers/drv_spi.h | 0 .../es32f0654/drivers/drv_spiflash.c | 1 + .../es32f0654/drivers/drv_spiflash.h | 0 bsp/{ => essemi}/es32f0654/drivers/drv_uart.c | 25 +- bsp/{ => essemi}/es32f0654/drivers/drv_uart.h | 0 .../es32f0654/drivers/linker_scripts/link.sct | 0 .../figures/ES-PDS-ES32F0654-V1.1.jpg | Bin .../es32f0654/figures/ESLinkII-mini.jpg | Bin .../EastSoft/ES32F065x/Include/es32f065x.h | 6631 ++++++++++++++++ .../ES32F065x/Startup/iar/startup_es32f065x.s | 0 .../Startup/keil/startup_es32f065x.s | 342 +- .../ES32F065x/System/system_es32f065x.c | 0 .../CMSIS/Include/arm_common_tables.h | 0 .../CMSIS/Include/arm_const_structs.h | 0 .../libraries/CMSIS/Include/arm_math.h | 0 .../libraries/CMSIS/Include/cmsis_armcc.h | 0 .../libraries/CMSIS/Include/cmsis_armcc_V6.h | 0 .../libraries/CMSIS/Include/cmsis_gcc.h | 0 .../libraries/CMSIS/Include/core_cm0.h | 0 .../libraries/CMSIS/Include/core_cm0plus.h | 0 .../libraries/CMSIS/Include/core_cmFunc.h | 0 .../libraries/CMSIS/Include/core_cmInstr.h | 0 .../libraries/CMSIS/Include/core_cmSimd.h | 0 .../libraries/CMSIS/Include/core_sc000.h | 0 .../libraries/CMSIS/Include/core_sc300.h | 0 .../Include/ald_acmp.h | 355 + .../Include/ald_adc.h | 572 ++ .../Include/ald_bkpc.h | 160 +- .../Include/ald_calc.h | 8 +- .../Include/ald_can.h | 491 ++ .../Include/ald_cmu.h | 653 ++ .../Include/ald_conf.h | 0 .../Include/ald_crc.h | 99 +- .../Include/ald_crypt.h | 164 +- .../Include/ald_dbgc.h | 48 +- .../Include/ald_dma.h | 409 + .../Include/ald_flash.h | 93 +- .../Include/ald_gpio.h | 288 + .../Include/ald_i2c.h | 534 ++ .../Include/ald_iap.h | 16 +- .../Include/ald_pis.h | 692 ++ .../Include/ald_pmu.h | 211 + .../Include/ald_rmu.h | 285 + .../Include/ald_rtc.h | 699 ++ .../Include/ald_smartcard.h | 176 +- .../Include/ald_spi.h | 398 + .../Include/ald_syscfg.h | 56 +- .../Include/ald_timer.h | 1193 +++ .../Include/ald_trng.h | 126 +- .../Include/ald_tsense.h | 227 + .../Include/ald_uart.h | 478 ++ .../Include/ald_usart.h | 316 +- .../Include/ald_wdt.h | 36 +- .../Include/type.h | 66 +- .../Include/utils.h | 73 +- .../Source/ald_acmp.c | 106 +- .../Source/ald_adc.c | 554 +- .../Source/ald_bkpc.c | 16 +- .../Source/ald_calc.c | 9 +- .../Source/ald_can.c | 448 +- .../Source/ald_cmu.c | 428 +- .../Source/ald_crc.c | 202 +- .../Source/ald_crypt.c | 114 +- .../Source/ald_dma.c | 170 +- .../Source/ald_flash.c | 222 + .../Source/ald_flash_ext.c} | 316 +- .../Source/ald_gpio.c | 48 +- .../Source/ald_i2c.c | 626 +- .../Source/ald_iap.c | 8 +- .../Source/ald_pis.c | 191 +- .../Source/ald_pmu.c | 58 +- .../Source/ald_rmu.c | 36 +- .../Source/ald_rtc.c | 213 +- .../Source/ald_smartcard.c | 170 +- .../Source/ald_spi.c | 309 +- .../Source/ald_timer.c | 1910 ++--- .../Source/ald_trng.c | 174 +- .../Source/ald_tsense.c} | 138 +- .../Source/ald_uart.c | 224 +- .../Source/ald_usart.c | 397 +- .../Source/ald_wdt.c | 24 +- .../Source/utils.c | 114 +- .../es32f0654/libraries/SConscript | 2 +- bsp/{ => essemi}/es32f0654/project.uvoptx | 0 bsp/{ => essemi}/es32f0654/project.uvprojx | 92 +- bsp/{ => essemi}/es32f0654/rtconfig.h | 14 +- bsp/{ => essemi}/es32f0654/rtconfig.py | 0 bsp/{ => essemi}/es32f0654/template.uvoptx | 0 bsp/{ => essemi}/es32f0654/template.uvprojx | 0 142 files changed, 20128 insertions(+), 26162 deletions(-) delete mode 100644 bsp/es32f0654/drivers/drv_pm.c delete mode 100644 bsp/es32f0654/libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf delete mode 100644 bsp/es32f0654/libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.rtf delete mode 100644 bsp/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Include/es32f065x.h delete mode 100644 bsp/es32f0654/libraries/CMSIS/Include/core_cm3.h delete mode 100644 bsp/es32f0654/libraries/CMSIS/Include/core_cm4.h delete mode 100644 bsp/es32f0654/libraries/CMSIS/Include/core_cm7.h delete mode 100644 bsp/es32f0654/libraries/CMSIS/RTOS/Template/cmsis_os.h delete mode 100644 bsp/es32f0654/libraries/CMSIS/index.html delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_acmp.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_adc.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_can.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_cmu.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dma.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_gpio.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_i2c.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pis.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pmu.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rmu.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rtc.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_spi.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_temp.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_timer.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_uart.h delete mode 100644 bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/ReleaseNote.html rename bsp/{ => essemi}/es32f0654/.config (69%) rename bsp/{ => essemi}/es32f0654/Kconfig (94%) rename bsp/{ => essemi}/es32f0654/README.md (98%) rename bsp/{ => essemi}/es32f0654/SConscript (100%) rename bsp/{ => essemi}/es32f0654/SConstruct (94%) rename bsp/{ => essemi}/es32f0654/applications/SConscript (100%) rename bsp/{ => essemi}/es32f0654/applications/main.c (100%) rename bsp/{ => essemi}/es32f0654/drivers/Kconfig (95%) rename bsp/{ => essemi}/es32f0654/drivers/SConscript (94%) rename bsp/{ => essemi}/es32f0654/drivers/board.c (89%) rename bsp/{ => essemi}/es32f0654/drivers/board.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/drv_adc.c (71%) rename bsp/{ => essemi}/es32f0654/drivers/drv_adc.h (100%) create mode 100644 bsp/essemi/es32f0654/drivers/drv_can.c create mode 100644 bsp/essemi/es32f0654/drivers/drv_can.h rename bsp/{ => essemi}/es32f0654/drivers/drv_gpio.c (93%) rename bsp/{ => essemi}/es32f0654/drivers/drv_gpio.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/drv_hwtimer.c (77%) rename bsp/{ => essemi}/es32f0654/drivers/drv_hwtimer.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/drv_i2c.c (86%) rename bsp/{ => essemi}/es32f0654/drivers/drv_i2c.h (100%) create mode 100644 bsp/essemi/es32f0654/drivers/drv_pm.c rename bsp/{ => essemi}/es32f0654/drivers/drv_pm.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/drv_pwm.c (79%) rename bsp/{ => essemi}/es32f0654/drivers/drv_pwm.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/drv_rtc.c (93%) rename bsp/{ => essemi}/es32f0654/drivers/drv_rtc.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/drv_spi.c (82%) rename bsp/{ => essemi}/es32f0654/drivers/drv_spi.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/drv_spiflash.c (92%) rename bsp/{ => essemi}/es32f0654/drivers/drv_spiflash.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/drv_uart.c (90%) rename bsp/{ => essemi}/es32f0654/drivers/drv_uart.h (100%) rename bsp/{ => essemi}/es32f0654/drivers/linker_scripts/link.sct (100%) rename bsp/{ => essemi}/es32f0654/figures/ES-PDS-ES32F0654-V1.1.jpg (100%) rename bsp/{ => essemi}/es32f0654/figures/ESLinkII-mini.jpg (100%) create mode 100644 bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Include/es32f065x.h rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/iar/startup_es32f065x.s (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/keil/startup_es32f065x.s (56%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/System/system_es32f065x.c (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/arm_common_tables.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/arm_const_structs.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/arm_math.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/cmsis_armcc.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/cmsis_armcc_V6.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/cmsis_gcc.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/core_cm0.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/core_cm0plus.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/core_cmFunc.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/core_cmInstr.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/core_cmSimd.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/core_sc000.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/CMSIS/Include/core_sc300.h (100%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_acmp.h create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_adc.h rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_bkpc.h (30%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_calc.h (73%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_can.h create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_cmu.h rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_conf.h (100%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crc.h (37%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crypt.h (30%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dbgc.h (58%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dma.h rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_flash.h (32%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_gpio.h create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_i2c.h rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_iap.h (74%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pis.h create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pmu.h create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rmu.h create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rtc.h rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_smartcard.h (34%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_spi.h rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_syscfg.h (50%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_timer.h rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_trng.h (39%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_tsense.h create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_uart.h rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_usart.h (43%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_wdt.h (66%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/type.h (55%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/utils.h (56%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_acmp.c (74%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_adc.c (69%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_bkpc.c (85%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_calc.c (91%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_can.c (73%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_cmu.c (71%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crc.c (54%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crypt.c (88%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_dma.c (79%) create mode 100644 bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash.c rename bsp/{es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash.c => essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash_ext.c} (60%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_gpio.c (91%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_i2c.c (85%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_iap.c (92%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pis.c (58%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pmu.c (75%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rmu.c (78%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rtc.c (84%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_smartcard.c (83%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_spi.c (83%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_timer.c (66%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_trng.c (43%) rename bsp/{es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_temp.c => essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_tsense.c} (40%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_uart.c (82%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_usart.c (85%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_wdt.c (88%) rename bsp/{ => essemi}/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/utils.c (78%) rename bsp/{ => essemi}/es32f0654/libraries/SConscript (96%) rename bsp/{ => essemi}/es32f0654/project.uvoptx (100%) rename bsp/{ => essemi}/es32f0654/project.uvprojx (90%) rename bsp/{ => essemi}/es32f0654/rtconfig.h (95%) rename bsp/{ => essemi}/es32f0654/rtconfig.py (100%) rename bsp/{ => essemi}/es32f0654/template.uvoptx (100%) rename bsp/{ => essemi}/es32f0654/template.uvprojx (100%) diff --git a/bsp/es32f0654/drivers/drv_pm.c b/bsp/es32f0654/drivers/drv_pm.c deleted file mode 100644 index aa2f07ec68..0000000000 --- a/bsp/es32f0654/drivers/drv_pm.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-04-01 wangyq the first version - * 2019-05-06 Zero-Free adapt to the new power management interface - */ - -#include -#include -#include "board.h" -#include "drv_pm.h" -#include - -#ifdef RT_USING_PM - -static void _drv_pm_enter(struct rt_pm *pm, uint8_t mode) -{ - switch (mode) - { - case PM_SLEEP_MODE_NONE: - break; - - case PM_SLEEP_MODE_IDLE: - __WFI(); - break; - - case PM_SLEEP_MODE_LIGHT: - break; - - case PM_SLEEP_MODE_DEEP: - pmu_stop2_enter(); - break; - - case PM_SLEEP_MODE_STANDBY: - pmu_standby_enter(PMU_STANDBY_PORT_NONE); - break; - - case PM_SLEEP_MODE_SHUTDOWN: - break; - - default: - RT_ASSERT(0); - break; - } -} - -static int drv_hw_pm_init(void) -{ - static const struct rt_pm_ops _ops = - { - _drv_pm_enter, - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL - }; - - rt_uint8_t timer_mask = 0; - - /* initialize timer mask(no need tickless) */ - timer_mask = 1UL << PM_SLEEP_MODE_DEEP; - - /* initialize system pm module */ - rt_system_pm_init(&_ops, timer_mask, RT_NULL); - - return 0; -} -INIT_BOARD_EXPORT(drv_hw_pm_init); - -#endif diff --git a/bsp/es32f0654/libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf b/bsp/es32f0654/libraries/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf deleted file mode 100644 index b374366930b2d1b5689ff5044caba49eace6aa68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172641 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 z 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 -#include "core_cm0.h" - -#if defined (__CC_ARM) -#pragma anon_unions -#endif - -/* Peripheral register define */ - -/****************** Bit definition for SYSCFG_PROT register ************************/ - -#define SYSCFG_PROT_KEY_POSS 1U -#define SYSCFG_PROT_KEY_POSE 31U -#define SYSCFG_PROT_KEY_MSK BITS(SYSCFG_PROT_KEY_POSS,SYSCFG_PROT_KEY_POSE) - -#define SYSCFG_PROT_PROT_POS 0U -#define SYSCFG_PROT_PROT_MSK BIT(SYSCFG_PROT_PROT_POS) - -/****************** Bit definition for SYSCFG_MEMRMP register ************************/ - -#define SYSCFG_MEMRMP_VTOEN_POS 16U -#define SYSCFG_MEMRMP_VTOEN_MSK BIT(SYSCFG_MEMRMP_VTOEN_POS) - -#define SYSCFG_MEMRMP_BFRMPEN_POS 8U -#define SYSCFG_MEMRMP_BFRMPEN_MSK BIT(SYSCFG_MEMRMP_BFRMPEN_POS) - -#define SYSCFG_MEMRMP_BRRMPEN_POS 0U -#define SYSCFG_MEMRMP_BRRMPEN_MSK BIT(SYSCFG_MEMRMP_BRRMPEN_POS) - -/****************** Bit definition for SYSCFG_VTOR register ************************/ - -#define SYSCFG_VTOR_VTO_POSS 0U -#define SYSCFG_VTOR_VTO_POSE 29U -#define SYSCFG_VTOR_VTO_MSK BITS(SYSCFG_VTOR_VTO_POSS,SYSCFG_VTOR_VTO_POSE) - -typedef struct -{ - __IO uint32_t PROT; - __IO uint32_t MEMRMP; - __IO uint32_t VTOR; -} SYSCFG_TypeDef; - -/****************** Bit definition for MSC_FLASHKEY register ************************/ - -#define MSC_FLASHKEY_STATUS_POSS 0U -#define MSC_FLASHKEY_STATUS_POSE 1U -#define MSC_FLASHKEY_STATUS_MSK BITS(MSC_FLASHKEY_STATUS_POSS,MSC_FLASHKEY_STATUS_POSE) - -/****************** Bit definition for MSC_INFOKEY register ************************/ - -#define MSC_INFOKEY_STATUS_POSS 0U -#define MSC_INFOKEY_STATUS_POSE 1U -#define MSC_INFOKEY_STATUS_MSK BITS(MSC_INFOKEY_STATUS_POSS,MSC_INFOKEY_STATUS_POSE) - -/****************** Bit definition for MSC_FLASHADDR register ************************/ - -#define MSC_FLASHADDR_IFREN_POS 18U -#define MSC_FLASHADDR_IFREN_MSK BIT(MSC_FLASHADDR_IFREN_POS) - -#define MSC_FLASHADDR_ADDR_POSS 0U -#define MSC_FLASHADDR_ADDR_POSE 17U -#define MSC_FLASHADDR_ADDR_MSK BITS(MSC_FLASHADDR_ADDR_POSS,MSC_FLASHADDR_ADDR_POSE) - -/****************** Bit definition for MSC_FLASHFIFO register ************************/ - -#define MSC_FLASHFIFO_FIFO_POSS 0U -#define MSC_FLASHFIFO_FIFO_POSE 31U -#define MSC_FLASHFIFO_FIFO_MSK BITS(MSC_FLASHFIFO_FIFO_POSS,MSC_FLASHFIFO_FIFO_POSE) - -/****************** Bit definition for MSC_FLASHDL register ************************/ - -#define MSC_FLASHDL_DATAL_POSS 0U -#define MSC_FLASHDL_DATAL_POSE 31U -#define MSC_FLASHDL_DATAL_MSK BITS(MSC_FLASHDL_DATAL_POSS,MSC_FLASHDL_DATAL_POSE) - -/****************** Bit definition for MSC_FLASHDH register ************************/ - -#define MSC_FLASHDH_DATAH_POSS 0U -#define MSC_FLASHDH_DATAH_POSE 31U -#define MSC_FLASHDH_DATAH_MSK BITS(MSC_FLASHDH_DATAH_POSS,MSC_FLASHDH_DATAH_POSE) - -/****************** Bit definition for MSC_FLASHCMD register ************************/ - -#define MSC_FLASHCMD_CMD_POSS 0U -#define MSC_FLASHCMD_CMD_POSE 31U -#define MSC_FLASHCMD_CMD_MSK BITS(MSC_FLASHCMD_CMD_POSS,MSC_FLASHCMD_CMD_POSE) - -/****************** Bit definition for MSC_FLASHCR register ************************/ - -#define MSC_FLASHCR_FIFOEN_POS 5U -#define MSC_FLASHCR_FIFOEN_MSK BIT(MSC_FLASHCR_FIFOEN_POS) - -#define MSC_FLASHCR_FLASHREQ_POS 4U -#define MSC_FLASHCR_FLASHREQ_MSK BIT(MSC_FLASHCR_FLASHREQ_POS) - -#define MSC_FLASHCR_IAPRST_POS 1U -#define MSC_FLASHCR_IAPRST_MSK BIT(MSC_FLASHCR_IAPRST_POS) - -#define MSC_FLASHCR_IAPEN_POS 0U -#define MSC_FLASHCR_IAPEN_MSK BIT(MSC_FLASHCR_IAPEN_POS) - -/****************** Bit definition for MSC_FLASHSR register ************************/ - -#define MSC_FLASHSR_TIMEOUT_POS 7U -#define MSC_FLASHSR_TIMEOUT_MSK BIT(MSC_FLASHSR_TIMEOUT_POS) - -#define MSC_FLASHSR_PROG_POS 6U -#define MSC_FLASHSR_PROG_MSK BIT(MSC_FLASHSR_PROG_POS) - -#define MSC_FLASHSR_SERA_POS 5U -#define MSC_FLASHSR_SERA_MSK BIT(MSC_FLASHSR_SERA_POS) - -#define MSC_FLASHSR_MASE_POS 4U -#define MSC_FLASHSR_MASE_MSK BIT(MSC_FLASHSR_MASE_POS) - -#define MSC_FLASHSR_ADDR_OV_POS 3U -#define MSC_FLASHSR_ADDR_OV_MSK BIT(MSC_FLASHSR_ADDR_OV_POS) - -#define MSC_FLASHSR_WRP_FLAG_POS 2U -#define MSC_FLASHSR_WRP_FLAG_MSK BIT(MSC_FLASHSR_WRP_FLAG_POS) - -#define MSC_FLASHSR_BUSY_POS 1U -#define MSC_FLASHSR_BUSY_MSK BIT(MSC_FLASHSR_BUSY_POS) - -#define MSC_FLASHSR_FLASHACK_POS 0U -#define MSC_FLASHSR_FLASHACK_MSK BIT(MSC_FLASHSR_FLASHACK_POS) - -/****************** Bit definition for MSC_FLASHPL register ************************/ - -#define MSC_FLASHPL_PROG_LEN_POSS 0U -#define MSC_FLASHPL_PROG_LEN_POSE 15U -#define MSC_FLASHPL_PROG_LEN_MSK BITS(MSC_FLASHPL_PROG_LEN_POSS,MSC_FLASHPL_PROG_LEN_POSE) - -/****************** Bit definition for MSC_MEMWAIT register ************************/ - -#define MSC_MEMWAIT_SRAM_W_POSS 8U -#define MSC_MEMWAIT_SRAM_W_POSE 9U -#define MSC_MEMWAIT_SRAM_W_MSK BITS(MSC_MEMWAIT_SRAM_W_POSS,MSC_MEMWAIT_SRAM_W_POSE) - -#define MSC_MEMWAIT_FLASH_W_POSS 0U -#define MSC_MEMWAIT_FLASH_W_POSE 3U -#define MSC_MEMWAIT_FLASH_W_MSK BITS(MSC_MEMWAIT_FLASH_W_POSS,MSC_MEMWAIT_FLASH_W_POSE) - -typedef struct -{ - __IO uint32_t FLASHKEY; - __IO uint32_t INFOKEY; - __IO uint32_t FLASHADDR; - __O uint32_t FLASHFIFO; - __IO uint32_t FLASHDL; - __IO uint32_t FLASHDH; - __O uint32_t FLASHCMD; - __IO uint32_t FLASHCR; - __I uint32_t FLASHSR; - __IO uint32_t FLASHPL; - __IO uint32_t MEMWAIT; -} MSC_TypeDef; - -/****************** Bit definition for BKPC_PROT register ************************/ - -#define BKPC_PROT_KEY_POSS 1U -#define BKPC_PROT_KEY_POSE 31U -#define BKPC_PROT_KEY_MSK BITS(BKPC_PROT_KEY_POSS,BKPC_PROT_KEY_POSE) - -#define BKPC_PROT_PROT_POS 0U -#define BKPC_PROT_PROT_MSK BIT(BKPC_PROT_PROT_POS) - -/****************** Bit definition for BKPC_CR register ************************/ - -#define BKPC_CR_LDO_VSEL_POSS 24U -#define BKPC_CR_LDO_VSEL_POSE 26U -#define BKPC_CR_LDO_VSEL_MSK BITS(BKPC_CR_LDO_VSEL_POSS,BKPC_CR_LDO_VSEL_POSE) - -#define BKPC_CR_MT_STDB_POS 19U -#define BKPC_CR_MT_STDB_MSK BIT(BKPC_CR_MT_STDB_POS) - -#define BKPC_CR_VR1P5_VSEL_POSS 16U -#define BKPC_CR_VR1P5_VSEL_POSE 18U -#define BKPC_CR_VR1P5_VSEL_MSK BITS(BKPC_CR_VR1P5_VSEL_POSS,BKPC_CR_VR1P5_VSEL_POSE) - -#define BKPC_CR_TC_PWRDWN_POS 13U -#define BKPC_CR_TC_PWRDWN_MSK BIT(BKPC_CR_TC_PWRDWN_POS) - -#define BKPC_CR_WKPOL_POS 12U -#define BKPC_CR_WKPOL_MSK BIT(BKPC_CR_WKPOL_POS) - -#define BKPC_CR_WKPS_POSS 9U -#define BKPC_CR_WKPS_POSE 11U -#define BKPC_CR_WKPS_MSK BITS(BKPC_CR_WKPS_POSS,BKPC_CR_WKPS_POSE) - -#define BKPC_CR_WKPEN_POS 8U -#define BKPC_CR_WKPEN_MSK BIT(BKPC_CR_WKPEN_POS) - -#define BKPC_CR_LRCEN_POS 2U -#define BKPC_CR_LRCEN_MSK BIT(BKPC_CR_LRCEN_POS) - -#define BKPC_CR_LOSMEN_POS 1U -#define BKPC_CR_LOSMEN_MSK BIT(BKPC_CR_LOSMEN_POS) - -#define BKPC_CR_LOSCEN_POS 0U -#define BKPC_CR_LOSCEN_MSK BIT(BKPC_CR_LOSCEN_POS) - -/****************** Bit definition for BKPC_PCCR register ************************/ - -#define BKPC_PCCR_TEMPCS_POSS 4U -#define BKPC_PCCR_TEMPCS_POSE 5U -#define BKPC_PCCR_TEMPCS_MSK BITS(BKPC_PCCR_TEMPCS_POSS,BKPC_PCCR_TEMPCS_POSE) - -#define BKPC_PCCR_RTCCS_POSS 0U -#define BKPC_PCCR_RTCCS_POSE 1U -#define BKPC_PCCR_RTCCS_MSK BITS(BKPC_PCCR_RTCCS_POSS,BKPC_PCCR_RTCCS_POSE) - -/****************** Bit definition for BKPC_PCR register ************************/ - -#define BKPC_PCR_BORS_POSS 1U -#define BKPC_PCR_BORS_POSE 4U -#define BKPC_PCR_BORS_MSK BITS(BKPC_PCR_BORS_POSS,BKPC_PCR_BORS_POSE) - -#define BKPC_PCR_BOREN_POS 0U -#define BKPC_PCR_BOREN_MSK BIT(BKPC_PCR_BOREN_POS) - -typedef struct -{ - __IO uint32_t PROT; - __IO uint32_t CR; - __IO uint32_t PCCR; - __IO uint32_t PCR; -} BKPC_TypeDef; - -/****************** Bit definition for PMU_CR register ************************/ - -#define PMU_CR_MTSTOP_POS 21U -#define PMU_CR_MTSTOP_MSK BIT(PMU_CR_MTSTOP_POS) - -#define PMU_CR_LPSTOP_POS 20U -#define PMU_CR_LPSTOP_MSK BIT(PMU_CR_LPSTOP_POS) - -#define PMU_CR_LPRUN_POS 19U -#define PMU_CR_LPRUN_MSK BIT(PMU_CR_LPRUN_POS) - -#define PMU_CR_LPVS_POSS 16U -#define PMU_CR_LPVS_POSE 18U -#define PMU_CR_LPVS_MSK BITS(PMU_CR_LPVS_POSS,PMU_CR_LPVS_POSE) - -#define PMU_CR_WKPS_POSS 9U -#define PMU_CR_WKPS_POSE 11U -#define PMU_CR_WKPS_MSK BITS(PMU_CR_WKPS_POSS,PMU_CR_WKPS_POSE) - -#define PMU_CR_WKPEN_POS 8U -#define PMU_CR_WKPEN_MSK BIT(PMU_CR_WKPEN_POS) - -#define PMU_CR_CSTANDBYF_POS 3U -#define PMU_CR_CSTANDBYF_MSK BIT(PMU_CR_CSTANDBYF_POS) - -#define PMU_CR_CWUF_POS 2U -#define PMU_CR_CWUF_MSK BIT(PMU_CR_CWUF_POS) - -#define PMU_CR_LPM_POSS 0U -#define PMU_CR_LPM_POSE 1U -#define PMU_CR_LPM_MSK BITS(PMU_CR_LPM_POSS,PMU_CR_LPM_POSE) - -/****************** Bit definition for PMU_SR register ************************/ - -#define PMU_SR_STANDBYF_POS 1U -#define PMU_SR_STANDBYF_MSK BIT(PMU_SR_STANDBYF_POS) - -#define PMU_SR_WUF_POS 0U -#define PMU_SR_WUF_MSK BIT(PMU_SR_WUF_POS) - -/****************** Bit definition for PMU_LVDCR register ************************/ - -#define PMU_LVDCR_LVDO_POS 15U -#define PMU_LVDCR_LVDO_MSK BIT(PMU_LVDCR_LVDO_POS) - -#define PMU_LVDCR_LVDFLT_POS 11U -#define PMU_LVDCR_LVDFLT_MSK BIT(PMU_LVDCR_LVDFLT_POS) - -#define PMU_LVDCR_LVIFS_POSS 8U -#define PMU_LVDCR_LVIFS_POSE 10U -#define PMU_LVDCR_LVIFS_MSK BITS(PMU_LVDCR_LVIFS_POSS,PMU_LVDCR_LVIFS_POSE) - -#define PMU_LVDCR_LVDS_POSS 4U -#define PMU_LVDCR_LVDS_POSE 7U -#define PMU_LVDCR_LVDS_MSK BITS(PMU_LVDCR_LVDS_POSS,PMU_LVDCR_LVDS_POSE) - -#define PMU_LVDCR_LVDCIF_POS 3U -#define PMU_LVDCR_LVDCIF_MSK BIT(PMU_LVDCR_LVDCIF_POS) - -#define PMU_LVDCR_LVDIF_POS 2U -#define PMU_LVDCR_LVDIF_MSK BIT(PMU_LVDCR_LVDIF_POS) - -#define PMU_LVDCR_LVDIE_POS 1U -#define PMU_LVDCR_LVDIE_MSK BIT(PMU_LVDCR_LVDIE_POS) - -#define PMU_LVDCR_LVDEN_POS 0U -#define PMU_LVDCR_LVDEN_MSK BIT(PMU_LVDCR_LVDEN_POS) - -/****************** Bit definition for PMU_PWRCR register ************************/ - -#define PMU_PWRCR_BXCAN_POS 4U -#define PMU_PWRCR_BXCAN_MSK BIT(PMU_PWRCR_BXCAN_POS) - -#define PMU_PWRCR_SRAM_POSS 0U -#define PMU_PWRCR_SRAM_POSE 1U -#define PMU_PWRCR_SRAM_MSK BITS(PMU_PWRCR_SRAM_POSS,PMU_PWRCR_SRAM_POSE) - -/****************** Bit definition for PMU_TWUR register ************************/ - -#define PMU_TWUR_TWU_POSS 0U -#define PMU_TWUR_TWU_POSE 11U -#define PMU_TWUR_TWU_MSK BITS(PMU_TWUR_TWU_POSS,PMU_TWUR_TWU_POSE) - -/****************** Bit definition for PMU_VREFCR register ************************/ - -#define PMU_VREFCR_FLTS_POSS 13U -#define PMU_VREFCR_FLTS_POSE 14U -#define PMU_VREFCR_FLTS_MSK BITS(PMU_VREFCR_FLTS_POSS,PMU_VREFCR_FLTS_POSE) - -#define PMU_VREFCR_CHOPCS_POSS 10U -#define PMU_VREFCR_CHOPCS_POSE 12U -#define PMU_VREFCR_CHOPCS_MSK BITS(PMU_VREFCR_CHOPCS_POSS,PMU_VREFCR_CHOPCS_POSE) - -#define PMU_VREFCR_CHOP1EN_POS 9U -#define PMU_VREFCR_CHOP1EN_MSK BIT(PMU_VREFCR_CHOP1EN_POS) - -#define PMU_VREFCR_CHOPEN_POS 8U -#define PMU_VREFCR_CHOPEN_MSK BIT(PMU_VREFCR_CHOPEN_POS) - -#define PMU_VREFCR_VREFEN_POS 0U -#define PMU_VREFCR_VREFEN_MSK BIT(PMU_VREFCR_VREFEN_POS) - -typedef struct -{ - __IO uint32_t CR; - __I uint32_t SR; - __IO uint32_t LVDCR; - __IO uint32_t PWRCR; - __IO uint32_t TWUR; - __IO uint32_t VREFCR; -} PMU_TypeDef; - -/****************** Bit definition for RMU_CR register ************************/ - -#define RMU_CR_BORVS_POSS 4U -#define RMU_CR_BORVS_POSE 7U -#define RMU_CR_BORVS_MSK BITS(RMU_CR_BORVS_POSS,RMU_CR_BORVS_POSE) - -#define RMU_CR_BORFLT_POSS 1U -#define RMU_CR_BORFLT_POSE 3U -#define RMU_CR_BORFLT_MSK BITS(RMU_CR_BORFLT_POSS,RMU_CR_BORFLT_POSE) - -#define RMU_CR_BOREN_POS 0U -#define RMU_CR_BOREN_MSK BIT(RMU_CR_BOREN_POS) - -/****************** Bit definition for RMU_RSTSR register ************************/ - -#define RMU_RSTSR_CFGERR_POS 16U -#define RMU_RSTSR_CFGERR_MSK BIT(RMU_RSTSR_CFGERR_POS) - -#define RMU_RSTSR_CFG_POS 10U -#define RMU_RSTSR_CFG_MSK BIT(RMU_RSTSR_CFG_POS) - -#define RMU_RSTSR_CPU_POS 9U -#define RMU_RSTSR_CPU_MSK BIT(RMU_RSTSR_CPU_POS) - -#define RMU_RSTSR_MCU_POS 8U -#define RMU_RSTSR_MCU_MSK BIT(RMU_RSTSR_MCU_POS) - -#define RMU_RSTSR_CHIP_POS 7U -#define RMU_RSTSR_CHIP_MSK BIT(RMU_RSTSR_CHIP_POS) - -#define RMU_RSTSR_LOCKUP_POS 6U -#define RMU_RSTSR_LOCKUP_MSK BIT(RMU_RSTSR_LOCKUP_POS) - -#define RMU_RSTSR_WWDT_POS 5U -#define RMU_RSTSR_WWDT_MSK BIT(RMU_RSTSR_WWDT_POS) - -#define RMU_RSTSR_IWDT_POS 4U -#define RMU_RSTSR_IWDT_MSK BIT(RMU_RSTSR_IWDT_POS) - -#define RMU_RSTSR_NMRST_POS 3U -#define RMU_RSTSR_NMRST_MSK BIT(RMU_RSTSR_NMRST_POS) - -#define RMU_RSTSR_BOR_POS 2U -#define RMU_RSTSR_BOR_MSK BIT(RMU_RSTSR_BOR_POS) - -#define RMU_RSTSR_WAKEUP_POS 1U -#define RMU_RSTSR_WAKEUP_MSK BIT(RMU_RSTSR_WAKEUP_POS) - -#define RMU_RSTSR_POR_POS 0U -#define RMU_RSTSR_POR_MSK BIT(RMU_RSTSR_POR_POS) - -/****************** Bit definition for RMU_CRSTSR register ************************/ - -#define RMU_CRSTSR_CFG_POS 10U -#define RMU_CRSTSR_CFG_MSK BIT(RMU_CRSTSR_CFG_POS) - -#define RMU_CRSTSR_CPU_POS 9U -#define RMU_CRSTSR_CPU_MSK BIT(RMU_CRSTSR_CPU_POS) - -#define RMU_CRSTSR_MCU_POS 8U -#define RMU_CRSTSR_MCU_MSK BIT(RMU_CRSTSR_MCU_POS) - -#define RMU_CRSTSR_CHIP_POS 7U -#define RMU_CRSTSR_CHIP_MSK BIT(RMU_CRSTSR_CHIP_POS) - -#define RMU_CRSTSR_LOCKUP_POS 6U -#define RMU_CRSTSR_LOCKUP_MSK BIT(RMU_CRSTSR_LOCKUP_POS) - -#define RMU_CRSTSR_WWDT_POS 5U -#define RMU_CRSTSR_WWDT_MSK BIT(RMU_CRSTSR_WWDT_POS) - -#define RMU_CRSTSR_IWDT_POS 4U -#define RMU_CRSTSR_IWDT_MSK BIT(RMU_CRSTSR_IWDT_POS) - -#define RMU_CRSTSR_NMRST_POS 3U -#define RMU_CRSTSR_NMRST_MSK BIT(RMU_CRSTSR_NMRST_POS) - -#define RMU_CRSTSR_BOR_POS 2U -#define RMU_CRSTSR_BOR_MSK BIT(RMU_CRSTSR_BOR_POS) - -#define RMU_CRSTSR_WAKEUP_POS 1U -#define RMU_CRSTSR_WAKEUP_MSK BIT(RMU_CRSTSR_WAKEUP_POS) - -#define RMU_CRSTSR_POR_POS 0U -#define RMU_CRSTSR_POR_MSK BIT(RMU_CRSTSR_POR_POS) - -/****************** Bit definition for RMU_AHB1RSTR register ************************/ - -#define RMU_AHB1RSTR_PISRST_POS 5U -#define RMU_AHB1RSTR_PISRST_MSK BIT(RMU_AHB1RSTR_PISRST_POS) - -#define RMU_AHB1RSTR_TRNGRST_POS 4U -#define RMU_AHB1RSTR_TRNGRST_MSK BIT(RMU_AHB1RSTR_TRNGRST_POS) - -#define RMU_AHB1RSTR_CRYPTRST_POS 3U -#define RMU_AHB1RSTR_CRYPTRST_MSK BIT(RMU_AHB1RSTR_CRYPTRST_POS) - -#define RMU_AHB1RSTR_CALCRST_POS 2U -#define RMU_AHB1RSTR_CALCRST_MSK BIT(RMU_AHB1RSTR_CALCRST_POS) - -#define RMU_AHB1RSTR_CRCRST_POS 1U -#define RMU_AHB1RSTR_CRCRST_MSK BIT(RMU_AHB1RSTR_CRCRST_POS) - -#define RMU_AHB1RSTR_GPIORST_POS 0U -#define RMU_AHB1RSTR_GPIORST_MSK BIT(RMU_AHB1RSTR_GPIORST_POS) - -/****************** Bit definition for RMU_AHB2RSTR register ************************/ - -#define RMU_AHB2RSTR_CPURST_POS 1U -#define RMU_AHB2RSTR_CPURST_MSK BIT(RMU_AHB2RSTR_CPURST_POS) - -#define RMU_AHB2RSTR_CHIPRST_POS 0U -#define RMU_AHB2RSTR_CHIPRST_MSK BIT(RMU_AHB2RSTR_CHIPRST_POS) - -/****************** Bit definition for RMU_APB1RSTR register ************************/ - -#define RMU_APB1RSTR_CAN0RST_POS 24U -#define RMU_APB1RSTR_CAN0RST_MSK BIT(RMU_APB1RSTR_CAN0RST_POS) - -#define RMU_APB1RSTR_I2C1RST_POS 21U -#define RMU_APB1RSTR_I2C1RST_MSK BIT(RMU_APB1RSTR_I2C1RST_POS) - -#define RMU_APB1RSTR_I2C0RST_POS 20U -#define RMU_APB1RSTR_I2C0RST_MSK BIT(RMU_APB1RSTR_I2C0RST_POS) - -#define RMU_APB1RSTR_SPI2RST_POS 18U -#define RMU_APB1RSTR_SPI2RST_MSK BIT(RMU_APB1RSTR_SPI2RST_POS) - -#define RMU_APB1RSTR_SPI1RST_POS 17U -#define RMU_APB1RSTR_SPI1RST_MSK BIT(RMU_APB1RSTR_SPI1RST_POS) - -#define RMU_APB1RSTR_SPI0RST_POS 16U -#define RMU_APB1RSTR_SPI0RST_MSK BIT(RMU_APB1RSTR_SPI0RST_POS) - -#define RMU_APB1RSTR_USART1RST_POS 13U -#define RMU_APB1RSTR_USART1RST_MSK BIT(RMU_APB1RSTR_USART1RST_POS) - -#define RMU_APB1RSTR_USART0RST_POS 12U -#define RMU_APB1RSTR_USART0RST_MSK BIT(RMU_APB1RSTR_USART0RST_POS) - -#define RMU_APB1RSTR_UART3RST_POS 11U -#define RMU_APB1RSTR_UART3RST_MSK BIT(RMU_APB1RSTR_UART3RST_POS) - -#define RMU_APB1RSTR_UART2RST_POS 10U -#define RMU_APB1RSTR_UART2RST_MSK BIT(RMU_APB1RSTR_UART2RST_POS) - -#define RMU_APB1RSTR_UART1RST_POS 9U -#define RMU_APB1RSTR_UART1RST_MSK BIT(RMU_APB1RSTR_UART1RST_POS) - -#define RMU_APB1RSTR_UART0RST_POS 8U -#define RMU_APB1RSTR_UART0RST_MSK BIT(RMU_APB1RSTR_UART0RST_POS) - -#define RMU_APB1RSTR_TIM7RST_POS 7U -#define RMU_APB1RSTR_TIM7RST_MSK BIT(RMU_APB1RSTR_TIM7RST_POS) - -#define RMU_APB1RSTR_TIM6RST_POS 6U -#define RMU_APB1RSTR_TIM6RST_MSK BIT(RMU_APB1RSTR_TIM6RST_POS) - -#define RMU_APB1RSTR_TIM5RST_POS 5U -#define RMU_APB1RSTR_TIM5RST_MSK BIT(RMU_APB1RSTR_TIM5RST_POS) - -#define RMU_APB1RSTR_TIM4RST_POS 4U -#define RMU_APB1RSTR_TIM4RST_MSK BIT(RMU_APB1RSTR_TIM4RST_POS) - -#define RMU_APB1RSTR_TIM3RST_POS 3U -#define RMU_APB1RSTR_TIM3RST_MSK BIT(RMU_APB1RSTR_TIM3RST_POS) - -#define RMU_APB1RSTR_TIM2RST_POS 2U -#define RMU_APB1RSTR_TIM2RST_MSK BIT(RMU_APB1RSTR_TIM2RST_POS) - -#define RMU_APB1RSTR_TIM1RST_POS 1U -#define RMU_APB1RSTR_TIM1RST_MSK BIT(RMU_APB1RSTR_TIM1RST_POS) - -#define RMU_APB1RSTR_TIM0RST_POS 0U -#define RMU_APB1RSTR_TIM0RST_MSK BIT(RMU_APB1RSTR_TIM0RST_POS) - -/****************** Bit definition for RMU_APB2RSTR register ************************/ - -#define RMU_APB2RSTR_BKPRAMRST_POS 18U -#define RMU_APB2RSTR_BKPRAMRST_MSK BIT(RMU_APB2RSTR_BKPRAMRST_POS) - -#define RMU_APB2RSTR_BKPCRST_POS 17U -#define RMU_APB2RSTR_BKPCRST_MSK BIT(RMU_APB2RSTR_BKPCRST_POS) - -#define RMU_APB2RSTR_TEMPRST_POS 16U -#define RMU_APB2RSTR_TEMPRST_MSK BIT(RMU_APB2RSTR_TEMPRST_POS) - -#define RMU_APB2RSTR_RTCRST_POS 15U -#define RMU_APB2RSTR_RTCRST_MSK BIT(RMU_APB2RSTR_RTCRST_POS) - -#define RMU_APB2RSTR_IWDTRST_POS 14U -#define RMU_APB2RSTR_IWDTRST_MSK BIT(RMU_APB2RSTR_IWDTRST_POS) - -#define RMU_APB2RSTR_LCDRST_POS 13U -#define RMU_APB2RSTR_LCDRST_MSK BIT(RMU_APB2RSTR_LCDRST_POS) - -#define RMU_APB2RSTR_WWDTRST_POS 12U -#define RMU_APB2RSTR_WWDTRST_MSK BIT(RMU_APB2RSTR_WWDTRST_POS) - -#define RMU_APB2RSTR_OPAMPRST_POS 8U -#define RMU_APB2RSTR_OPAMPRST_MSK BIT(RMU_APB2RSTR_OPAMPRST_POS) - -#define RMU_APB2RSTR_ACMP1RST_POS 7U -#define RMU_APB2RSTR_ACMP1RST_MSK BIT(RMU_APB2RSTR_ACMP1RST_POS) - -#define RMU_APB2RSTR_ACMP0RST_POS 6U -#define RMU_APB2RSTR_ACMP0RST_MSK BIT(RMU_APB2RSTR_ACMP0RST_POS) - -#define RMU_APB2RSTR_ADC0RST_POS 4U -#define RMU_APB2RSTR_ADC0RST_MSK BIT(RMU_APB2RSTR_ADC0RST_POS) - -#define RMU_APB2RSTR_LPUART0RST_POS 2U -#define RMU_APB2RSTR_LPUART0RST_MSK BIT(RMU_APB2RSTR_LPUART0RST_POS) - -#define RMU_APB2RSTR_LPTIM0RST_POS 0U -#define RMU_APB2RSTR_LPTIM0RST_MSK BIT(RMU_APB2RSTR_LPTIM0RST_POS) - -typedef struct -{ - __IO uint32_t CR; - uint32_t RESERVED0[3] ; - __I uint32_t RSTSR; - __O uint32_t CRSTSR; - uint32_t RESERVED1[2] ; - __O uint32_t AHB1RSTR; - __O uint32_t AHB2RSTR; - uint32_t RESERVED2[2] ; - __O uint32_t APB1RSTR; - __O uint32_t APB2RSTR; -} RMU_TypeDef; - -/****************** Bit definition for CMU_CSR register ************************/ - -#define CMU_CSR_CFT_RDYN_POS 25U -#define CMU_CSR_CFT_RDYN_MSK BIT(CMU_CSR_CFT_RDYN_POS) - -#define CMU_CSR_CFT_STU_POS 24U -#define CMU_CSR_CFT_STU_MSK BIT(CMU_CSR_CFT_STU_POS) - -#define CMU_CSR_CFT_CMD_POSS 16U -#define CMU_CSR_CFT_CMD_POSE 23U -#define CMU_CSR_CFT_CMD_MSK BITS(CMU_CSR_CFT_CMD_POSS,CMU_CSR_CFT_CMD_POSE) - -#define CMU_CSR_SYS_RDYN_POS 12U -#define CMU_CSR_SYS_RDYN_MSK BIT(CMU_CSR_SYS_RDYN_POS) - -#define CMU_CSR_SYS_STU_POSS 8U -#define CMU_CSR_SYS_STU_POSE 10U -#define CMU_CSR_SYS_STU_MSK BITS(CMU_CSR_SYS_STU_POSS,CMU_CSR_SYS_STU_POSE) - -#define CMU_CSR_SYS_CMD_POSS 0U -#define CMU_CSR_SYS_CMD_POSE 2U -#define CMU_CSR_SYS_CMD_MSK BITS(CMU_CSR_SYS_CMD_POSS,CMU_CSR_SYS_CMD_POSE) - -/****************** Bit definition for CMU_CFGR register ************************/ - -#define CMU_CFGR_HRCFST_POS 25U -#define CMU_CFGR_HRCFST_MSK BIT(CMU_CFGR_HRCFST_POS) - -#define CMU_CFGR_HRCFSW_POS 24U -#define CMU_CFGR_HRCFSW_MSK BIT(CMU_CFGR_HRCFSW_POS) - -#define CMU_CFGR_PCLK2DIV_POSS 20U -#define CMU_CFGR_PCLK2DIV_POSE 23U -#define CMU_CFGR_PCLK2DIV_MSK BITS(CMU_CFGR_PCLK2DIV_POSS,CMU_CFGR_PCLK2DIV_POSE) - -#define CMU_CFGR_PCLK1DIV_POSS 16U -#define CMU_CFGR_PCLK1DIV_POSE 19U -#define CMU_CFGR_PCLK1DIV_MSK BITS(CMU_CFGR_PCLK1DIV_POSS,CMU_CFGR_PCLK1DIV_POSE) - -#define CMU_CFGR_SYSDIV_POSS 12U -#define CMU_CFGR_SYSDIV_POSE 15U -#define CMU_CFGR_SYSDIV_MSK BITS(CMU_CFGR_SYSDIV_POSS,CMU_CFGR_SYSDIV_POSE) - -#define CMU_CFGR_HCLK1DIV_POSS 0U -#define CMU_CFGR_HCLK1DIV_POSE 3U -#define CMU_CFGR_HCLK1DIV_MSK BITS(CMU_CFGR_HCLK1DIV_POSS,CMU_CFGR_HCLK1DIV_POSE) - -/****************** Bit definition for CMU_CLKENR register ************************/ - -#define CMU_CLKENR_PLL2EN_POS 9U -#define CMU_CLKENR_PLL2EN_MSK BIT(CMU_CLKENR_PLL2EN_POS) - -#define CMU_CLKENR_PLL1EN_POS 8U -#define CMU_CLKENR_PLL1EN_MSK BIT(CMU_CLKENR_PLL1EN_POS) - -#define CMU_CLKENR_ULRCEN_POS 4U -#define CMU_CLKENR_ULRCEN_MSK BIT(CMU_CLKENR_ULRCEN_POS) - -#define CMU_CLKENR_LRCEN_POS 3U -#define CMU_CLKENR_LRCEN_MSK BIT(CMU_CLKENR_LRCEN_POS) - -#define CMU_CLKENR_HRCEN_POS 2U -#define CMU_CLKENR_HRCEN_MSK BIT(CMU_CLKENR_HRCEN_POS) - -#define CMU_CLKENR_LOSCEN_POS 1U -#define CMU_CLKENR_LOSCEN_MSK BIT(CMU_CLKENR_LOSCEN_POS) - -#define CMU_CLKENR_HOSCEN_POS 0U -#define CMU_CLKENR_HOSCEN_MSK BIT(CMU_CLKENR_HOSCEN_POS) - -/****************** Bit definition for CMU_CLKSR register ************************/ - -#define CMU_CLKSR_PLL2RDY_POS 25U -#define CMU_CLKSR_PLL2RDY_MSK BIT(CMU_CLKSR_PLL2RDY_POS) - -#define CMU_CLKSR_PLL1RDY_POS 24U -#define CMU_CLKSR_PLL1RDY_MSK BIT(CMU_CLKSR_PLL1RDY_POS) - -#define CMU_CLKSR_LRCRDY_POS 19U -#define CMU_CLKSR_LRCRDY_MSK BIT(CMU_CLKSR_LRCRDY_POS) - -#define CMU_CLKSR_HRCRDY_POS 18U -#define CMU_CLKSR_HRCRDY_MSK BIT(CMU_CLKSR_HRCRDY_POS) - -#define CMU_CLKSR_LOSCRDY_POS 17U -#define CMU_CLKSR_LOSCRDY_MSK BIT(CMU_CLKSR_LOSCRDY_POS) - -#define CMU_CLKSR_HOSCRDY_POS 16U -#define CMU_CLKSR_HOSCRDY_MSK BIT(CMU_CLKSR_HOSCRDY_POS) - -#define CMU_CLKSR_PLL2ACT_POS 9U -#define CMU_CLKSR_PLL2ACT_MSK BIT(CMU_CLKSR_PLL2ACT_POS) - -#define CMU_CLKSR_PLL1ACT_POS 8U -#define CMU_CLKSR_PLL1ACT_MSK BIT(CMU_CLKSR_PLL1ACT_POS) - -#define CMU_CLKSR_ULRCACT_POS 4U -#define CMU_CLKSR_ULRCACT_MSK BIT(CMU_CLKSR_ULRCACT_POS) - -#define CMU_CLKSR_LRCACT_POS 3U -#define CMU_CLKSR_LRCACT_MSK BIT(CMU_CLKSR_LRCACT_POS) - -#define CMU_CLKSR_HRCACT_POS 2U -#define CMU_CLKSR_HRCACT_MSK BIT(CMU_CLKSR_HRCACT_POS) - -#define CMU_CLKSR_LOSCACT_POS 1U -#define CMU_CLKSR_LOSCACT_MSK BIT(CMU_CLKSR_LOSCACT_POS) - -#define CMU_CLKSR_HOSCACT_POS 0U -#define CMU_CLKSR_HOSCACT_MSK BIT(CMU_CLKSR_HOSCACT_POS) - -/****************** Bit definition for CMU_PLLCFG register ************************/ - -#define CMU_PLLCFG_PLL2LCKN_POS 17U -#define CMU_PLLCFG_PLL2LCKN_MSK BIT(CMU_PLLCFG_PLL2LCKN_POS) - -#define CMU_PLLCFG_PLL1LCKN_POS 16U -#define CMU_PLLCFG_PLL1LCKN_MSK BIT(CMU_PLLCFG_PLL1LCKN_POS) - -#define CMU_PLLCFG_PLL2RFS_POSS 8U -#define CMU_PLLCFG_PLL2RFS_POSE 9U -#define CMU_PLLCFG_PLL2RFS_MSK BITS(CMU_PLLCFG_PLL2RFS_POSS,CMU_PLLCFG_PLL2RFS_POSE) - -#define CMU_PLLCFG_PLL1OS_POS 4U -#define CMU_PLLCFG_PLL1OS_MSK BIT(CMU_PLLCFG_PLL1OS_POS) - -#define CMU_PLLCFG_PLL1RFS_POSS 0U -#define CMU_PLLCFG_PLL1RFS_POSE 2U -#define CMU_PLLCFG_PLL1RFS_MSK BITS(CMU_PLLCFG_PLL1RFS_POSS,CMU_PLLCFG_PLL1RFS_POSE) - -/****************** Bit definition for CMU_HOSCCFG register ************************/ - -#define CMU_HOSCCFG_FREQ_POSS 0U -#define CMU_HOSCCFG_FREQ_POSE 4U -#define CMU_HOSCCFG_FREQ_MSK BITS(CMU_HOSCCFG_FREQ_POSS,CMU_HOSCCFG_FREQ_POSE) - -/****************** Bit definition for CMU_HOSMCR register ************************/ - -#define CMU_HOSMCR_NMIE_POS 20U -#define CMU_HOSMCR_NMIE_MSK BIT(CMU_HOSMCR_NMIE_POS) - -#define CMU_HOSMCR_STPIF_POS 19U -#define CMU_HOSMCR_STPIF_MSK BIT(CMU_HOSMCR_STPIF_POS) - -#define CMU_HOSMCR_STRIF_POS 18U -#define CMU_HOSMCR_STRIF_MSK BIT(CMU_HOSMCR_STRIF_POS) - -#define CMU_HOSMCR_STPIE_POS 17U -#define CMU_HOSMCR_STPIE_MSK BIT(CMU_HOSMCR_STPIE_POS) - -#define CMU_HOSMCR_STRIE_POS 16U -#define CMU_HOSMCR_STRIE_MSK BIT(CMU_HOSMCR_STRIE_POS) - -#define CMU_HOSMCR_FRQS_POSS 8U -#define CMU_HOSMCR_FRQS_POSE 10U -#define CMU_HOSMCR_FRQS_MSK BITS(CMU_HOSMCR_FRQS_POSS,CMU_HOSMCR_FRQS_POSE) - -#define CMU_HOSMCR_CLKS_POS 1U -#define CMU_HOSMCR_CLKS_MSK BIT(CMU_HOSMCR_CLKS_POS) - -#define CMU_HOSMCR_EN_POS 0U -#define CMU_HOSMCR_EN_MSK BIT(CMU_HOSMCR_EN_POS) - -/****************** Bit definition for CMU_LOSMCR register ************************/ - -#define CMU_LOSMCR_NMIE_POS 20U -#define CMU_LOSMCR_NMIE_MSK BIT(CMU_LOSMCR_NMIE_POS) - -#define CMU_LOSMCR_STPIF_POS 19U -#define CMU_LOSMCR_STPIF_MSK BIT(CMU_LOSMCR_STPIF_POS) - -#define CMU_LOSMCR_STRIF_POS 18U -#define CMU_LOSMCR_STRIF_MSK BIT(CMU_LOSMCR_STRIF_POS) - -#define CMU_LOSMCR_STPIE_POS 17U -#define CMU_LOSMCR_STPIE_MSK BIT(CMU_LOSMCR_STPIE_POS) - -#define CMU_LOSMCR_STRIE_POS 16U -#define CMU_LOSMCR_STRIE_MSK BIT(CMU_LOSMCR_STRIE_POS) - -#define CMU_LOSMCR_CLKS_POS 1U -#define CMU_LOSMCR_CLKS_MSK BIT(CMU_LOSMCR_CLKS_POS) - -#define CMU_LOSMCR_EN_POS 0U -#define CMU_LOSMCR_EN_MSK BIT(CMU_LOSMCR_EN_POS) - -/****************** Bit definition for CMU_PULMCR register ************************/ - -#define CMU_PULMCR_NMIE_POS 20U -#define CMU_PULMCR_NMIE_MSK BIT(CMU_PULMCR_NMIE_POS) - -#define CMU_PULMCR_ULKIF_POS 19U -#define CMU_PULMCR_ULKIF_MSK BIT(CMU_PULMCR_ULKIF_POS) - -#define CMU_PULMCR_LCKIF_POS 18U -#define CMU_PULMCR_LCKIF_MSK BIT(CMU_PULMCR_LCKIF_POS) - -#define CMU_PULMCR_ULKIE_POS 17U -#define CMU_PULMCR_ULKIE_MSK BIT(CMU_PULMCR_ULKIE_POS) - -#define CMU_PULMCR_LCKIE_POS 16U -#define CMU_PULMCR_LCKIE_MSK BIT(CMU_PULMCR_LCKIE_POS) - -#define CMU_PULMCR_MODE_POSS 8U -#define CMU_PULMCR_MODE_POSE 9U -#define CMU_PULMCR_MODE_MSK BITS(CMU_PULMCR_MODE_POSS,CMU_PULMCR_MODE_POSE) - -#define CMU_PULMCR_CLKS_POS 1U -#define CMU_PULMCR_CLKS_MSK BIT(CMU_PULMCR_CLKS_POS) - -#define CMU_PULMCR_EN_POS 0U -#define CMU_PULMCR_EN_MSK BIT(CMU_PULMCR_EN_POS) - -/****************** Bit definition for CMU_CLKOCR register ************************/ - -#define CMU_CLKOCR_LSCOS_POSS 24U -#define CMU_CLKOCR_LSCOS_POSE 26U -#define CMU_CLKOCR_LSCOS_MSK BITS(CMU_CLKOCR_LSCOS_POSS,CMU_CLKOCR_LSCOS_POSE) - -#define CMU_CLKOCR_LSCOEN_POS 16U -#define CMU_CLKOCR_LSCOEN_MSK BIT(CMU_CLKOCR_LSCOEN_POS) - -#define CMU_CLKOCR_HSCODIV_POSS 12U -#define CMU_CLKOCR_HSCODIV_POSE 14U -#define CMU_CLKOCR_HSCODIV_MSK BITS(CMU_CLKOCR_HSCODIV_POSS,CMU_CLKOCR_HSCODIV_POSE) - -#define CMU_CLKOCR_HSCOS_POSS 8U -#define CMU_CLKOCR_HSCOS_POSE 10U -#define CMU_CLKOCR_HSCOS_MSK BITS(CMU_CLKOCR_HSCOS_POSS,CMU_CLKOCR_HSCOS_POSE) - -#define CMU_CLKOCR_HSCOEN_POS 0U -#define CMU_CLKOCR_HSCOEN_MSK BIT(CMU_CLKOCR_HSCOEN_POS) - -/****************** Bit definition for CMU_BUZZCR register ************************/ - -#define CMU_BUZZCR_DAT_POSS 16U -#define CMU_BUZZCR_DAT_POSE 31U -#define CMU_BUZZCR_DAT_MSK BITS(CMU_BUZZCR_DAT_POSS,CMU_BUZZCR_DAT_POSE) - -#define CMU_BUZZCR_DIV_POSS 8U -#define CMU_BUZZCR_DIV_POSE 10U -#define CMU_BUZZCR_DIV_MSK BITS(CMU_BUZZCR_DIV_POSS,CMU_BUZZCR_DIV_POSE) - -#define CMU_BUZZCR_EN_POS 0U -#define CMU_BUZZCR_EN_MSK BIT(CMU_BUZZCR_EN_POS) - -/****************** Bit definition for CMU_AHB1ENR register ************************/ - -#define CMU_AHB1ENR_PISEN_POS 5U -#define CMU_AHB1ENR_PISEN_MSK BIT(CMU_AHB1ENR_PISEN_POS) - -#define CMU_AHB1ENR_TRNGEN_POS 4U -#define CMU_AHB1ENR_TRNGEN_MSK BIT(CMU_AHB1ENR_TRNGEN_POS) - -#define CMU_AHB1ENR_CRYPTEN_POS 3U -#define CMU_AHB1ENR_CRYPTEN_MSK BIT(CMU_AHB1ENR_CRYPTEN_POS) - -#define CMU_AHB1ENR_CALCEN_POS 2U -#define CMU_AHB1ENR_CALCEN_MSK BIT(CMU_AHB1ENR_CALCEN_POS) - -#define CMU_AHB1ENR_CRCEN_POS 1U -#define CMU_AHB1ENR_CRCEN_MSK BIT(CMU_AHB1ENR_CRCEN_POS) - -#define CMU_AHB1ENR_GPIOEN_POS 0U -#define CMU_AHB1ENR_GPIOEN_MSK BIT(CMU_AHB1ENR_GPIOEN_POS) - -/****************** Bit definition for CMU_APB1ENR register ************************/ - -#define CMU_APB1ENR_CAN0EN_POS 24U -#define CMU_APB1ENR_CAN0EN_MSK BIT(CMU_APB1ENR_CAN0EN_POS) - -#define CMU_APB1ENR_I2C1EN_POS 21U -#define CMU_APB1ENR_I2C1EN_MSK BIT(CMU_APB1ENR_I2C1EN_POS) - -#define CMU_APB1ENR_I2C0EN_POS 20U -#define CMU_APB1ENR_I2C0EN_MSK BIT(CMU_APB1ENR_I2C0EN_POS) - -#define CMU_APB1ENR_SPI2EN_POS 18U -#define CMU_APB1ENR_SPI2EN_MSK BIT(CMU_APB1ENR_SPI2EN_POS) - -#define CMU_APB1ENR_SPI1EN_POS 17U -#define CMU_APB1ENR_SPI1EN_MSK BIT(CMU_APB1ENR_SPI1EN_POS) - -#define CMU_APB1ENR_SPI0EN_POS 16U -#define CMU_APB1ENR_SPI0EN_MSK BIT(CMU_APB1ENR_SPI0EN_POS) - -#define CMU_APB1ENR_USART1EN_POS 13U -#define CMU_APB1ENR_USART1EN_MSK BIT(CMU_APB1ENR_USART1EN_POS) - -#define CMU_APB1ENR_USART0EN_POS 12U -#define CMU_APB1ENR_USART0EN_MSK BIT(CMU_APB1ENR_USART0EN_POS) - -#define CMU_APB1ENR_UART3EN_POS 11U -#define CMU_APB1ENR_UART3EN_MSK BIT(CMU_APB1ENR_UART3EN_POS) - -#define CMU_APB1ENR_UART2EN_POS 10U -#define CMU_APB1ENR_UART2EN_MSK BIT(CMU_APB1ENR_UART2EN_POS) - -#define CMU_APB1ENR_UART1EN_POS 9U -#define CMU_APB1ENR_UART1EN_MSK BIT(CMU_APB1ENR_UART1EN_POS) - -#define CMU_APB1ENR_UART0EN_POS 8U -#define CMU_APB1ENR_UART0EN_MSK BIT(CMU_APB1ENR_UART0EN_POS) - -#define CMU_APB1ENR_TIM7EN_POS 7U -#define CMU_APB1ENR_TIM7EN_MSK BIT(CMU_APB1ENR_TIM7EN_POS) - -#define CMU_APB1ENR_TIM6EN_POS 6U -#define CMU_APB1ENR_TIM6EN_MSK BIT(CMU_APB1ENR_TIM6EN_POS) - -#define CMU_APB1ENR_TIM5EN_POS 5U -#define CMU_APB1ENR_TIM5EN_MSK BIT(CMU_APB1ENR_TIM5EN_POS) - -#define CMU_APB1ENR_TIM4EN_POS 4U -#define CMU_APB1ENR_TIM4EN_MSK BIT(CMU_APB1ENR_TIM4EN_POS) - -#define CMU_APB1ENR_TIM3EN_POS 3U -#define CMU_APB1ENR_TIM3EN_MSK BIT(CMU_APB1ENR_TIM3EN_POS) - -#define CMU_APB1ENR_TIM2EN_POS 2U -#define CMU_APB1ENR_TIM2EN_MSK BIT(CMU_APB1ENR_TIM2EN_POS) - -#define CMU_APB1ENR_TIM1EN_POS 1U -#define CMU_APB1ENR_TIM1EN_MSK BIT(CMU_APB1ENR_TIM1EN_POS) - -#define CMU_APB1ENR_TIM0EN_POS 0U -#define CMU_APB1ENR_TIM0EN_MSK BIT(CMU_APB1ENR_TIM0EN_POS) - -/****************** Bit definition for CMU_APB2ENR register ************************/ - -#define CMU_APB2ENR_DBGCEN_POS 19U -#define CMU_APB2ENR_DBGCEN_MSK BIT(CMU_APB2ENR_DBGCEN_POS) - -#define CMU_APB2ENR_BKPCEN_POS 17U -#define CMU_APB2ENR_BKPCEN_MSK BIT(CMU_APB2ENR_BKPCEN_POS) - -#define CMU_APB2ENR_TEMPEN_POS 16U -#define CMU_APB2ENR_TEMPEN_MSK BIT(CMU_APB2ENR_TEMPEN_POS) - -#define CMU_APB2ENR_RTCEN_POS 15U -#define CMU_APB2ENR_RTCEN_MSK BIT(CMU_APB2ENR_RTCEN_POS) - -#define CMU_APB2ENR_IWDTEN_POS 14U -#define CMU_APB2ENR_IWDTEN_MSK BIT(CMU_APB2ENR_IWDTEN_POS) - -#define CMU_APB2ENR_LCDEN_POS 13U -#define CMU_APB2ENR_LCDEN_MSK BIT(CMU_APB2ENR_LCDEN_POS) - -#define CMU_APB2ENR_WWDTEN_POS 12U -#define CMU_APB2ENR_WWDTEN_MSK BIT(CMU_APB2ENR_WWDTEN_POS) - -#define CMU_APB2ENR_OPAMPEN_POS 8U -#define CMU_APB2ENR_OPAMPEN_MSK BIT(CMU_APB2ENR_OPAMPEN_POS) - -#define CMU_APB2ENR_ACMP1EN_POS 7U -#define CMU_APB2ENR_ACMP1EN_MSK BIT(CMU_APB2ENR_ACMP1EN_POS) - -#define CMU_APB2ENR_ACMP0EN_POS 6U -#define CMU_APB2ENR_ACMP0EN_MSK BIT(CMU_APB2ENR_ACMP0EN_POS) - -#define CMU_APB2ENR_ADC0EN_POS 4U -#define CMU_APB2ENR_ADC0EN_MSK BIT(CMU_APB2ENR_ADC0EN_POS) - -#define CMU_APB2ENR_LPUART0EN_POS 2U -#define CMU_APB2ENR_LPUART0EN_MSK BIT(CMU_APB2ENR_LPUART0EN_POS) - -#define CMU_APB2ENR_LPTIM0EN_POS 0U -#define CMU_APB2ENR_LPTIM0EN_MSK BIT(CMU_APB2ENR_LPTIM0EN_POS) - -/****************** Bit definition for CMU_LPENR register ************************/ - -#define CMU_LPENR_HOSCEN_POS 3U -#define CMU_LPENR_HOSCEN_MSK BIT(CMU_LPENR_HOSCEN_POS) - -#define CMU_LPENR_HRCEN_POS 2U -#define CMU_LPENR_HRCEN_MSK BIT(CMU_LPENR_HRCEN_POS) - -#define CMU_LPENR_LOSCEN_POS 1U -#define CMU_LPENR_LOSCEN_MSK BIT(CMU_LPENR_LOSCEN_POS) - -#define CMU_LPENR_LRCEN_POS 0U -#define CMU_LPENR_LRCEN_MSK BIT(CMU_LPENR_LRCEN_POS) - -/****************** Bit definition for CMU_PERICR register ************************/ - -#define CMU_PERICR_LCD_POSS 16U -#define CMU_PERICR_LCD_POSE 18U -#define CMU_PERICR_LCD_MSK BITS(CMU_PERICR_LCD_POSS,CMU_PERICR_LCD_POSE) - -#define CMU_PERICR_LPUART0_POSS 8U -#define CMU_PERICR_LPUART0_POSE 11U -#define CMU_PERICR_LPUART0_MSK BITS(CMU_PERICR_LPUART0_POSS,CMU_PERICR_LPUART0_POSE) - -#define CMU_PERICR_LPTIM0_POSS 0U -#define CMU_PERICR_LPTIM0_POSE 3U -#define CMU_PERICR_LPTIM0_MSK BITS(CMU_PERICR_LPTIM0_POSS,CMU_PERICR_LPTIM0_POSE) - -/****************** Bit definition for CMU_HRCACR register ************************/ - -#define CMU_HRCACR_IB_POSS 28U -#define CMU_HRCACR_IB_POSE 29U -#define CMU_HRCACR_IB_MSK BITS(CMU_HRCACR_IB_POSS,CMU_HRCACR_IB_POSE) - -#define CMU_HRCACR_CAP_POSS 26U -#define CMU_HRCACR_CAP_POSE 27U -#define CMU_HRCACR_CAP_MSK BITS(CMU_HRCACR_CAP_POSS,CMU_HRCACR_CAP_POSE) - -#define CMU_HRCACR_CAL_POSS 16U -#define CMU_HRCACR_CAL_POSE 25U -#define CMU_HRCACR_CAL_MSK BITS(CMU_HRCACR_CAL_POSS,CMU_HRCACR_CAL_POSE) - -#define CMU_HRCACR_IBSET_POSS 14U -#define CMU_HRCACR_IBSET_POSE 15U -#define CMU_HRCACR_IBSET_MSK BITS(CMU_HRCACR_IBSET_POSS,CMU_HRCACR_IBSET_POSE) - -#define CMU_HRCACR_CAPSET_POSS 12U -#define CMU_HRCACR_CAPSET_POSE 13U -#define CMU_HRCACR_CAPSET_MSK BITS(CMU_HRCACR_CAPSET_POSS,CMU_HRCACR_CAPSET_POSE) - -#define CMU_HRCACR_STA_POSS 9U -#define CMU_HRCACR_STA_POSE 10U -#define CMU_HRCACR_STA_MSK BITS(CMU_HRCACR_STA_POSS,CMU_HRCACR_STA_POSE) - -#define CMU_HRCACR_BUSY_POS 8U -#define CMU_HRCACR_BUSY_MSK BIT(CMU_HRCACR_BUSY_POS) - -#define CMU_HRCACR_WRTRG_POS 7U -#define CMU_HRCACR_WRTRG_MSK BIT(CMU_HRCACR_WRTRG_POS) - -#define CMU_HRCACR_AC_POSS 4U -#define CMU_HRCACR_AC_POSE 6U -#define CMU_HRCACR_AC_MSK BITS(CMU_HRCACR_AC_POSS,CMU_HRCACR_AC_POSE) - -#define CMU_HRCACR_IBS_POS 3U -#define CMU_HRCACR_IBS_MSK BIT(CMU_HRCACR_IBS_POS) - -#define CMU_HRCACR_RFSEL_POS 2U -#define CMU_HRCACR_RFSEL_MSK BIT(CMU_HRCACR_RFSEL_POS) - -#define CMU_HRCACR_FREQ_POS 1U -#define CMU_HRCACR_FREQ_MSK BIT(CMU_HRCACR_FREQ_POS) - -#define CMU_HRCACR_EN_POS 0U -#define CMU_HRCACR_EN_MSK BIT(CMU_HRCACR_EN_POS) - -typedef struct -{ - __O uint32_t CSR; - __IO uint32_t CFGR; - uint32_t RESERVED0[2] ; - __IO uint32_t CLKENR; - __I uint32_t CLKSR; - __IO uint32_t PLLCFG; - __IO uint32_t HOSCCFG; - __IO uint32_t HOSMCR; - __IO uint32_t LOSMCR; - __IO uint32_t PULMCR; - uint32_t RESERVED1 ; - __IO uint32_t CLKOCR; - __IO uint32_t BUZZCR; - uint32_t RESERVED2[2] ; - __IO uint32_t AHB1ENR; - uint32_t RESERVED3[3] ; - __IO uint32_t APB1ENR; - __IO uint32_t APB2ENR; - uint32_t RESERVED4[2] ; - __IO uint32_t LPENR; - uint32_t RESERVED5[7] ; - __IO uint32_t PERICR; - uint32_t RESERVED6[3] ; - __IO uint32_t HRCACR; -} CMU_TypeDef; - -/****************** Bit definition for DMA_STATUS register ************************/ - -#define DMA_STATUS_STATUS_POSS 4U -#define DMA_STATUS_STATUS_POSE 7U -#define DMA_STATUS_STATUS_MSK BITS(DMA_STATUS_STATUS_POSS,DMA_STATUS_STATUS_POSE) - -#define DMA_STATUS_MASTER_ENABLE_POS 0U -#define DMA_STATUS_MASTER_ENABLE_MSK BIT(DMA_STATUS_MASTER_ENABLE_POS) - -/****************** Bit definition for DMA_CFG register ************************/ - -#define DMA_CFG_CHNL_PROT_CTRL_POSS 5U -#define DMA_CFG_CHNL_PROT_CTRL_POSE 7U -#define DMA_CFG_CHNL_PROT_CTRL_MSK BITS(DMA_CFG_CHNL_PROT_CTRL_POSS,DMA_CFG_CHNL_PROT_CTRL_POSE) - -#define DMA_CFG_MASTER_ENABLE_POS 0U -#define DMA_CFG_MASTER_ENABLE_MSK BIT(DMA_CFG_MASTER_ENABLE_POS) - -/****************** Bit definition for DMA_CTRLBASE register ************************/ - -#define DMA_CTRLBASE_CTRL_BASE_PTR_POSS 9U -#define DMA_CTRLBASE_CTRL_BASE_PTR_POSE 31U -#define DMA_CTRLBASE_CTRL_BASE_PTR_MSK BITS(DMA_CTRLBASE_CTRL_BASE_PTR_POSS,DMA_CTRLBASE_CTRL_BASE_PTR_POSE) - -/****************** Bit definition for DMA_ALTCTRLBASE register ************************/ - -#define DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_POSS 0U -#define DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_POSE 31U -#define DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_MSK BITS(DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_POSS,DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_POSE) - -/****************** Bit definition for DMA_CHWAITSTATUS register ************************/ - -#define DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_POSS 0U -#define DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_POSE 31U -#define DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_MSK BITS(DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_POSS,DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_POSE) - -/****************** Bit definition for DMA_CHSWREQ register ************************/ - -#define DMA_CHSWREQ_CHSWREQ_POSS 0U -#define DMA_CHSWREQ_CHSWREQ_POSE 31U -#define DMA_CHSWREQ_CHSWREQ_MSK BITS(DMA_CHSWREQ_CHSWREQ_POSS,DMA_CHSWREQ_CHSWREQ_POSE) - -/****************** Bit definition for DMA_CHUSEBURSTSET register ************************/ - -#define DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_POSS 0U -#define DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_POSE 31U -#define DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_MSK BITS(DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_POSS,DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_POSE) - -/****************** Bit definition for DMA_CHUSEBURSTCLR register ************************/ - -#define DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_POSS 0U -#define DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_POSE 31U -#define DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_MSK BITS(DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_POSS,DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_POSE) - -/****************** Bit definition for DMA_CHREQMASKSET register ************************/ - -#define DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_POSS 0U -#define DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_POSE 31U -#define DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_MSK BITS(DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_POSS,DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_POSE) - -/****************** Bit definition for DMA_CHREQMASKCLR register ************************/ - -#define DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_POSS 0U -#define DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_POSE 31U -#define DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_MSK BITS(DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_POSS,DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_POSE) - -/****************** Bit definition for DMA_CHENSET register ************************/ - -#define DMA_CHENSET_CHNL_ENABLE_SET_POSS 0U -#define DMA_CHENSET_CHNL_ENABLE_SET_POSE 31U -#define DMA_CHENSET_CHNL_ENABLE_SET_MSK BITS(DMA_CHENSET_CHNL_ENABLE_SET_POSS,DMA_CHENSET_CHNL_ENABLE_SET_POSE) - -/****************** Bit definition for DMA_CHENCLR register ************************/ - -#define DMA_CHENCLR_CHNL_ENABLE_CLR_POSS 0U -#define DMA_CHENCLR_CHNL_ENABLE_CLR_POSE 31U -#define DMA_CHENCLR_CHNL_ENABLE_CLR_MSK BITS(DMA_CHENCLR_CHNL_ENABLE_CLR_POSS,DMA_CHENCLR_CHNL_ENABLE_CLR_POSE) - -/****************** Bit definition for DMA_CHPRIALTSET register ************************/ - -#define DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_POSS 0U -#define DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_POSE 31U -#define DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_MSK BITS(DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_POSS,DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_POSE) - -/****************** Bit definition for DMA_CHPRIALTCLR register ************************/ - -#define DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_POSS 0U -#define DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_POSE 31U -#define DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_MSK BITS(DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_POSS,DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_POSE) - -/****************** Bit definition for DMA_CHPRSET register ************************/ - -#define DMA_CHPRSET_CHNL_PRIORITY_SET_POSS 0U -#define DMA_CHPRSET_CHNL_PRIORITY_SET_POSE 31U -#define DMA_CHPRSET_CHNL_PRIORITY_SET_MSK BITS(DMA_CHPRSET_CHNL_PRIORITY_SET_POSS,DMA_CHPRSET_CHNL_PRIORITY_SET_POSE) - -/****************** Bit definition for DMA_CHPRCLR register ************************/ - -#define DMA_CHPRCLR_CHNL_PRIORITY_CLR_POSS 0U -#define DMA_CHPRCLR_CHNL_PRIORITY_CLR_POSE 31U -#define DMA_CHPRCLR_CHNL_PRIORITY_CLR_MSK BITS(DMA_CHPRCLR_CHNL_PRIORITY_CLR_POSS,DMA_CHPRCLR_CHNL_PRIORITY_CLR_POSE) - -/****************** Bit definition for DMA_ERRCLR register ************************/ - -#define DMA_ERRCLR_ERR_CLR_POS 0U -#define DMA_ERRCLR_ERR_CLR_MSK BIT(DMA_ERRCLR_ERR_CLR_POS) - -/****************** Bit definition for DMA_IFLAG register ************************/ - -#define DMA_IFLAG_DMAERRIF_POS 31U -#define DMA_IFLAG_DMAERRIF_MSK BIT(DMA_IFLAG_DMAERRIF_POS) - -#define DMA_IFLAG_CH5DONEIF_POS 5U -#define DMA_IFLAG_CH5DONEIF_MSK BIT(DMA_IFLAG_CH5DONEIF_POS) - -#define DMA_IFLAG_CH4DONEIF_POS 4U -#define DMA_IFLAG_CH4DONEIF_MSK BIT(DMA_IFLAG_CH4DONEIF_POS) - -#define DMA_IFLAG_CH3DONEIF_POS 3U -#define DMA_IFLAG_CH3DONEIF_MSK BIT(DMA_IFLAG_CH3DONEIF_POS) - -#define DMA_IFLAG_CH2DONEIF_POS 2U -#define DMA_IFLAG_CH2DONEIF_MSK BIT(DMA_IFLAG_CH2DONEIF_POS) - -#define DMA_IFLAG_CH1DONEIF_POS 1U -#define DMA_IFLAG_CH1DONEIF_MSK BIT(DMA_IFLAG_CH1DONEIF_POS) - -#define DMA_IFLAG_CH0DONEIF_POS 0U -#define DMA_IFLAG_CH0DONEIF_MSK BIT(DMA_IFLAG_CH0DONEIF_POS) - -/****************** Bit definition for DMA_ICFR register ************************/ - -#define DMA_ICFR_DMAERRC_POS 31U -#define DMA_ICFR_DMAERRC_MSK BIT(DMA_ICFR_DMAERRC_POS) - -#define DMA_ICFR_CH5DONEC_POS 5U -#define DMA_ICFR_CH5DONEC_MSK BIT(DMA_ICFR_CH5DONEC_POS) - -#define DMA_ICFR_CH4DONEC_POS 4U -#define DMA_ICFR_CH4DONEC_MSK BIT(DMA_ICFR_CH4DONEC_POS) - -#define DMA_ICFR_CH3DONEC_POS 3U -#define DMA_ICFR_CH3DONEC_MSK BIT(DMA_ICFR_CH3DONEC_POS) - -#define DMA_ICFR_CH2DONEC_POS 2U -#define DMA_ICFR_CH2DONEC_MSK BIT(DMA_ICFR_CH2DONEC_POS) - -#define DMA_ICFR_CH1DONEC_POS 1U -#define DMA_ICFR_CH1DONEC_MSK BIT(DMA_ICFR_CH1DONEC_POS) - -#define DMA_ICFR_CH0DONEC_POS 0U -#define DMA_ICFR_CH0DONEC_MSK BIT(DMA_ICFR_CH0DONEC_POS) - -/****************** Bit definition for DMA_IER register ************************/ - -#define DMA_IER_DMAERRIE_POS 31U -#define DMA_IER_DMAERRIE_MSK BIT(DMA_IER_DMAERRIE_POS) - -#define DMA_IER_CH5DONEIE_POS 5U -#define DMA_IER_CH5DONEIE_MSK BIT(DMA_IER_CH5DONEIE_POS) - -#define DMA_IER_CH4DONEIE_POS 4U -#define DMA_IER_CH4DONEIE_MSK BIT(DMA_IER_CH4DONEIE_POS) - -#define DMA_IER_CH3DONEIE_POS 3U -#define DMA_IER_CH3DONEIE_MSK BIT(DMA_IER_CH3DONEIE_POS) - -#define DMA_IER_CH2DONEIE_POS 2U -#define DMA_IER_CH2DONEIE_MSK BIT(DMA_IER_CH2DONEIE_POS) - -#define DMA_IER_CH1DONEIE_POS 1U -#define DMA_IER_CH1DONEIE_MSK BIT(DMA_IER_CH1DONEIE_POS) - -#define DMA_IER_CH0DONEIE_POS 0U -#define DMA_IER_CH0DONEIE_MSK BIT(DMA_IER_CH0DONEIE_POS) - -/****************** Bit definition for DMA_CH0_SELCON register ************************/ - -#define DMA_CH0_SELCON_MSEL_POSS 8U -#define DMA_CH0_SELCON_MSEL_POSE 13U -#define DMA_CH0_SELCON_MSEL_MSK BITS(DMA_CH0_SELCON_MSEL_POSS,DMA_CH0_SELCON_MSEL_POSE) - -#define DMA_CH0_SELCON_MSIGSEL_POSS 0U -#define DMA_CH0_SELCON_MSIGSEL_POSE 3U -#define DMA_CH0_SELCON_MSIGSEL_MSK BITS(DMA_CH0_SELCON_MSIGSEL_POSS,DMA_CH0_SELCON_MSIGSEL_POSE) - -typedef struct -{ - __I uint32_t STATUS; - __IO uint32_t CFG; - __IO uint32_t CTRLBASE; - __I uint32_t ALTCTRLBASE; - __I uint32_t CHWAITSTATUS; - __IO uint32_t CHSWREQ; - __IO uint32_t CHUSEBURSTSET; - __O uint32_t CHUSEBURSTCLR; - __IO uint32_t CHREQMASKSET; - __O uint32_t CHREQMASKCLR; - __IO uint32_t CHENSET; - __O uint32_t CHENCLR; - __IO uint32_t CHPRIALTSET; - __O uint32_t CHPRIALTCLR; - __IO uint32_t CHPRSET; - __O uint32_t CHPRCLR; - uint32_t RESERVED0[3] ; - __IO uint32_t ERRCLR; - uint32_t RESERVED1[1004] ; - __I uint32_t IFLAG; - uint32_t RESERVED2 ; - __O uint32_t ICFR; - __IO uint32_t IER; - uint32_t RESERVED3[60] ; - __IO uint32_t CH_SELCON[6]; -} DMA_TypeDef; - -/****************** Bit definition for PIS_CH0_CON register ************************/ - -#define PIS_CH0_CON_SYNCSEL_POSS 24U -#define PIS_CH0_CON_SYNCSEL_POSE 26U -#define PIS_CH0_CON_SYNCSEL_MSK BITS(PIS_CH0_CON_SYNCSEL_POSS,PIS_CH0_CON_SYNCSEL_POSE) - -#define PIS_CH0_CON_PULCK_POSS 18U -#define PIS_CH0_CON_PULCK_POSE 19U -#define PIS_CH0_CON_PULCK_MSK BITS(PIS_CH0_CON_PULCK_POSS,PIS_CH0_CON_PULCK_POSE) - -#define PIS_CH0_CON_EDGS_POSS 16U -#define PIS_CH0_CON_EDGS_POSE 17U -#define PIS_CH0_CON_EDGS_MSK BITS(PIS_CH0_CON_EDGS_POSS,PIS_CH0_CON_EDGS_POSE) - -#define PIS_CH0_CON_SRCS_POSS 8U -#define PIS_CH0_CON_SRCS_POSE 13U -#define PIS_CH0_CON_SRCS_MSK BITS(PIS_CH0_CON_SRCS_POSS,PIS_CH0_CON_SRCS_POSE) - -#define PIS_CH0_CON_MSIGS_POSS 0U -#define PIS_CH0_CON_MSIGS_POSE 3U -#define PIS_CH0_CON_MSIGS_MSK BITS(PIS_CH0_CON_MSIGS_POSS,PIS_CH0_CON_MSIGS_POSE) - -/****************** Bit definition for PIS_CH_OER register ************************/ - -#define PIS_CH_OER_CH3OE_POS 3U -#define PIS_CH_OER_CH3OE_MSK BIT(PIS_CH_OER_CH3OE_POS) - -#define PIS_CH_OER_CH2OE_POS 2U -#define PIS_CH_OER_CH2OE_MSK BIT(PIS_CH_OER_CH2OE_POS) - -#define PIS_CH_OER_CH1OE_POS 1U -#define PIS_CH_OER_CH1OE_MSK BIT(PIS_CH_OER_CH1OE_POS) - -#define PIS_CH_OER_CH0OE_POS 0U -#define PIS_CH_OER_CH0OE_MSK BIT(PIS_CH_OER_CH0OE_POS) - -/****************** Bit definition for PIS_TAR_CON0 register ************************/ - -#define PIS_TAR_CON0_TIM3_CH2IN_SEL_POS 25U -#define PIS_TAR_CON0_TIM3_CH2IN_SEL_MSK BIT(PIS_TAR_CON0_TIM3_CH2IN_SEL_POS) - -#define PIS_TAR_CON0_TIM3_CH1IN_SEL_POS 24U -#define PIS_TAR_CON0_TIM3_CH1IN_SEL_MSK BIT(PIS_TAR_CON0_TIM3_CH1IN_SEL_POS) - -#define PIS_TAR_CON0_TIM2_CH2IN_SEL_POS 17U -#define PIS_TAR_CON0_TIM2_CH2IN_SEL_MSK BIT(PIS_TAR_CON0_TIM2_CH2IN_SEL_POS) - -#define PIS_TAR_CON0_TIM2_CH1IN_SEL_POS 16U -#define PIS_TAR_CON0_TIM2_CH1IN_SEL_MSK BIT(PIS_TAR_CON0_TIM2_CH1IN_SEL_POS) - -#define PIS_TAR_CON0_TIM0_BRKIN_SEL_POS 4U -#define PIS_TAR_CON0_TIM0_BRKIN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_BRKIN_SEL_POS) - -#define PIS_TAR_CON0_TIM0_CH4IN_SEL_POS 3U -#define PIS_TAR_CON0_TIM0_CH4IN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_CH4IN_SEL_POS) - -#define PIS_TAR_CON0_TIM0_CH3IN_SEL_POS 2U -#define PIS_TAR_CON0_TIM0_CH3IN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_CH3IN_SEL_POS) - -#define PIS_TAR_CON0_TIM0_CH2IN_SEL_POS 1U -#define PIS_TAR_CON0_TIM0_CH2IN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_CH2IN_SEL_POS) - -#define PIS_TAR_CON0_TIM0_CH1IN_SEL_POS 0U -#define PIS_TAR_CON0_TIM0_CH1IN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_CH1IN_SEL_POS) - -/****************** Bit definition for PIS_TAR_CON1 register ************************/ - -#define PIS_TAR_CON1_SPI1_CLK_SEL_POS 15U -#define PIS_TAR_CON1_SPI1_CLK_SEL_MSK BIT(PIS_TAR_CON1_SPI1_CLK_SEL_POS) - -#define PIS_TAR_CON1_SPI1_RX_SEL_POS 14U -#define PIS_TAR_CON1_SPI1_RX_SEL_MSK BIT(PIS_TAR_CON1_SPI1_RX_SEL_POS) - -#define PIS_TAR_CON1_SPI0_CLK_SEL_POS 13U -#define PIS_TAR_CON1_SPI0_CLK_SEL_MSK BIT(PIS_TAR_CON1_SPI0_CLK_SEL_POS) - -#define PIS_TAR_CON1_SPI0_RX_SEL_POS 12U -#define PIS_TAR_CON1_SPI0_RX_SEL_MSK BIT(PIS_TAR_CON1_SPI0_RX_SEL_POS) - -#define PIS_TAR_CON1_LPUART0_RXD_SEL_POS 8U -#define PIS_TAR_CON1_LPUART0_RXD_SEL_MSK BIT(PIS_TAR_CON1_LPUART0_RXD_SEL_POS) - -#define PIS_TAR_CON1_USART1_RXD_SEL_POS 7U -#define PIS_TAR_CON1_USART1_RXD_SEL_MSK BIT(PIS_TAR_CON1_USART1_RXD_SEL_POS) - -#define PIS_TAR_CON1_USART0_RXD_SEL_POS 6U -#define PIS_TAR_CON1_USART0_RXD_SEL_MSK BIT(PIS_TAR_CON1_USART0_RXD_SEL_POS) - -#define PIS_TAR_CON1_UART3_RXD_SEL_POS 3U -#define PIS_TAR_CON1_UART3_RXD_SEL_MSK BIT(PIS_TAR_CON1_UART3_RXD_SEL_POS) - -#define PIS_TAR_CON1_UART2_RXD_SEL_POS 2U -#define PIS_TAR_CON1_UART2_RXD_SEL_MSK BIT(PIS_TAR_CON1_UART2_RXD_SEL_POS) - -#define PIS_TAR_CON1_UART1_RXD_SEL_POS 1U -#define PIS_TAR_CON1_UART1_RXD_SEL_MSK BIT(PIS_TAR_CON1_UART1_RXD_SEL_POS) - -#define PIS_TAR_CON1_UART0_RXD_SEL_POS 0U -#define PIS_TAR_CON1_UART0_RXD_SEL_MSK BIT(PIS_TAR_CON1_UART0_RXD_SEL_POS) - -/****************** Bit definition for PIS_TXMCR register ************************/ - -#define PIS_TXMCR_TXMLVLS_POS 8U -#define PIS_TXMCR_TXMLVLS_MSK BIT(PIS_TXMCR_TXMLVLS_POS) - -#define PIS_TXMCR_TXMSS_POSS 4U -#define PIS_TXMCR_TXMSS_POSE 7U -#define PIS_TXMCR_TXMSS_MSK BITS(PIS_TXMCR_TXMSS_POSS,PIS_TXMCR_TXMSS_POSE) - -#define PIS_TXMCR_TXSIGS_POSS 0U -#define PIS_TXMCR_TXSIGS_POSE 3U -#define PIS_TXMCR_TXSIGS_MSK BITS(PIS_TXMCR_TXSIGS_POSS,PIS_TXMCR_TXSIGS_POSE) - -typedef struct -{ - __IO uint32_t CH_CON[8]; - uint32_t RESERVED0[8] ; - __IO uint32_t CH_OER; - __IO uint32_t TAR_CON0; - __IO uint32_t TAR_CON1; - uint32_t RESERVED1[5] ; - __IO uint32_t UART0_TXMCR; - __IO uint32_t UART1_TXMCR; - __IO uint32_t UART2_TXMCR; - __IO uint32_t UART3_TXMCR; - __IO uint32_t LPUART0_TXMCR; -} PIS_TypeDef; - -/****************** Bit definition for GPIO_DIN register ************************/ - -#define GPIO_DIN_DIN_POSS 0U -#define GPIO_DIN_DIN_POSE 15U -#define GPIO_DIN_DIN_MSK BITS(GPIO_DIN_DIN_POSS,GPIO_DIN_DIN_POSE) - -/****************** Bit definition for GPIO_DOUT register ************************/ - -#define GPIO_DOUT_DOUT_POSS 0U -#define GPIO_DOUT_DOUT_POSE 15U -#define GPIO_DOUT_DOUT_MSK BITS(GPIO_DOUT_DOUT_POSS,GPIO_DOUT_DOUT_POSE) - -/****************** Bit definition for GPIO_BSRR register ************************/ - -#define GPIO_BSRR_BRR_POSS 16U -#define GPIO_BSRR_BRR_POSE 31U -#define GPIO_BSRR_BRR_MSK BITS(GPIO_BSRR_BRR_POSS,GPIO_BSRR_BRR_POSE) - -#define GPIO_BSRR_BSR_POSS 0U -#define GPIO_BSRR_BSR_POSE 15U -#define GPIO_BSRR_BSR_MSK BITS(GPIO_BSRR_BSR_POSS,GPIO_BSRR_BSR_POSE) - -/****************** Bit definition for GPIO_BIR register ************************/ - -#define GPIO_BIR_BIR_POSS 0U -#define GPIO_BIR_BIR_POSE 15U -#define GPIO_BIR_BIR_MSK BITS(GPIO_BIR_BIR_POSS,GPIO_BIR_BIR_POSE) - -/****************** Bit definition for GPIO_MODE register ************************/ - -#define GPIO_MODE_MODE_POSS 0U -#define GPIO_MODE_MODE_POSE 31U -#define GPIO_MODE_MODE_MSK BITS(GPIO_MODE_MODE_POSS,GPIO_MODE_MODE_POSE) - -/****************** Bit definition for GPIO_ODOS register ************************/ - -#define GPIO_ODOS_ODOS_POSS 0U -#define GPIO_ODOS_ODOS_POSE 31U -#define GPIO_ODOS_ODOS_MSK BITS(GPIO_ODOS_ODOS_POSS,GPIO_ODOS_ODOS_POSE) - -/****************** Bit definition for GPIO_PUPD register ************************/ - -#define GPIO_PUPD_PUPD_POSS 0U -#define GPIO_PUPD_PUPD_POSE 31U -#define GPIO_PUPD_PUPD_MSK BITS(GPIO_PUPD_PUPD_POSS,GPIO_PUPD_PUPD_POSE) - -/****************** Bit definition for GPIO_ODRV register ************************/ - -#define GPIO_ODRV_ODRV_POSS 0U -#define GPIO_ODRV_ODRV_POSE 31U -#define GPIO_ODRV_ODRV_MSK BITS(GPIO_ODRV_ODRV_POSS,GPIO_ODRV_ODRV_POSE) - -/****************** Bit definition for GPIO_FLT register ************************/ - -#define GPIO_FLT_FLT_POSS 0U -#define GPIO_FLT_FLT_POSE 15U -#define GPIO_FLT_FLT_MSK BITS(GPIO_FLT_FLT_POSS,GPIO_FLT_FLT_POSE) - -/****************** Bit definition for GPIO_TYPE register ************************/ - -#define GPIO_TYPE_TYPE_POSS 0U -#define GPIO_TYPE_TYPE_POSE 15U -#define GPIO_TYPE_TYPE_MSK BITS(GPIO_TYPE_TYPE_POSS,GPIO_TYPE_TYPE_POSE) - -/****************** Bit definition for GPIO_FUNC0 register ************************/ - -#define GPIO_FUNC0_FSEL_IO7_POSS 28U -#define GPIO_FUNC0_FSEL_IO7_POSE 31U -#define GPIO_FUNC0_FSEL_IO7_MSK BITS(GPIO_FUNC0_FSEL_IO7_POSS,GPIO_FUNC0_FSEL_IO7_POSE) - -#define GPIO_FUNC0_FSEL_IO6_POSS 24U -#define GPIO_FUNC0_FSEL_IO6_POSE 27U -#define GPIO_FUNC0_FSEL_IO6_MSK BITS(GPIO_FUNC0_FSEL_IO6_POSS,GPIO_FUNC0_FSEL_IO6_POSE) - -#define GPIO_FUNC0_FSEL_IO5_POSS 20U -#define GPIO_FUNC0_FSEL_IO5_POSE 23U -#define GPIO_FUNC0_FSEL_IO5_MSK BITS(GPIO_FUNC0_FSEL_IO5_POSS,GPIO_FUNC0_FSEL_IO5_POSE) - -#define GPIO_FUNC0_FSEL_IO4_POSS 16U -#define GPIO_FUNC0_FSEL_IO4_POSE 19U -#define GPIO_FUNC0_FSEL_IO4_MSK BITS(GPIO_FUNC0_FSEL_IO4_POSS,GPIO_FUNC0_FSEL_IO4_POSE) - -#define GPIO_FUNC0_FSEL_IO3_POSS 12U -#define GPIO_FUNC0_FSEL_IO3_POSE 15U -#define GPIO_FUNC0_FSEL_IO3_MSK BITS(GPIO_FUNC0_FSEL_IO3_POSS,GPIO_FUNC0_FSEL_IO3_POSE) - -#define GPIO_FUNC0_FSEL_IO2_POSS 8U -#define GPIO_FUNC0_FSEL_IO2_POSE 11U -#define GPIO_FUNC0_FSEL_IO2_MSK BITS(GPIO_FUNC0_FSEL_IO2_POSS,GPIO_FUNC0_FSEL_IO2_POSE) - -#define GPIO_FUNC0_FSEL_IO1_POSS 4U -#define GPIO_FUNC0_FSEL_IO1_POSE 7U -#define GPIO_FUNC0_FSEL_IO1_MSK BITS(GPIO_FUNC0_FSEL_IO1_POSS,GPIO_FUNC0_FSEL_IO1_POSE) - -#define GPIO_FUNC0_FSEL_IO0_POSS 0U -#define GPIO_FUNC0_FSEL_IO0_POSE 3U -#define GPIO_FUNC0_FSEL_IO0_MSK BITS(GPIO_FUNC0_FSEL_IO0_POSS,GPIO_FUNC0_FSEL_IO0_POSE) - -/****************** Bit definition for GPIO_FUNC1 register ************************/ - -#define GPIO_FUNC1_FSEL_IO15_POSS 28U -#define GPIO_FUNC1_FSEL_IO15_POSE 31U -#define GPIO_FUNC1_FSEL_IO15_MSK BITS(GPIO_FUNC1_FSEL_IO15_POSS,GPIO_FUNC1_FSEL_IO15_POSE) - -#define GPIO_FUNC1_FSEL_IO14_POSS 24U -#define GPIO_FUNC1_FSEL_IO14_POSE 27U -#define GPIO_FUNC1_FSEL_IO14_MSK BITS(GPIO_FUNC1_FSEL_IO14_POSS,GPIO_FUNC1_FSEL_IO14_POSE) - -#define GPIO_FUNC1_FSEL_IO13_POSS 20U -#define GPIO_FUNC1_FSEL_IO13_POSE 23U -#define GPIO_FUNC1_FSEL_IO13_MSK BITS(GPIO_FUNC1_FSEL_IO13_POSS,GPIO_FUNC1_FSEL_IO13_POSE) - -#define GPIO_FUNC1_FSEL_IO12_POSS 16U -#define GPIO_FUNC1_FSEL_IO12_POSE 19U -#define GPIO_FUNC1_FSEL_IO12_MSK BITS(GPIO_FUNC1_FSEL_IO12_POSS,GPIO_FUNC1_FSEL_IO12_POSE) - -#define GPIO_FUNC1_FSEL_IO11_POSS 12U -#define GPIO_FUNC1_FSEL_IO11_POSE 15U -#define GPIO_FUNC1_FSEL_IO11_MSK BITS(GPIO_FUNC1_FSEL_IO11_POSS,GPIO_FUNC1_FSEL_IO11_POSE) - -#define GPIO_FUNC1_FSEL_IO10_POSS 8U -#define GPIO_FUNC1_FSEL_IO10_POSE 11U -#define GPIO_FUNC1_FSEL_IO10_MSK BITS(GPIO_FUNC1_FSEL_IO10_POSS,GPIO_FUNC1_FSEL_IO10_POSE) - -#define GPIO_FUNC1_FSEL_IO9_POSS 4U -#define GPIO_FUNC1_FSEL_IO9_POSE 7U -#define GPIO_FUNC1_FSEL_IO9_MSK BITS(GPIO_FUNC1_FSEL_IO9_POSS,GPIO_FUNC1_FSEL_IO9_POSE) - -#define GPIO_FUNC1_FSEL_IO8_POSS 0U -#define GPIO_FUNC1_FSEL_IO8_POSE 3U -#define GPIO_FUNC1_FSEL_IO8_MSK BITS(GPIO_FUNC1_FSEL_IO8_POSS,GPIO_FUNC1_FSEL_IO8_POSE) - -/****************** Bit definition for GPIO_LOCK register ************************/ - -#define GPIO_LOCK_KEY_POSS 16U -#define GPIO_LOCK_KEY_POSE 31U -#define GPIO_LOCK_KEY_MSK BITS(GPIO_LOCK_KEY_POSS,GPIO_LOCK_KEY_POSE) - -#define GPIO_LOCK_LOCK_POSS 0U -#define GPIO_LOCK_LOCK_POSE 15U -#define GPIO_LOCK_LOCK_MSK BITS(GPIO_LOCK_LOCK_POSS,GPIO_LOCK_LOCK_POSE) - -typedef struct -{ - __I uint32_t DIN; - __IO uint32_t DOUT; - __O uint32_t BSRR; - __O uint32_t BIR; - __IO uint32_t MODE; - __IO uint32_t ODOS; - __IO uint32_t PUPD; - __IO uint32_t ODRV; - __IO uint32_t FLT; - __IO uint32_t TYPE; - __IO uint32_t FUNC0; - __IO uint32_t FUNC1; - __IO uint32_t LOCK; -} GPIO_TypeDef; - -/****************** Bit definition for GPIO_EXTIRER register ************************/ - -#define GPIO_EXTIRER_EXTIRER_POSS 0U -#define GPIO_EXTIRER_EXTIRER_POSE 15U -#define GPIO_EXTIRER_EXTIRER_MSK BITS(GPIO_EXTIRER_EXTIRER_POSS,GPIO_EXTIRER_EXTIRER_POSE) - -/****************** Bit definition for GPIO_EXTIFER register ************************/ - -#define GPIO_EXTIFER_EXTIFER_POSS 0U -#define GPIO_EXTIFER_EXTIFER_POSE 15U -#define GPIO_EXTIFER_EXTIFER_MSK BITS(GPIO_EXTIFER_EXTIFER_POSS,GPIO_EXTIFER_EXTIFER_POSE) - -/****************** Bit definition for GPIO_EXTIEN register ************************/ - -#define GPIO_EXTIEN_EXTIEN_POSS 0U -#define GPIO_EXTIEN_EXTIEN_POSE 15U -#define GPIO_EXTIEN_EXTIEN_MSK BITS(GPIO_EXTIEN_EXTIEN_POSS,GPIO_EXTIEN_EXTIEN_POSE) - -/****************** Bit definition for GPIO_EXTIFLAG register ************************/ - -#define GPIO_EXTIFLAG_EXTIFLAG_POSS 0U -#define GPIO_EXTIFLAG_EXTIFLAG_POSE 15U -#define GPIO_EXTIFLAG_EXTIFLAG_MSK BITS(GPIO_EXTIFLAG_EXTIFLAG_POSS,GPIO_EXTIFLAG_EXTIFLAG_POSE) - -/****************** Bit definition for GPIO_EXTISFR register ************************/ - -#define GPIO_EXTISFR_EXTISFR_POSS 0U -#define GPIO_EXTISFR_EXTISFR_POSE 15U -#define GPIO_EXTISFR_EXTISFR_MSK BITS(GPIO_EXTISFR_EXTISFR_POSS,GPIO_EXTISFR_EXTISFR_POSE) - -/****************** Bit definition for GPIO_EXTICFR register ************************/ - -#define GPIO_EXTICFR_EXTICFR_POSS 0U -#define GPIO_EXTICFR_EXTICFR_POSE 15U -#define GPIO_EXTICFR_EXTICFR_MSK BITS(GPIO_EXTICFR_EXTICFR_POSS,GPIO_EXTICFR_EXTICFR_POSE) - -/****************** Bit definition for GPIO_EXTIPSR0 register ************************/ - -#define GPIO_EXTIPSR0_EXTIS7_POSS 28U -#define GPIO_EXTIPSR0_EXTIS7_POSE 30U -#define GPIO_EXTIPSR0_EXTIS7_MSK BITS(GPIO_EXTIPSR0_EXTIS7_POSS,GPIO_EXTIPSR0_EXTIS7_POSE) - -#define GPIO_EXTIPSR0_EXTIS6_POSS 24U -#define GPIO_EXTIPSR0_EXTIS6_POSE 26U -#define GPIO_EXTIPSR0_EXTIS6_MSK BITS(GPIO_EXTIPSR0_EXTIS6_POSS,GPIO_EXTIPSR0_EXTIS6_POSE) - -#define GPIO_EXTIPSR0_EXTIS5_POSS 20U -#define GPIO_EXTIPSR0_EXTIS5_POSE 22U -#define GPIO_EXTIPSR0_EXTIS5_MSK BITS(GPIO_EXTIPSR0_EXTIS5_POSS,GPIO_EXTIPSR0_EXTIS5_POSE) - -#define GPIO_EXTIPSR0_EXTIS4_POSS 16U -#define GPIO_EXTIPSR0_EXTIS4_POSE 18U -#define GPIO_EXTIPSR0_EXTIS4_MSK BITS(GPIO_EXTIPSR0_EXTIS4_POSS,GPIO_EXTIPSR0_EXTIS4_POSE) - -#define GPIO_EXTIPSR0_EXTIS3_POSS 12U -#define GPIO_EXTIPSR0_EXTIS3_POSE 14U -#define GPIO_EXTIPSR0_EXTIS3_MSK BITS(GPIO_EXTIPSR0_EXTIS3_POSS,GPIO_EXTIPSR0_EXTIS3_POSE) - -#define GPIO_EXTIPSR0_EXTIS2_POSS 8U -#define GPIO_EXTIPSR0_EXTIS2_POSE 10U -#define GPIO_EXTIPSR0_EXTIS2_MSK BITS(GPIO_EXTIPSR0_EXTIS2_POSS,GPIO_EXTIPSR0_EXTIS2_POSE) - -#define GPIO_EXTIPSR0_EXTIS1_POSS 4U -#define GPIO_EXTIPSR0_EXTIS1_POSE 6U -#define GPIO_EXTIPSR0_EXTIS1_MSK BITS(GPIO_EXTIPSR0_EXTIS1_POSS,GPIO_EXTIPSR0_EXTIS1_POSE) - -#define GPIO_EXTIPSR0_EXTIS0_POSS 0U -#define GPIO_EXTIPSR0_EXTIS0_POSE 2U -#define GPIO_EXTIPSR0_EXTIS0_MSK BITS(GPIO_EXTIPSR0_EXTIS0_POSS,GPIO_EXTIPSR0_EXTIS0_POSE) - -/****************** Bit definition for GPIO_EXTIPSR1 register ************************/ - -#define GPIO_EXTIPSR1_EXTIS15_POSS 28U -#define GPIO_EXTIPSR1_EXTIS15_POSE 30U -#define GPIO_EXTIPSR1_EXTIS15_MSK BITS(GPIO_EXTIPSR1_EXTIS15_POSS,GPIO_EXTIPSR1_EXTIS15_POSE) - -#define GPIO_EXTIPSR1_EXTIS14_POSS 24U -#define GPIO_EXTIPSR1_EXTIS14_POSE 26U -#define GPIO_EXTIPSR1_EXTIS14_MSK BITS(GPIO_EXTIPSR1_EXTIS14_POSS,GPIO_EXTIPSR1_EXTIS14_POSE) - -#define GPIO_EXTIPSR1_EXTIS13_POSS 20U -#define GPIO_EXTIPSR1_EXTIS13_POSE 22U -#define GPIO_EXTIPSR1_EXTIS13_MSK BITS(GPIO_EXTIPSR1_EXTIS13_POSS,GPIO_EXTIPSR1_EXTIS13_POSE) - -#define GPIO_EXTIPSR1_EXTIS12_POSS 16U -#define GPIO_EXTIPSR1_EXTIS12_POSE 18U -#define GPIO_EXTIPSR1_EXTIS12_MSK BITS(GPIO_EXTIPSR1_EXTIS12_POSS,GPIO_EXTIPSR1_EXTIS12_POSE) - -#define GPIO_EXTIPSR1_EXTIS11_POSS 12U -#define GPIO_EXTIPSR1_EXTIS11_POSE 14U -#define GPIO_EXTIPSR1_EXTIS11_MSK BITS(GPIO_EXTIPSR1_EXTIS11_POSS,GPIO_EXTIPSR1_EXTIS11_POSE) - -#define GPIO_EXTIPSR1_EXTIS10_POSS 8U -#define GPIO_EXTIPSR1_EXTIS10_POSE 10U -#define GPIO_EXTIPSR1_EXTIS10_MSK BITS(GPIO_EXTIPSR1_EXTIS10_POSS,GPIO_EXTIPSR1_EXTIS10_POSE) - -#define GPIO_EXTIPSR1_EXTIS9_POSS 4U -#define GPIO_EXTIPSR1_EXTIS9_POSE 6U -#define GPIO_EXTIPSR1_EXTIS9_MSK BITS(GPIO_EXTIPSR1_EXTIS9_POSS,GPIO_EXTIPSR1_EXTIS9_POSE) - -#define GPIO_EXTIPSR1_EXTIS8_POSS 0U -#define GPIO_EXTIPSR1_EXTIS8_POSE 2U -#define GPIO_EXTIPSR1_EXTIS8_MSK BITS(GPIO_EXTIPSR1_EXTIS8_POSS,GPIO_EXTIPSR1_EXTIS8_POSE) - -/****************** Bit definition for GPIO_EXTIFLTCR register ************************/ - -#define GPIO_EXTIFLTCR_FLTCKS_POSS 24U -#define GPIO_EXTIFLTCR_FLTCKS_POSE 25U -#define GPIO_EXTIFLTCR_FLTCKS_MSK BITS(GPIO_EXTIFLTCR_FLTCKS_POSS,GPIO_EXTIFLTCR_FLTCKS_POSE) - -#define GPIO_EXTIFLTCR_FLTSEL_POSS 16U -#define GPIO_EXTIFLTCR_FLTSEL_POSE 23U -#define GPIO_EXTIFLTCR_FLTSEL_MSK BITS(GPIO_EXTIFLTCR_FLTSEL_POSS,GPIO_EXTIFLTCR_FLTSEL_POSE) - -#define GPIO_EXTIFLTCR_FLTEN_POSS 0U -#define GPIO_EXTIFLTCR_FLTEN_POSE 15U -#define GPIO_EXTIFLTCR_FLTEN_MSK BITS(GPIO_EXTIFLTCR_FLTEN_POSS,GPIO_EXTIFLTCR_FLTEN_POSE) - -typedef struct -{ - __IO uint32_t EXTIRER; - uint32_t RESERVED0 ; - __IO uint32_t EXTIFER; - uint32_t RESERVED1 ; - __IO uint32_t EXTIEN; - uint32_t RESERVED2 ; - __I uint32_t EXTIFLAG; - uint32_t RESERVED3 ; - __O uint32_t EXTISFR; - uint32_t RESERVED4 ; - __O uint32_t EXTICFR; - uint32_t RESERVED5 ; - __IO uint32_t EXTIPSR0; - __IO uint32_t EXTIPSR1; - uint32_t RESERVED6[2] ; - __IO uint32_t EXTIFLTCR; -} EXTI_TypeDef; - -/****************** Bit definition for RTC_WPR register ************************/ - -#define RTC_WPR_WP_POS 0U -#define RTC_WPR_WP_MSK BIT(RTC_WPR_WP_POS) - -/****************** Bit definition for RTC_CON register ************************/ - -#define RTC_CON_SSEC_POS 25U -#define RTC_CON_SSEC_MSK BIT(RTC_CON_SSEC_POS) - -#define RTC_CON_BUSY_POS 24U -#define RTC_CON_BUSY_MSK BIT(RTC_CON_BUSY_POS) - -#define RTC_CON_POL_POS 22U -#define RTC_CON_POL_MSK BIT(RTC_CON_POL_POS) - -#define RTC_CON_EOS_POSS 20U -#define RTC_CON_EOS_POSE 21U -#define RTC_CON_EOS_MSK BITS(RTC_CON_EOS_POSS,RTC_CON_EOS_POSE) - -#define RTC_CON_CKOS_POSS 17U -#define RTC_CON_CKOS_POSE 19U -#define RTC_CON_CKOS_MSK BITS(RTC_CON_CKOS_POSS,RTC_CON_CKOS_POSE) - -#define RTC_CON_CKOE_POS 16U -#define RTC_CON_CKOE_MSK BIT(RTC_CON_CKOE_POS) - -#define RTC_CON_WUCKS_POSS 13U -#define RTC_CON_WUCKS_POSE 15U -#define RTC_CON_WUCKS_MSK BITS(RTC_CON_WUCKS_POSS,RTC_CON_WUCKS_POSE) - -#define RTC_CON_WUTE_POS 12U -#define RTC_CON_WUTE_MSK BIT(RTC_CON_WUTE_POS) - -#define RTC_CON_DSTS_POS 10U -#define RTC_CON_DSTS_MSK BIT(RTC_CON_DSTS_POS) - -#define RTC_CON_SUB1H_POS 9U -#define RTC_CON_SUB1H_MSK BIT(RTC_CON_SUB1H_POS) - -#define RTC_CON_ADD1H_POS 8U -#define RTC_CON_ADD1H_MSK BIT(RTC_CON_ADD1H_POS) - -#define RTC_CON_TSPIN_POS 7U -#define RTC_CON_TSPIN_MSK BIT(RTC_CON_TSPIN_POS) - -#define RTC_CON_TSSEL_POS 6U -#define RTC_CON_TSSEL_MSK BIT(RTC_CON_TSSEL_POS) - -#define RTC_CON_TSEN_POS 5U -#define RTC_CON_TSEN_MSK BIT(RTC_CON_TSEN_POS) - -#define RTC_CON_SHDBP_POS 4U -#define RTC_CON_SHDBP_MSK BIT(RTC_CON_SHDBP_POS) - -#define RTC_CON_HFM_POS 3U -#define RTC_CON_HFM_MSK BIT(RTC_CON_HFM_POS) - -#define RTC_CON_ALMBEN_POS 2U -#define RTC_CON_ALMBEN_MSK BIT(RTC_CON_ALMBEN_POS) - -#define RTC_CON_ALMAEN_POS 1U -#define RTC_CON_ALMAEN_MSK BIT(RTC_CON_ALMAEN_POS) - -#define RTC_CON_GO_POS 0U -#define RTC_CON_GO_MSK BIT(RTC_CON_GO_POS) - -/****************** Bit definition for RTC_PSR register ************************/ - -#define RTC_PSR_APRS_POSS 16U -#define RTC_PSR_APRS_POSE 22U -#define RTC_PSR_APRS_MSK BITS(RTC_PSR_APRS_POSS,RTC_PSR_APRS_POSE) - -#define RTC_PSR_SPRS_POSS 0U -#define RTC_PSR_SPRS_POSE 14U -#define RTC_PSR_SPRS_MSK BITS(RTC_PSR_SPRS_POSS,RTC_PSR_SPRS_POSE) - -/****************** Bit definition for RTC_TAMPCON register ************************/ - -#define RTC_TAMPCON_TAMPFLT_POSS 20U -#define RTC_TAMPCON_TAMPFLT_POSE 21U -#define RTC_TAMPCON_TAMPFLT_MSK BITS(RTC_TAMPCON_TAMPFLT_POSS,RTC_TAMPCON_TAMPFLT_POSE) - -#define RTC_TAMPCON_TAMPCKS_POSS 17U -#define RTC_TAMPCON_TAMPCKS_POSE 19U -#define RTC_TAMPCON_TAMPCKS_MSK BITS(RTC_TAMPCON_TAMPCKS_POSS,RTC_TAMPCON_TAMPCKS_POSE) - -#define RTC_TAMPCON_TAMPTS_POS 16U -#define RTC_TAMPCON_TAMPTS_MSK BIT(RTC_TAMPCON_TAMPTS_POS) - -#define RTC_TAMPCON_TAMP2LV_POS 9U -#define RTC_TAMPCON_TAMP2LV_MSK BIT(RTC_TAMPCON_TAMP2LV_POS) - -#define RTC_TAMPCON_TAMP2EN_POS 8U -#define RTC_TAMPCON_TAMP2EN_MSK BIT(RTC_TAMPCON_TAMP2EN_POS) - -#define RTC_TAMPCON_TAMP1LV_POS 1U -#define RTC_TAMPCON_TAMP1LV_MSK BIT(RTC_TAMPCON_TAMP1LV_POS) - -#define RTC_TAMPCON_TAMP1EN_POS 0U -#define RTC_TAMPCON_TAMP1EN_MSK BIT(RTC_TAMPCON_TAMP1EN_POS) - -/****************** Bit definition for RTC_TIME register ************************/ - -#define RTC_TIME_PM_POS 22U -#define RTC_TIME_PM_MSK BIT(RTC_TIME_PM_POS) - -#define RTC_TIME_HRT_POSS 20U -#define RTC_TIME_HRT_POSE 21U -#define RTC_TIME_HRT_MSK BITS(RTC_TIME_HRT_POSS,RTC_TIME_HRT_POSE) - -#define RTC_TIME_HRU_POSS 16U -#define RTC_TIME_HRU_POSE 19U -#define RTC_TIME_HRU_MSK BITS(RTC_TIME_HRU_POSS,RTC_TIME_HRU_POSE) - -#define RTC_TIME_MINT_POSS 12U -#define RTC_TIME_MINT_POSE 14U -#define RTC_TIME_MINT_MSK BITS(RTC_TIME_MINT_POSS,RTC_TIME_MINT_POSE) - -#define RTC_TIME_MINU_POSS 8U -#define RTC_TIME_MINU_POSE 11U -#define RTC_TIME_MINU_MSK BITS(RTC_TIME_MINU_POSS,RTC_TIME_MINU_POSE) - -#define RTC_TIME_SECT_POSS 4U -#define RTC_TIME_SECT_POSE 6U -#define RTC_TIME_SECT_MSK BITS(RTC_TIME_SECT_POSS,RTC_TIME_SECT_POSE) - -#define RTC_TIME_SECU_POSS 0U -#define RTC_TIME_SECU_POSE 3U -#define RTC_TIME_SECU_MSK BITS(RTC_TIME_SECU_POSS,RTC_TIME_SECU_POSE) - -/****************** Bit definition for RTC_DATE register ************************/ - -#define RTC_DATE_WD_POSS 24U -#define RTC_DATE_WD_POSE 26U -#define RTC_DATE_WD_MSK BITS(RTC_DATE_WD_POSS,RTC_DATE_WD_POSE) - -#define RTC_DATE_YRT_POSS 20U -#define RTC_DATE_YRT_POSE 23U -#define RTC_DATE_YRT_MSK BITS(RTC_DATE_YRT_POSS,RTC_DATE_YRT_POSE) - -#define RTC_DATE_YRU_POSS 16U -#define RTC_DATE_YRU_POSE 19U -#define RTC_DATE_YRU_MSK BITS(RTC_DATE_YRU_POSS,RTC_DATE_YRU_POSE) - -#define RTC_DATE_MONT_POS 12U -#define RTC_DATE_MONT_MSK BIT(RTC_DATE_MONT_POS) - -#define RTC_DATE_MONU_POSS 8U -#define RTC_DATE_MONU_POSE 11U -#define RTC_DATE_MONU_MSK BITS(RTC_DATE_MONU_POSS,RTC_DATE_MONU_POSE) - -#define RTC_DATE_DAYT_POSS 4U -#define RTC_DATE_DAYT_POSE 5U -#define RTC_DATE_DAYT_MSK BITS(RTC_DATE_DAYT_POSS,RTC_DATE_DAYT_POSE) - -#define RTC_DATE_DAYU_POSS 0U -#define RTC_DATE_DAYU_POSE 3U -#define RTC_DATE_DAYU_MSK BITS(RTC_DATE_DAYU_POSS,RTC_DATE_DAYU_POSE) - -/****************** Bit definition for RTC_SSEC register ************************/ - -#define RTC_SSEC_VAL_POSS 0U -#define RTC_SSEC_VAL_POSE 15U -#define RTC_SSEC_VAL_MSK BITS(RTC_SSEC_VAL_POSS,RTC_SSEC_VAL_POSE) - -/****************** Bit definition for RTC_WUMAT register ************************/ - -#define RTC_WUMAT_VAL_POSS 0U -#define RTC_WUMAT_VAL_POSE 15U -#define RTC_WUMAT_VAL_MSK BITS(RTC_WUMAT_VAL_POSS,RTC_WUMAT_VAL_POSE) - -/****************** Bit definition for RTC_ALMA register ************************/ - -#define RTC_ALMA_WDS_POS 31U -#define RTC_ALMA_WDS_MSK BIT(RTC_ALMA_WDS_POS) - -#define RTC_ALMA_DAWD_POSS 24U -#define RTC_ALMA_DAWD_POSE 30U -#define RTC_ALMA_DAWD_MSK BITS(RTC_ALMA_DAWD_POSS,RTC_ALMA_DAWD_POSE) - -#define RTC_ALMA_DAYMSK_POS 30U -#define RTC_ALMA_DAYMSK_MSK BIT(RTC_ALMA_DAYMSK_POS) - -#define RTC_ALMA_DAWD_DAYT_POSS 28U -#define RTC_ALMA_DAWD_DAYT_POSE 29U -#define RTC_ALMA_DAWD_DAYT_MSK BITS(RTC_ALMA_DAWD_DAYT_POSS, RTC_ALMA_DAWD_DAYT_POSE) - -#define RTC_ALMA_DAWD_DAYU_POSS 24U -#define RTC_ALMA_DAWD_DAYU_POSE 27U -#define RTC_ALMA_DAWD_DAYU_MSK BITS(RTC_ALMA_DAWD_DAYU_POSS, RTC_ALMA_DAWD_DAYU_POSE) - -#define RTC_ALMA_HRMSK_POS 23U -#define RTC_ALMA_HRMSK_MSK BIT(RTC_ALMA_HRMSK_POS) - -#define RTC_ALMA_PM_POS 22U -#define RTC_ALMA_PM_MSK BIT(RTC_ALMA_PM_POS) - -#define RTC_ALMA_HRT_POSS 20U -#define RTC_ALMA_HRT_POSE 21U -#define RTC_ALMA_HRT_MSK BITS(RTC_ALMA_HRT_POSS,RTC_ALMA_HRT_POSE) - -#define RTC_ALMA_HRU_POSS 16U -#define RTC_ALMA_HRU_POSE 19U -#define RTC_ALMA_HRU_MSK BITS(RTC_ALMA_HRU_POSS,RTC_ALMA_HRU_POSE) - -#define RTC_ALMA_MINMSK_POS 15U -#define RTC_ALMA_MINMSK_MSK BIT(RTC_ALMA_MINMSK_POS) - -#define RTC_ALMA_MINT_POSS 12U -#define RTC_ALMA_MINT_POSE 14U -#define RTC_ALMA_MINT_MSK BITS(RTC_ALMA_MINT_POSS,RTC_ALMA_MINT_POSE) - -#define RTC_ALMA_MINU_POSS 8U -#define RTC_ALMA_MINU_POSE 11U -#define RTC_ALMA_MINU_MSK BITS(RTC_ALMA_MINU_POSS,RTC_ALMA_MINU_POSE) - -#define RTC_ALMA_SECMSK_POS 7U -#define RTC_ALMA_SECMSK_MSK BIT(RTC_ALMA_SECMSK_POS) - -#define RTC_ALMA_SECT_POSS 4U -#define RTC_ALMA_SECT_POSE 6U -#define RTC_ALMA_SECT_MSK BITS(RTC_ALMA_SECT_POSS,RTC_ALMA_SECT_POSE) - -#define RTC_ALMA_SECU_POSS 0U -#define RTC_ALMA_SECU_POSE 3U -#define RTC_ALMA_SECU_MSK BITS(RTC_ALMA_SECU_POSS,RTC_ALMA_SECU_POSE) - -/****************** Bit definition for RTC_ALMB register ************************/ - -#define RTC_ALMB_WDS_POS 31U -#define RTC_ALMB_WDS_MSK BIT(RTC_ALMB_WDS_POS) - -#define RTC_ALMB_DAWD_POSS 24U -#define RTC_ALMB_DAWD_POSE 30U -#define RTC_ALMB_DAWD_MSK BITS(RTC_ALMB_DAWD_POSS,RTC_ALMB_DAWD_POSE) - -#define RTC_ALMB_DAYMSK_POS 30U -#define RTC_ALMB_DAYMSK_MSK BIT(RTC_ALMB_DAYMSK_POS) - -#define RTC_ALMB_DAWD_DAYT_POSS 28U -#define RTC_ALMB_DAWD_DAYT_POSE 29U -#define RTC_ALMB_DAWD_DAYT_MSK BITS(RTC_ALMB_DAWD_DAYT_POSS, RTC_ALMB_DAWD_DAYT_POSE) - -#define RTC_ALMB_DAWD_DAYU_POSS 24U -#define RTC_ALMB_DAWD_DAYU_POSE 27U -#define RTC_ALMB_DAWD_DAYU_MSK BITS(RTC_ALMB_DAWD_DAYU_POSS, RTC_ALMB_DAWD_DAYU_POSE) - -#define RTC_ALMB_HRMSK_POS 23U -#define RTC_ALMB_HRMSK_MSK BIT(RTC_ALMB_HRMSK_POS) - -#define RTC_ALMB_PM_POS 22U -#define RTC_ALMB_PM_MSK BIT(RTC_ALMB_PM_POS) - -#define RTC_ALMB_HRT_POSS 20U -#define RTC_ALMB_HRT_POSE 21U -#define RTC_ALMB_HRT_MSK BITS(RTC_ALMB_HRT_POSS,RTC_ALMB_HRT_POSE) - -#define RTC_ALMB_HRU_POSS 16U -#define RTC_ALMB_HRU_POSE 19U -#define RTC_ALMB_HRU_MSK BITS(RTC_ALMB_HRU_POSS,RTC_ALMB_HRU_POSE) - -#define RTC_ALMB_MINMSK_POS 15U -#define RTC_ALMB_MINMSK_MSK BIT(RTC_ALMB_MINMSK_POS) - -#define RTC_ALMB_MINT_POSS 12U -#define RTC_ALMB_MINT_POSE 14U -#define RTC_ALMB_MINT_MSK BITS(RTC_ALMB_MINT_POSS,RTC_ALMB_MINT_POSE) - -#define RTC_ALMB_MINU_POSS 8U -#define RTC_ALMB_MINU_POSE 11U -#define RTC_ALMB_MINU_MSK BITS(RTC_ALMB_MINU_POSS,RTC_ALMB_MINU_POSE) - -#define RTC_ALMB_SECMSK_POS 7U -#define RTC_ALMB_SECMSK_MSK BIT(RTC_ALMB_SECMSK_POS) - -#define RTC_ALMB_SECT_POSS 4U -#define RTC_ALMB_SECT_POSE 6U -#define RTC_ALMB_SECT_MSK BITS(RTC_ALMB_SECT_POSS,RTC_ALMB_SECT_POSE) - -#define RTC_ALMB_SECU_POSS 0U -#define RTC_ALMB_SECU_POSE 3U -#define RTC_ALMB_SECU_MSK BITS(RTC_ALMB_SECU_POSS,RTC_ALMB_SECU_POSE) - -/****************** Bit definition for RTC_ALMASSEC register ************************/ - -#define RTC_ALMASSEC_SSECM_POSS 24U -#define RTC_ALMASSEC_SSECM_POSE 27U -#define RTC_ALMASSEC_SSECM_MSK BITS(RTC_ALMASSEC_SSECM_POSS,RTC_ALMASSEC_SSECM_POSE) - -#define RTC_ALMASSEC_SSEC_POSS 0U -#define RTC_ALMASSEC_SSEC_POSE 14U -#define RTC_ALMASSEC_SSEC_MSK BITS(RTC_ALMASSEC_SSEC_POSS,RTC_ALMASSEC_SSEC_POSE) - -/****************** Bit definition for RTC_ALMBSSEC register ************************/ - -#define RTC_ALMBSSEC_SSECM_POSS 24U -#define RTC_ALMBSSEC_SSECM_POSE 27U -#define RTC_ALMBSSEC_SSECM_MSK BITS(RTC_ALMBSSEC_SSECM_POSS,RTC_ALMBSSEC_SSECM_POSE) - -#define RTC_ALMBSSEC_SSEC_POSS 0U -#define RTC_ALMBSSEC_SSEC_POSE 14U -#define RTC_ALMBSSEC_SSEC_MSK BITS(RTC_ALMBSSEC_SSEC_POSS,RTC_ALMBSSEC_SSEC_POSE) - -/****************** Bit definition for RTC_TSTIME register ************************/ - -#define RTC_TSTIME_PM_POS 22U -#define RTC_TSTIME_PM_MSK BIT(RTC_TSTIME_PM_POS) - -#define RTC_TSTIME_HRT_POSS 20U -#define RTC_TSTIME_HRT_POSE 21U -#define RTC_TSTIME_HRT_MSK BITS(RTC_TSTIME_HRT_POSS,RTC_TSTIME_HRT_POSE) - -#define RTC_TSTIME_HRU_POSS 16U -#define RTC_TSTIME_HRU_POSE 19U -#define RTC_TSTIME_HRU_MSK BITS(RTC_TSTIME_HRU_POSS,RTC_TSTIME_HRU_POSE) - -#define RTC_TSTIME_MINT_POSS 12U -#define RTC_TSTIME_MINT_POSE 14U -#define RTC_TSTIME_MINT_MSK BITS(RTC_TSTIME_MINT_POSS,RTC_TSTIME_MINT_POSE) - -#define RTC_TSTIME_MINU_POSS 8U -#define RTC_TSTIME_MINU_POSE 11U -#define RTC_TSTIME_MINU_MSK BITS(RTC_TSTIME_MINU_POSS,RTC_TSTIME_MINU_POSE) - -#define RTC_TSTIME_SECT_POSS 4U -#define RTC_TSTIME_SECT_POSE 6U -#define RTC_TSTIME_SECT_MSK BITS(RTC_TSTIME_SECT_POSS,RTC_TSTIME_SECT_POSE) - -#define RTC_TSTIME_SECU_POSS 0U -#define RTC_TSTIME_SECU_POSE 3U -#define RTC_TSTIME_SECU_MSK BITS(RTC_TSTIME_SECU_POSS,RTC_TSTIME_SECU_POSE) - -/****************** Bit definition for RTC_TSDATE register ************************/ - -#define RTC_TSDATE_WD_POSS 24U -#define RTC_TSDATE_WD_POSE 26U -#define RTC_TSDATE_WD_MSK BITS(RTC_TSDATE_WD_POSS,RTC_TSDATE_WD_POSE) - -#define RTC_TSDATE_YRT_POSS 20U -#define RTC_TSDATE_YRT_POSE 23U -#define RTC_TSDATE_YRT_MSK BITS(RTC_TSDATE_YRT_POSS,RTC_TSDATE_YRT_POSE) - -#define RTC_TSDATE_YRU_POSS 16U -#define RTC_TSDATE_YRU_POSE 19U -#define RTC_TSDATE_YRU_MSK BITS(RTC_TSDATE_YRU_POSS,RTC_TSDATE_YRU_POSE) - -#define RTC_TSDATE_MONT_POS 12U -#define RTC_TSDATE_MONT_MSK BIT(RTC_TSDATE_MONT_POS) - -#define RTC_TSDATE_MONU_POSS 8U -#define RTC_TSDATE_MONU_POSE 11U -#define RTC_TSDATE_MONU_MSK BITS(RTC_TSDATE_MONU_POSS,RTC_TSDATE_MONU_POSE) - -#define RTC_TSDATE_DAYT_POSS 4U -#define RTC_TSDATE_DAYT_POSE 5U -#define RTC_TSDATE_DAYT_MSK BITS(RTC_TSDATE_DAYT_POSS,RTC_TSDATE_DAYT_POSE) - -#define RTC_TSDATE_DAYU_POSS 0U -#define RTC_TSDATE_DAYU_POSE 3U -#define RTC_TSDATE_DAYU_MSK BITS(RTC_TSDATE_DAYU_POSS,RTC_TSDATE_DAYU_POSE) - -/****************** Bit definition for RTC_TSSSEC register ************************/ - -#define RTC_TSSSEC_SSEC_POSS 0U -#define RTC_TSSSEC_SSEC_POSE 15U -#define RTC_TSSSEC_SSEC_MSK BITS(RTC_TSSSEC_SSEC_POSS,RTC_TSSSEC_SSEC_POSE) - -/****************** Bit definition for RTC_SSECTR register ************************/ - -#define RTC_SSECTR_INC_POS 31U -#define RTC_SSECTR_INC_MSK BIT(RTC_SSECTR_INC_POS) - -#define RTC_SSECTR_TRIM_POSS 0U -#define RTC_SSECTR_TRIM_POSE 14U -#define RTC_SSECTR_TRIM_MSK BITS(RTC_SSECTR_TRIM_POSS,RTC_SSECTR_TRIM_POSE) - -/****************** Bit definition for RTC_IER register ************************/ - -#define RTC_IER_TCE_POS 25U -#define RTC_IER_TCE_MSK BIT(RTC_IER_TCE_POS) - -#define RTC_IER_TCC_POS 24U -#define RTC_IER_TCC_MSK BIT(RTC_IER_TCC_POS) - -#define RTC_IER_WU_POS 18U -#define RTC_IER_WU_MSK BIT(RTC_IER_WU_POS) - -#define RTC_IER_SSTC_POS 17U -#define RTC_IER_SSTC_MSK BIT(RTC_IER_SSTC_POS) - -#define RTC_IER_RSC_POS 16U -#define RTC_IER_RSC_MSK BIT(RTC_IER_RSC_POS) - -#define RTC_IER_TAMP2_POS 13U -#define RTC_IER_TAMP2_MSK BIT(RTC_IER_TAMP2_POS) - -#define RTC_IER_TAMP1_POS 12U -#define RTC_IER_TAMP1_MSK BIT(RTC_IER_TAMP1_POS) - -#define RTC_IER_TSOV_POS 11U -#define RTC_IER_TSOV_MSK BIT(RTC_IER_TSOV_POS) - -#define RTC_IER_TS_POS 10U -#define RTC_IER_TS_MSK BIT(RTC_IER_TS_POS) - -#define RTC_IER_ALMB_POS 9U -#define RTC_IER_ALMB_MSK BIT(RTC_IER_ALMB_POS) - -#define RTC_IER_ALMA_POS 8U -#define RTC_IER_ALMA_MSK BIT(RTC_IER_ALMA_POS) - -#define RTC_IER_YR_POS 5U -#define RTC_IER_YR_MSK BIT(RTC_IER_YR_POS) - -#define RTC_IER_MON_POS 4U -#define RTC_IER_MON_MSK BIT(RTC_IER_MON_POS) - -#define RTC_IER_DAY_POS 3U -#define RTC_IER_DAY_MSK BIT(RTC_IER_DAY_POS) - -#define RTC_IER_HR_POS 2U -#define RTC_IER_HR_MSK BIT(RTC_IER_HR_POS) - -#define RTC_IER_MIN_POS 1U -#define RTC_IER_MIN_MSK BIT(RTC_IER_MIN_POS) - -#define RTC_IER_SEC_POS 0U -#define RTC_IER_SEC_MSK BIT(RTC_IER_SEC_POS) - -/****************** Bit definition for RTC_IFR register ************************/ - -#define RTC_IFR_TCEF_POS 25U -#define RTC_IFR_TCEF_MSK BIT(RTC_IFR_TCEF_POS) - -#define RTC_IFR_TCCF_POS 24U -#define RTC_IFR_TCCF_MSK BIT(RTC_IFR_TCCF_POS) - -#define RTC_IFR_WUF_POS 18U -#define RTC_IFR_WUF_MSK BIT(RTC_IFR_WUF_POS) - -#define RTC_IFR_SSTCF_POS 17U -#define RTC_IFR_SSTCF_MSK BIT(RTC_IFR_SSTCF_POS) - -#define RTC_IFR_RSCF_POS 16U -#define RTC_IFR_RSCF_MSK BIT(RTC_IFR_RSCF_POS) - -#define RTC_IFR_TAMP2F_POS 13U -#define RTC_IFR_TAMP2F_MSK BIT(RTC_IFR_TAMP2F_POS) - -#define RTC_IFR_TAMP1F_POS 12U -#define RTC_IFR_TAMP1F_MSK BIT(RTC_IFR_TAMP1F_POS) - -#define RTC_IFR_TSOVF_POS 11U -#define RTC_IFR_TSOVF_MSK BIT(RTC_IFR_TSOVF_POS) - -#define RTC_IFR_TSF_POS 10U -#define RTC_IFR_TSF_MSK BIT(RTC_IFR_TSF_POS) - -#define RTC_IFR_ALMBF_POS 9U -#define RTC_IFR_ALMBF_MSK BIT(RTC_IFR_ALMBF_POS) - -#define RTC_IFR_ALMAF_POS 8U -#define RTC_IFR_ALMAF_MSK BIT(RTC_IFR_ALMAF_POS) - -#define RTC_IFR_YRF_POS 5U -#define RTC_IFR_YRF_MSK BIT(RTC_IFR_YRF_POS) - -#define RTC_IFR_MONF_POS 4U -#define RTC_IFR_MONF_MSK BIT(RTC_IFR_MONF_POS) - -#define RTC_IFR_DAYF_POS 3U -#define RTC_IFR_DAYF_MSK BIT(RTC_IFR_DAYF_POS) - -#define RTC_IFR_HRF_POS 2U -#define RTC_IFR_HRF_MSK BIT(RTC_IFR_HRF_POS) - -#define RTC_IFR_MINF_POS 1U -#define RTC_IFR_MINF_MSK BIT(RTC_IFR_MINF_POS) - -#define RTC_IFR_SECF_POS 0U -#define RTC_IFR_SECF_MSK BIT(RTC_IFR_SECF_POS) - -/****************** Bit definition for RTC_IFCR register ************************/ - -#define RTC_IFCR_TCEFC_POS 25U -#define RTC_IFCR_TCEFC_MSK BIT(RTC_IFCR_TCEFC_POS) - -#define RTC_IFCR_TCCFC_POS 24U -#define RTC_IFCR_TCCFC_MSK BIT(RTC_IFCR_TCCFC_POS) - -#define RTC_IFCR_WUFC_POS 18U -#define RTC_IFCR_WUFC_MSK BIT(RTC_IFCR_WUFC_POS) - -#define RTC_IFCR_SSTCFC_POS 17U -#define RTC_IFCR_SSTCFC_MSK BIT(RTC_IFCR_SSTCFC_POS) - -#define RTC_IFCR_RSCFC_POS 16U -#define RTC_IFCR_RSCFC_MSK BIT(RTC_IFCR_RSCFC_POS) - -#define RTC_IFCR_TAMP2FC_POS 13U -#define RTC_IFCR_TAMP2FC_MSK BIT(RTC_IFCR_TAMP2FC_POS) - -#define RTC_IFCR_TAMP1FC_POS 12U -#define RTC_IFCR_TAMP1FC_MSK BIT(RTC_IFCR_TAMP1FC_POS) - -#define RTC_IFCR_TSOVFC_POS 11U -#define RTC_IFCR_TSOVFC_MSK BIT(RTC_IFCR_TSOVFC_POS) - -#define RTC_IFCR_TSSTC_POS 10U -#define RTC_IFCR_TSSTC_MSK BIT(RTC_IFCR_TSSTC_POS) - -#define RTC_IFCR_ALMBFC_POS 9U -#define RTC_IFCR_ALMBFC_MSK BIT(RTC_IFCR_ALMBFC_POS) - -#define RTC_IFCR_ALMAFC_POS 8U -#define RTC_IFCR_ALMAFC_MSK BIT(RTC_IFCR_ALMAFC_POS) - -#define RTC_IFCR_YRFC_POS 5U -#define RTC_IFCR_YRFC_MSK BIT(RTC_IFCR_YRFC_POS) - -#define RTC_IFCR_MONFC_POS 4U -#define RTC_IFCR_MONFC_MSK BIT(RTC_IFCR_MONFC_POS) - -#define RTC_IFCR_DAYFC_POS 3U -#define RTC_IFCR_DAYFC_MSK BIT(RTC_IFCR_DAYFC_POS) - -#define RTC_IFCR_HRFC_POS 2U -#define RTC_IFCR_HRFC_MSK BIT(RTC_IFCR_HRFC_POS) - -#define RTC_IFCR_MINFC_POS 1U -#define RTC_IFCR_MINFC_MSK BIT(RTC_IFCR_MINFC_POS) - -#define RTC_IFCR_SECFC_POS 0U -#define RTC_IFCR_SECFC_MSK BIT(RTC_IFCR_SECFC_POS) - -/****************** Bit definition for RTC_ISR register ************************/ - -#define RTC_ISR_TCEF_POS 25U -#define RTC_ISR_TCEF_MSK BIT(RTC_ISR_TCEF_POS) - -#define RTC_ISR_TCCF_POS 24U -#define RTC_ISR_TCCF_MSK BIT(RTC_ISR_TCCF_POS) - -#define RTC_ISR_WUF_POS 18U -#define RTC_ISR_WUF_MSK BIT(RTC_ISR_WUF_POS) - -#define RTC_ISR_SSTCF_POS 17U -#define RTC_ISR_SSTCF_MSK BIT(RTC_ISR_SSTCF_POS) - -#define RTC_ISR_RSCF_POS 16U -#define RTC_ISR_RSCF_MSK BIT(RTC_ISR_RSCF_POS) - -#define RTC_ISR_TAMP2F_POS 13U -#define RTC_ISR_TAMP2F_MSK BIT(RTC_ISR_TAMP2F_POS) - -#define RTC_ISR_TAMP1F_POS 12U -#define RTC_ISR_TAMP1F_MSK BIT(RTC_ISR_TAMP1F_POS) - -#define RTC_ISR_TSOVF_POS 11U -#define RTC_ISR_TSOVF_MSK BIT(RTC_ISR_TSOVF_POS) - -#define RTC_ISR_TSF_POS 10U -#define RTC_ISR_TSF_MSK BIT(RTC_ISR_TSF_POS) - -#define RTC_ISR_ALMBF_POS 9U -#define RTC_ISR_ALMBF_MSK BIT(RTC_ISR_ALMBF_POS) - -#define RTC_ISR_ALMAF_POS 8U -#define RTC_ISR_ALMAF_MSK BIT(RTC_ISR_ALMAF_POS) - -#define RTC_ISR_YRF_POS 5U -#define RTC_ISR_YRF_MSK BIT(RTC_ISR_YRF_POS) - -#define RTC_ISR_MONF_POS 4U -#define RTC_ISR_MONF_MSK BIT(RTC_ISR_MONF_POS) - -#define RTC_ISR_DAYF_POS 3U -#define RTC_ISR_DAYF_MSK BIT(RTC_ISR_DAYF_POS) - -#define RTC_ISR_HRF_POS 2U -#define RTC_ISR_HRF_MSK BIT(RTC_ISR_HRF_POS) - -#define RTC_ISR_MINF_POS 1U -#define RTC_ISR_MINF_MSK BIT(RTC_ISR_MINF_POS) - -#define RTC_ISR_SECF_POS 0U -#define RTC_ISR_SECF_MSK BIT(RTC_ISR_SECF_POS) - -/****************** Bit definition for RTC_CALWPR register ************************/ - -#define RTC_CALWPR_WP_POS 0U -#define RTC_CALWPR_WP_MSK BIT(RTC_CALWPR_WP_POS) - -/****************** Bit definition for RTC_CALCON register ************************/ - -#define RTC_CALCON_DCMACC_POS 24U -#define RTC_CALCON_DCMACC_MSK BIT(RTC_CALCON_DCMACC_POS) - -#define RTC_CALCON_ALG_POS 23U -#define RTC_CALCON_ALG_MSK BIT(RTC_CALCON_ALG_POS) - -#define RTC_CALCON_TCP_POSS 20U -#define RTC_CALCON_TCP_POSE 22U -#define RTC_CALCON_TCP_MSK BITS(RTC_CALCON_TCP_POSS,RTC_CALCON_TCP_POSE) - -#define RTC_CALCON_ERR_POS 19U -#define RTC_CALCON_ERR_MSK BIT(RTC_CALCON_ERR_POS) - -#define RTC_CALCON_BUSY_POS 18U -#define RTC_CALCON_BUSY_MSK BIT(RTC_CALCON_BUSY_POS) - -#define RTC_CALCON_TCM_POSS 16U -#define RTC_CALCON_TCM_POSE 17U -#define RTC_CALCON_TCM_MSK BITS(RTC_CALCON_TCM_POSS,RTC_CALCON_TCM_POSE) - -#define RTC_CALCON_CALP_POSS 1U -#define RTC_CALCON_CALP_POSE 3U -#define RTC_CALCON_CALP_MSK BITS(RTC_CALCON_CALP_POSS,RTC_CALCON_CALP_POSE) - -#define RTC_CALCON_CALEN_POS 0U -#define RTC_CALCON_CALEN_MSK BIT(RTC_CALCON_CALEN_POS) - -/****************** Bit definition for RTC_CALDR register ************************/ - -#define RTC_CALDR_DATA_POSS 16U -#define RTC_CALDR_DATA_POSE 31U -#define RTC_CALDR_DATA_MSK BITS(RTC_CALDR_DATA_POSS,RTC_CALDR_DATA_POSE) - -#define RTC_CALDR_VAL_POSS 0U -#define RTC_CALDR_VAL_POSE 15U -#define RTC_CALDR_VAL_MSK BITS(RTC_CALDR_VAL_POSS,RTC_CALDR_VAL_POSE) - -/****************** Bit definition for RTC_TEMPR register ************************/ - -#define RTC_TEMPR_DATA_POSS 16U -#define RTC_TEMPR_DATA_POSE 31U -#define RTC_TEMPR_DATA_MSK BITS(RTC_TEMPR_DATA_POSS,RTC_TEMPR_DATA_POSE) - -#define RTC_TEMPR_VAL_POSS 0U -#define RTC_TEMPR_VAL_POSE 15U -#define RTC_TEMPR_VAL_MSK BITS(RTC_TEMPR_VAL_POSS,RTC_TEMPR_VAL_POSE) - -/****************** Bit definition for RTC_TEMPBDR register ************************/ - -#define RTC_TEMPBDR_VAL_POSS 0U -#define RTC_TEMPBDR_VAL_POSE 15U -#define RTC_TEMPBDR_VAL_MSK BITS(RTC_TEMPBDR_VAL_POSS,RTC_TEMPBDR_VAL_POSE) - -/****************** Bit definition for RTC_BKP register ************************/ - -#define RTC_BKP_BKP_POSS 0U -#define RTC_BKP_BKP_POSE 31U -#define RTC_BKP_BKP_MSK BITS(RTC_BKP_BKP_POSS,RTC_BKP_BKP_POSE) - -typedef struct -{ - __IO uint32_t WPR; - __IO uint32_t CON; - __IO uint32_t PSR; - __IO uint32_t TAMPCON; - __IO uint32_t TIME; - __IO uint32_t DATE; - __IO uint32_t SSEC; - __IO uint32_t WUMAT; - __IO uint32_t ALMA; - __IO uint32_t ALMB; - __IO uint32_t ALMASSEC; - __IO uint32_t ALMBSSEC; - __I uint32_t TSTIME; - __I uint32_t TSDATE; - __I uint32_t TSSSEC; - __O uint32_t SSECTR; - __IO uint32_t IER; - __I uint32_t IFR; - __O uint32_t IFCR; - __I uint32_t ISR; - __IO uint32_t CALWPR; - __IO uint32_t CALCON; - __IO uint32_t CALDR; - __IO uint32_t TEMPR; - __IO uint32_t LTCAR; - __IO uint32_t LTCBR; - __IO uint32_t LTCCR; - __IO uint32_t LTCDR; - __IO uint32_t LTCER; - __IO uint32_t HTCAR; - __IO uint32_t HTCBR; - __IO uint32_t HTCCR; - __IO uint32_t HTCDR; - __IO uint32_t HTCER; - __IO uint32_t TEMPBDR; - uint32_t RESERVED0[29] ; - __IO uint32_t BKPR[32]; -} RTC_TypeDef; - -/****************** Bit definition for TIMER_CON1 register ************************/ - -#define TIMER_CON1_DFCKSEL_POSS 8U -#define TIMER_CON1_DFCKSEL_POSE 9U -#define TIMER_CON1_DFCKSEL_MSK BITS(TIMER_CON1_DFCKSEL_POSS,TIMER_CON1_DFCKSEL_POSE) - -#define TIMER_CON1_ARPEN_POS 7U -#define TIMER_CON1_ARPEN_MSK BIT(TIMER_CON1_ARPEN_POS) - -#define TIMER_CON1_CMSEL_POSS 5U -#define TIMER_CON1_CMSEL_POSE 6U -#define TIMER_CON1_CMSEL_MSK BITS(TIMER_CON1_CMSEL_POSS,TIMER_CON1_CMSEL_POSE) - -#define TIMER_CON1_DIRSEL_POS 4U -#define TIMER_CON1_DIRSEL_MSK BIT(TIMER_CON1_DIRSEL_POS) - -#define TIMER_CON1_SPMEN_POS 3U -#define TIMER_CON1_SPMEN_MSK BIT(TIMER_CON1_SPMEN_POS) - -#define TIMER_CON1_UERSEL_POS 2U -#define TIMER_CON1_UERSEL_MSK BIT(TIMER_CON1_UERSEL_POS) - -#define TIMER_CON1_DISUE_POS 1U -#define TIMER_CON1_DISUE_MSK BIT(TIMER_CON1_DISUE_POS) - -#define TIMER_CON1_CNTEN_POS 0U -#define TIMER_CON1_CNTEN_MSK BIT(TIMER_CON1_CNTEN_POS) - -/****************** Bit definition for TIMER_CON2 register ************************/ - -#define TIMER_CON2_OISS4_POS 14U -#define TIMER_CON2_OISS4_MSK BIT(TIMER_CON2_OISS4_POS) - -#define TIMER_CON2_OISS3N_POS 13U -#define TIMER_CON2_OISS3N_MSK BIT(TIMER_CON2_OISS3N_POS) - -#define TIMER_CON2_OISS3_POS 12U -#define TIMER_CON2_OISS3_MSK BIT(TIMER_CON2_OISS3_POS) - -#define TIMER_CON2_OISS2N_POS 11U -#define TIMER_CON2_OISS2N_MSK BIT(TIMER_CON2_OISS2N_POS) - -#define TIMER_CON2_OISS2_POS 10U -#define TIMER_CON2_OISS2_MSK BIT(TIMER_CON2_OISS2_POS) - -#define TIMER_CON2_OISS1N_POS 9U -#define TIMER_CON2_OISS1N_MSK BIT(TIMER_CON2_OISS1N_POS) - -#define TIMER_CON2_OISS1_POS 8U -#define TIMER_CON2_OISS1_MSK BIT(TIMER_CON2_OISS1_POS) - -#define TIMER_CON2_I1FSEL_POS 7U -#define TIMER_CON2_I1FSEL_MSK BIT(TIMER_CON2_I1FSEL_POS) - -#define TIMER_CON2_TRGOSEL_POSS 4U -#define TIMER_CON2_TRGOSEL_POSE 6U -#define TIMER_CON2_TRGOSEL_MSK BITS(TIMER_CON2_TRGOSEL_POSS,TIMER_CON2_TRGOSEL_POSE) - -#define TIMER_CON2_CCDMASEL_POS 3U -#define TIMER_CON2_CCDMASEL_MSK BIT(TIMER_CON2_CCDMASEL_POS) - -#define TIMER_CON2_CCUSEL_POS 2U -#define TIMER_CON2_CCUSEL_MSK BIT(TIMER_CON2_CCUSEL_POS) - -#define TIMER_CON2_CCPCEN_POS 0U -#define TIMER_CON2_CCPCEN_MSK BIT(TIMER_CON2_CCPCEN_POS) - -/****************** Bit definition for TIMER_SMCON register ************************/ - -#define TIMER_SMCON_ETPOL_POS 15U -#define TIMER_SMCON_ETPOL_MSK BIT(TIMER_SMCON_ETPOL_POS) - -#define TIMER_SMCON_ECM2EN_POS 14U -#define TIMER_SMCON_ECM2EN_MSK BIT(TIMER_SMCON_ECM2EN_POS) - -#define TIMER_SMCON_ETPSEL_POSS 12U -#define TIMER_SMCON_ETPSEL_POSE 13U -#define TIMER_SMCON_ETPSEL_MSK BITS(TIMER_SMCON_ETPSEL_POSS,TIMER_SMCON_ETPSEL_POSE) - -#define TIMER_SMCON_ETFLT_POSS 8U -#define TIMER_SMCON_ETFLT_POSE 11U -#define TIMER_SMCON_ETFLT_MSK BITS(TIMER_SMCON_ETFLT_POSS,TIMER_SMCON_ETFLT_POSE) - -#define TIMER_SMCON_MSCFG_POS 7U -#define TIMER_SMCON_MSCFG_MSK BIT(TIMER_SMCON_MSCFG_POS) - -#define TIMER_SMCON_TSSEL_POSS 4U -#define TIMER_SMCON_TSSEL_POSE 6U -#define TIMER_SMCON_TSSEL_MSK BITS(TIMER_SMCON_TSSEL_POSS,TIMER_SMCON_TSSEL_POSE) - -#define TIMER_SMCON_SMODS_POSS 0U -#define TIMER_SMCON_SMODS_POSE 2U -#define TIMER_SMCON_SMODS_MSK BITS(TIMER_SMCON_SMODS_POSS,TIMER_SMCON_SMODS_POSE) - -/****************** Bit definition for TIMER_DIER register ************************/ - -#define TIMER_DIER_TRGDMA_POS 14U -#define TIMER_DIER_TRGDMA_MSK BIT(TIMER_DIER_TRGDMA_POS) - -#define TIMER_DIER_COMDMA_POS 13U -#define TIMER_DIER_COMDMA_MSK BIT(TIMER_DIER_COMDMA_POS) - -#define TIMER_DIER_CC4DMA_POS 12U -#define TIMER_DIER_CC4DMA_MSK BIT(TIMER_DIER_CC4DMA_POS) - -#define TIMER_DIER_CC3DMA_POS 11U -#define TIMER_DIER_CC3DMA_MSK BIT(TIMER_DIER_CC3DMA_POS) - -#define TIMER_DIER_CC2DMA_POS 10U -#define TIMER_DIER_CC2DMA_MSK BIT(TIMER_DIER_CC2DMA_POS) - -#define TIMER_DIER_CC1DMA_POS 9U -#define TIMER_DIER_CC1DMA_MSK BIT(TIMER_DIER_CC1DMA_POS) - -#define TIMER_DIER_UDMA_POS 8U -#define TIMER_DIER_UDMA_MSK BIT(TIMER_DIER_UDMA_POS) - -#define TIMER_DIER_BRKIT_POS 7U -#define TIMER_DIER_BRKIT_MSK BIT(TIMER_DIER_BRKIT_POS) - -#define TIMER_DIER_TRGIT_POS 6U -#define TIMER_DIER_TRGIT_MSK BIT(TIMER_DIER_TRGIT_POS) - -#define TIMER_DIER_COMIT_POS 5U -#define TIMER_DIER_COMIT_MSK BIT(TIMER_DIER_COMIT_POS) - -#define TIMER_DIER_CC4IT_POS 4U -#define TIMER_DIER_CC4IT_MSK BIT(TIMER_DIER_CC4IT_POS) - -#define TIMER_DIER_CC3IT_POS 3U -#define TIMER_DIER_CC3IT_MSK BIT(TIMER_DIER_CC3IT_POS) - -#define TIMER_DIER_CC2IT_POS 2U -#define TIMER_DIER_CC2IT_MSK BIT(TIMER_DIER_CC2IT_POS) - -#define TIMER_DIER_CC1IT_POS 1U -#define TIMER_DIER_CC1IT_MSK BIT(TIMER_DIER_CC1IT_POS) - -#define TIMER_DIER_UIT_POS 0U -#define TIMER_DIER_UIT_MSK BIT(TIMER_DIER_UIT_POS) - -/****************** Bit definition for TIMER_DIDR register ************************/ - -#define TIMER_DIDR_TRGDMA_POS 14U -#define TIMER_DIDR_TRGDMA_MSK BIT(TIMER_DIDR_TRGDMA_POS) - -#define TIMER_DIDR_COMD_POS 13U -#define TIMER_DIDR_COMD_MSK BIT(TIMER_DIDR_COMD_POS) - -#define TIMER_DIDR_CC4D_POS 12U -#define TIMER_DIDR_CC4D_MSK BIT(TIMER_DIDR_CC4D_POS) - -#define TIMER_DIDR_CC3D_POS 11U -#define TIMER_DIDR_CC3D_MSK BIT(TIMER_DIDR_CC3D_POS) - -#define TIMER_DIDR_CC2D_POS 10U -#define TIMER_DIDR_CC2D_MSK BIT(TIMER_DIDR_CC2D_POS) - -#define TIMER_DIDR_CC1D_POS 9U -#define TIMER_DIDR_CC1D_MSK BIT(TIMER_DIDR_CC1D_POS) - -#define TIMER_DIDR_UD_POS 8U -#define TIMER_DIDR_UD_MSK BIT(TIMER_DIDR_UD_POS) - -#define TIMER_DIDR_BRKI_POS 7U -#define TIMER_DIDR_BRKI_MSK BIT(TIMER_DIDR_BRKI_POS) - -#define TIMER_DIDR_TRGI_POS 6U -#define TIMER_DIDR_TRGI_MSK BIT(TIMER_DIDR_TRGI_POS) - -#define TIMER_DIDR_COMI_POS 5U -#define TIMER_DIDR_COMI_MSK BIT(TIMER_DIDR_COMI_POS) - -#define TIMER_DIDR_CC4I_POS 4U -#define TIMER_DIDR_CC4I_MSK BIT(TIMER_DIDR_CC4I_POS) - -#define TIMER_DIDR_CC3I_POS 3U -#define TIMER_DIDR_CC3I_MSK BIT(TIMER_DIDR_CC3I_POS) - -#define TIMER_DIDR_CC2I_POS 2U -#define TIMER_DIDR_CC2I_MSK BIT(TIMER_DIDR_CC2I_POS) - -#define TIMER_DIDR_CC1I_POS 1U -#define TIMER_DIDR_CC1I_MSK BIT(TIMER_DIDR_CC1I_POS) - -#define TIMER_DIDR_UI_POS 0U -#define TIMER_DIDR_UI_MSK BIT(TIMER_DIDR_UI_POS) - -/****************** Bit definition for TIMER_DIVS register ************************/ - -#define TIMER_DIVS_TRGDMA_POS 14U -#define TIMER_DIVS_TRGDMA_MSK BIT(TIMER_DIVS_TRGDMA_POS) - -#define TIMER_DIVS_COMDMA_POS 13U -#define TIMER_DIVS_COMDMA_MSK BIT(TIMER_DIVS_COMDMA_POS) - -#define TIMER_DIVS_CC4DMA_POS 12U -#define TIMER_DIVS_CC4DMA_MSK BIT(TIMER_DIVS_CC4DMA_POS) - -#define TIMER_DIVS_CC3DMA_POS 11U -#define TIMER_DIVS_CC3DMA_MSK BIT(TIMER_DIVS_CC3DMA_POS) - -#define TIMER_DIVS_CC2DMA_POS 10U -#define TIMER_DIVS_CC2DMA_MSK BIT(TIMER_DIVS_CC2DMA_POS) - -#define TIMER_DIVS_CC1DMA_POS 9U -#define TIMER_DIVS_CC1DMA_MSK BIT(TIMER_DIVS_CC1DMA_POS) - -#define TIMER_DIVS_UEDTR_POS 8U -#define TIMER_DIVS_UEDTR_MSK BIT(TIMER_DIVS_UEDTR_POS) - -#define TIMER_DIVS_BKI_POS 7U -#define TIMER_DIVS_BKI_MSK BIT(TIMER_DIVS_BKI_POS) - -#define TIMER_DIVS_TRGI_POS 6U -#define TIMER_DIVS_TRGI_MSK BIT(TIMER_DIVS_TRGI_POS) - -#define TIMER_DIVS_COMI_POS 5U -#define TIMER_DIVS_COMI_MSK BIT(TIMER_DIVS_COMI_POS) - -#define TIMER_DIVS_CC4I_POS 4U -#define TIMER_DIVS_CC4I_MSK BIT(TIMER_DIVS_CC4I_POS) - -#define TIMER_DIVS_CC3I_POS 3U -#define TIMER_DIVS_CC3I_MSK BIT(TIMER_DIVS_CC3I_POS) - -#define TIMER_DIVS_CC2I_POS 2U -#define TIMER_DIVS_CC2I_MSK BIT(TIMER_DIVS_CC2I_POS) - -#define TIMER_DIVS_CC1I_POS 1U -#define TIMER_DIVS_CC1I_MSK BIT(TIMER_DIVS_CC1I_POS) - -#define TIMER_DIVS_UEI_POS 0U -#define TIMER_DIVS_UEI_MSK BIT(TIMER_DIVS_UEI_POS) - -/****************** Bit definition for TIMER_RIF register ************************/ - -#define TIMER_RIF_CH4OVIF_POS 12U -#define TIMER_RIF_CH4OVIF_MSK BIT(TIMER_RIF_CH4OVIF_POS) - -#define TIMER_RIF_CH3OVIF_POS 11U -#define TIMER_RIF_CH3OVIF_MSK BIT(TIMER_RIF_CH3OVIF_POS) - -#define TIMER_RIF_CH2OVIF_POS 10U -#define TIMER_RIF_CH2OVIF_MSK BIT(TIMER_RIF_CH2OVIF_POS) - -#define TIMER_RIF_CH1OVIF_POS 9U -#define TIMER_RIF_CH1OVIF_MSK BIT(TIMER_RIF_CH1OVIF_POS) - -#define TIMER_RIF_BRKIF_POS 7U -#define TIMER_RIF_BRKIF_MSK BIT(TIMER_RIF_BRKIF_POS) - -#define TIMER_RIF_TRGIF_POS 6U -#define TIMER_RIF_TRGIF_MSK BIT(TIMER_RIF_TRGIF_POS) - -#define TIMER_RIF_COMIF_POS 5U -#define TIMER_RIF_COMIF_MSK BIT(TIMER_RIF_COMIF_POS) - -#define TIMER_RIF_CH4IF_POS 4U -#define TIMER_RIF_CH4IF_MSK BIT(TIMER_RIF_CH4IF_POS) - -#define TIMER_RIF_CH3IF_POS 3U -#define TIMER_RIF_CH3IF_MSK BIT(TIMER_RIF_CH3IF_POS) - -#define TIMER_RIF_CH2IF_POS 2U -#define TIMER_RIF_CH2IF_MSK BIT(TIMER_RIF_CH2IF_POS) - -#define TIMER_RIF_CH1IF_POS 1U -#define TIMER_RIF_CH1IF_MSK BIT(TIMER_RIF_CH1IF_POS) - -#define TIMER_RIF_UEVTIF_POS 0U -#define TIMER_RIF_UEVTIF_MSK BIT(TIMER_RIF_UEVTIF_POS) - -/****************** Bit definition for TIMER_IFM register ************************/ - -#define TIMER_IFM_BRKIM_POS 7U -#define TIMER_IFM_BRKIM_MSK BIT(TIMER_IFM_BRKIM_POS) - -#define TIMER_IFM_TRGI_POS 6U -#define TIMER_IFM_TRGI_MSK BIT(TIMER_IFM_TRGI_POS) - -#define TIMER_IFM_COMI_POS 5U -#define TIMER_IFM_COMI_MSK BIT(TIMER_IFM_COMI_POS) - -#define TIMER_IFM_CH4CCI_POS 4U -#define TIMER_IFM_CH4CCI_MSK BIT(TIMER_IFM_CH4CCI_POS) - -#define TIMER_IFM_CH3CCI_POS 3U -#define TIMER_IFM_CH3CCI_MSK BIT(TIMER_IFM_CH3CCI_POS) - -#define TIMER_IFM_CH2CCI_POS 2U -#define TIMER_IFM_CH2CCI_MSK BIT(TIMER_IFM_CH2CCI_POS) - -#define TIMER_IFM_CH1CCI_POS 1U -#define TIMER_IFM_CH1CCI_MSK BIT(TIMER_IFM_CH1CCI_POS) - -#define TIMER_IFM_UEI_POS 0U -#define TIMER_IFM_UEI_MSK BIT(TIMER_IFM_UEI_POS) - -/****************** Bit definition for TIMER_ICR register ************************/ - -#define TIMER_ICR_BRKIC_POS 7U -#define TIMER_ICR_BRKIC_MSK BIT(TIMER_ICR_BRKIC_POS) - -#define TIMER_ICR_TRGIC_POS 6U -#define TIMER_ICR_TRGIC_MSK BIT(TIMER_ICR_TRGIC_POS) - -#define TIMER_ICR_COMIC_POS 5U -#define TIMER_ICR_COMIC_MSK BIT(TIMER_ICR_COMIC_POS) - -#define TIMER_ICR_CH4CCIC_POS 4U -#define TIMER_ICR_CH4CCIC_MSK BIT(TIMER_ICR_CH4CCIC_POS) - -#define TIMER_ICR_CH3CCIC_POS 3U -#define TIMER_ICR_CH3CCIC_MSK BIT(TIMER_ICR_CH3CCIC_POS) - -#define TIMER_ICR_CH2CCIC_POS 2U -#define TIMER_ICR_CH2CCIC_MSK BIT(TIMER_ICR_CH2CCIC_POS) - -#define TIMER_ICR_CH1CCIC_POS 1U -#define TIMER_ICR_CH1CCIC_MSK BIT(TIMER_ICR_CH1CCIC_POS) - -#define TIMER_ICR_UEIC_POS 0U -#define TIMER_ICR_UEIC_MSK BIT(TIMER_ICR_UEIC_POS) - -/****************** Bit definition for TIMER_SGE register ************************/ - -#define TIMER_SGE_SGBRK_POS 7U -#define TIMER_SGE_SGBRK_MSK BIT(TIMER_SGE_SGBRK_POS) - -#define TIMER_SGE_SGTRG_POS 6U -#define TIMER_SGE_SGTRG_MSK BIT(TIMER_SGE_SGTRG_POS) - -#define TIMER_SGE_SGCOM_POS 5U -#define TIMER_SGE_SGCOM_MSK BIT(TIMER_SGE_SGCOM_POS) - -#define TIMER_SGE_SGCC4E_POS 4U -#define TIMER_SGE_SGCC4E_MSK BIT(TIMER_SGE_SGCC4E_POS) - -#define TIMER_SGE_SGCC3E_POS 3U -#define TIMER_SGE_SGCC3E_MSK BIT(TIMER_SGE_SGCC3E_POS) - -#define TIMER_SGE_SGCC2E_POS 2U -#define TIMER_SGE_SGCC2E_MSK BIT(TIMER_SGE_SGCC2E_POS) - -#define TIMER_SGE_SGCC1E_POS 1U -#define TIMER_SGE_SGCC1E_MSK BIT(TIMER_SGE_SGCC1E_POS) - -#define TIMER_SGE_SGU_POS 0U -#define TIMER_SGE_SGU_MSK BIT(TIMER_SGE_SGU_POS) - -/****************** Bit definition for TIMER_CHMR1 register ************************/ -/* Output */ -#define TIMER_CHMR1_CH2OCLREN_POS 15U -#define TIMER_CHMR1_CH2OCLREN_MSK BIT(TIMER_CHMR1_CH2OCLREN_POS) - -#define TIMER_CHMR1_CH2OMOD_POSS 12U -#define TIMER_CHMR1_CH2OMOD_POSE 14U -#define TIMER_CHMR1_CH2OMOD_MSK BITS(TIMER_CHMR1_CH2OMOD_POSS,TIMER_CHMR1_CH2OMOD_POSE) - -#define TIMER_CHMR1_CH2OPEN_POS 11U -#define TIMER_CHMR1_CH2OPEN_MSK BIT(TIMER_CHMR1_CH2OPEN_POS) - -#define TIMER_CHMR1_CH2OFEN_POS 10U -#define TIMER_CHMR1_CH2OFEN_MSK BIT(TIMER_CHMR1_CH2OFEN_POS) - -#define TIMER_CHMR1_CC2SSEL_POSS 8U -#define TIMER_CHMR1_CC2SSEL_POSE 9U -#define TIMER_CHMR1_CC2SSEL_MSK BITS(TIMER_CHMR1_CC2SSEL_POSS,TIMER_CHMR1_CC2SSEL_POSE) - -#define TIMER_CHMR1_CH1OCLREN_POS 7U -#define TIMER_CHMR1_CH1OCLREN_MSK BIT(TIMER_CHMR1_CH1OCLREN_POS) - -#define TIMER_CHMR1_CH1OMOD_POSS 4U -#define TIMER_CHMR1_CH1OMOD_POSE 6U -#define TIMER_CHMR1_CH1OMOD_MSK BITS(TIMER_CHMR1_CH1OMOD_POSS,TIMER_CHMR1_CH1OMOD_POSE) - -#define TIMER_CHMR1_CH1OPREN_POS 3U -#define TIMER_CHMR1_CH1OPREN_MSK BIT(TIMER_CHMR1_CH1OPREN_POS) - -#define TIMER_CHMR1_CH1OHSEN_POS 2U -#define TIMER_CHMR1_CH1OHSEN_MSK BIT(TIMER_CHMR1_CH1OHSEN_POS) - -#define TIMER_CHMR1_CC1SSEL_POSS 0U -#define TIMER_CHMR1_CC1SSEL_POSE 1U -#define TIMER_CHMR1_CC1SSEL_MSK BITS(TIMER_CHMR1_CC1SSEL_POSS,TIMER_CHMR1_CC1SSEL_POSE) - -/* Input */ -#define TIMER_CHMR1_I2FLT_POSS 12U -#define TIMER_CHMR1_I2FLT_POSE 15U -#define TIMER_CHMR1_I2FLT_MSK BITS(TIMER_CHMR1_I2FLT_POSS,TIMER_CHMR1_I2FLT_POSE) - -#define TIMER_CHMR1_IC2PRES_POSS 10U -#define TIMER_CHMR1_IC2PRES_POSE 11U -#define TIMER_CHMR1_IC2PRES_MSK BITS(TIMER_CHMR1_IC2PRES_POSS,TIMER_CHMR1_IC2PRES_POSE) - -#define TIMER_CHMR1_CC2SSEL_POSS 8U -#define TIMER_CHMR1_CC2SSEL_POSE 9U -#define TIMER_CHMR1_CC2SSEL_MSK BITS(TIMER_CHMR1_CC2SSEL_POSS,TIMER_CHMR1_CC2SSEL_POSE) - -#define TIMER_CHMR1_I1FLT_POSS 4U -#define TIMER_CHMR1_I1FLT_POSE 7U -#define TIMER_CHMR1_I1FLT_MSK BITS(TIMER_CHMR1_I1FLT_POSS,TIMER_CHMR1_I1FLT_POSE) - -#define TIMER_CHMR1_IC1PRES_POSS 2U -#define TIMER_CHMR1_IC1PRES_POSE 3U -#define TIMER_CHMR1_IC1PRES_MSK BITS(TIMER_CHMR1_IC1PRES_POSS,TIMER_CHMR1_IC1PRES_POSE) - -#define TIMER_CHMR1_CC1SSEL_POSS 0U -#define TIMER_CHMR1_CC1SSEL_POSE 1U -#define TIMER_CHMR1_CC1SSEL_MSK BITS(TIMER_CHMR1_CC1SSEL_POSS,TIMER_CHMR1_CC1SSEL_POSE) - -/****************** Bit definition for TIMER_CHMR2 register ************************/ -/* Output */ -#define TIMER_CHMR2_CH4OCLREN_POS 15U -#define TIMER_CHMR2_CH4OCLREN_MSK BIT(TIMER_CHMR2_CH4OCLREN_POS) - -#define TIMER_CHMR2_CH4OMOD_POSS 12U -#define TIMER_CHMR2_CH4OMOD_POSE 14U -#define TIMER_CHMR2_CH4OMOD_MSK BITS(TIMER_CHMR2_CH4OMOD_POSS,TIMER_CHMR2_CH4OMOD_POSE) - -#define TIMER_CHMR2_CH4OPEN_POS 11U -#define TIMER_CHMR2_CH4OPEN_MSK BIT(TIMER_CHMR2_CH4OPEN_POS) - -#define TIMER_CHMR2_CH4OHSEN_POS 10U -#define TIMER_CHMR2_CH4OHSEN_MSK BIT(TIMER_CHMR2_CH4OHSEN_POS) - -#define TIMER_CHMR2_CC4SSEL_POSS 8U -#define TIMER_CHMR2_CC4SSEL_POSE 9U -#define TIMER_CHMR2_CC4SSEL_MSK BITS(TIMER_CHMR2_CC4SSEL_POSS,TIMER_CHMR2_CC4SSEL_POSE) - -#define TIMER_CHMR2_CH3OCLREN_POS 7U -#define TIMER_CHMR2_CH3OCLREN_MSK BIT(TIMER_CHMR2_CH3OCLREN_POS) - -#define TIMER_CHMR2_CH3OMOD_POSS 4U -#define TIMER_CHMR2_CH3OMOD_POSE 6U -#define TIMER_CHMR2_CH3OMOD_MSK BITS(TIMER_CHMR2_CH3OMOD_POSS,TIMER_CHMR2_CH3OMOD_POSE) - -#define TIMER_CHMR2_CH3OPEN_POS 3U -#define TIMER_CHMR2_CH3OPEN_MSK BIT(TIMER_CHMR2_CH3OPEN_POS) - -#define TIMER_CHMR2_CH3OFEN_POS 2U -#define TIMER_CHMR2_CH3OFEN_MSK BIT(TIMER_CHMR2_CH3OFEN_POS) - -#define TIMER_CHMR2_CC3SSEL_POSS 0U -#define TIMER_CHMR2_CC3SSEL_POSE 1U -#define TIMER_CHMR2_CC3SSEL_MSK BITS(TIMER_CHMR2_CC3SSEL_POSS,TIMER_CHMR2_CC3SSEL_POSE) - -/* Input */ -#define TIMER_CHMR2_I4FLT_POSS 12U -#define TIMER_CHMR2_I4FLT_POSE 15U -#define TIMER_CHMR2_I4FLT_MSK BITS(TIMER_CHMR2_I4FLT_POSS,TIMER_CHMR2_I4FLT_POSE) - -#define TIMER_CHMR2_IC4PRES_POSS 10U -#define TIMER_CHMR2_IC4PRES_POSE 11U -#define TIMER_CHMR2_IC4PRES_MSK BITS(TIMER_CHMR2_IC4PRES_POSS,TIMER_CHMR2_IC4PRES_POSE) - -#define TIMER_CHMR2_CC4SSEL_POSS 8U -#define TIMER_CHMR2_CC4SSEL_POSE 9U -#define TIMER_CHMR2_CC4SSEL_MSK BITS(TIMER_CHMR2_CC4SSEL_POSS,TIMER_CHMR2_CC4SSEL_POSE) - -#define TIMER_CHMR2_I3FLT_POSS 4U -#define TIMER_CHMR2_I3FLT_POSE 7U -#define TIMER_CHMR2_I3FLT_MSK BITS(TIMER_CHMR2_I3FLT_POSS,TIMER_CHMR2_I3FLT_POSE) - -#define TIMER_CHMR2_IC3PRES_POSS 2U -#define TIMER_CHMR2_IC3PRES_POSE 3U -#define TIMER_CHMR2_IC3PRES_MSK BITS(TIMER_CHMR2_IC3PRES_POSS,TIMER_CHMR2_IC3PRES_POSE) - -#define TIMER_CHMR2_CC3SSEL_POSS 0U -#define TIMER_CHMR2_CC3SSEL_POSE 1U -#define TIMER_CHMR2_CC3SSEL_MSK BITS(TIMER_CHMR2_CC3SSEL_POSS,TIMER_CHMR2_CC3SSEL_POSE) - -/****************** Bit definition for TIMER_CCEP register ************************/ - -#define TIMER_CCEP_CC4POL_POS 13U -#define TIMER_CCEP_CC4POL_MSK BIT(TIMER_CCEP_CC4POL_POS) - -#define TIMER_CCEP_CC4EN_POS 12U -#define TIMER_CCEP_CC4EN_MSK BIT(TIMER_CCEP_CC4EN_POS) - -#define TIMER_CCEP_CC3NPOL_POS 11U -#define TIMER_CCEP_CC3NPOL_MSK BIT(TIMER_CCEP_CC3NPOL_POS) - -#define TIMER_CCEP_CC3NEN_POS 10U -#define TIMER_CCEP_CC3NEN_MSK BIT(TIMER_CCEP_CC3NEN_POS) - -#define TIMER_CCEP_CC3POL_POS 9U -#define TIMER_CCEP_CC3POL_MSK BIT(TIMER_CCEP_CC3POL_POS) - -#define TIMER_CCEP_CC3EN_POS 8U -#define TIMER_CCEP_CC3EN_MSK BIT(TIMER_CCEP_CC3EN_POS) - -#define TIMER_CCEP_CC2NPOL_POS 7U -#define TIMER_CCEP_CC2NPOL_MSK BIT(TIMER_CCEP_CC2NPOL_POS) - -#define TIMER_CCEP_CC2NEN_POS 6U -#define TIMER_CCEP_CC2NEN_MSK BIT(TIMER_CCEP_CC2NEN_POS) - -#define TIMER_CCEP_CC2POL_POS 5U -#define TIMER_CCEP_CC2POL_MSK BIT(TIMER_CCEP_CC2POL_POS) - -#define TIMER_CCEP_CC2EN_POS 4U -#define TIMER_CCEP_CC2EN_MSK BIT(TIMER_CCEP_CC2EN_POS) - -#define TIMER_CCEP_CC1NPOL_POS 3U -#define TIMER_CCEP_CC1NPOL_MSK BIT(TIMER_CCEP_CC1NPOL_POS) - -#define TIMER_CCEP_CC1NEN_POS 2U -#define TIMER_CCEP_CC1NEN_MSK BIT(TIMER_CCEP_CC1NEN_POS) - -#define TIMER_CCEP_CC1POL_POS 1U -#define TIMER_CCEP_CC1POL_MSK BIT(TIMER_CCEP_CC1POL_POS) - -#define TIMER_CCEP_CC1EN_POS 0U -#define TIMER_CCEP_CC1EN_MSK BIT(TIMER_CCEP_CC1EN_POS) - -/****************** Bit definition for TIMER_COUNT register ************************/ - -#define TIMER_COUNT_CNTV_POSS 0U -#define TIMER_COUNT_CNTV_POSE 15U -#define TIMER_COUNT_CNTV_MSK BITS(TIMER_COUNT_CNTV_POSS,TIMER_COUNT_CNTV_POSE) - -/****************** Bit definition for TIMER_PRES register ************************/ - -#define TIMER_PRES_PSCV_POSS 0U -#define TIMER_PRES_PSCV_POSE 15U -#define TIMER_PRES_PSCV_MSK BITS(TIMER_PRES_PSCV_POSS,TIMER_PRES_PSCV_POSE) - -/****************** Bit definition for TIMER_AR register ************************/ - -#define TIMER_AR_ARRV_POSS 0U -#define TIMER_AR_ARRV_POSE 15U -#define TIMER_AR_ARRV_MSK BITS(TIMER_AR_ARRV_POSS,TIMER_AR_ARRV_POSE) - -/****************** Bit definition for TIMER_REPAR register ************************/ - -#define TIMER_REPAR_REPV_POSS 0U -#define TIMER_REPAR_REPV_POSE 7U -#define TIMER_REPAR_REPV_MSK BITS(TIMER_REPAR_REPV_POSS,TIMER_REPAR_REPV_POSE) - -/****************** Bit definition for TIMER_CCVAL1 register ************************/ - -#define TIMER_CCVAL1_CCRV1_POSS 0U -#define TIMER_CCVAL1_CCRV1_POSE 15U -#define TIMER_CCVAL1_CCRV1_MSK BITS(TIMER_CCVAL1_CCRV1_POSS,TIMER_CCVAL1_CCRV1_POSE) - -/****************** Bit definition for TIMER_CCVAL2 register ************************/ - -#define TIMER_CCVAL2_CCRV2_POSS 0U -#define TIMER_CCVAL2_CCRV2_POSE 15U -#define TIMER_CCVAL2_CCRV2_MSK BITS(TIMER_CCVAL2_CCRV2_POSS,TIMER_CCVAL2_CCRV2_POSE) - -/****************** Bit definition for TIMER_CCVAL3 register ************************/ - -#define TIMER_CCVAL3_CCRV3_POSS 0U -#define TIMER_CCVAL3_CCRV3_POSE 15U -#define TIMER_CCVAL3_CCRV3_MSK BITS(TIMER_CCVAL3_CCRV3_POSS,TIMER_CCVAL3_CCRV3_POSE) - -/****************** Bit definition for TIMER_CCVAL4 register ************************/ - -#define TIMER_CCVAL4_CCRV4_POSS 0U -#define TIMER_CCVAL4_CCRV4_POSE 15U -#define TIMER_CCVAL4_CCRV4_MSK BITS(TIMER_CCVAL4_CCRV4_POSS,TIMER_CCVAL4_CCRV4_POSE) - -/****************** Bit definition for TIMER_BDCFG register ************************/ - -#define TIMER_BDCFG_GOEN_POS 15U -#define TIMER_BDCFG_GOEN_MSK BIT(TIMER_BDCFG_GOEN_POS) - -#define TIMER_BDCFG_AOEN_POS 14U -#define TIMER_BDCFG_AOEN_MSK BIT(TIMER_BDCFG_AOEN_POS) - -#define TIMER_BDCFG_BRKP_POS 13U -#define TIMER_BDCFG_BRKP_MSK BIT(TIMER_BDCFG_BRKP_POS) - -#define TIMER_BDCFG_BRKEN_POS 12U -#define TIMER_BDCFG_BRKEN_MSK BIT(TIMER_BDCFG_BRKEN_POS) - -#define TIMER_BDCFG_OFFSSR_POS 11U -#define TIMER_BDCFG_OFFSSR_MSK BIT(TIMER_BDCFG_OFFSSR_POS) - -#define TIMER_BDCFG_OFFSSI_POS 10U -#define TIMER_BDCFG_OFFSSI_MSK BIT(TIMER_BDCFG_OFFSSI_POS) - -#define TIMER_BDCFG_LOCKLVL_POSS 8U -#define TIMER_BDCFG_LOCKLVL_POSE 9U -#define TIMER_BDCFG_LOCKLVL_MSK BITS(TIMER_BDCFG_LOCKLVL_POSS,TIMER_BDCFG_LOCKLVL_POSE) - -#define TIMER_BDCFG_DT_POSS 0U -#define TIMER_BDCFG_DT_POSE 7U -#define TIMER_BDCFG_DT_MSK BITS(TIMER_BDCFG_DT_POSS,TIMER_BDCFG_DT_POSE) - -typedef struct -{ - __IO uint32_t CON1; - __IO uint32_t CON2; - __IO uint32_t SMCON; - __O uint32_t DIER; - __O uint32_t DIDR; - __I uint32_t DIVS; - __I uint32_t RIF; - __I uint32_t IFM; - __O uint32_t ICR; - __O uint32_t SGE; - __IO uint32_t CHMR1; - __IO uint32_t CHMR2; - __IO uint32_t CCEP; - __IO uint32_t COUNT; - __IO uint32_t PRES; - __IO uint32_t AR; - __IO uint32_t REPAR; - __IO uint32_t CCVAL1; - __IO uint32_t CCVAL2; - __IO uint32_t CCVAL3; - __IO uint32_t CCVAL4; - __IO uint32_t BDCFG; -} TIMER_TypeDef; - -/****************** Bit definition for USART_STAT register ************************/ - -#define USART_STAT_CTSIF_POS 9U -#define USART_STAT_CTSIF_MSK BIT(USART_STAT_CTSIF_POS) - -#define USART_STAT_TXEMPIF_POS 7U -#define USART_STAT_TXEMPIF_MSK BIT(USART_STAT_TXEMPIF_POS) - -#define USART_STAT_TXCIF_POS 6U -#define USART_STAT_TXCIF_MSK BIT(USART_STAT_TXCIF_POS) - -#define USART_STAT_RXNEIF_POS 5U -#define USART_STAT_RXNEIF_MSK BIT(USART_STAT_RXNEIF_POS) - -#define USART_STAT_IDLEIF_POS 4U -#define USART_STAT_IDLEIF_MSK BIT(USART_STAT_IDLEIF_POS) - -#define USART_STAT_OVRIF_POS 3U -#define USART_STAT_OVRIF_MSK BIT(USART_STAT_OVRIF_POS) - -#define USART_STAT_NDETIF_POS 2U -#define USART_STAT_NDETIF_MSK BIT(USART_STAT_NDETIF_POS) - -#define USART_STAT_FERRIF_POS 1U -#define USART_STAT_FERRIF_MSK BIT(USART_STAT_FERRIF_POS) - -#define USART_STAT_PERRIF_POS 0U -#define USART_STAT_PERRIF_MSK BIT(USART_STAT_PERRIF_POS) - -/****************** Bit definition for USART_DATA register ************************/ - -#define USART_DATA_VAL_POSS 0U -#define USART_DATA_VAL_POSE 8U -#define USART_DATA_VAL_MSK BITS(USART_DATA_VAL_POSS,USART_DATA_VAL_POSE) - -/****************** Bit definition for USART_BAUDCON register ************************/ - -#define USART_BAUDCON_DIV_M_POSS 4U -#define USART_BAUDCON_DIV_M_POSE 15U -#define USART_BAUDCON_DIV_M_MSK BITS(USART_BAUDCON_DIV_M_POSS,USART_BAUDCON_DIV_M_POSE) - -#define USART_BAUDCON_DIV_F_POSS 0U -#define USART_BAUDCON_DIV_F_POSE 3U -#define USART_BAUDCON_DIV_F_MSK BITS(USART_BAUDCON_DIV_F_POSS,USART_BAUDCON_DIV_F_POSE) - -/****************** Bit definition for USART_CON0 register ************************/ - -#define USART_CON0_EN_POS 13U -#define USART_CON0_EN_MSK BIT(USART_CON0_EN_POS) - -#define USART_CON0_DLEN_POS 12U -#define USART_CON0_DLEN_MSK BIT(USART_CON0_DLEN_POS) - -#define USART_CON0_WKMOD_POS 11U -#define USART_CON0_WKMOD_MSK BIT(USART_CON0_WKMOD_POS) - -#define USART_CON0_PEN_POS 10U -#define USART_CON0_PEN_MSK BIT(USART_CON0_PEN_POS) - -#define USART_CON0_PSEL_POS 9U -#define USART_CON0_PSEL_MSK BIT(USART_CON0_PSEL_POS) - -#define USART_CON0_PERRIE_POS 8U -#define USART_CON0_PERRIE_MSK BIT(USART_CON0_PERRIE_POS) - -#define USART_CON0_TXEMPIE_POS 7U -#define USART_CON0_TXEMPIE_MSK BIT(USART_CON0_TXEMPIE_POS) - -#define USART_CON0_TXCIE_POS 6U -#define USART_CON0_TXCIE_MSK BIT(USART_CON0_TXCIE_POS) - -#define USART_CON0_RXNEIE_POS 5U -#define USART_CON0_RXNEIE_MSK BIT(USART_CON0_RXNEIE_POS) - -#define USART_CON0_IDLEIE_POS 4U -#define USART_CON0_IDLEIE_MSK BIT(USART_CON0_IDLEIE_POS) - -#define USART_CON0_TXEN_POS 3U -#define USART_CON0_TXEN_MSK BIT(USART_CON0_TXEN_POS) - -#define USART_CON0_RXEN_POS 2U -#define USART_CON0_RXEN_MSK BIT(USART_CON0_RXEN_POS) - -#define USART_CON0_RXWK_POS 1U -#define USART_CON0_RXWK_MSK BIT(USART_CON0_RXWK_POS) - -/****************** Bit definition for USART_CON1 register ************************/ - -#define USART_CON1_STPLEN_POSS 12U -#define USART_CON1_STPLEN_POSE 13U -#define USART_CON1_STPLEN_MSK BITS(USART_CON1_STPLEN_POSS,USART_CON1_STPLEN_POSE) - -#define USART_CON1_SCKEN_POS 11U -#define USART_CON1_SCKEN_MSK BIT(USART_CON1_SCKEN_POS) - -#define USART_CON1_SCKPOL_POS 10U -#define USART_CON1_SCKPOL_MSK BIT(USART_CON1_SCKPOL_POS) - -#define USART_CON1_SCKPHA_POS 9U -#define USART_CON1_SCKPHA_MSK BIT(USART_CON1_SCKPHA_POS) - -#define USART_CON1_LBCP_POS 8U -#define USART_CON1_LBCP_MSK BIT(USART_CON1_LBCP_POS) - -#define USART_CON1_ADDR_POSS 0U -#define USART_CON1_ADDR_POSE 3U -#define USART_CON1_ADDR_MSK BITS(USART_CON1_ADDR_POSS,USART_CON1_ADDR_POSE) - -/****************** Bit definition for USART_CON2 register ************************/ - -#define USART_CON2_CTSIE_POS 10U -#define USART_CON2_CTSIE_MSK BIT(USART_CON2_CTSIE_POS) - -#define USART_CON2_CTSEN_POS 9U -#define USART_CON2_CTSEN_MSK BIT(USART_CON2_CTSEN_POS) - -#define USART_CON2_RTSEN_POS 8U -#define USART_CON2_RTSEN_MSK BIT(USART_CON2_RTSEN_POS) - -#define USART_CON2_TXDMAEN_POS 7U -#define USART_CON2_TXDMAEN_MSK BIT(USART_CON2_TXDMAEN_POS) - -#define USART_CON2_RXDMAEN_POS 6U -#define USART_CON2_RXDMAEN_MSK BIT(USART_CON2_RXDMAEN_POS) - -#define USART_CON2_SMARTEN_POS 5U -#define USART_CON2_SMARTEN_MSK BIT(USART_CON2_SMARTEN_POS) - -#define USART_CON2_NACK_POS 4U -#define USART_CON2_NACK_MSK BIT(USART_CON2_NACK_POS) - -#define USART_CON2_HDPSEL_POS 3U -#define USART_CON2_HDPSEL_MSK BIT(USART_CON2_HDPSEL_POS) - -#define USART_CON2_IREN_POS 1U -#define USART_CON2_IREN_MSK BIT(USART_CON2_IREN_POS) - -#define USART_CON2_ERRIE_POS 0U -#define USART_CON2_ERRIE_MSK BIT(USART_CON2_ERRIE_POS) - -/****************** Bit definition for USART_GP register ************************/ - -#define USART_GP_GTVAL_POSS 8U -#define USART_GP_GTVAL_POSE 15U -#define USART_GP_GTVAL_MSK BITS(USART_GP_GTVAL_POSS,USART_GP_GTVAL_POSE) - -#define USART_GP_PSC_POSS 0U -#define USART_GP_PSC_POSE 7U -#define USART_GP_PSC_MSK BITS(USART_GP_PSC_POSS,USART_GP_PSC_POSE) - -typedef struct -{ - __IO uint32_t STAT; - __IO uint32_t DATA; - __IO uint32_t BAUDCON; - __IO uint32_t CON0; - __IO uint32_t CON1; - __IO uint32_t CON2; - __IO uint32_t GP; -} USART_TypeDef; - -/****************** Bit definition for UART_RBR register ************************/ - -#define UART_RBR_RBR_POSS 0U -#define UART_RBR_RBR_POSE 8U -#define UART_RBR_RBR_MSK BITS(UART_RBR_RBR_POSS,UART_RBR_RBR_POSE) - -/****************** Bit definition for UART_TBR register ************************/ - -#define UART_TBR_TBR_POSS 0U -#define UART_TBR_TBR_POSE 8U -#define UART_TBR_TBR_MSK BITS(UART_TBR_TBR_POSS,UART_TBR_TBR_POSE) - -/****************** Bit definition for UART_BRR register ************************/ - -#define UART_BRR_BRR_POSS 0U -#define UART_BRR_BRR_POSE 15U -#define UART_BRR_BRR_MSK BITS(UART_BRR_BRR_POSS,UART_BRR_BRR_POSE) - -/****************** Bit definition for UART_LCR register ************************/ - -#define UART_LCR_SWAP_POS 13U -#define UART_LCR_SWAP_MSK BIT(UART_LCR_SWAP_POS) - -#define UART_LCR_TXINV_POS 12U -#define UART_LCR_TXINV_MSK BIT(UART_LCR_TXINV_POS) - -#define UART_LCR_RXINV_POS 11U -#define UART_LCR_RXINV_MSK BIT(UART_LCR_RXINV_POS) - -#define UART_LCR_DATAINV_POS 10U -#define UART_LCR_DATAINV_MSK BIT(UART_LCR_DATAINV_POS) - -#define UART_LCR_MSBFIRST_POS 9U -#define UART_LCR_MSBFIRST_MSK BIT(UART_LCR_MSBFIRST_POS) - -#define UART_LCR_RTOEN_POS 8U -#define UART_LCR_RTOEN_MSK BIT(UART_LCR_RTOEN_POS) - -#define UART_LCR_BRWEN_POS 7U -#define UART_LCR_BRWEN_MSK BIT(UART_LCR_BRWEN_POS) - -#define UART_LCR_BC_POS 6U -#define UART_LCR_BC_MSK BIT(UART_LCR_BC_POS) - -#define UART_LCR_RXEN_POS 5U -#define UART_LCR_RXEN_MSK BIT(UART_LCR_RXEN_POS) - -#define UART_LCR_PS_POS 4U -#define UART_LCR_PS_MSK BIT(UART_LCR_PS_POS) - -#define UART_LCR_PEN_POS 3U -#define UART_LCR_PEN_MSK BIT(UART_LCR_PEN_POS) - -#define UART_LCR_STOP_POS 2U -#define UART_LCR_STOP_MSK BIT(UART_LCR_STOP_POS) - -#define UART_LCR_DLS_POSS 0U -#define UART_LCR_DLS_POSE 1U -#define UART_LCR_DLS_MSK BITS(UART_LCR_DLS_POSS,UART_LCR_DLS_POSE) - -/****************** Bit definition for UART_MCR register ************************/ - -#define UART_MCR_HDSEL_POS 22U -#define UART_MCR_HDSEL_MSK BIT(UART_MCR_HDSEL_POS) - -#define UART_MCR_ABRRS_POS 15U -#define UART_MCR_ABRRS_MSK BIT(UART_MCR_ABRRS_POS) - -#define UART_MCR_ABRMOD_POSS 13U -#define UART_MCR_ABRMOD_POSE 14U -#define UART_MCR_ABRMOD_MSK BITS(UART_MCR_ABRMOD_POSS,UART_MCR_ABRMOD_POSE) - -#define UART_MCR_ABREN_POS 12U -#define UART_MCR_ABREN_MSK BIT(UART_MCR_ABREN_POS) - -#define UART_MCR_DMAEN_POS 11U -#define UART_MCR_DMAEN_MSK BIT(UART_MCR_DMAEN_POS) - -#define UART_MCR_LINBDL_POS 10U -#define UART_MCR_LINBDL_MSK BIT(UART_MCR_LINBDL_POS) - -#define UART_MCR_BKREQ_POS 9U -#define UART_MCR_BKREQ_MSK BIT(UART_MCR_BKREQ_POS) - -#define UART_MCR_LINEN_POS 8U -#define UART_MCR_LINEN_MSK BIT(UART_MCR_LINEN_POS) - -#define UART_MCR_AADINV_POS 7U -#define UART_MCR_AADINV_MSK BIT(UART_MCR_AADINV_POS) - -#define UART_MCR_AADDIR_POS 6U -#define UART_MCR_AADDIR_MSK BIT(UART_MCR_AADDIR_POS) - -#define UART_MCR_AADNOR_POS 5U -#define UART_MCR_AADNOR_MSK BIT(UART_MCR_AADNOR_POS) - -#define UART_MCR_AADEN_POS 4U -#define UART_MCR_AADEN_MSK BIT(UART_MCR_AADEN_POS) - -#define UART_MCR_RTSCTRL_POS 3U -#define UART_MCR_RTSCTRL_MSK BIT(UART_MCR_RTSCTRL_POS) - -#define UART_MCR_AFCEN_POS 2U -#define UART_MCR_AFCEN_MSK BIT(UART_MCR_AFCEN_POS) - -#define UART_MCR_LBEN_POS 1U -#define UART_MCR_LBEN_MSK BIT(UART_MCR_LBEN_POS) - -#define UART_MCR_IREN_POS 0U -#define UART_MCR_IREN_MSK BIT(UART_MCR_IREN_POS) - -/****************** Bit definition for UART_CR register ************************/ - -#define UART_CR_PSC_POSS 16U -#define UART_CR_PSC_POSE 23U -#define UART_CR_PSC_MSK BITS(UART_CR_PSC_POSS,UART_CR_PSC_POSE) - -#define UART_CR_DLY_POSS 8U -#define UART_CR_DLY_POSE 15U -#define UART_CR_DLY_MSK BITS(UART_CR_DLY_POSS,UART_CR_DLY_POSE) - -#define UART_CR_ADDR_POSS 0U -#define UART_CR_ADDR_POSE 7U -#define UART_CR_ADDR_MSK BITS(UART_CR_ADDR_POSS,UART_CR_ADDR_POSE) - -/****************** Bit definition for UART_RTOR register ************************/ - -#define UART_RTOR_BLEN_POSS 24U -#define UART_RTOR_BLEN_POSE 31U -#define UART_RTOR_BLEN_MSK BITS(UART_RTOR_BLEN_POSS,UART_RTOR_BLEN_POSE) - -#define UART_RTOR_RTO_POSS 0U -#define UART_RTOR_RTO_POSE 23U -#define UART_RTOR_RTO_MSK BITS(UART_RTOR_RTO_POSS,UART_RTOR_RTO_POSE) - -/****************** Bit definition for UART_FCR register ************************/ - -#define UART_FCR_TXFL_POSS 12U -#define UART_FCR_TXFL_POSE 15U -#define UART_FCR_TXFL_MSK BITS(UART_FCR_TXFL_POSS,UART_FCR_TXFL_POSE) - -#define UART_FCR_RXFL_POSS 8U -#define UART_FCR_RXFL_POSE 11U -#define UART_FCR_RXFL_MSK BITS(UART_FCR_RXFL_POSS,UART_FCR_RXFL_POSE) - -#define UART_FCR_TXTL_POSS 6U -#define UART_FCR_TXTL_POSE 7U -#define UART_FCR_TXTL_MSK BITS(UART_FCR_TXTL_POSS,UART_FCR_TXTL_POSE) - -#define UART_FCR_RXTL_POSS 4U -#define UART_FCR_RXTL_POSE 5U -#define UART_FCR_RXTL_MSK BITS(UART_FCR_RXTL_POSS,UART_FCR_RXTL_POSE) - -#define UART_FCR_TFRST_POS 2U -#define UART_FCR_TFRST_MSK BIT(UART_FCR_TFRST_POS) - -#define UART_FCR_RFRST_POS 1U -#define UART_FCR_RFRST_MSK BIT(UART_FCR_RFRST_POS) - -#define UART_FCR_FIFOEN_POS 0U -#define UART_FCR_FIFOEN_MSK BIT(UART_FCR_FIFOEN_POS) - -/****************** Bit definition for UART_SR register ************************/ - -#define UART_SR_CTS_POS 14U -#define UART_SR_CTS_MSK BIT(UART_SR_CTS_POS) - -#define UART_SR_DCTS_POS 13U -#define UART_SR_DCTS_MSK BIT(UART_SR_DCTS_POS) - -#define UART_SR_RFF_POS 12U -#define UART_SR_RFF_MSK BIT(UART_SR_RFF_POS) - -#define UART_SR_RFNE_POS 11U -#define UART_SR_RFNE_MSK BIT(UART_SR_RFNE_POS) - -#define UART_SR_TFEM_POS 10U -#define UART_SR_TFEM_MSK BIT(UART_SR_TFEM_POS) - -#define UART_SR_TFNF_POS 9U -#define UART_SR_TFNF_MSK BIT(UART_SR_TFNF_POS) - -#define UART_SR_BUSY_POS 8U -#define UART_SR_BUSY_MSK BIT(UART_SR_BUSY_POS) - -#define UART_SR_RFE_POS 7U -#define UART_SR_RFE_MSK BIT(UART_SR_RFE_POS) - -#define UART_SR_TEM_POS 6U -#define UART_SR_TEM_MSK BIT(UART_SR_TEM_POS) - -#define UART_SR_TBEM_POS 5U -#define UART_SR_TBEM_MSK BIT(UART_SR_TBEM_POS) - -#define UART_SR_BF_POS 4U -#define UART_SR_BF_MSK BIT(UART_SR_BF_POS) - -#define UART_SR_FE_POS 3U -#define UART_SR_FE_MSK BIT(UART_SR_FE_POS) - -#define UART_SR_PE_POS 2U -#define UART_SR_PE_MSK BIT(UART_SR_PE_POS) - -#define UART_SR_OE_POS 1U -#define UART_SR_OE_MSK BIT(UART_SR_OE_POS) - -#define UART_SR_DR_POS 0U -#define UART_SR_DR_MSK BIT(UART_SR_DR_POS) - -/****************** Bit definition for UART_IER register ************************/ - -#define UART_IER_CMIE_POS 11U -#define UART_IER_CMIE_MSK BIT(UART_IER_CMIE_POS) - -#define UART_IER_EOBIE_POS 10U -#define UART_IER_EOBIE_MSK BIT(UART_IER_EOBIE_POS) - -#define UART_IER_TCIE_POS 9U -#define UART_IER_TCIE_MSK BIT(UART_IER_TCIE_POS) - -#define UART_IER_LINBKIE_POS 8U -#define UART_IER_LINBKIE_MSK BIT(UART_IER_LINBKIE_POS) - -#define UART_IER_ABTOIE_POS 7U -#define UART_IER_ABTOIE_MSK BIT(UART_IER_ABTOIE_POS) - -#define UART_IER_ABEIE_POS 6U -#define UART_IER_ABEIE_MSK BIT(UART_IER_ABEIE_POS) - -#define UART_IER_BZIE_POS 5U -#define UART_IER_BZIE_MSK BIT(UART_IER_BZIE_POS) - -#define UART_IER_RTOIE_POS 4U -#define UART_IER_RTOIE_MSK BIT(UART_IER_RTOIE_POS) - -#define UART_IER_MDSIE_POS 3U -#define UART_IER_MDSIE_MSK BIT(UART_IER_MDSIE_POS) - -#define UART_IER_RXSIE_POS 2U -#define UART_IER_RXSIE_MSK BIT(UART_IER_RXSIE_POS) - -#define UART_IER_TXSIE_POS 1U -#define UART_IER_TXSIE_MSK BIT(UART_IER_TXSIE_POS) - -#define UART_IER_RXRDIE_POS 0U -#define UART_IER_RXRDIE_MSK BIT(UART_IER_RXRDIE_POS) - -/****************** Bit definition for UART_IDR register ************************/ - -#define UART_IDR_CMID_POS 11U -#define UART_IDR_CMID_MSK BIT(UART_IDR_CMID_POS) - -#define UART_IDR_EOBID_POS 10U -#define UART_IDR_EOBID_MSK BIT(UART_IDR_EOBID_POS) - -#define UART_IDR_TCID_POS 9U -#define UART_IDR_TCID_MSK BIT(UART_IDR_TCID_POS) - -#define UART_IDR_LINBKID_POS 8U -#define UART_IDR_LINBKID_MSK BIT(UART_IDR_LINBKID_POS) - -#define UART_IDR_ABTOID_POS 7U -#define UART_IDR_ABTOID_MSK BIT(UART_IDR_ABTOID_POS) - -#define UART_IDR_ABEID_POS 6U -#define UART_IDR_ABEID_MSK BIT(UART_IDR_ABEID_POS) - -#define UART_IDR_BZID_POS 5U -#define UART_IDR_BZID_MSK BIT(UART_IDR_BZID_POS) - -#define UART_IDR_RTOID_POS 4U -#define UART_IDR_RTOID_MSK BIT(UART_IDR_RTOID_POS) - -#define UART_IDR_MDSID_POS 3U -#define UART_IDR_MDSID_MSK BIT(UART_IDR_MDSID_POS) - -#define UART_IDR_RXSID_POS 2U -#define UART_IDR_RXSID_MSK BIT(UART_IDR_RXSID_POS) - -#define UART_IDR_TXSID_POS 1U -#define UART_IDR_TXSID_MSK BIT(UART_IDR_TXSID_POS) - -#define UART_IDR_RXRDID_POS 0U -#define UART_IDR_RXRDID_MSK BIT(UART_IDR_RXRDID_POS) - -/****************** Bit definition for UART_IVS register ************************/ - -#define UART_IVS_CMIS_POS 11U -#define UART_IVS_CMIS_MSK BIT(UART_IVS_CMIS_POS) - -#define UART_IVS_EOBIS_POS 10U -#define UART_IVS_EOBIS_MSK BIT(UART_IVS_EOBIS_POS) - -#define UART_IVS_TCIS_POS 9U -#define UART_IVS_TCIS_MSK BIT(UART_IVS_TCIS_POS) - -#define UART_IVS_LINBKIS_POS 8U -#define UART_IVS_LINBKIS_MSK BIT(UART_IVS_LINBKIS_POS) - -#define UART_IVS_ABTOIS_POS 7U -#define UART_IVS_ABTOIS_MSK BIT(UART_IVS_ABTOIS_POS) - -#define UART_IVS_ABEIS_POS 6U -#define UART_IVS_ABEIS_MSK BIT(UART_IVS_ABEIS_POS) - -#define UART_IVS_BZIS_POS 5U -#define UART_IVS_BZIS_MSK BIT(UART_IVS_BZIS_POS) - -#define UART_IVS_RTOIS_POS 4U -#define UART_IVS_RTOIS_MSK BIT(UART_IVS_RTOIS_POS) - -#define UART_IVS_MDSIS_POS 3U -#define UART_IVS_MDSIS_MSK BIT(UART_IVS_MDSIS_POS) - -#define UART_IVS_RXSIS_POS 2U -#define UART_IVS_RXSIS_MSK BIT(UART_IVS_RXSIS_POS) - -#define UART_IVS_TXSIS_POS 1U -#define UART_IVS_TXSIS_MSK BIT(UART_IVS_TXSIS_POS) - -#define UART_IVS_RXRDIS_POS 0U -#define UART_IVS_RXRDIS_MSK BIT(UART_IVS_RXRDIS_POS) - -/****************** Bit definition for UART_RIF register ************************/ - -#define UART_RIF_CMIF_POS 11U -#define UART_RIF_CMIF_MSK BIT(UART_RIF_CMIF_POS) - -#define UART_RIF_EOBIF_POS 10U -#define UART_RIF_EOBIF_MSK BIT(UART_RIF_EOBIF_POS) - -#define UART_RIF_TCIF_POS 9U -#define UART_RIF_TCIF_MSK BIT(UART_RIF_TCIF_POS) - -#define UART_RIF_LINBKIF_POS 8U -#define UART_RIF_LINBKIF_MSK BIT(UART_RIF_LINBKIF_POS) - -#define UART_RIF_ABTOIF_POS 7U -#define UART_RIF_ABTOIF_MSK BIT(UART_RIF_ABTOIF_POS) - -#define UART_RIF_ABEIF_POS 6U -#define UART_RIF_ABEIF_MSK BIT(UART_RIF_ABEIF_POS) - -#define UART_RIF_BZIF_POS 5U -#define UART_RIF_BZIF_MSK BIT(UART_RIF_BZIF_POS) - -#define UART_RIF_RTOIF_POS 4U -#define UART_RIF_RTOIF_MSK BIT(UART_RIF_RTOIF_POS) - -#define UART_RIF_MDSIF_POS 3U -#define UART_RIF_MDSIF_MSK BIT(UART_RIF_MDSIF_POS) - -#define UART_RIF_RXSIF_POS 2U -#define UART_RIF_RXSIF_MSK BIT(UART_RIF_RXSIF_POS) - -#define UART_RIF_TXSIF_POS 1U -#define UART_RIF_TXSIF_MSK BIT(UART_RIF_TXSIF_POS) - -#define UART_RIF_RXRDIF_POS 0U -#define UART_RIF_RXRDIF_MSK BIT(UART_RIF_RXRDIF_POS) - -/****************** Bit definition for UART_IFM register ************************/ - -#define UART_IFM_CMIM_POS 11U -#define UART_IFM_CMIM_MSK BIT(UART_IFM_CMIM_POS) - -#define UART_IFM_EOBIM_POS 10U -#define UART_IFM_EOBIM_MSK BIT(UART_IFM_EOBIM_POS) - -#define UART_IFM_TCIM_POS 9U -#define UART_IFM_TCIM_MSK BIT(UART_IFM_TCIM_POS) - -#define UART_IFM_LINBKIM_POS 8U -#define UART_IFM_LINBKIM_MSK BIT(UART_IFM_LINBKIM_POS) - -#define UART_IFM_ABTOIM_POS 7U -#define UART_IFM_ABTOIM_MSK BIT(UART_IFM_ABTOIM_POS) - -#define UART_IFM_ABEIM_POS 6U -#define UART_IFM_ABEIM_MSK BIT(UART_IFM_ABEIM_POS) - -#define UART_IFM_BZIM_POS 5U -#define UART_IFM_BZIM_MSK BIT(UART_IFM_BZIM_POS) - -#define UART_IFM_RTOIM_POS 4U -#define UART_IFM_RTOIM_MSK BIT(UART_IFM_RTOIM_POS) - -#define UART_IFM_MDSIM_POS 3U -#define UART_IFM_MDSIM_MSK BIT(UART_IFM_MDSIM_POS) - -#define UART_IFM_RXSIM_POS 2U -#define UART_IFM_RXSIM_MSK BIT(UART_IFM_RXSIM_POS) - -#define UART_IFM_TXSIM_POS 1U -#define UART_IFM_TXSIM_MSK BIT(UART_IFM_TXSIM_POS) - -#define UART_IFM_RXRDIM_POS 0U -#define UART_IFM_RXRDIM_MSK BIT(UART_IFM_RXRDIM_POS) - -/****************** Bit definition for UART_ICR register ************************/ - -#define UART_ICR_CMIC_POS 11U -#define UART_ICR_CMIC_MSK BIT(UART_ICR_CMIC_POS) - -#define UART_ICR_EOBIC_POS 10U -#define UART_ICR_EOBIC_MSK BIT(UART_ICR_EOBIC_POS) - -#define UART_ICR_TCIC_POS 9U -#define UART_ICR_TCIC_MSK BIT(UART_ICR_TCIC_POS) - -#define UART_ICR_LINBKIC_POS 8U -#define UART_ICR_LINBKIC_MSK BIT(UART_ICR_LINBKIC_POS) - -#define UART_ICR_ABTOIC_POS 7U -#define UART_ICR_ABTOIC_MSK BIT(UART_ICR_ABTOIC_POS) - -#define UART_ICR_ABEIC_POS 6U -#define UART_ICR_ABEIC_MSK BIT(UART_ICR_ABEIC_POS) - -#define UART_ICR_BZIC_POS 5U -#define UART_ICR_BZIC_MSK BIT(UART_ICR_BZIC_POS) - -#define UART_ICR_CHTOIC_POS 4U -#define UART_ICR_CHTOIC_MSK BIT(UART_ICR_CHTOIC_POS) - -#define UART_ICR_MDSIC_POS 3U -#define UART_ICR_MDSIC_MSK BIT(UART_ICR_MDSIC_POS) - -#define UART_ICR_RXSIC_POS 2U -#define UART_ICR_RXSIC_MSK BIT(UART_ICR_RXSIC_POS) - -#define UART_ICR_TXSIC_POS 1U -#define UART_ICR_TXSIC_MSK BIT(UART_ICR_TXSIC_POS) - -#define UART_ICR_RXRDIC_POS 0U -#define UART_ICR_RXRDIC_MSK BIT(UART_ICR_RXRDIC_POS) - -typedef struct -{ - __I uint32_t RBR; - __IO uint32_t TBR; - __IO uint32_t BRR; - __IO uint32_t LCR; - __IO uint32_t MCR; - __IO uint32_t CR; - __IO uint32_t RTOR; - __IO uint32_t FCR; - __I uint32_t SR; - __O uint32_t IER; - __O uint32_t IDR; - __I uint32_t IVS; - __I uint32_t RIF; - __I uint32_t IFM; - __O uint32_t ICR; -} UART_TypeDef; - -/****************** Bit definition for LPUART_CON0 register ************************/ - -#define LPUART_CON0_MODESEL_POSS 30U -#define LPUART_CON0_MODESEL_POSE 31U -#define LPUART_CON0_MODESEL_MSK BITS(LPUART_CON0_MODESEL_POSS,LPUART_CON0_MODESEL_POSE) - -#define LPUART_CON0_TXDMAE_POS 29U -#define LPUART_CON0_TXDMAE_MSK BIT(LPUART_CON0_TXDMAE_POS) - -#define LPUART_CON0_RXDMAE_POS 28U -#define LPUART_CON0_RXDMAE_MSK BIT(LPUART_CON0_RXDMAE_POS) - -#define LPUART_CON0_INTERVAL_POSS 16U -#define LPUART_CON0_INTERVAL_POSE 23U -#define LPUART_CON0_INTERVAL_MSK BITS(LPUART_CON0_INTERVAL_POSS,LPUART_CON0_INTERVAL_POSE) - -#define LPUART_CON0_SYNCBP_POS 15U -#define LPUART_CON0_SYNCBP_MSK BIT(LPUART_CON0_SYNCBP_POS) - -#define LPUART_CON0_CTSPOL_POS 13U -#define LPUART_CON0_CTSPOL_MSK BIT(LPUART_CON0_CTSPOL_POS) - -#define LPUART_CON0_RTSPOL_POS 12U -#define LPUART_CON0_RTSPOL_MSK BIT(LPUART_CON0_RTSPOL_POS) - -#define LPUART_CON0_ATCTSE_POS 11U -#define LPUART_CON0_ATCTSE_MSK BIT(LPUART_CON0_ATCTSE_POS) - -#define LPUART_CON0_ATRTSE_POS 10U -#define LPUART_CON0_ATRTSE_MSK BIT(LPUART_CON0_ATRTSE_POS) - -#define LPUART_CON0_BRKCE_POS 8U -#define LPUART_CON0_BRKCE_MSK BIT(LPUART_CON0_BRKCE_POS) - -#define LPUART_CON0_LPBMOD_POS 7U -#define LPUART_CON0_LPBMOD_MSK BIT(LPUART_CON0_LPBMOD_POS) - -#define LPUART_CON0_STICKPARSEL_POS 6U -#define LPUART_CON0_STICKPARSEL_MSK BIT(LPUART_CON0_STICKPARSEL_POS) - -#define LPUART_CON0_EVENPARSEL_POS 5U -#define LPUART_CON0_EVENPARSEL_MSK BIT(LPUART_CON0_EVENPARSEL_POS) - -#define LPUART_CON0_PARCHKE_POS 4U -#define LPUART_CON0_PARCHKE_MSK BIT(LPUART_CON0_PARCHKE_POS) - -#define LPUART_CON0_STPLENTH_POS 3U -#define LPUART_CON0_STPLENTH_MSK BIT(LPUART_CON0_STPLENTH_POS) - -#define LPUART_CON0_DATLENTH_POSS 0U -#define LPUART_CON0_DATLENTH_POSE 2U -#define LPUART_CON0_DATLENTH_MSK BITS(LPUART_CON0_DATLENTH_POSS,LPUART_CON0_DATLENTH_POSE) - -/****************** Bit definition for LPUART_CON1 register ************************/ - -#define LPUART_CON1_ADDCMP_POSS 24U -#define LPUART_CON1_ADDCMP_POSE 31U -#define LPUART_CON1_ADDCMP_MSK BITS(LPUART_CON1_ADDCMP_POSS,LPUART_CON1_ADDCMP_POSE) - -#define LPUART_CON1_ADETE_POS 23U -#define LPUART_CON1_ADETE_MSK BIT(LPUART_CON1_ADETE_POS) - -#define LPUART_CON1_ATDIRM_POS 22U -#define LPUART_CON1_ATDIRM_MSK BIT(LPUART_CON1_ATDIRM_POS) - -#define LPUART_CON1_ATADETE_POS 21U -#define LPUART_CON1_ATADETE_MSK BIT(LPUART_CON1_ATADETE_POS) - -#define LPUART_CON1_NMPMOD_POS 20U -#define LPUART_CON1_NMPMOD_MSK BIT(LPUART_CON1_NMPMOD_POS) - -#define LPUART_CON1_IRWIDTH_POS 16U -#define LPUART_CON1_IRWIDTH_MSK BIT(LPUART_CON1_IRWIDTH_POS) - -#define LPUART_CON1_TOICMP_POSS 8U -#define LPUART_CON1_TOICMP_POSE 15U -#define LPUART_CON1_TOICMP_MSK BITS(LPUART_CON1_TOICMP_POSS,LPUART_CON1_TOICMP_POSE) - -#define LPUART_CON1_TOCNTE_POS 7U -#define LPUART_CON1_TOCNTE_MSK BIT(LPUART_CON1_TOCNTE_POS) - -#define LPUART_CON1_IRTXINV_POS 3U -#define LPUART_CON1_IRTXINV_MSK BIT(LPUART_CON1_IRTXINV_POS) - -#define LPUART_CON1_IRRXINV_POS 2U -#define LPUART_CON1_IRRXINV_MSK BIT(LPUART_CON1_IRRXINV_POS) - -#define LPUART_CON1_IRTXE_POS 1U -#define LPUART_CON1_IRTXE_MSK BIT(LPUART_CON1_IRTXE_POS) - -#define LPUART_CON1_RTS_POS 0U -#define LPUART_CON1_RTS_MSK BIT(LPUART_CON1_RTS_POS) - -/****************** Bit definition for LPUART_CLKDIV register ************************/ - -#define LPUART_CLKDIV_CLKDIV_POSS 0U -#define LPUART_CLKDIV_CLKDIV_POSE 19U -#define LPUART_CLKDIV_CLKDIV_MSK BITS(LPUART_CLKDIV_CLKDIV_POSS,LPUART_CLKDIV_CLKDIV_POSE) - -/****************** Bit definition for LPUART_FIFOCON register ************************/ - -#define LPUART_FIFOCON_RTSTRGLVL_POSS 12U -#define LPUART_FIFOCON_RTSTRGLVL_POSE 15U -#define LPUART_FIFOCON_RTSTRGLVL_MSK BITS(LPUART_FIFOCON_RTSTRGLVL_POSS,LPUART_FIFOCON_RTSTRGLVL_POSE) - -#define LPUART_FIFOCON_RXTRGLVL_POSS 8U -#define LPUART_FIFOCON_RXTRGLVL_POSE 11U -#define LPUART_FIFOCON_RXTRGLVL_MSK BITS(LPUART_FIFOCON_RXTRGLVL_POSS,LPUART_FIFOCON_RXTRGLVL_POSE) - -#define LPUART_FIFOCON_NMPMRXDIS_POS 2U -#define LPUART_FIFOCON_NMPMRXDIS_MSK BIT(LPUART_FIFOCON_NMPMRXDIS_POS) - -#define LPUART_FIFOCON_TXRESET_POS 1U -#define LPUART_FIFOCON_TXRESET_MSK BIT(LPUART_FIFOCON_TXRESET_POS) - -#define LPUART_FIFOCON_RXRESET_POS 0U -#define LPUART_FIFOCON_RXRESET_MSK BIT(LPUART_FIFOCON_RXRESET_POS) - -/****************** Bit definition for LPUART_RXDR register ************************/ - -#define LPUART_RXDR_FERR_POS 15U -#define LPUART_RXDR_FERR_MSK BIT(LPUART_RXDR_FERR_POS) - -#define LPUART_RXDR_PERR_POS 14U -#define LPUART_RXDR_PERR_MSK BIT(LPUART_RXDR_PERR_POS) - -#define LPUART_RXDR_RXDR_POSS 0U -#define LPUART_RXDR_RXDR_POSE 8U -#define LPUART_RXDR_RXDR_MSK BITS(LPUART_RXDR_RXDR_POSS,LPUART_RXDR_RXDR_POSE) - -/****************** Bit definition for LPUART_TXDR register ************************/ - -#define LPUART_TXDR_TXDR_POSS 0U -#define LPUART_TXDR_TXDR_POSE 8U -#define LPUART_TXDR_TXDR_MSK BITS(LPUART_TXDR_TXDR_POSS,LPUART_TXDR_TXDR_POSE) - -/****************** Bit definition for LPUART_STAT register ************************/ - -#define LPUART_STAT_RTSSTAT_POS 18U -#define LPUART_STAT_RTSSTAT_MSK BIT(LPUART_STAT_RTSSTAT_POS) - -#define LPUART_STAT_CTSSTAT_POS 17U -#define LPUART_STAT_CTSSTAT_MSK BIT(LPUART_STAT_CTSSTAT_POS) - -#define LPUART_STAT_TXIDLE_POS 16U -#define LPUART_STAT_TXIDLE_MSK BIT(LPUART_STAT_TXIDLE_POS) - -#define LPUART_STAT_TXFULL_POS 15U -#define LPUART_STAT_TXFULL_MSK BIT(LPUART_STAT_TXFULL_POS) - -#define LPUART_STAT_TXEMP_POS 14U -#define LPUART_STAT_TXEMP_MSK BIT(LPUART_STAT_TXEMP_POS) - -#define LPUART_STAT_TXPTR_POSS 8U -#define LPUART_STAT_TXPTR_POSE 13U -#define LPUART_STAT_TXPTR_MSK BITS(LPUART_STAT_TXPTR_POSS,LPUART_STAT_TXPTR_POSE) - -#define LPUART_STAT_RXFULL_POS 7U -#define LPUART_STAT_RXFULL_MSK BIT(LPUART_STAT_RXFULL_POS) - -#define LPUART_STAT_RXEMP_POS 6U -#define LPUART_STAT_RXEMP_MSK BIT(LPUART_STAT_RXEMP_POS) - -#define LPUART_STAT_RXPTR_POSS 0U -#define LPUART_STAT_RXPTR_POSE 5U -#define LPUART_STAT_RXPTR_MSK BITS(LPUART_STAT_RXPTR_POSS,LPUART_STAT_RXPTR_POSE) - -/****************** Bit definition for LPUART_IER register ************************/ - -#define LPUART_IER_TCIE_POS 15U -#define LPUART_IER_TCIE_MSK BIT(LPUART_IER_TCIE_POS) - -#define LPUART_IER_ADETIE_POS 12U -#define LPUART_IER_ADETIE_MSK BIT(LPUART_IER_ADETIE_POS) - -#define LPUART_IER_BRKERRIE_POS 11U -#define LPUART_IER_BRKERRIE_MSK BIT(LPUART_IER_BRKERRIE_POS) - -#define LPUART_IER_FERRIE_POS 10U -#define LPUART_IER_FERRIE_MSK BIT(LPUART_IER_FERRIE_POS) - -#define LPUART_IER_PERRIE_POS 9U -#define LPUART_IER_PERRIE_MSK BIT(LPUART_IER_PERRIE_POS) - -#define LPUART_IER_DATWKIE_POS 8U -#define LPUART_IER_DATWKIE_MSK BIT(LPUART_IER_DATWKIE_POS) - -#define LPUART_IER_CTSWKIE_POS 7U -#define LPUART_IER_CTSWKIE_MSK BIT(LPUART_IER_CTSWKIE_POS) - -#define LPUART_IER_TXOVIE_POS 5U -#define LPUART_IER_TXOVIE_MSK BIT(LPUART_IER_TXOVIE_POS) - -#define LPUART_IER_RXOVIE_POS 4U -#define LPUART_IER_RXOVIE_MSK BIT(LPUART_IER_RXOVIE_POS) - -#define LPUART_IER_RXTOIE_POS 3U -#define LPUART_IER_RXTOIE_MSK BIT(LPUART_IER_RXTOIE_POS) - -#define LPUART_IER_CTSDETIE_POS 2U -#define LPUART_IER_CTSDETIE_MSK BIT(LPUART_IER_CTSDETIE_POS) - -#define LPUART_IER_TBEMPIE_POS 1U -#define LPUART_IER_TBEMPIE_MSK BIT(LPUART_IER_TBEMPIE_POS) - -#define LPUART_IER_RBRIE_POS 0U -#define LPUART_IER_RBRIE_MSK BIT(LPUART_IER_RBRIE_POS) - -/****************** Bit definition for LPUART_IFLAG register ************************/ - -#define LPUART_IFLAG_TCIF_POS 15U -#define LPUART_IFLAG_TCIF_MSK BIT(LPUART_IFLAG_TCIF_POS) - -#define LPUART_IFLAG_ADETIF_POS 12U -#define LPUART_IFLAG_ADETIF_MSK BIT(LPUART_IFLAG_ADETIF_POS) - -#define LPUART_IFLAG_BRKERRIF_POS 11U -#define LPUART_IFLAG_BRKERRIF_MSK BIT(LPUART_IFLAG_BRKERRIF_POS) - -#define LPUART_IFLAG_FERRIF_POS 10U -#define LPUART_IFLAG_FERRIF_MSK BIT(LPUART_IFLAG_FERRIF_POS) - -#define LPUART_IFLAG_PERRIF_POS 9U -#define LPUART_IFLAG_PERRIF_MSK BIT(LPUART_IFLAG_PERRIF_POS) - -#define LPUART_IFLAG_DATWKIF_POS 8U -#define LPUART_IFLAG_DATWKIF_MSK BIT(LPUART_IFLAG_DATWKIF_POS) - -#define LPUART_IFLAG_CTSWKIF_POS 7U -#define LPUART_IFLAG_CTSWKIF_MSK BIT(LPUART_IFLAG_CTSWKIF_POS) - -#define LPUART_IFLAG_TXOVIF_POS 5U -#define LPUART_IFLAG_TXOVIF_MSK BIT(LPUART_IFLAG_TXOVIF_POS) - -#define LPUART_IFLAG_RXOVIF_POS 4U -#define LPUART_IFLAG_RXOVIF_MSK BIT(LPUART_IFLAG_RXOVIF_POS) - -#define LPUART_IFLAG_RXTOIF_POS 3U -#define LPUART_IFLAG_RXTOIF_MSK BIT(LPUART_IFLAG_RXTOIF_POS) - -#define LPUART_IFLAG_CTSDETIF_POS 2U -#define LPUART_IFLAG_CTSDETIF_MSK BIT(LPUART_IFLAG_CTSDETIF_POS) - -#define LPUART_IFLAG_TBEMPIF_POS 1U -#define LPUART_IFLAG_TBEMPIF_MSK BIT(LPUART_IFLAG_TBEMPIF_POS) - -#define LPUART_IFLAG_RBRIF_POS 0U -#define LPUART_IFLAG_RBRIF_MSK BIT(LPUART_IFLAG_RBRIF_POS) - -/****************** Bit definition for LPUART_IFC register ************************/ - -#define LPUART_IFC_TCIFC_POS 15U -#define LPUART_IFC_TCIFC_MSK BIT(LPUART_IFC_TCIFC_POS) - -#define LPUART_IFC_ADETIFC_POS 12U -#define LPUART_IFC_ADETIFC_MSK BIT(LPUART_IFC_ADETIFC_POS) - -#define LPUART_IFC_BRKERRIFC_POS 11U -#define LPUART_IFC_BRKERRIFC_MSK BIT(LPUART_IFC_BRKERRIFC_POS) - -#define LPUART_IFC_FERRIFC_POS 10U -#define LPUART_IFC_FERRIFC_MSK BIT(LPUART_IFC_FERRIFC_POS) - -#define LPUART_IFC_PERRIFC_POS 9U -#define LPUART_IFC_PERRIFC_MSK BIT(LPUART_IFC_PERRIFC_POS) - -#define LPUART_IFC_DATWKIFC_POS 8U -#define LPUART_IFC_DATWKIFC_MSK BIT(LPUART_IFC_DATWKIFC_POS) - -#define LPUART_IFC_CTSWKIFC_POS 7U -#define LPUART_IFC_CTSWKIFC_MSK BIT(LPUART_IFC_CTSWKIFC_POS) - -#define LPUART_IFC_TXOVIFC_POS 5U -#define LPUART_IFC_TXOVIFC_MSK BIT(LPUART_IFC_TXOVIFC_POS) - -#define LPUART_IFC_RXOVIFC_POS 4U -#define LPUART_IFC_RXOVIFC_MSK BIT(LPUART_IFC_RXOVIFC_POS) - -#define LPUART_IFC_CTSDETIFC_POS 2U -#define LPUART_IFC_CTSDETIFC_MSK BIT(LPUART_IFC_CTSDETIFC_POS) - -#define LPUART_IFC_TBEMPIFC_POS 1U -#define LPUART_IFC_TBEMPIFC_MSK BIT(LPUART_IFC_TBEMPIFC_POS) - -#define LPUART_IFC_RBRIFC_POS 0U -#define LPUART_IFC_RBRIFC_MSK BIT(LPUART_IFC_RBRIFC_POS) - -/****************** Bit definition for LPUART_ISTAT register ************************/ - -#define LPUART_ISTAT_TCINT_POS 15U -#define LPUART_ISTAT_TCINT_MSK BIT(LPUART_ISTAT_TCINT_POS) - -#define LPUART_ISTAT_RXSTATINT_POS 9U -#define LPUART_ISTAT_RXSTATINT_MSK BIT(LPUART_ISTAT_RXSTATINT_POS) - -#define LPUART_ISTAT_DATWKINT_POS 8U -#define LPUART_ISTAT_DATWKINT_MSK BIT(LPUART_ISTAT_DATWKINT_POS) - -#define LPUART_ISTAT_CTSWKINT_POS 7U -#define LPUART_ISTAT_CTSWKINT_MSK BIT(LPUART_ISTAT_CTSWKINT_POS) - -#define LPUART_ISTAT_BUFERRINT_POS 4U -#define LPUART_ISTAT_BUFERRINT_MSK BIT(LPUART_ISTAT_BUFERRINT_POS) - -#define LPUART_ISTAT_RXTOINT_POS 3U -#define LPUART_ISTAT_RXTOINT_MSK BIT(LPUART_ISTAT_RXTOINT_POS) - -#define LPUART_ISTAT_CTSDETINT_POS 2U -#define LPUART_ISTAT_CTSDETINT_MSK BIT(LPUART_ISTAT_CTSDETINT_POS) - -#define LPUART_ISTAT_TBEMPINT_POS 1U -#define LPUART_ISTAT_TBEMPINT_MSK BIT(LPUART_ISTAT_TBEMPINT_POS) - -#define LPUART_ISTAT_RBRINT_POS 0U -#define LPUART_ISTAT_RBRINT_MSK BIT(LPUART_ISTAT_RBRINT_POS) - -/****************** Bit definition for LPUART_UPDATE register ************************/ - -#define LPUART_UPDATE_UDIS_POS 0U -#define LPUART_UPDATE_UDIS_MSK BIT(LPUART_UPDATE_UDIS_POS) - -/****************** Bit definition for LPUART_SYNCSTAT register ************************/ - -#define LPUART_SYNCSTAT_FIFOCONWBSY_POS 3U -#define LPUART_SYNCSTAT_FIFOCONWBSY_MSK BIT(LPUART_SYNCSTAT_FIFOCONWBSY_POS) - -#define LPUART_SYNCSTAT_CLKDIVWBSY_POS 2U -#define LPUART_SYNCSTAT_CLKDIVWBSY_MSK BIT(LPUART_SYNCSTAT_CLKDIVWBSY_POS) - -#define LPUART_SYNCSTAT_CON1WBSY_POS 1U -#define LPUART_SYNCSTAT_CON1WBSY_MSK BIT(LPUART_SYNCSTAT_CON1WBSY_POS) - -#define LPUART_SYNCSTAT_CON0WBSY_POS 0U -#define LPUART_SYNCSTAT_CON0WBSY_MSK BIT(LPUART_SYNCSTAT_CON0WBSY_POS) - -typedef struct -{ - __IO uint32_t CON0; - __IO uint32_t CON1; - __IO uint32_t CLKDIV; - __IO uint32_t FIFOCON; - uint32_t RESERVED0 ; - __I uint32_t RXDR; - __O uint32_t TXDR; - __I uint32_t STAT; - __IO uint32_t IER; - __I uint32_t IFLAG; - __O uint32_t IFC; - __I uint32_t ISTAT; - uint32_t RESERVED1[2] ; - __IO uint32_t UPDATE; - __I uint32_t SYNCSTAT; -} LPUART_TypeDef; - -/****************** Bit definition for SPI_CON1 register ************************/ - -#define SPI_CON1_BIDEN_POS 15U -#define SPI_CON1_BIDEN_MSK BIT(SPI_CON1_BIDEN_POS) - -#define SPI_CON1_BIDOEN_POS 14U -#define SPI_CON1_BIDOEN_MSK BIT(SPI_CON1_BIDOEN_POS) - -#define SPI_CON1_CRCEN_POS 13U -#define SPI_CON1_CRCEN_MSK BIT(SPI_CON1_CRCEN_POS) - -#define SPI_CON1_NXTCRC_POS 12U -#define SPI_CON1_NXTCRC_MSK BIT(SPI_CON1_NXTCRC_POS) - -#define SPI_CON1_FLEN_POS 11U -#define SPI_CON1_FLEN_MSK BIT(SPI_CON1_FLEN_POS) - -#define SPI_CON1_RXO_POS 10U -#define SPI_CON1_RXO_MSK BIT(SPI_CON1_RXO_POS) - -#define SPI_CON1_SSEN_POS 9U -#define SPI_CON1_SSEN_MSK BIT(SPI_CON1_SSEN_POS) - -#define SPI_CON1_SSOUT_POS 8U -#define SPI_CON1_SSOUT_MSK BIT(SPI_CON1_SSOUT_POS) - -#define SPI_CON1_LSBFST_POS 7U -#define SPI_CON1_LSBFST_MSK BIT(SPI_CON1_LSBFST_POS) - -#define SPI_CON1_SPIEN_POS 6U -#define SPI_CON1_SPIEN_MSK BIT(SPI_CON1_SPIEN_POS) - -#define SPI_CON1_BAUD_POSS 3U -#define SPI_CON1_BAUD_POSE 5U -#define SPI_CON1_BAUD_MSK BITS(SPI_CON1_BAUD_POSS,SPI_CON1_BAUD_POSE) - -#define SPI_CON1_MSTREN_POS 2U -#define SPI_CON1_MSTREN_MSK BIT(SPI_CON1_MSTREN_POS) - -#define SPI_CON1_CPOL_POS 1U -#define SPI_CON1_CPOL_MSK BIT(SPI_CON1_CPOL_POS) - -#define SPI_CON1_CPHA_POS 0U -#define SPI_CON1_CPHA_MSK BIT(SPI_CON1_CPHA_POS) - -/****************** Bit definition for SPI_CON2 register ************************/ - -#define SPI_CON2_TXBEIE_POS 7U -#define SPI_CON2_TXBEIE_MSK BIT(SPI_CON2_TXBEIE_POS) - -#define SPI_CON2_RXBNEIE_POS 6U -#define SPI_CON2_RXBNEIE_MSK BIT(SPI_CON2_RXBNEIE_POS) - -#define SPI_CON2_ERRIE_POS 5U -#define SPI_CON2_ERRIE_MSK BIT(SPI_CON2_ERRIE_POS) - -#define SPI_CON2_NSSOE_POS 2U -#define SPI_CON2_NSSOE_MSK BIT(SPI_CON2_NSSOE_POS) - -#define SPI_CON2_TXDMA_POS 1U -#define SPI_CON2_TXDMA_MSK BIT(SPI_CON2_TXDMA_POS) - -#define SPI_CON2_RXDMA_POS 0U -#define SPI_CON2_RXDMA_MSK BIT(SPI_CON2_RXDMA_POS) - -/****************** Bit definition for SPI_STAT register ************************/ - -#define SPI_STAT_BUSY_POS 7U -#define SPI_STAT_BUSY_MSK BIT(SPI_STAT_BUSY_POS) - -#define SPI_STAT_OVERR_POS 6U -#define SPI_STAT_OVERR_MSK BIT(SPI_STAT_OVERR_POS) - -#define SPI_STAT_MODERR_POS 5U -#define SPI_STAT_MODERR_MSK BIT(SPI_STAT_MODERR_POS) - -#define SPI_STAT_CRCERR_POS 4U -#define SPI_STAT_CRCERR_MSK BIT(SPI_STAT_CRCERR_POS) - -#define SPI_STAT_TXBE_POS 1U -#define SPI_STAT_TXBE_MSK BIT(SPI_STAT_TXBE_POS) - -#define SPI_STAT_RXBNE_POS 0U -#define SPI_STAT_RXBNE_MSK BIT(SPI_STAT_RXBNE_POS) - -/****************** Bit definition for SPI_DATA register ************************/ - -#define SPI_DATA_VALUE_POSS 0U -#define SPI_DATA_VALUE_POSE 15U -#define SPI_DATA_VALUE_MSK BITS(SPI_DATA_VALUE_POSS,SPI_DATA_VALUE_POSE) - -/****************** Bit definition for SPI_CRCPOLY register ************************/ - -#define SPI_CRCPOLY_VALUE_POSS 0U -#define SPI_CRCPOLY_VALUE_POSE 15U -#define SPI_CRCPOLY_VALUE_MSK BITS(SPI_CRCPOLY_VALUE_POSS,SPI_CRCPOLY_VALUE_POSE) - -/****************** Bit definition for SPI_RXCRC register ************************/ - -#define SPI_RXCRC_CRCVAL_POSS 0U -#define SPI_RXCRC_CRCVAL_POSE 15U -#define SPI_RXCRC_CRCVAL_MSK BITS(SPI_RXCRC_CRCVAL_POSS,SPI_RXCRC_CRCVAL_POSE) - -/****************** Bit definition for SPI_TXCRC register ************************/ - -#define SPI_TXCRC_CRCVAL_POSS 0U -#define SPI_TXCRC_CRCVAL_POSE 15U -#define SPI_TXCRC_CRCVAL_MSK BITS(SPI_TXCRC_CRCVAL_POSS,SPI_TXCRC_CRCVAL_POSE) - -typedef struct -{ - __IO uint32_t CON1; - __IO uint32_t CON2; - __IO uint32_t STAT; - __IO uint32_t DATA; - __IO uint32_t CRCPOLY; - __I uint32_t RXCRC; - __I uint32_t TXCRC; -} SPI_TypeDef; - -/****************** Bit definition for I2C_CON1 register ************************/ - -#define I2C_CON1_SRST_POS 15U -#define I2C_CON1_SRST_MSK BIT(I2C_CON1_SRST_POS) - -#define I2C_CON1_ALARM_POS 13U -#define I2C_CON1_ALARM_MSK BIT(I2C_CON1_ALARM_POS) - -#define I2C_CON1_TRPEC_POS 12U -#define I2C_CON1_TRPEC_MSK BIT(I2C_CON1_TRPEC_POS) - -#define I2C_CON1_POSAP_POS 11U -#define I2C_CON1_POSAP_MSK BIT(I2C_CON1_POSAP_POS) - -#define I2C_CON1_ACKEN_POS 10U -#define I2C_CON1_ACKEN_MSK BIT(I2C_CON1_ACKEN_POS) - -#define I2C_CON1_STOP_POS 9U -#define I2C_CON1_STOP_MSK BIT(I2C_CON1_STOP_POS) - -#define I2C_CON1_START_POS 8U -#define I2C_CON1_START_MSK BIT(I2C_CON1_START_POS) - -#define I2C_CON1_DISCS_POS 7U -#define I2C_CON1_DISCS_MSK BIT(I2C_CON1_DISCS_POS) - -#define I2C_CON1_GCEN_POS 6U -#define I2C_CON1_GCEN_MSK BIT(I2C_CON1_GCEN_POS) - -#define I2C_CON1_PECEN_POS 5U -#define I2C_CON1_PECEN_MSK BIT(I2C_CON1_PECEN_POS) - -#define I2C_CON1_ARPEN_POS 4U -#define I2C_CON1_ARPEN_MSK BIT(I2C_CON1_ARPEN_POS) - -#define I2C_CON1_SMBMOD_POS 3U -#define I2C_CON1_SMBMOD_MSK BIT(I2C_CON1_SMBMOD_POS) - -#define I2C_CON1_PMOD_POS 1U -#define I2C_CON1_PMOD_MSK BIT(I2C_CON1_PMOD_POS) - -#define I2C_CON1_PEN_POS 0U -#define I2C_CON1_PEN_MSK BIT(I2C_CON1_PEN_POS) - -/****************** Bit definition for I2C_CON2 register ************************/ - -#define I2C_CON2_LDMA_POS 12U -#define I2C_CON2_LDMA_MSK BIT(I2C_CON2_LDMA_POS) - -#define I2C_CON2_DMAEN_POS 11U -#define I2C_CON2_DMAEN_MSK BIT(I2C_CON2_DMAEN_POS) - -#define I2C_CON2_BUFIE_POS 10U -#define I2C_CON2_BUFIE_MSK BIT(I2C_CON2_BUFIE_POS) - -#define I2C_CON2_EVTIE_POS 9U -#define I2C_CON2_EVTIE_MSK BIT(I2C_CON2_EVTIE_POS) - -#define I2C_CON2_ERRIE_POS 8U -#define I2C_CON2_ERRIE_MSK BIT(I2C_CON2_ERRIE_POS) - -#define I2C_CON2_CLKF_POSS 0U -#define I2C_CON2_CLKF_POSE 5U -#define I2C_CON2_CLKF_MSK BITS(I2C_CON2_CLKF_POSS,I2C_CON2_CLKF_POSE) - -/****************** Bit definition for I2C_ADDR1 register ************************/ - -#define I2C_ADDR1_ADDTYPE_POS 15U -#define I2C_ADDR1_ADDTYPE_MSK BIT(I2C_ADDR1_ADDTYPE_POS) - -#define I2C_ADDR1_ADDH_POSS 8U -#define I2C_ADDR1_ADDH_POSE 9U -#define I2C_ADDR1_ADDH_MSK BITS(I2C_ADDR1_ADDH_POSS,I2C_ADDR1_ADDH_POSE) - -#define I2C_ADDR1_ADD_POSS 1U -#define I2C_ADDR1_ADD_POSE 7U -#define I2C_ADDR1_ADD_MSK BITS(I2C_ADDR1_ADD_POSS,I2C_ADDR1_ADD_POSE) - -#define I2C_ADDR1_ADDLSB_POS 0U -#define I2C_ADDR1_ADDLSB_MSK BIT(I2C_ADDR1_ADDLSB_POS) - -/****************** Bit definition for I2C_ADDR2 register ************************/ - -#define I2C_ADDR2_ADD_POSS 1U -#define I2C_ADDR2_ADD_POSE 7U -#define I2C_ADDR2_ADD_MSK BITS(I2C_ADDR2_ADD_POSS,I2C_ADDR2_ADD_POSE) - -#define I2C_ADDR2_DUALEN_POS 0U -#define I2C_ADDR2_DUALEN_MSK BIT(I2C_ADDR2_DUALEN_POS) - -/****************** Bit definition for I2C_DATA register ************************/ - -#define I2C_DATA_TRBUF_POSS 0U -#define I2C_DATA_TRBUF_POSE 7U -#define I2C_DATA_TRBUF_MSK BITS(I2C_DATA_TRBUF_POSS,I2C_DATA_TRBUF_POSE) - -/****************** Bit definition for I2C_STAT1 register ************************/ - -#define I2C_STAT1_SMBALARM_POS 15U -#define I2C_STAT1_SMBALARM_MSK BIT(I2C_STAT1_SMBALARM_POS) - -#define I2C_STAT1_SMBTO_POS 14U -#define I2C_STAT1_SMBTO_MSK BIT(I2C_STAT1_SMBTO_POS) - -#define I2C_STAT1_PECERR_POS 12U -#define I2C_STAT1_PECERR_MSK BIT(I2C_STAT1_PECERR_POS) - -#define I2C_STAT1_ROUERR_POS 11U -#define I2C_STAT1_ROUERR_MSK BIT(I2C_STAT1_ROUERR_POS) - -#define I2C_STAT1_ACKERR_POS 10U -#define I2C_STAT1_ACKERR_MSK BIT(I2C_STAT1_ACKERR_POS) - -#define I2C_STAT1_LARB_POS 9U -#define I2C_STAT1_LARB_MSK BIT(I2C_STAT1_LARB_POS) - -#define I2C_STAT1_BUSERR_POS 8U -#define I2C_STAT1_BUSERR_MSK BIT(I2C_STAT1_BUSERR_POS) - -#define I2C_STAT1_TXBE_POS 7U -#define I2C_STAT1_TXBE_MSK BIT(I2C_STAT1_TXBE_POS) - -#define I2C_STAT1_RXBNE_POS 6U -#define I2C_STAT1_RXBNE_MSK BIT(I2C_STAT1_RXBNE_POS) - -#define I2C_STAT1_DETSTP_POS 4U -#define I2C_STAT1_DETSTP_MSK BIT(I2C_STAT1_DETSTP_POS) - -#define I2C_STAT1_SENDADD10_POS 3U -#define I2C_STAT1_SENDADD10_MSK BIT(I2C_STAT1_SENDADD10_POS) - -#define I2C_STAT1_BTC_POS 2U -#define I2C_STAT1_BTC_MSK BIT(I2C_STAT1_BTC_POS) - -#define I2C_STAT1_ADDR_POS 1U -#define I2C_STAT1_ADDR_MSK BIT(I2C_STAT1_ADDR_POS) - -#define I2C_STAT1_SENDSTR_POS 0U -#define I2C_STAT1_SENDSTR_MSK BIT(I2C_STAT1_SENDSTR_POS) - -/****************** Bit definition for I2C_STAT2 register ************************/ - -#define I2C_STAT2_PECV_POSS 8U -#define I2C_STAT2_PECV_POSE 15U -#define I2C_STAT2_PECV_MSK BITS(I2C_STAT2_PECV_POSS,I2C_STAT2_PECV_POSE) - -#define I2C_STAT2_DMF_POS 7U -#define I2C_STAT2_DMF_MSK BIT(I2C_STAT2_DMF_POS) - -#define I2C_STAT2_SMBHH_POS 6U -#define I2C_STAT2_SMBHH_MSK BIT(I2C_STAT2_SMBHH_POS) - -#define I2C_STAT2_SMBDEF_POS 5U -#define I2C_STAT2_SMBDEF_MSK BIT(I2C_STAT2_SMBDEF_POS) - -#define I2C_STAT2_RXGCF_POS 4U -#define I2C_STAT2_RXGCF_MSK BIT(I2C_STAT2_RXGCF_POS) - -#define I2C_STAT2_TRF_POS 2U -#define I2C_STAT2_TRF_MSK BIT(I2C_STAT2_TRF_POS) - -#define I2C_STAT2_BSYF_POS 1U -#define I2C_STAT2_BSYF_MSK BIT(I2C_STAT2_BSYF_POS) - -#define I2C_STAT2_MASTER_POS 0U -#define I2C_STAT2_MASTER_MSK BIT(I2C_STAT2_MASTER_POS) - -/****************** Bit definition for I2C_CKCFG register ************************/ - -#define I2C_CKCFG_CLKMOD_POS 15U -#define I2C_CKCFG_CLKMOD_MSK BIT(I2C_CKCFG_CLKMOD_POS) - -#define I2C_CKCFG_DUTY_POS 14U -#define I2C_CKCFG_DUTY_MSK BIT(I2C_CKCFG_DUTY_POS) - -#define I2C_CKCFG_CLKSET_POSS 0U -#define I2C_CKCFG_CLKSET_POSE 11U -#define I2C_CKCFG_CLKSET_MSK BITS(I2C_CKCFG_CLKSET_POSS,I2C_CKCFG_CLKSET_POSE) - -/****************** Bit definition for I2C_RT register ************************/ - -#define I2C_RT_RISET_POSS 0U -#define I2C_RT_RISET_POSE 5U -#define I2C_RT_RISET_MSK BITS(I2C_RT_RISET_POSS,I2C_RT_RISET_POSE) - -typedef struct -{ - __IO uint32_t CON1; - __IO uint32_t CON2; - __IO uint32_t ADDR1; - __IO uint32_t ADDR2; - __IO uint32_t DATA; - __IO uint32_t STAT1; - __I uint32_t STAT2; - __IO uint32_t CKCFG; - __IO uint32_t RT; -} I2C_TypeDef; - -/****************** Bit definition for CAN_CON register ************************/ - -#define CAN_CON_DBGSTP_POS 16U -#define CAN_CON_DBGSTP_MSK BIT(CAN_CON_DBGSTP_POS) - -#define CAN_CON_RST_POS 15U -#define CAN_CON_RST_MSK BIT(CAN_CON_RST_POS) - -#define CAN_CON_TTCEN_POS 7U -#define CAN_CON_TTCEN_MSK BIT(CAN_CON_TTCEN_POS) - -#define CAN_CON_ABOFFEN_POS 6U -#define CAN_CON_ABOFFEN_MSK BIT(CAN_CON_ABOFFEN_POS) - -#define CAN_CON_AWKEN_POS 5U -#define CAN_CON_AWKEN_MSK BIT(CAN_CON_AWKEN_POS) - -#define CAN_CON_ARTXDIS_POS 4U -#define CAN_CON_ARTXDIS_MSK BIT(CAN_CON_ARTXDIS_POS) - -#define CAN_CON_RXFOPM_POS 3U -#define CAN_CON_RXFOPM_MSK BIT(CAN_CON_RXFOPM_POS) - -#define CAN_CON_TXMP_POS 2U -#define CAN_CON_TXMP_MSK BIT(CAN_CON_TXMP_POS) - -#define CAN_CON_SLPREQ_POS 1U -#define CAN_CON_SLPREQ_MSK BIT(CAN_CON_SLPREQ_POS) - -#define CAN_CON_INIREQ_POS 0U -#define CAN_CON_INIREQ_MSK BIT(CAN_CON_INIREQ_POS) - -/****************** Bit definition for CAN_STAT register ************************/ - -#define CAN_STAT_RX_POS 11U -#define CAN_STAT_RX_MSK BIT(CAN_STAT_RX_POS) - -#define CAN_STAT_PRESMP_POS 10U -#define CAN_STAT_PRESMP_MSK BIT(CAN_STAT_PRESMP_POS) - -#define CAN_STAT_RXSTAT_POS 9U -#define CAN_STAT_RXSTAT_MSK BIT(CAN_STAT_RXSTAT_POS) - -#define CAN_STAT_TXSTAT_POS 8U -#define CAN_STAT_TXSTAT_MSK BIT(CAN_STAT_TXSTAT_POS) - -#define CAN_STAT_SLPIF_POS 4U -#define CAN_STAT_SLPIF_MSK BIT(CAN_STAT_SLPIF_POS) - -#define CAN_STAT_WKIF_POS 3U -#define CAN_STAT_WKIF_MSK BIT(CAN_STAT_WKIF_POS) - -#define CAN_STAT_ERRIF_POS 2U -#define CAN_STAT_ERRIF_MSK BIT(CAN_STAT_ERRIF_POS) - -#define CAN_STAT_SLPSTAT_POS 1U -#define CAN_STAT_SLPSTAT_MSK BIT(CAN_STAT_SLPSTAT_POS) - -#define CAN_STAT_INISTAT_POS 0U -#define CAN_STAT_INISTAT_MSK BIT(CAN_STAT_INISTAT_POS) - -/****************** Bit definition for CAN_IFC register ************************/ - -#define CAN_IFC_SLPIFC_POS 4U -#define CAN_IFC_SLPIFC_MSK BIT(CAN_IFC_SLPIFC_POS) - -#define CAN_IFC_WKIFC_POS 3U -#define CAN_IFC_WKIFC_MSK BIT(CAN_IFC_WKIFC_POS) - -#define CAN_IFC_ERRIFC_POS 2U -#define CAN_IFC_ERRIFC_MSK BIT(CAN_IFC_ERRIFC_POS) - -/****************** Bit definition for CAN_TXSTAT register ************************/ - -#define CAN_TXSTAT_TXM2LPF_POS 31U -#define CAN_TXSTAT_TXM2LPF_MSK BIT(CAN_TXSTAT_TXM2LPF_POS) - -#define CAN_TXSTAT_TXM1LPF_POS 30U -#define CAN_TXSTAT_TXM1LPF_MSK BIT(CAN_TXSTAT_TXM1LPF_POS) - -#define CAN_TXSTAT_TXM0LPF_POS 29U -#define CAN_TXSTAT_TXM0LPF_MSK BIT(CAN_TXSTAT_TXM0LPF_POS) - -#define CAN_TXSTAT_TXM2EF_POS 28U -#define CAN_TXSTAT_TXM2EF_MSK BIT(CAN_TXSTAT_TXM2EF_POS) - -#define CAN_TXSTAT_TXM1EF_POS 27U -#define CAN_TXSTAT_TXM1EF_MSK BIT(CAN_TXSTAT_TXM1EF_POS) - -#define CAN_TXSTAT_TXM0EF_POS 26U -#define CAN_TXSTAT_TXM0EF_MSK BIT(CAN_TXSTAT_TXM0EF_POS) - -#define CAN_TXSTAT_CODE_POSS 24U -#define CAN_TXSTAT_CODE_POSE 25U -#define CAN_TXSTAT_CODE_MSK BITS(CAN_TXSTAT_CODE_POSS,CAN_TXSTAT_CODE_POSE) - -#define CAN_TXSTAT_M2STPREQ_POS 23U -#define CAN_TXSTAT_M2STPREQ_MSK BIT(CAN_TXSTAT_M2STPREQ_POS) - -#define CAN_TXSTAT_M2TXERR_POS 19U -#define CAN_TXSTAT_M2TXERR_MSK BIT(CAN_TXSTAT_M2TXERR_POS) - -#define CAN_TXSTAT_M2ARBLST_POS 18U -#define CAN_TXSTAT_M2ARBLST_MSK BIT(CAN_TXSTAT_M2ARBLST_POS) - -#define CAN_TXSTAT_M2TXC_POS 17U -#define CAN_TXSTAT_M2TXC_MSK BIT(CAN_TXSTAT_M2TXC_POS) - -#define CAN_TXSTAT_M2REQC_POS 16U -#define CAN_TXSTAT_M2REQC_MSK BIT(CAN_TXSTAT_M2REQC_POS) - -#define CAN_TXSTAT_M1STPREQ_POS 15U -#define CAN_TXSTAT_M1STPREQ_MSK BIT(CAN_TXSTAT_M1STPREQ_POS) - -#define CAN_TXSTAT_M1TXERR_POS 11U -#define CAN_TXSTAT_M1TXERR_MSK BIT(CAN_TXSTAT_M1TXERR_POS) - -#define CAN_TXSTAT_M1ARBLST_POS 10U -#define CAN_TXSTAT_M1ARBLST_MSK BIT(CAN_TXSTAT_M1ARBLST_POS) - -#define CAN_TXSTAT_M1TXC_POS 9U -#define CAN_TXSTAT_M1TXC_MSK BIT(CAN_TXSTAT_M1TXC_POS) - -#define CAN_TXSTAT_M1REQC_POS 8U -#define CAN_TXSTAT_M1REQC_MSK BIT(CAN_TXSTAT_M1REQC_POS) - -#define CAN_TXSTAT_M0STPREQ_POS 7U -#define CAN_TXSTAT_M0STPREQ_MSK BIT(CAN_TXSTAT_M0STPREQ_POS) - -#define CAN_TXSTAT_M0TXERR_POS 3U -#define CAN_TXSTAT_M0TXERR_MSK BIT(CAN_TXSTAT_M0TXERR_POS) - -#define CAN_TXSTAT_M0ARBLST_POS 2U -#define CAN_TXSTAT_M0ARBLST_MSK BIT(CAN_TXSTAT_M0ARBLST_POS) - -#define CAN_TXSTAT_M0TXC_POS 1U -#define CAN_TXSTAT_M0TXC_MSK BIT(CAN_TXSTAT_M0TXC_POS) - -#define CAN_TXSTAT_M0REQC_POS 0U -#define CAN_TXSTAT_M0REQC_MSK BIT(CAN_TXSTAT_M0REQC_POS) - -/****************** Bit definition for CAN_TXSTATC register ************************/ - -#define CAN_TXSTATC_M2TXERR_POS 19U -#define CAN_TXSTATC_M2TXERR_MSK BIT(CAN_TXSTATC_M2TXERR_POS) - -#define CAN_TXSTATC_M2ARBLST_POS 18U -#define CAN_TXSTATC_M2ARBLST_MSK BIT(CAN_TXSTATC_M2ARBLST_POS) - -#define CAN_TXSTATC_M2TXC_POS 17U -#define CAN_TXSTATC_M2TXC_MSK BIT(CAN_TXSTATC_M2TXC_POS) - -#define CAN_TXSTATC_M2REQC_POS 16U -#define CAN_TXSTATC_M2REQC_MSK BIT(CAN_TXSTATC_M2REQC_POS) - -#define CAN_TXSTATC_M1TXERR_POS 11U -#define CAN_TXSTATC_M1TXERR_MSK BIT(CAN_TXSTATC_M1TXERR_POS) - -#define CAN_TXSTATC_M1ARBLST_POS 10U -#define CAN_TXSTATC_M1ARBLST_MSK BIT(CAN_TXSTATC_M1ARBLST_POS) - -#define CAN_TXSTATC_M1TXC_POS 9U -#define CAN_TXSTATC_M1TXC_MSK BIT(CAN_TXSTATC_M1TXC_POS) - -#define CAN_TXSTATC_M1REQC_POS 8U -#define CAN_TXSTATC_M1REQC_MSK BIT(CAN_TXSTATC_M1REQC_POS) - -#define CAN_TXSTATC_M0TXERR_POS 3U -#define CAN_TXSTATC_M0TXERR_MSK BIT(CAN_TXSTATC_M0TXERR_POS) - -#define CAN_TXSTATC_M0ARBLST_POS 2U -#define CAN_TXSTATC_M0ARBLST_MSK BIT(CAN_TXSTATC_M0ARBLST_POS) - -#define CAN_TXSTATC_M0TXC_POS 1U -#define CAN_TXSTATC_M0TXC_MSK BIT(CAN_TXSTATC_M0TXC_POS) - -#define CAN_TXSTATC_M0REQC_POS 0U -#define CAN_TXSTATC_M0REQC_MSK BIT(CAN_TXSTATC_M0REQC_POS) - -/****************** Bit definition for CAN_RXF0 register ************************/ - -#define CAN_RXF0_FREE_POS 5U -#define CAN_RXF0_FREE_MSK BIT(CAN_RXF0_FREE_POS) - -#define CAN_RXF0_OVR_POS 4U -#define CAN_RXF0_OVR_MSK BIT(CAN_RXF0_OVR_POS) - -#define CAN_RXF0_FULL_POS 3U -#define CAN_RXF0_FULL_MSK BIT(CAN_RXF0_FULL_POS) - -#define CAN_RXF0_PEND_POSS 0U -#define CAN_RXF0_PEND_POSE 1U -#define CAN_RXF0_PEND_MSK BITS(CAN_RXF0_PEND_POSS,CAN_RXF0_PEND_POSE) - -/****************** Bit definition for CAN_RXF0C register ************************/ - -#define CAN_RXF0C_OVRC_POS 4U -#define CAN_RXF0C_OVRC_MSK BIT(CAN_RXF0C_OVRC_POS) - -#define CAN_RXF0C_FULLC_POS 3U -#define CAN_RXF0C_FULLC_MSK BIT(CAN_RXF0C_FULLC_POS) - -/****************** Bit definition for CAN_RXF1 register ************************/ - -#define CAN_RXF1_FREE_POS 5U -#define CAN_RXF1_FREE_MSK BIT(CAN_RXF1_FREE_POS) - -#define CAN_RXF1_OVR_POS 4U -#define CAN_RXF1_OVR_MSK BIT(CAN_RXF1_OVR_POS) - -#define CAN_RXF1_FULL_POS 3U -#define CAN_RXF1_FULL_MSK BIT(CAN_RXF1_FULL_POS) - -#define CAN_RXF1_PEND_POSS 0U -#define CAN_RXF1_PEND_POSE 1U -#define CAN_RXF1_PEND_MSK BITS(CAN_RXF1_PEND_POSS,CAN_RXF1_PEND_POSE) - -/****************** Bit definition for CAN_RXF1C register ************************/ - -#define CAN_RXF1C_OVRC_POS 4U -#define CAN_RXF1C_OVRC_MSK BIT(CAN_RXF1C_OVRC_POS) - -#define CAN_RXF1C_FULLC_POS 3U -#define CAN_RXF1C_FULLC_MSK BIT(CAN_RXF1C_FULLC_POS) - -/****************** Bit definition for CAN_IE register ************************/ - -#define CAN_IE_SLPIE_POS 17U -#define CAN_IE_SLPIE_MSK BIT(CAN_IE_SLPIE_POS) - -#define CAN_IE_WKIE_POS 16U -#define CAN_IE_WKIE_MSK BIT(CAN_IE_WKIE_POS) - -#define CAN_IE_ERRIE_POS 15U -#define CAN_IE_ERRIE_MSK BIT(CAN_IE_ERRIE_POS) - -#define CAN_IE_PRERRIE_POS 11U -#define CAN_IE_PRERRIE_MSK BIT(CAN_IE_PRERRIE_POS) - -#define CAN_IE_BOFFIE_POS 10U -#define CAN_IE_BOFFIE_MSK BIT(CAN_IE_BOFFIE_POS) - -#define CAN_IE_PERRIE_POS 9U -#define CAN_IE_PERRIE_MSK BIT(CAN_IE_PERRIE_POS) - -#define CAN_IE_WARNIE_POS 8U -#define CAN_IE_WARNIE_MSK BIT(CAN_IE_WARNIE_POS) - -#define CAN_IE_F1OVRIE_POS 6U -#define CAN_IE_F1OVRIE_MSK BIT(CAN_IE_F1OVRIE_POS) - -#define CAN_IE_F1FULIE_POS 5U -#define CAN_IE_F1FULIE_MSK BIT(CAN_IE_F1FULIE_POS) - -#define CAN_IE_F1PIE_POS 4U -#define CAN_IE_F1PIE_MSK BIT(CAN_IE_F1PIE_POS) - -#define CAN_IE_F0OVRIE_POS 3U -#define CAN_IE_F0OVRIE_MSK BIT(CAN_IE_F0OVRIE_POS) - -#define CAN_IE_F0FULIE_POS 2U -#define CAN_IE_F0FULIE_MSK BIT(CAN_IE_F0FULIE_POS) - -#define CAN_IE_F0PIE_POS 1U -#define CAN_IE_F0PIE_MSK BIT(CAN_IE_F0PIE_POS) - -#define CAN_IE_TXMEIE_POS 0U -#define CAN_IE_TXMEIE_MSK BIT(CAN_IE_TXMEIE_POS) - -/****************** Bit definition for CAN_ERRSTAT register ************************/ - -#define CAN_ERRSTAT_RXERRC_POSS 24U -#define CAN_ERRSTAT_RXERRC_POSE 31U -#define CAN_ERRSTAT_RXERRC_MSK BITS(CAN_ERRSTAT_RXERRC_POSS,CAN_ERRSTAT_RXERRC_POSE) - -#define CAN_ERRSTAT_TXERRC_POSS 16U -#define CAN_ERRSTAT_TXERRC_POSE 23U -#define CAN_ERRSTAT_TXERRC_MSK BITS(CAN_ERRSTAT_TXERRC_POSS,CAN_ERRSTAT_TXERRC_POSE) - -#define CAN_ERRSTAT_PRERRF_POSS 4U -#define CAN_ERRSTAT_PRERRF_POSE 6U -#define CAN_ERRSTAT_PRERRF_MSK BITS(CAN_ERRSTAT_PRERRF_POSS,CAN_ERRSTAT_PRERRF_POSE) - -#define CAN_ERRSTAT_BOFF_POS 2U -#define CAN_ERRSTAT_BOFF_MSK BIT(CAN_ERRSTAT_BOFF_POS) - -#define CAN_ERRSTAT_PERRF_POS 1U -#define CAN_ERRSTAT_PERRF_MSK BIT(CAN_ERRSTAT_PERRF_POS) - -#define CAN_ERRSTAT_WARNF_POS 0U -#define CAN_ERRSTAT_WARNF_MSK BIT(CAN_ERRSTAT_WARNF_POS) - -/****************** Bit definition for CAN_BTIME register ************************/ - -#define CAN_BTIME_SILENT_POS 31U -#define CAN_BTIME_SILENT_MSK BIT(CAN_BTIME_SILENT_POS) - -#define CAN_BTIME_LOOP_POS 30U -#define CAN_BTIME_LOOP_MSK BIT(CAN_BTIME_LOOP_POS) - -#define CAN_BTIME_RESJW_POSS 24U -#define CAN_BTIME_RESJW_POSE 25U -#define CAN_BTIME_RESJW_MSK BITS(CAN_BTIME_RESJW_POSS,CAN_BTIME_RESJW_POSE) - -#define CAN_BTIME_SEG2_POSS 20U -#define CAN_BTIME_SEG2_POSE 22U -#define CAN_BTIME_SEG2_MSK BITS(CAN_BTIME_SEG2_POSS,CAN_BTIME_SEG2_POSE) - -#define CAN_BTIME_SEG1_POSS 16U -#define CAN_BTIME_SEG1_POSE 19U -#define CAN_BTIME_SEG1_MSK BITS(CAN_BTIME_SEG1_POSS,CAN_BTIME_SEG1_POSE) - -#define CAN_BTIME_BPSC_POSS 0U -#define CAN_BTIME_BPSC_POSE 9U -#define CAN_BTIME_BPSC_MSK BITS(CAN_BTIME_BPSC_POSS,CAN_BTIME_BPSC_POSE) - -/****************** Bit definition for CAN_TXID0 register ************************/ - -#define CAN_TXID0_STDID_POSS 21U -#define CAN_TXID0_STDID_POSE 31U -#define CAN_TXID0_STDID_MSK BITS(CAN_TXID0_STDID_POSS,CAN_TXID0_STDID_POSE) - -#define CAN_TXID0_EXID_POSS 3U -#define CAN_TXID0_EXID_POSE 20U -#define CAN_TXID0_EXID_MSK BITS(CAN_TXID0_EXID_POSS,CAN_TXID0_EXID_POSE) - -#define CAN_TXID0_IDE_POS 2U -#define CAN_TXID0_IDE_MSK BIT(CAN_TXID0_IDE_POS) - -#define CAN_TXID0_RTR_POS 1U -#define CAN_TXID0_RTR_MSK BIT(CAN_TXID0_RTR_POS) - -#define CAN_TXID0_TXMREQ_POS 0U -#define CAN_TXID0_TXMREQ_MSK BIT(CAN_TXID0_TXMREQ_POS) - -/****************** Bit definition for CAN_TXFCON0 register ************************/ - -#define CAN_TXFCON0_STAMP_POSS 16U -#define CAN_TXFCON0_STAMP_POSE 31U -#define CAN_TXFCON0_STAMP_MSK BITS(CAN_TXFCON0_STAMP_POSS,CAN_TXFCON0_STAMP_POSE) - -#define CAN_TXFCON0_TXGT_POS 8U -#define CAN_TXFCON0_TXGT_MSK BIT(CAN_TXFCON0_TXGT_POS) - -#define CAN_TXFCON0_DLEN_POSS 0U -#define CAN_TXFCON0_DLEN_POSE 3U -#define CAN_TXFCON0_DLEN_MSK BITS(CAN_TXFCON0_DLEN_POSS,CAN_TXFCON0_DLEN_POSE) - -/****************** Bit definition for CAN_TXDL0 register ************************/ - -#define CAN_TXDL0_BYTE3_POSS 24U -#define CAN_TXDL0_BYTE3_POSE 31U -#define CAN_TXDL0_BYTE3_MSK BITS(CAN_TXDL0_BYTE3_POSS,CAN_TXDL0_BYTE3_POSE) - -#define CAN_TXDL0_BYTE2_POSS 16U -#define CAN_TXDL0_BYTE2_POSE 23U -#define CAN_TXDL0_BYTE2_MSK BITS(CAN_TXDL0_BYTE2_POSS,CAN_TXDL0_BYTE2_POSE) - -#define CAN_TXDL0_BYTE1_POSS 8U -#define CAN_TXDL0_BYTE1_POSE 15U -#define CAN_TXDL0_BYTE1_MSK BITS(CAN_TXDL0_BYTE1_POSS,CAN_TXDL0_BYTE1_POSE) - -#define CAN_TXDL0_BYTE0_POSS 0U -#define CAN_TXDL0_BYTE0_POSE 7U -#define CAN_TXDL0_BYTE0_MSK BITS(CAN_TXDL0_BYTE0_POSS,CAN_TXDL0_BYTE0_POSE) - -/****************** Bit definition for CAN_TXDH0 register ************************/ - -#define CAN_TXDH0_BYTE7_POSS 24U -#define CAN_TXDH0_BYTE7_POSE 31U -#define CAN_TXDH0_BYTE7_MSK BITS(CAN_TXDH0_BYTE7_POSS,CAN_TXDH0_BYTE7_POSE) - -#define CAN_TXDH0_BYTE6_POSS 16U -#define CAN_TXDH0_BYTE6_POSE 23U -#define CAN_TXDH0_BYTE6_MSK BITS(CAN_TXDH0_BYTE6_POSS,CAN_TXDH0_BYTE6_POSE) - -#define CAN_TXDH0_BYTE5_POSS 8U -#define CAN_TXDH0_BYTE5_POSE 15U -#define CAN_TXDH0_BYTE5_MSK BITS(CAN_TXDH0_BYTE5_POSS,CAN_TXDH0_BYTE5_POSE) - -#define CAN_TXDH0_BYTE4_POSS 0U -#define CAN_TXDH0_BYTE4_POSE 7U -#define CAN_TXDH0_BYTE4_MSK BITS(CAN_TXDH0_BYTE4_POSS,CAN_TXDH0_BYTE4_POSE) - -/****************** Bit definition for CAN_TXID1 register ************************/ - -#define CAN_TXID1_STDID_POSS 21U -#define CAN_TXID1_STDID_POSE 31U -#define CAN_TXID1_STDID_MSK BITS(CAN_TXID1_STDID_POSS,CAN_TXID1_STDID_POSE) - -#define CAN_TXID1_EXID_POSS 3U -#define CAN_TXID1_EXID_POSE 20U -#define CAN_TXID1_EXID_MSK BITS(CAN_TXID1_EXID_POSS,CAN_TXID1_EXID_POSE) - -#define CAN_TXID1_IDE_POS 2U -#define CAN_TXID1_IDE_MSK BIT(CAN_TXID1_IDE_POS) - -#define CAN_TXID1_RTR_POS 1U -#define CAN_TXID1_RTR_MSK BIT(CAN_TXID1_RTR_POS) - -#define CAN_TXID1_TXMREQ_POS 0U -#define CAN_TXID1_TXMREQ_MSK BIT(CAN_TXID1_TXMREQ_POS) - -/****************** Bit definition for CAN_TXFCON1 register ************************/ - -#define CAN_TXFCON1_STAMP_POSS 16U -#define CAN_TXFCON1_STAMP_POSE 31U -#define CAN_TXFCON1_STAMP_MSK BITS(CAN_TXFCON1_STAMP_POSS,CAN_TXFCON1_STAMP_POSE) - -#define CAN_TXFCON1_TXGT_POS 8U -#define CAN_TXFCON1_TXGT_MSK BIT(CAN_TXFCON1_TXGT_POS) - -#define CAN_TXFCON1_DLEN_POSS 0U -#define CAN_TXFCON1_DLEN_POSE 3U -#define CAN_TXFCON1_DLEN_MSK BITS(CAN_TXFCON1_DLEN_POSS,CAN_TXFCON1_DLEN_POSE) - -/****************** Bit definition for CAN_TXDL1 register ************************/ - -#define CAN_TXDL1_BYTE3_POSS 24U -#define CAN_TXDL1_BYTE3_POSE 31U -#define CAN_TXDL1_BYTE3_MSK BITS(CAN_TXDL1_BYTE3_POSS,CAN_TXDL1_BYTE3_POSE) - -#define CAN_TXDL1_BYTE2_POSS 16U -#define CAN_TXDL1_BYTE2_POSE 23U -#define CAN_TXDL1_BYTE2_MSK BITS(CAN_TXDL1_BYTE2_POSS,CAN_TXDL1_BYTE2_POSE) - -#define CAN_TXDL1_BYTE1_POSS 8U -#define CAN_TXDL1_BYTE1_POSE 15U -#define CAN_TXDL1_BYTE1_MSK BITS(CAN_TXDL1_BYTE1_POSS,CAN_TXDL1_BYTE1_POSE) - -#define CAN_TXDL1_BYTE0_POSS 0U -#define CAN_TXDL1_BYTE0_POSE 7U -#define CAN_TXDL1_BYTE0_MSK BITS(CAN_TXDL1_BYTE0_POSS,CAN_TXDL1_BYTE0_POSE) - -/****************** Bit definition for CAN_TXDH1 register ************************/ - -#define CAN_TXDH1_BYTE7_POSS 24U -#define CAN_TXDH1_BYTE7_POSE 31U -#define CAN_TXDH1_BYTE7_MSK BITS(CAN_TXDH1_BYTE7_POSS,CAN_TXDH1_BYTE7_POSE) - -#define CAN_TXDH1_BYTE6_POSS 16U -#define CAN_TXDH1_BYTE6_POSE 23U -#define CAN_TXDH1_BYTE6_MSK BITS(CAN_TXDH1_BYTE6_POSS,CAN_TXDH1_BYTE6_POSE) - -#define CAN_TXDH1_BYTE5_POSS 8U -#define CAN_TXDH1_BYTE5_POSE 15U -#define CAN_TXDH1_BYTE5_MSK BITS(CAN_TXDH1_BYTE5_POSS,CAN_TXDH1_BYTE5_POSE) - -#define CAN_TXDH1_BYTE4_POSS 0U -#define CAN_TXDH1_BYTE4_POSE 7U -#define CAN_TXDH1_BYTE4_MSK BITS(CAN_TXDH1_BYTE4_POSS,CAN_TXDH1_BYTE4_POSE) - -/****************** Bit definition for CAN_TXID2 register ************************/ - -#define CAN_TXID2_STDID_POSS 21U -#define CAN_TXID2_STDID_POSE 31U -#define CAN_TXID2_STDID_MSK BITS(CAN_TXID2_STDID_POSS,CAN_TXID2_STDID_POSE) - -#define CAN_TXID2_EXID_POSS 3U -#define CAN_TXID2_EXID_POSE 20U -#define CAN_TXID2_EXID_MSK BITS(CAN_TXID2_EXID_POSS,CAN_TXID2_EXID_POSE) - -#define CAN_TXID2_IDE_POS 2U -#define CAN_TXID2_IDE_MSK BIT(CAN_TXID2_IDE_POS) - -#define CAN_TXID2_RTR_POS 1U -#define CAN_TXID2_RTR_MSK BIT(CAN_TXID2_RTR_POS) - -#define CAN_TXID2_TXMREQ_POS 0U -#define CAN_TXID2_TXMREQ_MSK BIT(CAN_TXID2_TXMREQ_POS) - -/****************** Bit definition for CAN_TXFCON2 register ************************/ - -#define CAN_TXFCON2_STAMP_POSS 16U -#define CAN_TXFCON2_STAMP_POSE 31U -#define CAN_TXFCON2_STAMP_MSK BITS(CAN_TXFCON2_STAMP_POSS,CAN_TXFCON2_STAMP_POSE) - -#define CAN_TXFCON2_TXGT_POS 8U -#define CAN_TXFCON2_TXGT_MSK BIT(CAN_TXFCON2_TXGT_POS) - -#define CAN_TXFCON2_DLEN_POSS 0U -#define CAN_TXFCON2_DLEN_POSE 3U -#define CAN_TXFCON2_DLEN_MSK BITS(CAN_TXFCON2_DLEN_POSS,CAN_TXFCON2_DLEN_POSE) - -/****************** Bit definition for CAN_TXDL2 register ************************/ - -#define CAN_TXDL2_BYTE3_POSS 24U -#define CAN_TXDL2_BYTE3_POSE 31U -#define CAN_TXDL2_BYTE3_MSK BITS(CAN_TXDL2_BYTE3_POSS,CAN_TXDL2_BYTE3_POSE) - -#define CAN_TXDL2_BYTE2_POSS 16U -#define CAN_TXDL2_BYTE2_POSE 23U -#define CAN_TXDL2_BYTE2_MSK BITS(CAN_TXDL2_BYTE2_POSS,CAN_TXDL2_BYTE2_POSE) - -#define CAN_TXDL2_BYTE1_POSS 8U -#define CAN_TXDL2_BYTE1_POSE 15U -#define CAN_TXDL2_BYTE1_MSK BITS(CAN_TXDL2_BYTE1_POSS,CAN_TXDL2_BYTE1_POSE) - -#define CAN_TXDL2_BYTE0_POSS 0U -#define CAN_TXDL2_BYTE0_POSE 7U -#define CAN_TXDL2_BYTE0_MSK BITS(CAN_TXDL2_BYTE0_POSS,CAN_TXDL2_BYTE0_POSE) - -/****************** Bit definition for CAN_TXDH2 register ************************/ - -#define CAN_TXDH2_BYTE7_POSS 24U -#define CAN_TXDH2_BYTE7_POSE 31U -#define CAN_TXDH2_BYTE7_MSK BITS(CAN_TXDH2_BYTE7_POSS,CAN_TXDH2_BYTE7_POSE) - -#define CAN_TXDH2_BYTE6_POSS 16U -#define CAN_TXDH2_BYTE6_POSE 23U -#define CAN_TXDH2_BYTE6_MSK BITS(CAN_TXDH2_BYTE6_POSS,CAN_TXDH2_BYTE6_POSE) - -#define CAN_TXDH2_BYTE5_POSS 8U -#define CAN_TXDH2_BYTE5_POSE 15U -#define CAN_TXDH2_BYTE5_MSK BITS(CAN_TXDH2_BYTE5_POSS,CAN_TXDH2_BYTE5_POSE) - -#define CAN_TXDH2_BYTE4_POSS 0U -#define CAN_TXDH2_BYTE4_POSE 7U -#define CAN_TXDH2_BYTE4_MSK BITS(CAN_TXDH2_BYTE4_POSS,CAN_TXDH2_BYTE4_POSE) - -/****************** Bit definition for CAN_RXF0ID register ************************/ - -#define CAN_RXF0ID_STDID_POSS 21U -#define CAN_RXF0ID_STDID_POSE 31U -#define CAN_RXF0ID_STDID_MSK BITS(CAN_RXF0ID_STDID_POSS,CAN_RXF0ID_STDID_POSE) - -#define CAN_RXF0ID_EXID_POSS 3U -#define CAN_RXF0ID_EXID_POSE 20U -#define CAN_RXF0ID_EXID_MSK BITS(CAN_RXF0ID_EXID_POSS,CAN_RXF0ID_EXID_POSE) - -#define CAN_RXF0ID_IDE_POS 2U -#define CAN_RXF0ID_IDE_MSK BIT(CAN_RXF0ID_IDE_POS) - -#define CAN_RXF0ID_RTR_POS 1U -#define CAN_RXF0ID_RTR_MSK BIT(CAN_RXF0ID_RTR_POS) - -/****************** Bit definition for CAN_RXF0INF register ************************/ - -#define CAN_RXF0INF_STAMP_POSS 16U -#define CAN_RXF0INF_STAMP_POSE 31U -#define CAN_RXF0INF_STAMP_MSK BITS(CAN_RXF0INF_STAMP_POSS,CAN_RXF0INF_STAMP_POSE) - -#define CAN_RXF0INF_FLTIDX_POSS 8U -#define CAN_RXF0INF_FLTIDX_POSE 15U -#define CAN_RXF0INF_FLTIDX_MSK BITS(CAN_RXF0INF_FLTIDX_POSS,CAN_RXF0INF_FLTIDX_POSE) - -#define CAN_RXF0INF_DLEN_POSS 0U -#define CAN_RXF0INF_DLEN_POSE 3U -#define CAN_RXF0INF_DLEN_MSK BITS(CAN_RXF0INF_DLEN_POSS,CAN_RXF0INF_DLEN_POSE) - -/****************** Bit definition for CAN_RXF0DL register ************************/ - -#define CAN_RXF0DL_BYTE3_POSS 24U -#define CAN_RXF0DL_BYTE3_POSE 31U -#define CAN_RXF0DL_BYTE3_MSK BITS(CAN_RXF0DL_BYTE3_POSS,CAN_RXF0DL_BYTE3_POSE) - -#define CAN_RXF0DL_BYTE2_POSS 16U -#define CAN_RXF0DL_BYTE2_POSE 23U -#define CAN_RXF0DL_BYTE2_MSK BITS(CAN_RXF0DL_BYTE2_POSS,CAN_RXF0DL_BYTE2_POSE) - -#define CAN_RXF0DL_BYTE1_POSS 8U -#define CAN_RXF0DL_BYTE1_POSE 15U -#define CAN_RXF0DL_BYTE1_MSK BITS(CAN_RXF0DL_BYTE1_POSS,CAN_RXF0DL_BYTE1_POSE) - -#define CAN_RXF0DL_BYTE0_POSS 0U -#define CAN_RXF0DL_BYTE0_POSE 7U -#define CAN_RXF0DL_BYTE0_MSK BITS(CAN_RXF0DL_BYTE0_POSS,CAN_RXF0DL_BYTE0_POSE) - -/****************** Bit definition for CAN_RXF0DH register ************************/ - -#define CAN_RXF0DH_BYTE7_POSS 24U -#define CAN_RXF0DH_BYTE7_POSE 31U -#define CAN_RXF0DH_BYTE7_MSK BITS(CAN_RXF0DH_BYTE7_POSS,CAN_RXF0DH_BYTE7_POSE) - -#define CAN_RXF0DH_BYTE6_POSS 16U -#define CAN_RXF0DH_BYTE6_POSE 23U -#define CAN_RXF0DH_BYTE6_MSK BITS(CAN_RXF0DH_BYTE6_POSS,CAN_RXF0DH_BYTE6_POSE) - -#define CAN_RXF0DH_BYTE5_POSS 8U -#define CAN_RXF0DH_BYTE5_POSE 15U -#define CAN_RXF0DH_BYTE5_MSK BITS(CAN_RXF0DH_BYTE5_POSS,CAN_RXF0DH_BYTE5_POSE) - -#define CAN_RXF0DH_BYTE4_POSS 0U -#define CAN_RXF0DH_BYTE4_POSE 7U -#define CAN_RXF0DH_BYTE4_MSK BITS(CAN_RXF0DH_BYTE4_POSS,CAN_RXF0DH_BYTE4_POSE) - -/****************** Bit definition for CAN_RXF1ID register ************************/ - -#define CAN_RXF1ID_STDID_POSS 21U -#define CAN_RXF1ID_STDID_POSE 31U -#define CAN_RXF1ID_STDID_MSK BITS(CAN_RXF1ID_STDID_POSS,CAN_RXF1ID_STDID_POSE) - -#define CAN_RXF1ID_EXID_POSS 3U -#define CAN_RXF1ID_EXID_POSE 20U -#define CAN_RXF1ID_EXID_MSK BITS(CAN_RXF1ID_EXID_POSS,CAN_RXF1ID_EXID_POSE) - -#define CAN_RXF1ID_IDE_POS 2U -#define CAN_RXF1ID_IDE_MSK BIT(CAN_RXF1ID_IDE_POS) - -#define CAN_RXF1ID_RTR_POS 1U -#define CAN_RXF1ID_RTR_MSK BIT(CAN_RXF1ID_RTR_POS) - -/****************** Bit definition for CAN_RXF1INF register ************************/ - -#define CAN_RXF1INF_STAMP_POSS 16U -#define CAN_RXF1INF_STAMP_POSE 31U -#define CAN_RXF1INF_STAMP_MSK BITS(CAN_RXF1INF_STAMP_POSS,CAN_RXF1INF_STAMP_POSE) - -#define CAN_RXF1INF_FLTIDX_POSS 8U -#define CAN_RXF1INF_FLTIDX_POSE 15U -#define CAN_RXF1INF_FLTIDX_MSK BITS(CAN_RXF1INF_FLTIDX_POSS,CAN_RXF1INF_FLTIDX_POSE) - -#define CAN_RXF1INF_DLEN_POSS 0U -#define CAN_RXF1INF_DLEN_POSE 3U -#define CAN_RXF1INF_DLEN_MSK BITS(CAN_RXF1INF_DLEN_POSS,CAN_RXF1INF_DLEN_POSE) - -/****************** Bit definition for CAN_RXF1DL register ************************/ - -#define CAN_RXF1DL_BYTE3_POSS 24U -#define CAN_RXF1DL_BYTE3_POSE 31U -#define CAN_RXF1DL_BYTE3_MSK BITS(CAN_RXF1DL_BYTE3_POSS,CAN_RXF1DL_BYTE3_POSE) - -#define CAN_RXF1DL_BYTE2_POSS 16U -#define CAN_RXF1DL_BYTE2_POSE 23U -#define CAN_RXF1DL_BYTE2_MSK BITS(CAN_RXF1DL_BYTE2_POSS,CAN_RXF1DL_BYTE2_POSE) - -#define CAN_RXF1DL_BYTE1_POSS 8U -#define CAN_RXF1DL_BYTE1_POSE 15U -#define CAN_RXF1DL_BYTE1_MSK BITS(CAN_RXF1DL_BYTE1_POSS,CAN_RXF1DL_BYTE1_POSE) - -#define CAN_RXF1DL_BYTE0_POSS 0U -#define CAN_RXF1DL_BYTE0_POSE 7U -#define CAN_RXF1DL_BYTE0_MSK BITS(CAN_RXF1DL_BYTE0_POSS,CAN_RXF1DL_BYTE0_POSE) - -/****************** Bit definition for CAN_RXF1DH register ************************/ - -#define CAN_RXF1DH_BYTE7_POSS 24U -#define CAN_RXF1DH_BYTE7_POSE 31U -#define CAN_RXF1DH_BYTE7_MSK BITS(CAN_RXF1DH_BYTE7_POSS,CAN_RXF1DH_BYTE7_POSE) - -#define CAN_RXF1DH_BYTE6_POSS 16U -#define CAN_RXF1DH_BYTE6_POSE 23U -#define CAN_RXF1DH_BYTE6_MSK BITS(CAN_RXF1DH_BYTE6_POSS,CAN_RXF1DH_BYTE6_POSE) - -#define CAN_RXF1DH_BYTE5_POSS 8U -#define CAN_RXF1DH_BYTE5_POSE 15U -#define CAN_RXF1DH_BYTE5_MSK BITS(CAN_RXF1DH_BYTE5_POSS,CAN_RXF1DH_BYTE5_POSE) - -#define CAN_RXF1DH_BYTE4_POSS 0U -#define CAN_RXF1DH_BYTE4_POSE 7U -#define CAN_RXF1DH_BYTE4_MSK BITS(CAN_RXF1DH_BYTE4_POSS,CAN_RXF1DH_BYTE4_POSE) - -/****************** Bit definition for CAN_FLTCON register ************************/ - -#define CAN_FLTCON_FLTINI_POS 0U -#define CAN_FLTCON_FLTINI_MSK BIT(CAN_FLTCON_FLTINI_POS) - -/****************** Bit definition for CAN_FLTM register ************************/ - -#define CAN_FLTM_MOD_POSS 0U -#define CAN_FLTM_MOD_POSE 13U -#define CAN_FLTM_MOD_MSK BITS(CAN_FLTM_MOD_POSS,CAN_FLTM_MOD_POSE) - -/****************** Bit definition for CAN_FLTWS register ************************/ - -#define CAN_FLTWS_SEL_POSS 0U -#define CAN_FLTWS_SEL_POSE 13U -#define CAN_FLTWS_SEL_MSK BITS(CAN_FLTWS_SEL_POSS,CAN_FLTWS_SEL_POSE) - -/****************** Bit definition for CAN_FLTAS register ************************/ - -#define CAN_FLTAS_ASSIGN_POSS 0U -#define CAN_FLTAS_ASSIGN_POSE 13U -#define CAN_FLTAS_ASSIGN_MSK BITS(CAN_FLTAS_ASSIGN_POSS,CAN_FLTAS_ASSIGN_POSE) - -/****************** Bit definition for CAN_FLTGO register ************************/ - -#define CAN_FLTGO_GO_POSS 0U -#define CAN_FLTGO_GO_POSE 13U -#define CAN_FLTGO_GO_MSK BITS(CAN_FLTGO_GO_POSS,CAN_FLTGO_GO_POSE) - -typedef struct { - __IO uint32_t TXID; - __IO uint32_t TXFCON; - __IO uint32_t TXDL; - __IO uint32_t TXDH; -} CAN_TxMailBox_Typedef; - -typedef struct { - __IO uint32_t RXFID; - __IO uint32_t RXFINF; - __IO uint32_t RXFDL; - __IO uint32_t RXFDH; -} CAN_RxFIFO_Typedef; - -typedef struct { - __IO uint32_t FLT1; - __IO uint32_t FLT2; -} CAN_Filter_Typedef; - -typedef struct -{ - __IO uint32_t CON; - __I uint32_t STAT; - __O uint32_t IFC; - __IO uint32_t TXSTAT; - __O uint32_t TXSTATC; - __IO uint32_t RXF0; - __O uint32_t RXF0C; - __IO uint32_t RXF1; - __O uint32_t RXF1C; - __IO uint32_t IE; - __IO uint32_t ERRSTAT; - __IO uint32_t BTIME; - uint32_t RESERVED0[84] ; - CAN_TxMailBox_Typedef TxMailBox[3]; - CAN_RxFIFO_Typedef RxFIFO[2]; - uint32_t RESERVED1[12] ; - __IO uint32_t FLTCON; - __IO uint32_t FLTM; - uint32_t RESERVED2 ; - __IO uint32_t FLTWS; - uint32_t RESERVED3 ; - __IO uint32_t FLTAS; - uint32_t RESERVED4 ; - __IO uint32_t FLTGO; - uint32_t RESERVED5[8] ; - CAN_Filter_Typedef Filter[14]; -} CAN_TypeDef; - -/****************** Bit definition for CRC_CR register ************************/ -#define CRC_CR_BYTORD_POS 24U -#define CRC_CR_BYTORD_MSK BIT(CRC_CR_BYTORD_POS) - -#define CRC_CR_DATLEN_POSS 22U -#define CRC_CR_DATLEN_POSE 23U -#define CRC_CR_DATLEN_MSK BITS(CRC_CR_DATLEN_POSS,CRC_CR_DATLEN_POSE) - -#define CRC_CR_MODE_POSS 20U -#define CRC_CR_MODE_POSE 21U -#define CRC_CR_MODE_MSK BITS(CRC_CR_MODE_POSS,CRC_CR_MODE_POSE) - -#define CRC_CR_CHSINV_POS 19U -#define CRC_CR_CHSINV_MSK BIT(CRC_CR_CHSINV_POS) - -#define CRC_CR_DATINV_POS 18U -#define CRC_CR_DATINV_MSK BIT(CRC_CR_DATINV_POS) - -#define CRC_CR_CHSREV_POS 17U -#define CRC_CR_CHSREV_MSK BIT(CRC_CR_CHSREV_POS) - -#define CRC_CR_DATREV_POS 16U -#define CRC_CR_DATREV_MSK BIT(CRC_CR_DATREV_POS) - -#define CRC_CR_DMAEN_POS 4U -#define CRC_CR_DMAEN_MSK BIT(CRC_CR_DMAEN_POS) - -#define CRC_CR_CWERR_POS 3U -#define CRC_CR_CWERR_MSK BIT(CRC_CR_CWERR_POS) - -#define CRC_CR_WERR_POS 2U -#define CRC_CR_WERR_MSK BIT(CRC_CR_WERR_POS) - -#define CRC_CR_RST_POS 1U -#define CRC_CR_RST_MSK BIT(CRC_CR_RST_POS) - -#define CRC_CR_EN_POS 0U -#define CRC_CR_EN_MSK BIT(CRC_CR_EN_POS) - -/****************** Bit definition for CRC_DATA register ************************/ - -#define CRC_DATA_DATA_POSS 0U -#define CRC_DATA_DATA_POSE 31U -#define CRC_DATA_DATA_MSK BITS(CRC_DATA_DATA_POSS,CRC_DATA_DATA_POSE) - -/****************** Bit definition for CRC_SEED register ************************/ - -#define CRC_SEED_SEED_POSS 0U -#define CRC_SEED_SEED_POSE 31U -#define CRC_SEED_SEED_MSK BITS(CRC_SEED_SEED_POSS,CRC_SEED_SEED_POSE) - -/****************** Bit definition for CRC_CHECKSUM register ************************/ - -#define CRC_CHECKSUM_CHECKSUM_POSS 0U -#define CRC_CHECKSUM_CHECKSUM_POSE 31U -#define CRC_CHECKSUM_CHECKSUM_MSK BITS(CRC_CHECKSUM_CHECKSUM_POSS,CRC_CHECKSUM_CHECKSUM_POSE) - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t DATA; - __IO uint32_t SEED; - __I uint32_t CHECKSUM; -} CRC_TypeDef; - -/****************** Bit definition for CRYPT_CON register ************************/ - -#define CRYPT_CON_CRYSEL_POS 31U -#define CRYPT_CON_CRYSEL_MSK BIT(CRYPT_CON_CRYSEL_POS) - -#define CRYPT_CON_RESCLR_POS 15U -#define CRYPT_CON_RESCLR_MSK BIT(CRYPT_CON_RESCLR_POS) - -#define CRYPT_CON_DMAEN_POS 14U -#define CRYPT_CON_DMAEN_MSK BIT(CRYPT_CON_DMAEN_POS) - -#define CRYPT_CON_FIFOODR_POS 13U -#define CRYPT_CON_FIFOODR_MSK BIT(CRYPT_CON_FIFOODR_POS) - -#define CRYPT_CON_FIFOEN_POS 12U -#define CRYPT_CON_FIFOEN_MSK BIT(CRYPT_CON_FIFOEN_POS) - -#define CRYPT_CON_DESKS_POS 11U -#define CRYPT_CON_DESKS_MSK BIT(CRYPT_CON_DESKS_POS) - -#define CRYPT_CON_TDES_POS 10U -#define CRYPT_CON_TDES_MSK BIT(CRYPT_CON_TDES_POS) - -#define CRYPT_CON_TYPE_POSS 8U -#define CRYPT_CON_TYPE_POSE 9U -#define CRYPT_CON_TYPE_MSK BITS(CRYPT_CON_TYPE_POSS,CRYPT_CON_TYPE_POSE) - -#define CRYPT_CON_IE_POS 7U -#define CRYPT_CON_IE_MSK BIT(CRYPT_CON_IE_POS) - -#define CRYPT_CON_IVEN_POS 6U -#define CRYPT_CON_IVEN_MSK BIT(CRYPT_CON_IVEN_POS) - -#define CRYPT_CON_MODE_POSS 4U -#define CRYPT_CON_MODE_POSE 5U -#define CRYPT_CON_MODE_MSK BITS(CRYPT_CON_MODE_POSS,CRYPT_CON_MODE_POSE) - -#define CRYPT_CON_AESKS_POSS 2U -#define CRYPT_CON_AESKS_POSE 3U -#define CRYPT_CON_AESKS_MSK BITS(CRYPT_CON_AESKS_POSS,CRYPT_CON_AESKS_POSE) - -#define CRYPT_CON_ENCS_POS 1U -#define CRYPT_CON_ENCS_MSK BIT(CRYPT_CON_ENCS_POS) - -#define CRYPT_CON_GO_POS 0U -#define CRYPT_CON_GO_MSK BIT(CRYPT_CON_GO_POS) - -/****************** Bit definition for CRYPT_IF register ************************/ - -#define CRYPT_IF_DONE_POS 8U -#define CRYPT_IF_DONE_MSK BIT(CRYPT_IF_DONE_POS) - -#define CRYPT_IF_MULTHIF_POS 2U -#define CRYPT_IF_MULTHIF_MSK BIT(CRYPT_IF_MULTHIF_POS) - -#define CRYPT_IF_DESIF_POS 1U -#define CRYPT_IF_DESIF_MSK BIT(CRYPT_IF_DESIF_POS) - -#define CRYPT_IF_AESIF_POS 0U -#define CRYPT_IF_AESIF_MSK BIT(CRYPT_IF_AESIF_POS) - -/****************** Bit definition for CRYPT_IFC register ************************/ - -#define CRYPT_IFC_MULTHIFC_POS 2U -#define CRYPT_IFC_MULTHIFC_MSK BIT(CRYPT_IFC_MULTHIFC_POS) - -#define CRYPT_IFC_DESIFC_POS 1U -#define CRYPT_IFC_DESIFC_MSK BIT(CRYPT_IFC_DESIFC_POS) - -#define CRYPT_IFC_AESIFC_POS 0U -#define CRYPT_IFC_AESIFC_MSK BIT(CRYPT_IFC_AESIFC_POS) - -/****************** Bit definition for CRYPT_FIFO register ************************/ - -#define CRYPT_FIFO_FIFO_POSS 0U -#define CRYPT_FIFO_FIFO_POSE 31U -#define CRYPT_FIFO_FIFO_MSK BITS(CRYPT_FIFO_FIFO_POSS,CRYPT_FIFO_FIFO_POSE) - -typedef struct -{ - __IO uint32_t DATA[4]; - __IO uint32_t KEY[8]; - __IO uint32_t IV[4]; - __I uint32_t RES[4]; - __IO uint32_t CON; - __I uint32_t IF; - __O uint32_t IFC; - __IO uint32_t FIFO; -} CRYPT_TypeDef; - -/****************** Bit definition for LCD_CR register ************************/ - -#define LCD_CR_VCHPS_POSS 24U -#define LCD_CR_VCHPS_POSE 25U -#define LCD_CR_VCHPS_MSK BITS(LCD_CR_VCHPS_POSS,LCD_CR_VCHPS_POSE) - -#define LCD_CR_DSLD_POSS 20U -#define LCD_CR_DSLD_POSE 23U -#define LCD_CR_DSLD_MSK BITS(LCD_CR_DSLD_POSS,LCD_CR_DSLD_POSE) - -#define LCD_CR_DSHD_POSS 16U -#define LCD_CR_DSHD_POSE 19U -#define LCD_CR_DSHD_MSK BITS(LCD_CR_DSHD_POSS,LCD_CR_DSHD_POSE) - -#define LCD_CR_VBUFLD_POS 15U -#define LCD_CR_VBUFLD_MSK BIT(LCD_CR_VBUFLD_POS) - -#define LCD_CR_VBUFHD_POS 14U -#define LCD_CR_VBUFHD_MSK BIT(LCD_CR_VBUFHD_POS) - -#define LCD_CR_RESLD_POSS 12U -#define LCD_CR_RESLD_POSE 13U -#define LCD_CR_RESLD_MSK BITS(LCD_CR_RESLD_POSS,LCD_CR_RESLD_POSE) - -#define LCD_CR_RESHD_POSS 10U -#define LCD_CR_RESHD_POSE 11U -#define LCD_CR_RESHD_MSK BITS(LCD_CR_RESHD_POSS,LCD_CR_RESHD_POSE) - -#define LCD_CR_BIAS_POSS 8U -#define LCD_CR_BIAS_POSE 9U -#define LCD_CR_BIAS_MSK BITS(LCD_CR_BIAS_POSS,LCD_CR_BIAS_POSE) - -#define LCD_CR_DUTY_POSS 4U -#define LCD_CR_DUTY_POSE 6U -#define LCD_CR_DUTY_MSK BITS(LCD_CR_DUTY_POSS,LCD_CR_DUTY_POSE) - -#define LCD_CR_OE_POS 3U -#define LCD_CR_OE_MSK BIT(LCD_CR_OE_POS) - -#define LCD_CR_VSEL_POSS 1U -#define LCD_CR_VSEL_POSE 2U -#define LCD_CR_VSEL_MSK BITS(LCD_CR_VSEL_POSS,LCD_CR_VSEL_POSE) - -#define LCD_CR_EN_POS 0U -#define LCD_CR_EN_MSK BIT(LCD_CR_EN_POS) - -/****************** Bit definition for LCD_FCR register ************************/ - -#define LCD_FCR_WFS_POS 31U -#define LCD_FCR_WFS_MSK BIT(LCD_FCR_WFS_POS) - -#define LCD_FCR_PRS_POSS 24U -#define LCD_FCR_PRS_POSE 27U -#define LCD_FCR_PRS_MSK BITS(LCD_FCR_PRS_POSS,LCD_FCR_PRS_POSE) - -#define LCD_FCR_DIV_POSS 20U -#define LCD_FCR_DIV_POSE 23U -#define LCD_FCR_DIV_MSK BITS(LCD_FCR_DIV_POSS,LCD_FCR_DIV_POSE) - -#define LCD_FCR_BLMOD_POSS 16U -#define LCD_FCR_BLMOD_POSE 17U -#define LCD_FCR_BLMOD_MSK BITS(LCD_FCR_BLMOD_POSS,LCD_FCR_BLMOD_POSE) - -#define LCD_FCR_BLFRQ_POSS 12U -#define LCD_FCR_BLFRQ_POSE 14U -#define LCD_FCR_BLFRQ_MSK BITS(LCD_FCR_BLFRQ_POSS,LCD_FCR_BLFRQ_POSE) - -#define LCD_FCR_DEAD_POSS 8U -#define LCD_FCR_DEAD_POSE 10U -#define LCD_FCR_DEAD_MSK BITS(LCD_FCR_DEAD_POSS,LCD_FCR_DEAD_POSE) - -#define LCD_FCR_HD_POS 7U -#define LCD_FCR_HD_MSK BIT(LCD_FCR_HD_POS) - -#define LCD_FCR_PON_POSS 4U -#define LCD_FCR_PON_POSE 6U -#define LCD_FCR_PON_MSK BITS(LCD_FCR_PON_POSS,LCD_FCR_PON_POSE) - -#define LCD_FCR_VGS_POSS 0U -#define LCD_FCR_VGS_POSE 3U -#define LCD_FCR_VGS_MSK BITS(LCD_FCR_VGS_POSS,LCD_FCR_VGS_POSE) - -/****************** Bit definition for LCD_SEGCR0 register ************************/ - -#define LCD_SEGCR0_SEG_OE_POSS 0U -#define LCD_SEGCR0_SEG_OE_POSE 31U -#define LCD_SEGCR0_SEG_OE_MSK BITS(LCD_SEGCR0_SEG_OE_POSS,LCD_SEGCR0_SEG_OE_POSE) - -/****************** Bit definition for LCD_SEGCR1 register ************************/ - -#define LCD_SEGCR1_SEG_OE_POSS 0U -#define LCD_SEGCR1_SEG_OE_POSE 11U -#define LCD_SEGCR1_SEG_OE_MSK BITS(LCD_SEGCR1_SEG_OE_POSS,LCD_SEGCR1_SEG_OE_POSE) - -/****************** Bit definition for LCD_IE register ************************/ - -#define LCD_IE_UDDIE_POS 1U -#define LCD_IE_UDDIE_MSK BIT(LCD_IE_UDDIE_POS) - -#define LCD_IE_SOFIE_POS 0U -#define LCD_IE_SOFIE_MSK BIT(LCD_IE_SOFIE_POS) - -/****************** Bit definition for LCD_IF register ************************/ - -#define LCD_IF_UDDIF_POS 1U -#define LCD_IF_UDDIF_MSK BIT(LCD_IF_UDDIF_POS) - -#define LCD_IF_SOFIF_POS 0U -#define LCD_IF_SOFIF_MSK BIT(LCD_IF_SOFIF_POS) - -/****************** Bit definition for LCD_IFCR register ************************/ - -#define LCD_IFCR_UDDIFC_POS 1U -#define LCD_IFCR_UDDIFC_MSK BIT(LCD_IFCR_UDDIFC_POS) - -#define LCD_IFCR_SOFIFC_POS 0U -#define LCD_IFCR_SOFIFC_MSK BIT(LCD_IFCR_SOFIFC_POS) - -/****************** Bit definition for LCD_SR register ************************/ - -#define LCD_SR_FCRSF_POS 3U -#define LCD_SR_FCRSF_MSK BIT(LCD_SR_FCRSF_POS) - -#define LCD_SR_UDR_POS 2U -#define LCD_SR_UDR_MSK BIT(LCD_SR_UDR_POS) - -#define LCD_SR_ENS_POS 1U -#define LCD_SR_ENS_MSK BIT(LCD_SR_ENS_POS) - -#define LCD_SR_RDY_POS 0U -#define LCD_SR_RDY_MSK BIT(LCD_SR_RDY_POS) - -/****************** Bit definition for LCD_BUF register ************************/ - -#define LCD_BUF_SEG_DATA_POSS 0U -#define LCD_BUF_SEG_DATA_POSE 31U -#define LCD_BUF_SEG_DATA_MSK BITS(LCD_BUF_SEG_DATA_POSS,LCD_BUF_SEG_DATA_POSE) - -typedef struct -{ - __IO uint32_t CR; - __IO uint32_t FCR; - __IO uint32_t SEGCR0; - __IO uint32_t SEGCR1; - __IO uint32_t IE; - __I uint32_t IF; - __O uint32_t IFCR; - __I uint32_t SR; - uint32_t RESERVED0[8] ; - __IO uint32_t BUF[16]; -} LCD_TypeDef; - -/****************** Bit definition for ADC_STAT register ************************/ - -#define ADC_STAT_ICHS_POS 9U -#define ADC_STAT_ICHS_MSK BIT(ADC_STAT_ICHS_POS) - -#define ADC_STAT_NCHS_POS 8U -#define ADC_STAT_NCHS_MSK BIT(ADC_STAT_NCHS_POS) - -#define ADC_STAT_OVR_POS 3U -#define ADC_STAT_OVR_MSK BIT(ADC_STAT_OVR_POS) - -#define ADC_STAT_ICHE_POS 2U -#define ADC_STAT_ICHE_MSK BIT(ADC_STAT_ICHE_POS) - -#define ADC_STAT_NCHE_POS 1U -#define ADC_STAT_NCHE_MSK BIT(ADC_STAT_NCHE_POS) - -#define ADC_STAT_AWDF_POS 0U -#define ADC_STAT_AWDF_MSK BIT(ADC_STAT_AWDF_POS) - -/****************** Bit definition for ADC_CLR register ************************/ - -#define ADC_CLR_ICHS_POS 9U -#define ADC_CLR_ICHS_MSK BIT(ADC_CLR_ICHS_POS) - -#define ADC_CLR_NCHS_POS 8U -#define ADC_CLR_NCHS_MSK BIT(ADC_CLR_NCHS_POS) - -#define ADC_CLR_OVR_POS 3U -#define ADC_CLR_OVR_MSK BIT(ADC_CLR_OVR_POS) - -#define ADC_CLR_ICHE_POS 2U -#define ADC_CLR_ICHE_MSK BIT(ADC_CLR_ICHE_POS) - -#define ADC_CLR_NCHE_POS 1U -#define ADC_CLR_NCHE_MSK BIT(ADC_CLR_NCHE_POS) - -#define ADC_CLR_AWDF_POS 0U -#define ADC_CLR_AWDF_MSK BIT(ADC_CLR_AWDF_POS) - -/****************** Bit definition for ADC_CON0 register ************************/ - -#define ADC_CON0_OVRIE_POS 26U -#define ADC_CON0_OVRIE_MSK BIT(ADC_CON0_OVRIE_POS) - -#define ADC_CON0_RSEL_POSS 24U -#define ADC_CON0_RSEL_POSE 25U -#define ADC_CON0_RSEL_MSK BITS(ADC_CON0_RSEL_POSS,ADC_CON0_RSEL_POSE) - -#define ADC_CON0_NCHWDEN_POS 23U -#define ADC_CON0_NCHWDEN_MSK BIT(ADC_CON0_NCHWDEN_POS) - -#define ADC_CON0_ICHWDTEN_POS 22U -#define ADC_CON0_ICHWDTEN_MSK BIT(ADC_CON0_ICHWDTEN_POS) - -#define ADC_CON0_ETRGN_POSS 13U -#define ADC_CON0_ETRGN_POSE 15U -#define ADC_CON0_ETRGN_MSK BITS(ADC_CON0_ETRGN_POSS,ADC_CON0_ETRGN_POSE) - -#define ADC_CON0_ICHDCEN_POS 12U -#define ADC_CON0_ICHDCEN_MSK BIT(ADC_CON0_ICHDCEN_POS) - -#define ADC_CON0_NCHDCEN_POS 11U -#define ADC_CON0_NCHDCEN_MSK BIT(ADC_CON0_NCHDCEN_POS) - -#define ADC_CON0_IAUTO_POS 10U -#define ADC_CON0_IAUTO_MSK BIT(ADC_CON0_IAUTO_POS) - -#define ADC_CON0_AWDSGL_POS 9U -#define ADC_CON0_AWDSGL_MSK BIT(ADC_CON0_AWDSGL_POS) - -#define ADC_CON0_SCANEN_POS 8U -#define ADC_CON0_SCANEN_MSK BIT(ADC_CON0_SCANEN_POS) - -#define ADC_CON0_ICHEIE_POS 7U -#define ADC_CON0_ICHEIE_MSK BIT(ADC_CON0_ICHEIE_POS) - -#define ADC_CON0_AWDIE_POS 6U -#define ADC_CON0_AWDIE_MSK BIT(ADC_CON0_AWDIE_POS) - -#define ADC_CON0_NCHEIE_POS 5U -#define ADC_CON0_NCHEIE_MSK BIT(ADC_CON0_NCHEIE_POS) - -#define ADC_CON0_AWDCH_POSS 0U -#define ADC_CON0_AWDCH_POSE 4U -#define ADC_CON0_AWDCH_MSK BITS(ADC_CON0_AWDCH_POSS,ADC_CON0_AWDCH_POSE) - -/****************** Bit definition for ADC_CON1 register ************************/ - -#define ADC_CON1_NCHTRG_POS 30U -#define ADC_CON1_NCHTRG_MSK BIT(ADC_CON1_NCHTRG_POS) - -#define ADC_CON1_ICHTRG_POS 22U -#define ADC_CON1_ICHTRG_MSK BIT(ADC_CON1_ICHTRG_POS) - -#define ADC_CON1_ALIGN_POS 11U -#define ADC_CON1_ALIGN_MSK BIT(ADC_CON1_ALIGN_POS) - -#define ADC_CON1_NCHESEL_POS 10U -#define ADC_CON1_NCHESEL_MSK BIT(ADC_CON1_NCHESEL_POS) - -#define ADC_CON1_OVRDIS_POS 8U -#define ADC_CON1_OVRDIS_MSK BIT(ADC_CON1_OVRDIS_POS) - -#define ADC_CON1_CM_POS 1U -#define ADC_CON1_CM_MSK BIT(ADC_CON1_CM_POS) - -#define ADC_CON1_ADCEN_POS 0U -#define ADC_CON1_ADCEN_MSK BIT(ADC_CON1_ADCEN_POS) - -/****************** Bit definition for ADC_SMPT1 register ************************/ - -#define ADC_SMPT1_CHT_POSS 0U -#define ADC_SMPT1_CHT_POSE 31U -#define ADC_SMPT1_CHT_MSK BITS(ADC_SMPT1_CHT_POSS,ADC_SMPT1_CHT_POSE) - -/****************** Bit definition for ADC_SMPT2 register ************************/ - -#define ADC_SMPT2_CHT_POSS 0U -#define ADC_SMPT2_CHT_POSE 7U -#define ADC_SMPT2_CHT_MSK BITS(ADC_SMPT2_CHT_POSS,ADC_SMPT2_CHT_POSE) - -/****************** Bit definition for ADC_ICHOFF1 register ************************/ - -#define ADC_ICHOFF1_IOFF_POSS 0U -#define ADC_ICHOFF1_IOFF_POSE 11U -#define ADC_ICHOFF1_IOFF_MSK BITS(ADC_ICHOFF1_IOFF_POSS,ADC_ICHOFF1_IOFF_POSE) - -/****************** Bit definition for ADC_ICHOFF2 register ************************/ - -#define ADC_ICHOFF2_IOFF_POSS 0U -#define ADC_ICHOFF2_IOFF_POSE 11U -#define ADC_ICHOFF2_IOFF_MSK BITS(ADC_ICHOFF2_IOFF_POSS,ADC_ICHOFF2_IOFF_POSE) - -/****************** Bit definition for ADC_ICHOFF3 register ************************/ - -#define ADC_ICHOFF3_IOFF_POSS 0U -#define ADC_ICHOFF3_IOFF_POSE 11U -#define ADC_ICHOFF3_IOFF_MSK BITS(ADC_ICHOFF3_IOFF_POSS,ADC_ICHOFF3_IOFF_POSE) - -/****************** Bit definition for ADC_ICHOFF4 register ************************/ - -#define ADC_ICHOFF4_IOFF_POSS 0U -#define ADC_ICHOFF4_IOFF_POSE 11U -#define ADC_ICHOFF4_IOFF_MSK BITS(ADC_ICHOFF4_IOFF_POSS,ADC_ICHOFF4_IOFF_POSE) - -/****************** Bit definition for ADC_WDTH register ************************/ - -#define ADC_WDTH_HT_POSS 0U -#define ADC_WDTH_HT_POSE 11U -#define ADC_WDTH_HT_MSK BITS(ADC_WDTH_HT_POSS,ADC_WDTH_HT_POSE) - -/****************** Bit definition for ADC_WDTL register ************************/ - -#define ADC_WDTL_LT_POSS 0U -#define ADC_WDTL_LT_POSE 11U -#define ADC_WDTL_LT_MSK BITS(ADC_WDTL_LT_POSS,ADC_WDTL_LT_POSE) - -/****************** Bit definition for ADC_NCHS1 register ************************/ - -#define ADC_NCHS1_NS4_POSS 24U -#define ADC_NCHS1_NS4_POSE 28U -#define ADC_NCHS1_NS4_MSK BITS(ADC_NCHS1_NS4_POSS,ADC_NCHS1_NS4_POSE) - -#define ADC_NCHS1_NS3_POSS 16U -#define ADC_NCHS1_NS3_POSE 20U -#define ADC_NCHS1_NS3_MSK BITS(ADC_NCHS1_NS3_POSS,ADC_NCHS1_NS3_POSE) - -#define ADC_NCHS1_NS2_POSS 8U -#define ADC_NCHS1_NS2_POSE 12U -#define ADC_NCHS1_NS2_MSK BITS(ADC_NCHS1_NS2_POSS,ADC_NCHS1_NS2_POSE) - -#define ADC_NCHS1_NS1_POSS 0U -#define ADC_NCHS1_NS1_POSE 4U -#define ADC_NCHS1_NS1_MSK BITS(ADC_NCHS1_NS1_POSS,ADC_NCHS1_NS1_POSE) - -/****************** Bit definition for ADC_NCHS2 register ************************/ - -#define ADC_NCHS2_NS8_POSS 24U -#define ADC_NCHS2_NS8_POSE 28U -#define ADC_NCHS2_NS8_MSK BITS(ADC_NCHS2_NS8_POSS,ADC_NCHS2_NS8_POSE) - -#define ADC_NCHS2_NS7_POSS 16U -#define ADC_NCHS2_NS7_POSE 20U -#define ADC_NCHS2_NS7_MSK BITS(ADC_NCHS2_NS7_POSS,ADC_NCHS2_NS7_POSE) - -#define ADC_NCHS2_NS6_POSS 8U -#define ADC_NCHS2_NS6_POSE 12U -#define ADC_NCHS2_NS6_MSK BITS(ADC_NCHS2_NS6_POSS,ADC_NCHS2_NS6_POSE) - -#define ADC_NCHS2_NS5_POSS 0U -#define ADC_NCHS2_NS5_POSE 4U -#define ADC_NCHS2_NS5_MSK BITS(ADC_NCHS2_NS5_POSS,ADC_NCHS2_NS5_POSE) - -/****************** Bit definition for ADC_NCHS3 register ************************/ - -#define ADC_NCHS3_NS12_POSS 24U -#define ADC_NCHS3_NS12_POSE 28U -#define ADC_NCHS3_NS12_MSK BITS(ADC_NCHS3_NS12_POSS,ADC_NCHS3_NS12_POSE) - -#define ADC_NCHS3_NS11_POSS 16U -#define ADC_NCHS3_NS11_POSE 20U -#define ADC_NCHS3_NS11_MSK BITS(ADC_NCHS3_NS11_POSS,ADC_NCHS3_NS11_POSE) - -#define ADC_NCHS3_NS10_POSS 8U -#define ADC_NCHS3_NS10_POSE 12U -#define ADC_NCHS3_NS10_MSK BITS(ADC_NCHS3_NS10_POSS,ADC_NCHS3_NS10_POSE) - -#define ADC_NCHS3_NS9_POSS 0U -#define ADC_NCHS3_NS9_POSE 4U -#define ADC_NCHS3_NS9_MSK BITS(ADC_NCHS3_NS9_POSS,ADC_NCHS3_NS9_POSE) - -/****************** Bit definition for ADC_NCHS4 register ************************/ - -#define ADC_NCHS4_NS16_POSS 24U -#define ADC_NCHS4_NS16_POSE 28U -#define ADC_NCHS4_NS16_MSK BITS(ADC_NCHS4_NS16_POSS,ADC_NCHS4_NS16_POSE) - -#define ADC_NCHS4_NS15_POSS 16U -#define ADC_NCHS4_NS15_POSE 20U -#define ADC_NCHS4_NS15_MSK BITS(ADC_NCHS4_NS15_POSS,ADC_NCHS4_NS15_POSE) - -#define ADC_NCHS4_NS14_POSS 8U -#define ADC_NCHS4_NS14_POSE 12U -#define ADC_NCHS4_NS14_MSK BITS(ADC_NCHS4_NS14_POSS,ADC_NCHS4_NS14_POSE) - -#define ADC_NCHS4_NS13_POSS 0U -#define ADC_NCHS4_NS13_POSE 4U -#define ADC_NCHS4_NS13_MSK BITS(ADC_NCHS4_NS13_POSS,ADC_NCHS4_NS13_POSE) - -/****************** Bit definition for ADC_ICHS register ************************/ - -#define ADC_ICHS_IS4_POSS 24U -#define ADC_ICHS_IS4_POSE 28U -#define ADC_ICHS_IS4_MSK BITS(ADC_ICHS_IS4_POSS,ADC_ICHS_IS4_POSE) - -#define ADC_ICHS_IS3_POSS 16U -#define ADC_ICHS_IS3_POSE 20U -#define ADC_ICHS_IS3_MSK BITS(ADC_ICHS_IS3_POSS,ADC_ICHS_IS3_POSE) - -#define ADC_ICHS_IS2_POSS 8U -#define ADC_ICHS_IS2_POSE 12U -#define ADC_ICHS_IS2_MSK BITS(ADC_ICHS_IS2_POSS,ADC_ICHS_IS2_POSE) - -#define ADC_ICHS_IS1_POSS 0U -#define ADC_ICHS_IS1_POSE 4U -#define ADC_ICHS_IS1_MSK BITS(ADC_ICHS_IS1_POSS,ADC_ICHS_IS1_POSE) - -/****************** Bit definition for ADC_CHSL register ************************/ - -#define ADC_CHSL_ISL_POSS 8U -#define ADC_CHSL_ISL_POSE 9U -#define ADC_CHSL_ISL_MSK BITS(ADC_CHSL_ISL_POSS,ADC_CHSL_ISL_POSE) - -#define ADC_CHSL_NSL_POSS 0U -#define ADC_CHSL_NSL_POSE 3U -#define ADC_CHSL_NSL_MSK BITS(ADC_CHSL_NSL_POSS,ADC_CHSL_NSL_POSE) - -/****************** Bit definition for ADC_ICHDR1 register ************************/ - -#define ADC_ICHDR1_VAL_POSS 0U -#define ADC_ICHDR1_VAL_POSE 15U -#define ADC_ICHDR1_VAL_MSK BITS(ADC_ICHDR1_VAL_POSS,ADC_ICHDR1_VAL_POSE) - -/****************** Bit definition for ADC_ICHDR2 register ************************/ - -#define ADC_ICHDR2_VAL_POSS 0U -#define ADC_ICHDR2_VAL_POSE 15U -#define ADC_ICHDR2_VAL_MSK BITS(ADC_ICHDR2_VAL_POSS,ADC_ICHDR2_VAL_POSE) - -/****************** Bit definition for ADC_ICHDR3 register ************************/ - -#define ADC_ICHDR3_VAL_POSS 0U -#define ADC_ICHDR3_VAL_POSE 15U -#define ADC_ICHDR3_VAL_MSK BITS(ADC_ICHDR3_VAL_POSS,ADC_ICHDR3_VAL_POSE) - -/****************** Bit definition for ADC_ICHDR4 register ************************/ - -#define ADC_ICHDR4_VAL_POSS 0U -#define ADC_ICHDR4_VAL_POSE 15U -#define ADC_ICHDR4_VAL_MSK BITS(ADC_ICHDR4_VAL_POSS,ADC_ICHDR4_VAL_POSE) - -/****************** Bit definition for ADC_NCHDR register ************************/ - -#define ADC_NCHDR_VAL_POSS 0U -#define ADC_NCHDR_VAL_POSE 15U -#define ADC_NCHDR_VAL_MSK BITS(ADC_NCHDR_VAL_POSS,ADC_NCHDR_VAL_POSE) - -/****************** Bit definition for ADC_CCR register ************************/ - -#define ADC_CCR_TRMEN_POS 28U -#define ADC_CCR_TRMEN_MSK BIT(ADC_CCR_TRMEN_POS) - -#define ADC_CCR_GAINCALEN_POS 25U -#define ADC_CCR_GAINCALEN_MSK BIT(ADC_CCR_GAINCALEN_POS) - -#define ADC_CCR_OFFCALEN_POS 24U -#define ADC_CCR_OFFCALEN_MSK BIT(ADC_CCR_OFFCALEN_POS) - -#define ADC_CCR_VREFOEN_POS 19U -#define ADC_CCR_VREFOEN_MSK BIT(ADC_CCR_VREFOEN_POS) - -#define ADC_CCR_VRNSEL_POS 18U -#define ADC_CCR_VRNSEL_MSK BIT(ADC_CCR_VRNSEL_POS) - -#define ADC_CCR_VRPSEL_POSS 16U -#define ADC_CCR_VRPSEL_POSE 17U -#define ADC_CCR_VRPSEL_MSK BITS(ADC_CCR_VRPSEL_POSS,ADC_CCR_VRPSEL_POSE) - -#define ADC_CCR_PWRMODSEL_POS 15U -#define ADC_CCR_PWRMODSEL_MSK BIT(ADC_CCR_PWRMODSEL_POS) - -#define ADC_CCR_DIFFEN_POS 12U -#define ADC_CCR_DIFFEN_MSK BIT(ADC_CCR_DIFFEN_POS) - -#define ADC_CCR_IREFEN_POS 11U -#define ADC_CCR_IREFEN_MSK BIT(ADC_CCR_IREFEN_POS) - -#define ADC_CCR_VRBUFEN_POS 10U -#define ADC_CCR_VRBUFEN_MSK BIT(ADC_CCR_VRBUFEN_POS) - -#define ADC_CCR_VCMBUFEN_POS 9U -#define ADC_CCR_VCMBUFEN_MSK BIT(ADC_CCR_VCMBUFEN_POS) - -#define ADC_CCR_VREFEN_POS 8U -#define ADC_CCR_VREFEN_MSK BIT(ADC_CCR_VREFEN_POS) - -#define ADC_CCR_CKDIV_POSS 0U -#define ADC_CCR_CKDIV_POSE 2U -#define ADC_CCR_CKDIV_MSK BITS(ADC_CCR_CKDIV_POSS,ADC_CCR_CKDIV_POSE) - -typedef struct -{ - __I uint32_t STAT; - __O uint32_t CLR; - __IO uint32_t CON0; - __IO uint32_t CON1; - __IO uint32_t SMPT1; - __IO uint32_t SMPT2; - __IO uint32_t ICHOFF[4]; - __IO uint32_t WDTH; - __IO uint32_t WDTL; - __IO uint32_t NCHS1; - __IO uint32_t NCHS2; - __IO uint32_t NCHS3; - __IO uint32_t NCHS4; - __IO uint32_t ICHS; - __IO uint32_t CHSL; - __I uint32_t ICHDR[4]; - __I uint32_t NCHDR; - __IO uint32_t CCR; -} ADC_TypeDef; - -/****************** Bit definition for ACMP_CON register ************************/ - -#define ACMP_CON_FALLEN_POS 17U -#define ACMP_CON_FALLEN_MSK BIT(ACMP_CON_FALLEN_POS) - -#define ACMP_CON_RISEEN_POS 16U -#define ACMP_CON_RISEEN_MSK BIT(ACMP_CON_RISEEN_POS) - -#define ACMP_CON_MODSEL_POSS 14U -#define ACMP_CON_MODSEL_POSE 15U -#define ACMP_CON_MODSEL_MSK BITS(ACMP_CON_MODSEL_POSS,ACMP_CON_MODSEL_POSE) - -#define ACMP_CON_WARMUPT_POSS 8U -#define ACMP_CON_WARMUPT_POSE 10U -#define ACMP_CON_WARMUPT_MSK BITS(ACMP_CON_WARMUPT_POSS,ACMP_CON_WARMUPT_POSE) - -#define ACMP_CON_HYSTSEL_POSS 4U -#define ACMP_CON_HYSTSEL_POSE 6U -#define ACMP_CON_HYSTSEL_MSK BITS(ACMP_CON_HYSTSEL_POSS,ACMP_CON_HYSTSEL_POSE) - -#define ACMP_CON_OUTINV_POS 3U -#define ACMP_CON_OUTINV_MSK BIT(ACMP_CON_OUTINV_POS) - -#define ACMP_CON_INACTV_POS 2U -#define ACMP_CON_INACTV_MSK BIT(ACMP_CON_INACTV_POS) - -#define ACMP_CON_EN_POS 0U -#define ACMP_CON_EN_MSK BIT(ACMP_CON_EN_POS) - -/****************** Bit definition for ACMP_INPUTSEL register ************************/ - -#define ACMP_INPUTSEL_VDDLVL_POSS 8U -#define ACMP_INPUTSEL_VDDLVL_POSE 13U -#define ACMP_INPUTSEL_VDDLVL_MSK BITS(ACMP_INPUTSEL_VDDLVL_POSS,ACMP_INPUTSEL_VDDLVL_POSE) - -#define ACMP_INPUTSEL_NSEL_POSS 4U -#define ACMP_INPUTSEL_NSEL_POSE 7U -#define ACMP_INPUTSEL_NSEL_MSK BITS(ACMP_INPUTSEL_NSEL_POSS,ACMP_INPUTSEL_NSEL_POSE) - -#define ACMP_INPUTSEL_PSEL_POSS 0U -#define ACMP_INPUTSEL_PSEL_POSE 2U -#define ACMP_INPUTSEL_PSEL_MSK BITS(ACMP_INPUTSEL_PSEL_POSS,ACMP_INPUTSEL_PSEL_POSE) - -/****************** Bit definition for ACMP_STAT register ************************/ - -#define ACMP_STAT_OUT_POS 1U -#define ACMP_STAT_OUT_MSK BIT(ACMP_STAT_OUT_POS) - -#define ACMP_STAT_ACT_POS 0U -#define ACMP_STAT_ACT_MSK BIT(ACMP_STAT_ACT_POS) - -/****************** Bit definition for ACMP_IES register ************************/ - -#define ACMP_IES_WARMUP_POS 1U -#define ACMP_IES_WARMUP_MSK BIT(ACMP_IES_WARMUP_POS) - -#define ACMP_IES_EDGE_POS 0U -#define ACMP_IES_EDGE_MSK BIT(ACMP_IES_EDGE_POS) - -/****************** Bit definition for ACMP_IEV register ************************/ - -#define ACMP_IEV_WARMUP_POS 1U -#define ACMP_IEV_WARMUP_MSK BIT(ACMP_IEV_WARMUP_POS) - -#define ACMP_IEV_EDGE_POS 0U -#define ACMP_IEV_EDGE_MSK BIT(ACMP_IEV_EDGE_POS) - -/****************** Bit definition for ACMP_IEC register ************************/ - -#define ACMP_IEC_WARMUP_POS 1U -#define ACMP_IEC_WARMUP_MSK BIT(ACMP_IEC_WARMUP_POS) - -#define ACMP_IEC_EDGE_POS 0U -#define ACMP_IEC_EDGE_MSK BIT(ACMP_IEC_EDGE_POS) - -/****************** Bit definition for ACMP_RIF register ************************/ - -#define ACMP_RIF_WARMUP_POS 1U -#define ACMP_RIF_WARMUP_MSK BIT(ACMP_RIF_WARMUP_POS) - -#define ACMP_RIF_EDGE_POS 0U -#define ACMP_RIF_EDGE_MSK BIT(ACMP_RIF_EDGE_POS) - -/****************** Bit definition for ACMP_IFM register ************************/ - -#define ACMP_IFM_WARMUP_POS 1U -#define ACMP_IFM_WARMUP_MSK BIT(ACMP_IFM_WARMUP_POS) - -#define ACMP_IFM_EDGE_POS 0U -#define ACMP_IFM_EDGE_MSK BIT(ACMP_IFM_EDGE_POS) - -/****************** Bit definition for ACMP_IFC register ************************/ - -#define ACMP_IFC_WARMUP_POS 1U -#define ACMP_IFC_WARMUP_MSK BIT(ACMP_IFC_WARMUP_POS) - -#define ACMP_IFC_EDGE_POS 0U -#define ACMP_IFC_EDGE_MSK BIT(ACMP_IFC_EDGE_POS) - -/****************** Bit definition for ACMP_PORT register ************************/ - -#define ACMP_PORT_PEN_POS 0U -#define ACMP_PORT_PEN_MSK BIT(ACMP_PORT_PEN_POS) - -typedef struct -{ - __IO uint32_t CON; - __IO uint32_t INPUTSEL; - __I uint32_t STAT; - __O uint32_t IES; - __I uint32_t IEV; - __O uint32_t IEC; - __I uint32_t RIF; - __O uint32_t IFM; - __O uint32_t IFC; - __IO uint32_t PORT; -} ACMP_TypeDef; - -/****************** Bit definition for CALC_SQRTSR register ************************/ - -#define CALC_SQRTSR_BUSY_POS 0U -#define CALC_SQRTSR_BUSY_MSK BIT(CALC_SQRTSR_BUSY_POS) - -/****************** Bit definition for CALC_RDCND register ************************/ - -#define CALC_RDCND_RADICAND_POSS 0U -#define CALC_RDCND_RADICAND_POSE 31U -#define CALC_RDCND_RADICAND_MSK BITS(CALC_RDCND_RADICAND_POSS,CALC_RDCND_RADICAND_POSE) - -/****************** Bit definition for CALC_SQRTRES register ************************/ - -#define CALC_SQRTRES_RESULT_POSS 0U -#define CALC_SQRTRES_RESULT_POSE 15U -#define CALC_SQRTRES_RESULT_MSK BITS(CALC_SQRTRES_RESULT_POSS,CALC_SQRTRES_RESULT_POSE) - -/****************** Bit definition for CALC_DIVDR register ************************/ - -#define CALC_DIVDR_DIVD_POSS 0U -#define CALC_DIVDR_DIVD_POSE 31U -#define CALC_DIVDR_DIVD_MSK BITS(CALC_DIVDR_DIVD_POSS,CALC_DIVDR_DIVD_POSE) - -/****************** Bit definition for CALC_DIVSR register ************************/ - -#define CALC_DIVSR_DIVS_POSS 0U -#define CALC_DIVSR_DIVS_POSE 31U -#define CALC_DIVSR_DIVS_MSK BITS(CALC_DIVSR_DIVS_POSS,CALC_DIVSR_DIVS_POSE) - -/****************** Bit definition for CALC_DIVQR register ************************/ - -#define CALC_DIVQR_DIVQ_POSS 0U -#define CALC_DIVQR_DIVQ_POSE 31U -#define CALC_DIVQR_DIVQ_MSK BITS(CALC_DIVQR_DIVQ_POSS,CALC_DIVQR_DIVQ_POSE) - -/****************** Bit definition for CALC_DIVRR register ************************/ - -#define CALC_DIVRR_DIVS_POSS 0U -#define CALC_DIVRR_DIVS_POSE 31U -#define CALC_DIVRR_DIVS_MSK BITS(CALC_DIVRR_DIVS_POSS,CALC_DIVRR_DIVS_POSE) - -/****************** Bit definition for CALC_DIVCSR register ************************/ - -#define CALC_DIVCSR_TRM_POS 9U -#define CALC_DIVCSR_TRM_MSK BIT(CALC_DIVCSR_TRM_POS) - -#define CALC_DIVCSR_SIGN_POS 8U -#define CALC_DIVCSR_SIGN_MSK BIT(CALC_DIVCSR_SIGN_POS) - -#define CALC_DIVCSR_DZ_POS 1U -#define CALC_DIVCSR_DZ_MSK BIT(CALC_DIVCSR_DZ_POS) - -#define CALC_DIVCSR_BUSY_POS 0U -#define CALC_DIVCSR_BUSY_MSK BIT(CALC_DIVCSR_BUSY_POS) - -typedef struct -{ - __I uint32_t SQRTSR; - __IO uint32_t RDCND; - __I uint32_t SQRTRES; - uint32_t RESERVED0[5] ; - __IO uint32_t DIVDR; - __IO uint32_t DIVSR; - __I uint32_t DIVQR; - __I uint32_t DIVRR; - __IO uint32_t DIVCSR; -} CALC_TypeDef; - -/****************** Bit definition for TRNG_CR register ************************/ - -#define TRNG_CR_ADJC_POSS 16U -#define TRNG_CR_ADJC_POSE 17U -#define TRNG_CR_ADJC_MSK BITS(TRNG_CR_ADJC_POSS,TRNG_CR_ADJC_POSE) - -#define TRNG_CR_SDSEL_POSS 10U -#define TRNG_CR_SDSEL_POSE 11U -#define TRNG_CR_SDSEL_MSK BITS(TRNG_CR_SDSEL_POSS,TRNG_CR_SDSEL_POSE) - -#define TRNG_CR_DSEL_POSS 8U -#define TRNG_CR_DSEL_POSE 9U -#define TRNG_CR_DSEL_MSK BITS(TRNG_CR_DSEL_POSS,TRNG_CR_DSEL_POSE) - -#define TRNG_CR_POSTEN_POS 3U -#define TRNG_CR_POSTEN_MSK BIT(TRNG_CR_POSTEN_POS) - -#define TRNG_CR_TRNGSEL_POS 2U -#define TRNG_CR_TRNGSEL_MSK BIT(TRNG_CR_TRNGSEL_POS) - -#define TRNG_CR_ADJM_POS 1U -#define TRNG_CR_ADJM_MSK BIT(TRNG_CR_ADJM_POS) - -#define TRNG_CR_TRNGEN_POS 0U -#define TRNG_CR_TRNGEN_MSK BIT(TRNG_CR_TRNGEN_POS) - -/****************** Bit definition for TRNG_SR register ************************/ - -#define TRNG_SR_OVER_POS 3U -#define TRNG_SR_OVER_MSK BIT(TRNG_SR_OVER_POS) - -#define TRNG_SR_SERR_POS 2U -#define TRNG_SR_SERR_MSK BIT(TRNG_SR_SERR_POS) - -#define TRNG_SR_DAVLD_POS 1U -#define TRNG_SR_DAVLD_MSK BIT(TRNG_SR_DAVLD_POS) - -#define TRNG_SR_START_POS 0U -#define TRNG_SR_START_MSK BIT(TRNG_SR_START_POS) - -/****************** Bit definition for TRNG_DR register ************************/ - -#define TRNG_DR_DATA_POSS 0U -#define TRNG_DR_DATA_POSE 31U -#define TRNG_DR_DATA_MSK BITS(TRNG_DR_DATA_POSS,TRNG_DR_DATA_POSE) - -/****************** Bit definition for TRNG_SEED register ************************/ - -#define TRNG_SEED_SEED_POSS 0U -#define TRNG_SEED_SEED_POSE 31U -#define TRNG_SEED_SEED_MSK BITS(TRNG_SEED_SEED_POSS,TRNG_SEED_SEED_POSE) - -/****************** Bit definition for TRNG_CFGR register ************************/ - -#define TRNG_CFGR_TOPLMT_POSS 16U -#define TRNG_CFGR_TOPLMT_POSE 24U -#define TRNG_CFGR_TOPLMT_MSK BITS(TRNG_CFGR_TOPLMT_POSS,TRNG_CFGR_TOPLMT_POSE) - -#define TRNG_CFGR_CKDIV_POSS 8U -#define TRNG_CFGR_CKDIV_POSE 11U -#define TRNG_CFGR_CKDIV_MSK BITS(TRNG_CFGR_CKDIV_POSS,TRNG_CFGR_CKDIV_POSE) - -#define TRNG_CFGR_TSTART_POSS 0U -#define TRNG_CFGR_TSTART_POSE 2U -#define TRNG_CFGR_TSTART_MSK BITS(TRNG_CFGR_TSTART_POSS,TRNG_CFGR_TSTART_POSE) - -/****************** Bit definition for TRNG_IER register ************************/ - -#define TRNG_IER_SERR_POS 2U -#define TRNG_IER_SERR_MSK BIT(TRNG_IER_SERR_POS) - -#define TRNG_IER_DAVLD_POS 1U -#define TRNG_IER_DAVLD_MSK BIT(TRNG_IER_DAVLD_POS) - -#define TRNG_IER_START_POS 0U -#define TRNG_IER_START_MSK BIT(TRNG_IER_START_POS) - -/****************** Bit definition for TRNG_IFR register ************************/ - -#define TRNG_IFR_SERR_POS 2U -#define TRNG_IFR_SERR_MSK BIT(TRNG_IFR_SERR_POS) - -#define TRNG_IFR_DAVLD_POS 1U -#define TRNG_IFR_DAVLD_MSK BIT(TRNG_IFR_DAVLD_POS) - -#define TRNG_IFR_START_POS 0U -#define TRNG_IFR_START_MSK BIT(TRNG_IFR_START_POS) - -/****************** Bit definition for TRNG_IFCR register ************************/ - -#define TRNG_IFCR_SERRC_POS 2U -#define TRNG_IFCR_SERRC_MSK BIT(TRNG_IFCR_SERRC_POS) - -#define TRNG_IFCR_DAVLDC_POS 1U -#define TRNG_IFCR_DAVLDC_MSK BIT(TRNG_IFCR_DAVLDC_POS) - -#define TRNG_IFCR_STARTC_POS 0U -#define TRNG_IFCR_STARTC_MSK BIT(TRNG_IFCR_STARTC_POS) - -/****************** Bit definition for TRNG_ISR register ************************/ - -#define TRNG_ISR_SERR_POS 2U -#define TRNG_ISR_SERR_MSK BIT(TRNG_ISR_SERR_POS) - -#define TRNG_ISR_DAVLD_POS 1U -#define TRNG_ISR_DAVLD_MSK BIT(TRNG_ISR_DAVLD_POS) - -#define TRNG_ISR_START_POS 0U -#define TRNG_ISR_START_MSK BIT(TRNG_ISR_START_POS) - -typedef struct -{ - __IO uint32_t CR; - __I uint32_t SR; - __I uint32_t DR; - __IO uint32_t SEED; - __IO uint32_t CFGR; - __IO uint32_t IER; - __I uint32_t IFR; - __O uint32_t IFCR; - __I uint32_t ISR; -} TRNG_TypeDef; - -/****************** Bit definition for TEMP_WPR register ************************/ - -#define TEMP_WPR_WP_POS 0U -#define TEMP_WPR_WP_MSK BIT(TEMP_WPR_WP_POS) - -/****************** Bit definition for TEMP_CR register ************************/ - -#define TEMP_CR_TSU_POSS 12U -#define TEMP_CR_TSU_POSE 14U -#define TEMP_CR_TSU_MSK BITS(TEMP_CR_TSU_POSS,TEMP_CR_TSU_POSE) - -#define TEMP_CR_TOM_POSS 8U -#define TEMP_CR_TOM_POSE 10U -#define TEMP_CR_TOM_MSK BITS(TEMP_CR_TOM_POSS,TEMP_CR_TOM_POSE) - -#define TEMP_CR_CTN_POS 4U -#define TEMP_CR_CTN_MSK BIT(TEMP_CR_CTN_POS) - -#define TEMP_CR_RST_POS 3U -#define TEMP_CR_RST_MSK BIT(TEMP_CR_RST_POS) - -#define TEMP_CR_ENS_POS 2U -#define TEMP_CR_ENS_MSK BIT(TEMP_CR_ENS_POS) - -#define TEMP_CR_REQEN_POS 1U -#define TEMP_CR_REQEN_MSK BIT(TEMP_CR_REQEN_POS) - -#define TEMP_CR_EN_POS 0U -#define TEMP_CR_EN_MSK BIT(TEMP_CR_EN_POS) - -/****************** Bit definition for TEMP_DR register ************************/ - -#define TEMP_DR_ERR_POS 31U -#define TEMP_DR_ERR_MSK BIT(TEMP_DR_ERR_POS) - -#define TEMP_DR_DATA_POSS 0U -#define TEMP_DR_DATA_POSE 15U -#define TEMP_DR_DATA_MSK BITS(TEMP_DR_DATA_POSS,TEMP_DR_DATA_POSE) - -/****************** Bit definition for TEMP_PSR register ************************/ - -#define TEMP_PSR_PRS_POSS 0U -#define TEMP_PSR_PRS_POSE 7U -#define TEMP_PSR_PRS_MSK BITS(TEMP_PSR_PRS_POSS,TEMP_PSR_PRS_POSE) - -/****************** Bit definition for TEMP_IE register ************************/ - -#define TEMP_IE_TEMP_POS 0U -#define TEMP_IE_TEMP_MSK BIT(TEMP_IE_TEMP_POS) - -/****************** Bit definition for TEMP_IF register ************************/ - -#define TEMP_IF_TEMP_POS 0U -#define TEMP_IF_TEMP_MSK BIT(TEMP_IF_TEMP_POS) - -/****************** Bit definition for TEMP_IFCR register ************************/ - -#define TEMP_IFCR_TEMP_POS 0U -#define TEMP_IFCR_TEMP_MSK BIT(TEMP_IFCR_TEMP_POS) - -/****************** Bit definition for TEMP_LTGR register ************************/ - -#define TEMP_LTGR_LTG_POSS 0U -#define TEMP_LTGR_LTG_POSE 20U -#define TEMP_LTGR_LTG_MSK BITS(TEMP_LTGR_LTG_POSS,TEMP_LTGR_LTG_POSE) - -/****************** Bit definition for TEMP_HTGR register ************************/ - -#define TEMP_HTGR_HTG_POSS 0U -#define TEMP_HTGR_HTG_POSE 20U -#define TEMP_HTGR_HTG_MSK BITS(TEMP_HTGR_HTG_POSS,TEMP_HTGR_HTG_POSE) - -/****************** Bit definition for TEMP_TBDR register ************************/ - -#define TEMP_TBDR_TBD_POSS 0U -#define TEMP_TBDR_TBD_POSE 15U -#define TEMP_TBDR_TBD_MSK BITS(TEMP_TBDR_TBD_POSS,TEMP_TBDR_TBD_POSE) - -/****************** Bit definition for TEMP_TCALBDR register ************************/ - -#define TEMP_TCALBDR_TCAL_POSS 0U -#define TEMP_TCALBDR_TCAL_POSE 16U -#define TEMP_TCALBDR_TCAL_MSK BITS(TEMP_TCALBDR_TCAL_POSS,TEMP_TCALBDR_TCAL_POSE) - -/****************** Bit definition for TEMP_SR register ************************/ - -#define TEMP_SR_TSOUT_POS 31U -#define TEMP_SR_TSOUT_MSK BIT(TEMP_SR_TSOUT_POS) - -#define TEMP_SR_NVLD_POS 25U -#define TEMP_SR_NVLD_MSK BIT(TEMP_SR_NVLD_POS) - -#define TEMP_SR_TCAL_POSS 0U -#define TEMP_SR_TCAL_POSE 24U -#define TEMP_SR_TCAL_MSK BITS(TEMP_SR_TCAL_POSS,TEMP_SR_TCAL_POSE) - -typedef struct -{ - __IO uint32_t WPR; - __IO uint32_t CR; - __I uint32_t DR; - __IO uint32_t PSR; - __IO uint32_t IE; - __I uint32_t IF; - __IO uint32_t IFCR; - __IO uint32_t LTGR; - __IO uint32_t HTGR; - __IO uint32_t TBDR; - __IO uint32_t TCALBDR; - __I uint32_t SR; -} TEMP_TypeDef; - -/****************** Bit definition for IWDT_LOAD register ************************/ - -#define IWDT_LOAD_LOAD_POSS 0U -#define IWDT_LOAD_LOAD_POSE 31U -#define IWDT_LOAD_LOAD_MSK BITS(IWDT_LOAD_LOAD_POSS,IWDT_LOAD_LOAD_POSE) - -/****************** Bit definition for IWDT_VALUE register ************************/ - -#define IWDT_VALUE_VALUE_POSS 0U -#define IWDT_VALUE_VALUE_POSE 31U -#define IWDT_VALUE_VALUE_MSK BITS(IWDT_VALUE_VALUE_POSS,IWDT_VALUE_VALUE_POSE) - -/****************** Bit definition for IWDT_CON register ************************/ - -#define IWDT_CON_CLKS_POS 3U -#define IWDT_CON_CLKS_MSK BIT(IWDT_CON_CLKS_POS) - -#define IWDT_CON_RSTEN_POS 2U -#define IWDT_CON_RSTEN_MSK BIT(IWDT_CON_RSTEN_POS) - -#define IWDT_CON_IE_POS 1U -#define IWDT_CON_IE_MSK BIT(IWDT_CON_IE_POS) - -#define IWDT_CON_EN_POS 0U -#define IWDT_CON_EN_MSK BIT(IWDT_CON_EN_POS) - -/****************** Bit definition for IWDT_INTCLR register ************************/ - -#define IWDT_INTCLR_INTCLR_POSS 0U -#define IWDT_INTCLR_INTCLR_POSE 31U -#define IWDT_INTCLR_INTCLR_MSK BITS(IWDT_INTCLR_INTCLR_POSS,IWDT_INTCLR_INTCLR_POSE) - -/****************** Bit definition for IWDT_RIS register ************************/ - -#define IWDT_RIS_WDTIF_POS 0U -#define IWDT_RIS_WDTIF_MSK BIT(IWDT_RIS_WDTIF_POS) - -/****************** Bit definition for IWDT_LOCK register ************************/ - -#define IWDT_LOCK_LOCK_POS 0U -#define IWDT_LOCK_LOCK_MSK BIT(IWDT_LOCK_LOCK_POS) - -typedef struct -{ - __O uint32_t LOAD; - __I uint32_t VALUE; - __IO uint32_t CON; - __O uint32_t INTCLR; - __I uint32_t RIS; - uint32_t RESERVED0[59] ; - __IO uint32_t LOCK; -} IWDT_TypeDef; - -/****************** Bit definition for WWDT_LOAD register ************************/ - -#define WWDT_LOAD_LOAD_POSS 0U -#define WWDT_LOAD_LOAD_POSE 31U -#define WWDT_LOAD_LOAD_MSK BITS(WWDT_LOAD_LOAD_POSS,WWDT_LOAD_LOAD_POSE) - -/****************** Bit definition for WWDT_VALUE register ************************/ - -#define WWDT_VALUE_VALUE_POSS 0U -#define WWDT_VALUE_VALUE_POSE 31U -#define WWDT_VALUE_VALUE_MSK BITS(WWDT_VALUE_VALUE_POSS,WWDT_VALUE_VALUE_POSE) - -/****************** Bit definition for WWDT_CON register ************************/ - -#define WWDT_CON_WWDTWIN_POSS 4U -#define WWDT_CON_WWDTWIN_POSE 5U -#define WWDT_CON_WWDTWIN_MSK BITS(WWDT_CON_WWDTWIN_POSS,WWDT_CON_WWDTWIN_POSE) - -#define WWDT_CON_CLKS_POS 3U -#define WWDT_CON_CLKS_MSK BIT(WWDT_CON_CLKS_POS) - -#define WWDT_CON_RSTEN_POS 2U -#define WWDT_CON_RSTEN_MSK BIT(WWDT_CON_RSTEN_POS) - -#define WWDT_CON_IE_POS 1U -#define WWDT_CON_IE_MSK BIT(WWDT_CON_IE_POS) - -#define WWDT_CON_EN_POS 0U -#define WWDT_CON_EN_MSK BIT(WWDT_CON_EN_POS) - -/****************** Bit definition for WWDT_INTCLR register ************************/ - -#define WWDT_INTCLR_INTCLR_POSS 0U -#define WWDT_INTCLR_INTCLR_POSE 31U -#define WWDT_INTCLR_INTCLR_MSK BITS(WWDT_INTCLR_INTCLR_POSS,WWDT_INTCLR_INTCLR_POSE) - -/****************** Bit definition for WWDT_RIS register ************************/ - -#define WWDT_RIS_WWDTIF_POS 0U -#define WWDT_RIS_WWDTIF_MSK BIT(WWDT_RIS_WWDTIF_POS) - -/****************** Bit definition for WWDT_LOCK register ************************/ - -#define WWDT_LOCK_LOCK_POS 0U -#define WWDT_LOCK_LOCK_MSK BIT(WWDT_LOCK_LOCK_POS) - -typedef struct -{ - __O uint32_t LOAD; - __I uint32_t VALUE; - __IO uint32_t CON; - __O uint32_t INTCLR; - __I uint32_t RIS; - uint32_t RESERVED0[59]; - __IO uint32_t LOCK; -} WWDT_TypeDef; - -/****************** Bit definition for LP16T_CON0 register ************************/ - -#define LP16T_CON0_PRELOAD_POS 22U -#define LP16T_CON0_PRELOAD_MSK BIT(LP16T_CON0_PRELOAD_POS) - -#define LP16T_CON0_WAVEPOL_POS 21U -#define LP16T_CON0_WAVEPOL_MSK BIT(LP16T_CON0_WAVEPOL_POS) - -#define LP16T_CON0_WAVE_POSS 19U -#define LP16T_CON0_WAVE_POSE 20U -#define LP16T_CON0_WAVE_MSK BITS(LP16T_CON0_WAVE_POSS,LP16T_CON0_WAVE_POSE) - -#define LP16T_CON0_TRIGEN_POSS 17U -#define LP16T_CON0_TRIGEN_POSE 18U -#define LP16T_CON0_TRIGEN_MSK BITS(LP16T_CON0_TRIGEN_POSS,LP16T_CON0_TRIGEN_POSE) - -#define LP16T_CON0_TRIGSEL_POSS 13U -#define LP16T_CON0_TRIGSEL_POSE 15U -#define LP16T_CON0_TRIGSEL_MSK BITS(LP16T_CON0_TRIGSEL_POSS,LP16T_CON0_TRIGSEL_POSE) - -#define LP16T_CON0_PRESC_POSS 9U -#define LP16T_CON0_PRESC_POSE 11U -#define LP16T_CON0_PRESC_MSK BITS(LP16T_CON0_PRESC_POSS,LP16T_CON0_PRESC_POSE) - -#define LP16T_CON0_TRGFLT_POSS 6U -#define LP16T_CON0_TRGFLT_POSE 7U -#define LP16T_CON0_TRGFLT_MSK BITS(LP16T_CON0_TRGFLT_POSS,LP16T_CON0_TRGFLT_POSE) - -#define LP16T_CON0_CKFLT_POSS 3U -#define LP16T_CON0_CKFLT_POSE 4U -#define LP16T_CON0_CKFLT_MSK BITS(LP16T_CON0_CKFLT_POSS,LP16T_CON0_CKFLT_POSE) - -#define LP16T_CON0_CKPOL_POS 1U -#define LP16T_CON0_CKPOL_MSK BIT(LP16T_CON0_CKPOL_POS) - -#define LP16T_CON0_CKSEL_POS 0U -#define LP16T_CON0_CKSEL_MSK BIT(LP16T_CON0_CKSEL_POS) - -/****************** Bit definition for LP16T_CON1 register ************************/ - -#define LP16T_CON1_CNTSTRT_POS 2U -#define LP16T_CON1_CNTSTRT_MSK BIT(LP16T_CON1_CNTSTRT_POS) - -#define LP16T_CON1_SNGSTRT_POS 1U -#define LP16T_CON1_SNGSTRT_MSK BIT(LP16T_CON1_SNGSTRT_POS) - -#define LP16T_CON1_ENABLE_POS 0U -#define LP16T_CON1_ENABLE_MSK BIT(LP16T_CON1_ENABLE_POS) - -/****************** Bit definition for LP16T_ARR register ************************/ - -#define LP16T_ARR_ARR_POSS 0U -#define LP16T_ARR_ARR_POSE 15U -#define LP16T_ARR_ARR_MSK BITS(LP16T_ARR_ARR_POSS,LP16T_ARR_ARR_POSE) - -/****************** Bit definition for LP16T_CNT register ************************/ - -#define LP16T_CNT_CNT_POSS 0U -#define LP16T_CNT_CNT_POSE 15U -#define LP16T_CNT_CNT_MSK BITS(LP16T_CNT_CNT_POSS,LP16T_CNT_CNT_POSE) - -/****************** Bit definition for LP16T_CMP register ************************/ - -#define LP16T_CMP_CMP_POSS 0U -#define LP16T_CMP_CMP_POSE 15U -#define LP16T_CMP_CMP_MSK BITS(LP16T_CMP_CMP_POSS,LP16T_CMP_CMP_POSE) - -/****************** Bit definition for LP16T_IER register ************************/ - -#define LP16T_IER_EXTTRIGIE_POS 2U -#define LP16T_IER_EXTTRIGIE_MSK BIT(LP16T_IER_EXTTRIGIE_POS) - -#define LP16T_IER_ARRMIE_POS 1U -#define LP16T_IER_ARRMIE_MSK BIT(LP16T_IER_ARRMIE_POS) - -#define LP16T_IER_CMPMIE_POS 0U -#define LP16T_IER_CMPMIE_MSK BIT(LP16T_IER_CMPMIE_POS) - -/****************** Bit definition for LP16T_ISR register ************************/ - -#define LP16T_ISR_EXTTRIG_POS 2U -#define LP16T_ISR_EXTTRIG_MSK BIT(LP16T_ISR_EXTTRIG_POS) - -#define LP16T_ISR_ARRM_POS 1U -#define LP16T_ISR_ARRM_MSK BIT(LP16T_ISR_ARRM_POS) - -#define LP16T_ISR_CMPM_POS 0U -#define LP16T_ISR_CMPM_MSK BIT(LP16T_ISR_CMPM_POS) - -/****************** Bit definition for LP16T_IFC register ************************/ - -#define LP16T_IFC_EXTTRIG_POS 2U -#define LP16T_IFC_EXTTRIG_MSK BIT(LP16T_IFC_EXTTRIG_POS) - -#define LP16T_IFC_ARRM_POS 1U -#define LP16T_IFC_ARRM_MSK BIT(LP16T_IFC_ARRM_POS) - -#define LP16T_IFC_CMPM_POS 0U -#define LP16T_IFC_CMPM_MSK BIT(LP16T_IFC_CMPM_POS) - -/****************** Bit definition for LP16T_UPDATE register ************************/ - -#define LP16T_UPDATE_UDIS_POS 0U -#define LP16T_UPDATE_UDIS_MSK BIT(LP16T_UPDATE_UDIS_POS) - -/****************** Bit definition for LP16T_SYNCSTAT register ************************/ - -#define LP16T_SYNCSTAT_CMPWBSY_POS 3U -#define LP16T_SYNCSTAT_CMPWBSY_MSK BIT(LP16T_SYNCSTAT_CMPWBSY_POS) - -#define LP16T_SYNCSTAT_ARRWBSY_POS 2U -#define LP16T_SYNCSTAT_ARRWBSY_MSK BIT(LP16T_SYNCSTAT_ARRWBSY_POS) - -#define LP16T_SYNCSTAT_CON1WBSY_POS 1U -#define LP16T_SYNCSTAT_CON1WBSY_MSK BIT(LP16T_SYNCSTAT_CON1WBSY_POS) - -typedef struct -{ - __IO uint32_t CON0; - __IO uint32_t CON1; - __IO uint32_t ARR; - __I uint32_t CNT; - __IO uint32_t CMP; - uint32_t RESERVED0 ; - __IO uint32_t IER; - __I uint32_t ISR; - __O uint32_t IFC; - uint32_t RESERVED1[3] ; - __IO uint32_t UPDATE; - __I uint32_t SYNCSTAT; -} LPTIM_TypeDef; - -/****************** Bit definition for DBGC_IDCODE register ************************/ - -#define DBGC_IDCODE_REV_ID_POSS 16U -#define DBGC_IDCODE_REV_ID_POSE 31U -#define DBGC_IDCODE_REV_ID_MSK BITS(DBGC_IDCODE_REV_ID_POSS,DBGC_IDCODE_REV_ID_POSE) - -#define DBGC_IDCODE_CORE_ID_POSS 12U -#define DBGC_IDCODE_CORE_ID_POSE 15U -#define DBGC_IDCODE_CORE_ID_MSK BITS(DBGC_IDCODE_CORE_ID_POSS,DBGC_IDCODE_CORE_ID_POSE) - -#define DBGC_IDCODE_DEV_ID_POSS 0U -#define DBGC_IDCODE_DEV_ID_POSE 11U -#define DBGC_IDCODE_DEV_ID_MSK BITS(DBGC_IDCODE_DEV_ID_POSS,DBGC_IDCODE_DEV_ID_POSE) - -/****************** Bit definition for DBGC_CR register ************************/ - -#define DBGC_CR_DBG_STANDBY_POS 3U -#define DBGC_CR_DBG_STANDBY_MSK BIT(DBGC_CR_DBG_STANDBY_POS) - -#define DBGC_CR_DBG_STOP2_POS 2U -#define DBGC_CR_DBG_STOP2_MSK BIT(DBGC_CR_DBG_STOP2_POS) - -#define DBGC_CR_DBG_STOP1_POS 1U -#define DBGC_CR_DBG_STOP1_MSK BIT(DBGC_CR_DBG_STOP1_POS) - -#define DBGC_CR_DBG_SLEEP_POS 0U -#define DBGC_CR_DBG_SLEEP_MSK BIT(DBGC_CR_DBG_SLEEP_POS) - -/****************** Bit definition for DBGC_APB1FZ register ************************/ - -#define DBGC_APB1FZ_CAN_STOP_POS 12U -#define DBGC_APB1FZ_CAN_STOP_MSK BIT(DBGC_APB1FZ_CAN_STOP_POS) - -#define DBGC_APB1FZ_I2C1_SMBUS_TO_POS 9U -#define DBGC_APB1FZ_I2C1_SMBUS_TO_MSK BIT(DBGC_APB1FZ_I2C1_SMBUS_TO_POS) - -#define DBGC_APB1FZ_I2C0_SMBUS_TO_POS 8U -#define DBGC_APB1FZ_I2C0_SMBUS_TO_MSK BIT(DBGC_APB1FZ_I2C0_SMBUS_TO_POS) - -#define DBGC_APB1FZ_TIM7_STOP_POS 7U -#define DBGC_APB1FZ_TIM7_STOP_MSK BIT(DBGC_APB1FZ_TIM7_STOP_POS) - -#define DBGC_APB1FZ_TIM6_STOP_POS 6U -#define DBGC_APB1FZ_TIM6_STOP_MSK BIT(DBGC_APB1FZ_TIM6_STOP_POS) - -#define DBGC_APB1FZ_TIM5_STOP_POS 5U -#define DBGC_APB1FZ_TIM5_STOP_MSK BIT(DBGC_APB1FZ_TIM5_STOP_POS) - -#define DBGC_APB1FZ_TIM4_STOP_POS 4U -#define DBGC_APB1FZ_TIM4_STOP_MSK BIT(DBGC_APB1FZ_TIM4_STOP_POS) - -#define DBGC_APB1FZ_TIM3_STOP_POS 3U -#define DBGC_APB1FZ_TIM3_STOP_MSK BIT(DBGC_APB1FZ_TIM3_STOP_POS) - -#define DBGC_APB1FZ_TIM2_STOP_POS 2U -#define DBGC_APB1FZ_TIM2_STOP_MSK BIT(DBGC_APB1FZ_TIM2_STOP_POS) - -#define DBGC_APB1FZ_TIM1_STOP_POS 1U -#define DBGC_APB1FZ_TIM1_STOP_MSK BIT(DBGC_APB1FZ_TIM1_STOP_POS) - -#define DBGC_APB1FZ_TIM0_STOP_POS 0U -#define DBGC_APB1FZ_TIM0_STOP_MSK BIT(DBGC_APB1FZ_TIM0_STOP_POS) - -/****************** Bit definition for DBGC_APB2FZ register ************************/ - -#define DBGC_APB2FZ_RTC_STOP_POS 10U -#define DBGC_APB2FZ_RTC_STOP_MSK BIT(DBGC_APB2FZ_RTC_STOP_POS) - -#define DBGC_APB2FZ_WWDT_STOP_POS 9U -#define DBGC_APB2FZ_WWDT_STOP_MSK BIT(DBGC_APB2FZ_WWDT_STOP_POS) - -#define DBGC_APB2FZ_IWDT_STOP_POS 8U -#define DBGC_APB2FZ_IWDT_STOP_MSK BIT(DBGC_APB2FZ_IWDT_STOP_POS) - -#define DBGC_APB2FZ_LPTIM0_STOP_POS 0U -#define DBGC_APB2FZ_LPTIM0_STOP_MSK BIT(DBGC_APB2FZ_LPTIM0_STOP_POS) - -typedef struct -{ - __I uint32_t IDCODE; - __IO uint32_t CR; - __IO uint32_t APB1FZ; - __IO uint32_t APB2FZ; -} DBGC_TypeDef; - - -/* Base addresses */ -#define SRAM_BASE (0x20000000UL) -#define APB1_BASE (0x40000000UL) -#define APB2_BASE (0x40040000UL) -#define AHB_BASE (0x40080000UL) - -/* Timer memory map */ -#define TIMER0_BASE (APB1_BASE + 0x0000) -#define TIMER1_BASE (APB1_BASE + 0x0400) -#define TIMER2_BASE (APB1_BASE + 0x0800) -#define TIMER3_BASE (APB1_BASE + 0x0C00) -#define TIMER4_BASE (APB1_BASE + 0x1000) -#define TIMER5_BASE (APB1_BASE + 0x1400) -#define TIMER6_BASE (APB1_BASE + 0x1800) -#define TIMER7_BASE (APB1_BASE + 0x1C00) - -/* SPI memory map */ -#define SPI0_BASE (APB1_BASE + 0x6000) -#define SPI1_BASE (APB1_BASE + 0x6400) -#define SPI2_BASE (APB1_BASE + 0x6800) - -/* I2C memory map */ -#define I2C0_BASE (APB1_BASE + 0x8000) -#define I2C1_BASE (APB1_BASE + 0x8400) - -/* AHB peripherals */ -#define SYSTEM_BASE (AHB_BASE + 0x0000) -#define GPIOA_BASE (AHB_BASE + 0x4000) -#define GPIOB_BASE (AHB_BASE + 0x4040) -#define GPIOC_BASE (AHB_BASE + 0x4080) -#define GPIOD_BASE (AHB_BASE + 0x40C0) -#define GPIOE_BASE (AHB_BASE + 0x4100) -#define GPIOF_BASE (AHB_BASE + 0x4140) -#define GPIOG_BASE (AHB_BASE + 0x4180) -#define GPIOH_BASE (AHB_BASE + 0x41C0) -#define EXTI_BASE (AHB_BASE + 0x4300) -#define CRC_BASE (AHB_BASE + 0x5000) -#define CALC_BASE (AHB_BASE + 0x5400) -#define TRNG_BASE (AHB_BASE + 0x5C00) -#define CRYPT_BASE (AHB_BASE + 0x5800) - -#define SYSCFG_BASE (SYSTEM_BASE + 0x0000) -#define CMU_BASE (SYSTEM_BASE + 0x0400) -#define RMU_BASE (SYSTEM_BASE + 0x0800) -#define PMU_BASE (SYSTEM_BASE + 0x0C00) -#define MSC_BASE (SYSTEM_BASE + 0x1000) -#define PIS_BASE (SYSTEM_BASE + 0x6000) - -/* APB1 peripherals */ -#define CAN0_BASE (APB1_BASE + 0xB000) -#define USART0_BASE (APB1_BASE + 0x5000) -#define USART1_BASE (APB1_BASE + 0x5400) -#define UART0_BASE (APB1_BASE + 0x4000) -#define UART1_BASE (APB1_BASE + 0x4400) -#define UART2_BASE (APB1_BASE + 0x4800) -#define UART3_BASE (APB1_BASE + 0x4C00) -#define DMA0_BASE (APB1_BASE + 0xC000) - -/* APB2 peripherals */ -#define LPTIM0_BASE (APB2_BASE + 0x0000) -#define LPUART0_BASE (APB2_BASE + 0x1000) -#define DBGC_BASE (APB2_BASE + 0xA000) -#define WWDT_BASE (APB2_BASE + 0x6000) -#define IWDT_BASE (APB2_BASE + 0x6400) -#define RTC_BASE (APB2_BASE + 0x8400) -#define LCD_BASE (APB2_BASE + 0x7000) -#define ADC0_BASE (APB2_BASE + 0x2000) -#define ADC1_BASE (APB2_BASE + 0x2400) -#define ACMP0_BASE (APB2_BASE + 0x3000) -#define ACMP1_BASE (APB2_BASE + 0x3400) -#define OPAMP_BASE (APB2_BASE + 0x4000) -#define DAC0_BASE (APB2_BASE + 0x5000) -#define BKPC_BASE (APB2_BASE + 0x8000) -#define TEMP_BASE (APB2_BASE + 0x8800) - -/* RTC Peripheral declaration */ -#define RTC ((RTC_TypeDef *)RTC_BASE) - -/* GPIO Peripheral_declaration */ -#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE) -#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE) -#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE) -#define GPIOD ((GPIO_TypeDef *)GPIOD_BASE) -#define GPIOE ((GPIO_TypeDef *)GPIOE_BASE) -#define GPIOF ((GPIO_TypeDef *)GPIOF_BASE) -#define GPIOG ((GPIO_TypeDef *)GPIOG_BASE) -#define GPIOH ((GPIO_TypeDef *)GPIOH_BASE) -#define EXTI ((EXTI_TypeDef *)EXTI_BASE) - -#define CRC ((CRC_TypeDef *)CRC_BASE) -#define TRNG ((TRNG_TypeDef *)TRNG_BASE) -#define CALC ((CALC_TypeDef *)CALC_BASE) -#define CRYPT ((CRYPT_TypeDef *)CRYPT_BASE) -#define PIS ((PIS_TypeDef *)PIS_BASE) - -/* LCD Peripheral declaration */ -#define LCD ((LCD_TypeDef *)LCD_BASE) -/* ADC Peripheral declaration */ -#define ADC0 ((ADC_TypeDef *)ADC0_BASE) -#define ADC1 ((ADC_TypeDef *)ADC1_BASE) -/* ACMP Peripheral declaration */ -#define ACMP0 ((ACMP_TypeDef *)ACMP0_BASE) -#define ACMP1 ((ACMP_TypeDef *)ACMP1_BASE) -/* OPAMP Peripheral declaration */ -#define OPAMP ((OPAMP_TypeDef *)OPAMP_BASE) -/* DAC Peripheral declaration */ -#define DAC0 ((DAC_TypeDef *)DAC0_BASE) -/* TEMP Peripheral declaration */ -#define TEMP ((TEMP_TypeDef *)TEMP_BASE) -/* BKPC Peripheral declaration */ -#define BKPC ((BKPC_TypeDef *)BKPC_BASE) - -/* Timer Peripheral_declaration */ -#define TIMER0 ((TIMER_TypeDef *)TIMER0_BASE) -#define TIMER1 ((TIMER_TypeDef *)TIMER1_BASE) -#define TIMER2 ((TIMER_TypeDef *)TIMER2_BASE) -#define TIMER3 ((TIMER_TypeDef *)TIMER3_BASE) -#define TIMER4 ((TIMER_TypeDef *)TIMER4_BASE) -#define TIMER5 ((TIMER_TypeDef *)TIMER5_BASE) -#define TIMER6 ((TIMER_TypeDef *)TIMER6_BASE) -#define TIMER7 ((TIMER_TypeDef *)TIMER7_BASE) - -#define AD16C4T0 TIMER0 -#define GP16C4T0 TIMER6 -#define GP16C2T0 TIMER2 -#define GP16C2T1 TIMER3 -#define BS16T0 TIMER1 -#define BS16T1 TIMER4 -#define BS16T2 TIMER5 -#define BS16T3 TIMER7 - -/* SPI Peripheral_declaration */ -#define SPI0 ((SPI_TypeDef *)SPI0_BASE) -#define SPI1 ((SPI_TypeDef *)SPI1_BASE) -#define SPI2 ((SPI_TypeDef *)SPI2_BASE) - -/* I2C Peripheral_declaration */ -#define I2C0 ((I2C_TypeDef *)I2C0_BASE) -#define I2C1 ((I2C_TypeDef *)I2C1_BASE) - -/* CAN Peripheral_declaration */ -#define CAN0 ((CAN_TypeDef *)CAN0_BASE) - -/* DMA Peripheral_declaration */ -#define DMA0 ((DMA_TypeDef *)DMA0_BASE) - -/* UART Peripheral_declaration */ -#define USART0 ((USART_TypeDef *)USART0_BASE) -#define USART1 ((USART_TypeDef *)USART1_BASE) -#define UART0 ((UART_TypeDef *)UART0_BASE) -#define UART1 ((UART_TypeDef *)UART1_BASE) -#define UART2 ((UART_TypeDef *)UART2_BASE) -#define UART3 ((UART_TypeDef *)UART3_BASE) -#define LPTIM0 ((LPTIM_TypeDef *)LPTIM0_BASE) -#define LPUART0 ((LPUART_TypeDef *)LPUART0_BASE) -#define DBGC ((DBGC_TypeDef *)DBGC_BASE) -#define WWDT ((WWDT_TypeDef *)WWDT_BASE) -#define IWDT ((IWDT_TypeDef *)IWDT_BASE) - -#define SYSCFG ((SYSCFG_TypeDef *)SYSCFG_BASE) -#define CMU ((CMU_TypeDef *)CMU_BASE) -#define RMU ((RMU_TypeDef *)RMU_BASE) -#define PMU ((PMU_TypeDef *)PMU_BASE) -#define MSC ((MSC_TypeDef *)MSC_BASE) - -#endif diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_cm3.h b/bsp/es32f0654/libraries/CMSIS/Include/core_cm3.h deleted file mode 100644 index b4ac4c7b05..0000000000 --- a/bsp/es32f0654/libraries/CMSIS/Include/core_cm3.h +++ /dev/null @@ -1,1763 +0,0 @@ -/**************************************************************************//** - * @file core_cm3.h - * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File - * @version V4.30 - * @date 20. October 2015 - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #pragma clang system_header /* treat file as system include file */ -#endif - -#ifndef __CORE_CM3_H_GENERIC -#define __CORE_CM3_H_GENERIC - -#include - -#ifdef __cplusplus - extern "C" { -#endif - -/** - \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
    - Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    - Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
    - Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** - \ingroup Cortex_M3 - @{ - */ - -/* CMSIS CM3 definitions */ -#define __CM3_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ -#define __CM3_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ -#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ - __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x03U) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ - #define __STATIC_INLINE static inline - -#else - #error Unknown compiler -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - This core does not support an FPU at all -*/ -#define __FPU_USED 0U - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #if defined __ARM_PCS_VFP - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI_VFP_SUPPORT__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __CSMC__ ) - #if ( __CSMC__ & 0x400U) - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#endif - -#include "core_cmInstr.h" /* Core Instruction Access */ -#include "core_cmFunc.h" /* Core Function Access */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM3_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM3_H_DEPENDANT -#define __CORE_CM3_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM3_REV - #define __CM3_REV 0x0200U - #warning "__CM3_REV not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0U - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4U - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0U - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -/* following defines should be used for structure members */ -#define __IM volatile const /*! Defines 'read only' structure member permissions */ -#define __OM volatile /*! Defines 'write only' structure member permissions */ -#define __IOM volatile /*! Defines 'read / write' structure member permissions */ - -/*@} end of group Cortex_M3 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - ******************************************************************************/ -/** - \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** - \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31U /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30U /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29U /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28U /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - -#define APSR_Q_Pos 27U /*!< APSR: Q Position */ -#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ - - -/** - \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** - \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31U /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29U /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28U /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ -#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ - -#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ - -#define xPSR_T_Pos 24U /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** - \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/* CONTROL Register Definitions */ -#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** - \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24U]; - __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24U]; - __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24U]; - __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24U]; - __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56U]; - __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644U]; - __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** - \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5U]; - __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#if (__CM3_REV < 0x0201U) /* core r2p1 */ -#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ -#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ - -#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ -#else -#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ -#endif - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Register Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Register Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** - \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1U]; - __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ -#if ((defined __CM3_REV) && (__CM3_REV >= 0x200U)) - __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -#else - uint32_t RESERVED1[1U]; -#endif -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** - \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** - \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __OM union - { - __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864U]; - __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15U]; - __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15U]; - __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29U]; - __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43U]; - __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6U]; - __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** - \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1U]; - __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1U]; - __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1U]; - __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** - \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2U]; - __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55U]; - __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131U]; - __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1U]; - __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39U]; - __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8U]; - __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1U) -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** - \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register Definitions */ -#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register Definitions */ -#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register Definitions */ -#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register Definitions */ -#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register Definitions */ -#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** - \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register Definitions */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register Definitions */ -#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register Definitions */ -#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_core_bitfield Core register bit field macros - \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). - @{ - */ - -/** - \brief Mask and shift a bit field value for use in a register bit range. - \param[in] field Name of the register bit field. - \param[in] value Value of the bit field. - \return Masked and shifted value. -*/ -#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) - -/** - \brief Mask and shift a register value to extract a bit filed value. - \param[in] field Name of the register bit field. - \param[in] value Value of register. - \return Masked and shifted bit field value. -*/ -#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) - -/*@} end of group CMSIS_core_bitfield */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M3 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1U) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions - ******************************************************************************/ -/** - \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/** - \brief Set Priority Grouping - \details Sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** - \brief Get Priority Grouping - \details Reads the priority grouping field from the NVIC Interrupt Controller. - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); -} - - -/** - \brief Enable External Interrupt - \details Enables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Disable External Interrupt - \details Disables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Get Pending Interrupt - \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. - \param [in] IRQn Interrupt number. - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** - \brief Set Pending Interrupt - \details Sets the pending bit of an external interrupt. - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Clear Pending Interrupt - \details Clears the pending bit of an external interrupt. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Get Active Interrupt - \details Reads the active register in NVIC and returns the active bit. - \param [in] IRQn Interrupt number. - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** - \brief Set Interrupt Priority - \details Sets the priority of an interrupt. - \note The priority cannot be set for every core interrupt. - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if ((int32_t)(IRQn) < 0) - { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } - else - { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } -} - - -/** - \brief Get Interrupt Priority - \details Reads the priority of an interrupt. - The interrupt number can be positive to specify an external (device specific) interrupt, - or negative to specify an internal (core) interrupt. - \param [in] IRQn Interrupt number. - \return Interrupt Priority. - Value is aligned automatically to the implemented priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if ((int32_t)(IRQn) < 0) - { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); - } - else - { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); - } -} - - -/** - \brief Encode Priority - \details Encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - return ( - ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | - ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) - ); -} - - -/** - \brief Decode Priority - \details Decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); - *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); -} - - -/** - \brief System Reset - \details Initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - - for(;;) /* wait until reset */ - { - __NOP(); - } -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0U) - -/** - \brief System Tick Configuration - \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - \param [in] ticks Number of ticks between two interrupts. - \return 0 Function succeeded. - \return 1 Function failed. - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) - { - return (1UL); /* Reload value impossible */ - } - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** - \brief ITM Send Character - \details Transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - \param [in] ch Character to transmit. - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ - ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0U].u32 == 0UL) - { - __NOP(); - } - ITM->PORT[0U].u8 = (uint8_t)ch; - } - return (ch); -} - - -/** - \brief ITM Receive Character - \details Inputs a character via the external variable \ref ITM_RxBuffer. - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) -{ - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) - { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** - \brief ITM Check Character - \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) -{ - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) - { - return (0); /* no character available */ - } - else - { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM3_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_cm4.h b/bsp/es32f0654/libraries/CMSIS/Include/core_cm4.h deleted file mode 100644 index dc840ebf22..0000000000 --- a/bsp/es32f0654/libraries/CMSIS/Include/core_cm4.h +++ /dev/null @@ -1,1937 +0,0 @@ -/**************************************************************************//** - * @file core_cm4.h - * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V4.30 - * @date 20. October 2015 - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #pragma clang system_header /* treat file as system include file */ -#endif - -#ifndef __CORE_CM4_H_GENERIC -#define __CORE_CM4_H_GENERIC - -#include - -#ifdef __cplusplus - extern "C" { -#endif - -/** - \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
    - Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    - Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
    - Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** - \ingroup Cortex_M4 - @{ - */ - -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ -#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ - __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x04U) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ - #define __STATIC_INLINE static inline - -#else - #error Unknown compiler -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. -*/ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #if defined __ARM_PCS_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1U - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI_VFP_SUPPORT__ - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __CSMC__ ) - #if ( __CSMC__ & 0x400U) - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#endif - -#include "core_cmInstr.h" /* Core Instruction Access */ -#include "core_cmFunc.h" /* Core Function Access */ -#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM4_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM4_H_DEPENDANT -#define __CORE_CM4_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM4_REV - #define __CM4_REV 0x0000U - #warning "__CM4_REV not defined in device header file; using default!" - #endif - - #ifndef __FPU_PRESENT - #define __FPU_PRESENT 0U - #warning "__FPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0U - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4U - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0U - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -/* following defines should be used for structure members */ -#define __IM volatile const /*! Defines 'read only' structure member permissions */ -#define __OM volatile /*! Defines 'write only' structure member permissions */ -#define __IOM volatile /*! Defines 'read / write' structure member permissions */ - -/*@} end of group Cortex_M4 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - - Core FPU Register - ******************************************************************************/ -/** - \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** - \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31U /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30U /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29U /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28U /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - -#define APSR_Q_Pos 27U /*!< APSR: Q Position */ -#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ - -#define APSR_GE_Pos 16U /*!< APSR: GE Position */ -#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ - - -/** - \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** - \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31U /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29U /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28U /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ -#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ - -#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ - -#define xPSR_T_Pos 24U /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ -#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ - -#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** - \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/* CONTROL Register Definitions */ -#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ -#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ - -#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** - \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24U]; - __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24U]; - __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24U]; - __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24U]; - __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56U]; - __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644U]; - __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** - \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5U]; - __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Register Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Register Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** - \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1U]; - __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ -#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ - -#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ -#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** - \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** - \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __OM union - { - __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864U]; - __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15U]; - __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15U]; - __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29U]; - __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43U]; - __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6U]; - __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** - \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1U]; - __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1U]; - __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1U]; - __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** - \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2U]; - __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55U]; - __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131U]; - __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1U]; - __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39U]; - __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8U]; - __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1U) -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** - \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register Definitions */ -#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register Definitions */ -#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register Definitions */ -#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register Definitions */ -#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register Definitions */ -#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -#if (__FPU_PRESENT == 1U) -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_FPU Floating Point Unit (FPU) - \brief Type definitions for the Floating Point Unit (FPU) - @{ - */ - -/** - \brief Structure type to access the Floating Point Unit (FPU). - */ -typedef struct -{ - uint32_t RESERVED0[1U]; - __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ - __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ - __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ - __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ - __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ -} FPU_Type; - -/* Floating-Point Context Control Register Definitions */ -#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ -#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ - -#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ -#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ - -#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ -#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ - -#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ -#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ - -#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ -#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ - -#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ -#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ - -#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ -#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ - -#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ -#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ - -#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ -#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ - -/* Floating-Point Context Address Register Definitions */ -#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ -#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ - -/* Floating-Point Default Status Control Register Definitions */ -#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ -#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ - -#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ -#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ - -#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ -#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ - -#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ -#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ - -/* Media and FP Feature Register 0 Definitions */ -#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ -#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ - -#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ -#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ - -#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ -#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ - -#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ -#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ - -#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ -#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ - -#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ -#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ - -#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ -#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ - -#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ -#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ - -/* Media and FP Feature Register 1 Definitions */ -#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ -#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ - -#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ -#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ - -#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ -#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ - -#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ -#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ - -/*@} end of group CMSIS_FPU */ -#endif - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** - \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register Definitions */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register Definitions */ -#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register Definitions */ -#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_core_bitfield Core register bit field macros - \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). - @{ - */ - -/** - \brief Mask and shift a bit field value for use in a register bit range. - \param[in] field Name of the register bit field. - \param[in] value Value of the bit field. - \return Masked and shifted value. -*/ -#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) - -/** - \brief Mask and shift a register value to extract a bit filed value. - \param[in] field Name of the register bit field. - \param[in] value Value of register. - \return Masked and shifted bit field value. -*/ -#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) - -/*@} end of group CMSIS_core_bitfield */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M4 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1U) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -#if (__FPU_PRESENT == 1U) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions - ******************************************************************************/ -/** - \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/** - \brief Set Priority Grouping - \details Sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** - \brief Get Priority Grouping - \details Reads the priority grouping field from the NVIC Interrupt Controller. - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); -} - - -/** - \brief Enable External Interrupt - \details Enables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Disable External Interrupt - \details Disables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Get Pending Interrupt - \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. - \param [in] IRQn Interrupt number. - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** - \brief Set Pending Interrupt - \details Sets the pending bit of an external interrupt. - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Clear Pending Interrupt - \details Clears the pending bit of an external interrupt. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Get Active Interrupt - \details Reads the active register in NVIC and returns the active bit. - \param [in] IRQn Interrupt number. - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** - \brief Set Interrupt Priority - \details Sets the priority of an interrupt. - \note The priority cannot be set for every core interrupt. - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if ((int32_t)(IRQn) < 0) - { - SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } - else - { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } -} - - -/** - \brief Get Interrupt Priority - \details Reads the priority of an interrupt. - The interrupt number can be positive to specify an external (device specific) interrupt, - or negative to specify an internal (core) interrupt. - \param [in] IRQn Interrupt number. - \return Interrupt Priority. - Value is aligned automatically to the implemented priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if ((int32_t)(IRQn) < 0) - { - return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); - } - else - { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); - } -} - - -/** - \brief Encode Priority - \details Encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - return ( - ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | - ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) - ); -} - - -/** - \brief Decode Priority - \details Decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); - *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); -} - - -/** - \brief System Reset - \details Initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - - for(;;) /* wait until reset */ - { - __NOP(); - } -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0U) - -/** - \brief System Tick Configuration - \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - \param [in] ticks Number of ticks between two interrupts. - \return 0 Function succeeded. - \return 1 Function failed. - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) - { - return (1UL); /* Reload value impossible */ - } - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** - \brief ITM Send Character - \details Transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - \param [in] ch Character to transmit. - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ - ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0U].u32 == 0UL) - { - __NOP(); - } - ITM->PORT[0U].u8 = (uint8_t)ch; - } - return (ch); -} - - -/** - \brief ITM Receive Character - \details Inputs a character via the external variable \ref ITM_RxBuffer. - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) -{ - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) - { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** - \brief ITM Check Character - \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) -{ - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) - { - return (0); /* no character available */ - } - else - { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM4_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_cm7.h b/bsp/es32f0654/libraries/CMSIS/Include/core_cm7.h deleted file mode 100644 index 3b7530ad50..0000000000 --- a/bsp/es32f0654/libraries/CMSIS/Include/core_cm7.h +++ /dev/null @@ -1,2512 +0,0 @@ -/**************************************************************************//** - * @file core_cm7.h - * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File - * @version V4.30 - * @date 20. October 2015 - ******************************************************************************/ -/* Copyright (c) 2009 - 2015 ARM LIMITED - - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - Neither the name of ARM nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - * - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------*/ - - -#if defined ( __ICCARM__ ) - #pragma system_include /* treat file as system include file for MISRA check */ -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #pragma clang system_header /* treat file as system include file */ -#endif - -#ifndef __CORE_CM7_H_GENERIC -#define __CORE_CM7_H_GENERIC - -#include - -#ifdef __cplusplus - extern "C" { -#endif - -/** - \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions - CMSIS violates the following MISRA-C:2004 rules: - - \li Required Rule 8.5, object/function definition in header file.
    - Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    - Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
    - Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** - \ingroup Cortex_M7 - @{ - */ - -/* CMSIS CM7 definitions */ -#define __CM7_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ -#define __CM7_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ -#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ - __CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x07U) /*!< Cortex-M Core */ - - -#if defined ( __CC_ARM ) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #define __ASM __asm /*!< asm keyword for ARM Compiler */ - #define __INLINE __inline /*!< inline keyword for ARM Compiler */ - #define __STATIC_INLINE static __inline - -#elif defined ( __GNUC__ ) - #define __ASM __asm /*!< asm keyword for GNU Compiler */ - #define __INLINE inline /*!< inline keyword for GNU Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __ICCARM__ ) - #define __ASM __asm /*!< asm keyword for IAR Compiler */ - #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ - #define __STATIC_INLINE static inline - -#elif defined ( __TMS470__ ) - #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __TASKING__ ) - #define __ASM __asm /*!< asm keyword for TASKING Compiler */ - #define __INLINE inline /*!< inline keyword for TASKING Compiler */ - #define __STATIC_INLINE static inline - -#elif defined ( __CSMC__ ) - #define __packed - #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ - #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ - #define __STATIC_INLINE static inline - -#else - #error Unknown compiler -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. -*/ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) - #if defined __ARM_PCS_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1U - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI_VFP_SUPPORT__ - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#elif defined ( __CSMC__ ) - #if ( __CSMC__ & 0x400U) - #if (__FPU_PRESENT == 1U) - #define __FPU_USED 1U - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0U - #endif - #else - #define __FPU_USED 0U - #endif - -#endif - -#include "core_cmInstr.h" /* Core Instruction Access */ -#include "core_cmFunc.h" /* Core Function Access */ -#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM7_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM7_H_DEPENDANT -#define __CORE_CM7_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM7_REV - #define __CM7_REV 0x0000U - #warning "__CM7_REV not defined in device header file; using default!" - #endif - - #ifndef __FPU_PRESENT - #define __FPU_PRESENT 0U - #warning "__FPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0U - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __ICACHE_PRESENT - #define __ICACHE_PRESENT 0U - #warning "__ICACHE_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __DCACHE_PRESENT - #define __DCACHE_PRESENT 0U - #warning "__DCACHE_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __DTCM_PRESENT - #define __DTCM_PRESENT 0U - #warning "__DTCM_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 3U - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0U - #warning "__Vendor_SysTickConfig not defined in device header file; using default!" - #endif -#endif - -/* IO definitions (access restrictions to peripheral registers) */ -/** - \defgroup CMSIS_glob_defs CMSIS Global Defines - - IO Type Qualifiers are used - \li to specify the access to peripheral variables. - \li for automatic generation of peripheral register debug information. -*/ -#ifdef __cplusplus - #define __I volatile /*!< Defines 'read only' permissions */ -#else - #define __I volatile const /*!< Defines 'read only' permissions */ -#endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -/* following defines should be used for structure members */ -#define __IM volatile const /*! Defines 'read only' structure member permissions */ -#define __OM volatile /*! Defines 'write only' structure member permissions */ -#define __IOM volatile /*! Defines 'read / write' structure member permissions */ - -/*@} end of group Cortex_M7 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - - Core FPU Register - ******************************************************************************/ -/** - \defgroup CMSIS_core_register Defines and Type Definitions - \brief Type definitions and defines for Cortex-M processor based devices. -*/ - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_CORE Status and Control Registers - \brief Core Register type definitions. - @{ - */ - -/** - \brief Union type to access the Application Program Status Register (APSR). - */ -typedef union -{ - struct - { - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} APSR_Type; - -/* APSR Register Definitions */ -#define APSR_N_Pos 31U /*!< APSR: N Position */ -#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ - -#define APSR_Z_Pos 30U /*!< APSR: Z Position */ -#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ - -#define APSR_C_Pos 29U /*!< APSR: C Position */ -#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ - -#define APSR_V_Pos 28U /*!< APSR: V Position */ -#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ - -#define APSR_Q_Pos 27U /*!< APSR: Q Position */ -#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ - -#define APSR_GE_Pos 16U /*!< APSR: GE Position */ -#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ - - -/** - \brief Union type to access the Interrupt Program Status Register (IPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} IPSR_Type; - -/* IPSR Register Definitions */ -#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ -#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ - - -/** - \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ - uint32_t C:1; /*!< bit: 29 Carry condition code flag */ - uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ - uint32_t N:1; /*!< bit: 31 Negative condition code flag */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} xPSR_Type; - -/* xPSR Register Definitions */ -#define xPSR_N_Pos 31U /*!< xPSR: N Position */ -#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ - -#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ -#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ - -#define xPSR_C_Pos 29U /*!< xPSR: C Position */ -#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ - -#define xPSR_V_Pos 28U /*!< xPSR: V Position */ -#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ - -#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ -#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ - -#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ -#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ - -#define xPSR_T_Pos 24U /*!< xPSR: T Position */ -#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ - -#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ -#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ - -#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ -#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ - - -/** - \brief Union type to access the Control Registers (CONTROL). - */ -typedef union -{ - struct - { - uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ - uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ - uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/* CONTROL Register Definitions */ -#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ -#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ - -#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ -#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ - -#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ -#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ - -/*@} end of group CMSIS_CORE */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) - \brief Type definitions for the NVIC Registers - @{ - */ - -/** - \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). - */ -typedef struct -{ - __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24U]; - __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24U]; - __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24U]; - __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24U]; - __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56U]; - __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644U]; - __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ - -/*@} end of group CMSIS_NVIC */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SCB System Control Block (SCB) - \brief Type definitions for the System Control Block Registers - @{ - */ - -/** - \brief Structure type to access the System Control Block (SCB). - */ -typedef struct -{ - __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[1U]; - __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ - __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ - __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ - __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ - __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ - uint32_t RESERVED3[93U]; - __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ - uint32_t RESERVED4[15U]; - __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ - __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ - __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ - uint32_t RESERVED5[1U]; - __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ - uint32_t RESERVED6[1U]; - __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ - __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ - __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ - __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ - __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ - __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ - __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ - __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ - uint32_t RESERVED7[6U]; - __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ - __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ - __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ - __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ - __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ - uint32_t RESERVED8[1U]; - __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ -#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ - -/* SCB Interrupt Control State Register Definitions */ -#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ -#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ - -/* SCB Configuration Control Register Definitions */ -#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ -#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ - -#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ -#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ - -#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ -#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ - -#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Register Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Register Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ - -/* SCB Cache Level ID Register Definitions */ -#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ -#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ - -#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ -#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ - -/* SCB Cache Type Register Definitions */ -#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ -#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ - -#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ -#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ - -#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ -#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ - -#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ -#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ - -#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ -#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ - -/* SCB Cache Size ID Register Definitions */ -#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ -#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ - -#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ -#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ - -#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ -#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ - -#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ -#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ - -#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ -#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ - -#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ -#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ - -#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ -#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ - -/* SCB Cache Size Selection Register Definitions */ -#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ -#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ - -#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ -#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ - -/* SCB Software Triggered Interrupt Register Definitions */ -#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ -#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ - -/* SCB D-Cache Invalidate by Set-way Register Definitions */ -#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ -#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ - -#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ -#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ - -/* SCB D-Cache Clean by Set-way Register Definitions */ -#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ -#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ - -#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ -#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ - -/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ -#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ -#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ - -#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ -#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ - -/* Instruction Tightly-Coupled Memory Control Register Definitions */ -#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ -#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ - -#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ -#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ - -#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ -#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ - -#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ -#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ - -/* Data Tightly-Coupled Memory Control Register Definitions */ -#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ -#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ - -#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ -#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ - -#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ -#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ - -#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ -#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ - -/* AHBP Control Register Definitions */ -#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ -#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ - -#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ -#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ - -/* L1 Cache Control Register Definitions */ -#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ -#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ - -#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ -#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ - -#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ -#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ - -/* AHBS Control Register Definitions */ -#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ -#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ - -#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ -#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ - -#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ -#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ - -/* Auxiliary Bus Fault Status Register Definitions */ -#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ -#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ - -#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ -#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ - -#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ -#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ - -#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ -#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ - -#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ -#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ - -#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ -#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** - \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1U]; - __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ -#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ - -#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ -#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ - -#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ -#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_SysTick System Tick Timer (SysTick) - \brief Type definitions for the System Timer Registers. - @{ - */ - -/** - \brief Structure type to access the System Timer (SysTick). - */ -typedef struct -{ - __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ -#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ - -/* SysTick Reload Register Definitions */ -#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ -#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ - -/* SysTick Current Register Definitions */ -#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ -#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ - -/* SysTick Calibration Register Definitions */ -#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** - \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __OM union - { - __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864U]; - __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15U]; - __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15U]; - __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29U]; - __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43U]; - __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6U]; - __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** - \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1U]; - __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1U]; - __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1U]; - __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ - uint32_t RESERVED3[981U]; - __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ - __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** - \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2U]; - __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55U]; - __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131U]; - __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759U]; - __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1U]; - __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39U]; - __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8U]; - __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1U) -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_MPU Memory Protection Unit (MPU) - \brief Type definitions for the Memory Protection Unit (MPU) - @{ - */ - -/** - \brief Structure type to access the Memory Protection Unit (MPU). - */ -typedef struct -{ - __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register Definitions */ -#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register Definitions */ -#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register Definitions */ -#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register Definitions */ -#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register Definitions */ -#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ -#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ - -#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ -#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ - -#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ -#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ - -#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ -#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ - -#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ -#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ - -#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ -#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ - -#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ -#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ - -#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ -#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ - -#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ -#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ - -#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -#if (__FPU_PRESENT == 1U) -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_FPU Floating Point Unit (FPU) - \brief Type definitions for the Floating Point Unit (FPU) - @{ - */ - -/** - \brief Structure type to access the Floating Point Unit (FPU). - */ -typedef struct -{ - uint32_t RESERVED0[1U]; - __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ - __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ - __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ - __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ - __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ - __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ -} FPU_Type; - -/* Floating-Point Context Control Register Definitions */ -#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ -#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ - -#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ -#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ - -#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ -#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ - -#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ -#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ - -#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ -#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ - -#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ -#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ - -#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ -#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ - -#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ -#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ - -#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ -#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ - -/* Floating-Point Context Address Register Definitions */ -#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ -#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ - -/* Floating-Point Default Status Control Register Definitions */ -#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ -#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ - -#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ -#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ - -#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ -#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ - -#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ -#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ - -/* Media and FP Feature Register 0 Definitions */ -#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ -#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ - -#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ -#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ - -#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ -#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ - -#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ -#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ - -#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ -#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ - -#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ -#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ - -#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ -#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ - -#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ -#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ - -/* Media and FP Feature Register 1 Definitions */ -#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ -#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ - -#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ -#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ - -#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ -#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ - -#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ -#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ - -/* Media and FP Feature Register 2 Definitions */ - -/*@} end of group CMSIS_FPU */ -#endif - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** - \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register Definitions */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register Definitions */ -#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register Definitions */ -#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_core_bitfield Core register bit field macros - \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). - @{ - */ - -/** - \brief Mask and shift a bit field value for use in a register bit range. - \param[in] field Name of the register bit field. - \param[in] value Value of the bit field. - \return Masked and shifted value. -*/ -#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) - -/** - \brief Mask and shift a register value to extract a bit filed value. - \param[in] field Name of the register bit field. - \param[in] value Value of register. - \return Masked and shifted bit field value. -*/ -#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) - -/*@} end of group CMSIS_core_bitfield */ - - -/** - \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M4 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ -#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ -#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ -#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ -#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1U) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -#if (__FPU_PRESENT == 1U) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug Functions - - Core Register Access Functions - ******************************************************************************/ -/** - \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference -*/ - - - -/* ########################## NVIC functions #################################### */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_NVICFunctions NVIC Functions - \brief Functions that manage interrupts and exceptions via the NVIC. - @{ - */ - -/** - \brief Set Priority Grouping - \details Sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** - \brief Get Priority Grouping - \details Reads the priority grouping field from the NVIC Interrupt Controller. - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); -} - - -/** - \brief Enable External Interrupt - \details Enables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Disable External Interrupt - \details Disables a device-specific interrupt in the NVIC interrupt controller. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Get Pending Interrupt - \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. - \param [in] IRQn Interrupt number. - \return 0 Interrupt status is not pending. - \return 1 Interrupt status is pending. - */ -__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** - \brief Set Pending Interrupt - \details Sets the pending bit of an external interrupt. - \param [in] IRQn Interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Clear Pending Interrupt - \details Clears the pending bit of an external interrupt. - \param [in] IRQn External interrupt number. Value cannot be negative. - */ -__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); -} - - -/** - \brief Get Active Interrupt - \details Reads the active register in NVIC and returns the active bit. - \param [in] IRQn Interrupt number. - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); -} - - -/** - \brief Set Interrupt Priority - \details Sets the priority of an interrupt. - \note The priority cannot be set for every core interrupt. - \param [in] IRQn Interrupt number. - \param [in] priority Priority to set. - */ -__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) -{ - if ((int32_t)(IRQn) < 0) - { - SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } - else - { - NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); - } -} - - -/** - \brief Get Interrupt Priority - \details Reads the priority of an interrupt. - The interrupt number can be positive to specify an external (device specific) interrupt, - or negative to specify an internal (core) interrupt. - \param [in] IRQn Interrupt number. - \return Interrupt Priority. - Value is aligned automatically to the implemented priority bits of the microcontroller. - */ -__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) -{ - - if ((int32_t)(IRQn) < 0) - { - return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); - } - else - { - return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); - } -} - - -/** - \brief Encode Priority - \details Encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - return ( - ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | - ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) - ); -} - - -/** - \brief Decode Priority - \details Decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); - SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); - - *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); - *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); -} - - -/** - \brief System Reset - \details Initiates a system reset request to reset the MCU. - */ -__STATIC_INLINE void NVIC_SystemReset(void) -{ - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - - for(;;) /* wait until reset */ - { - __NOP(); - } -} - -/*@} end of CMSIS_Core_NVICFunctions */ - - -/* ########################## FPU functions #################################### */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_FpuFunctions FPU Functions - \brief Function that provides FPU type. - @{ - */ - -/** - \brief get FPU type - \details returns the FPU type - \returns - - \b 0: No FPU - - \b 1: Single precision FPU - - \b 2: Double + Single precision FPU - */ -__STATIC_INLINE uint32_t SCB_GetFPUType(void) -{ - uint32_t mvfr0; - - mvfr0 = SCB->MVFR0; - if ((mvfr0 & 0x00000FF0UL) == 0x220UL) - { - return 2UL; /* Double + Single precision FPU */ - } - else if ((mvfr0 & 0x00000FF0UL) == 0x020UL) - { - return 1UL; /* Single precision FPU */ - } - else - { - return 0UL; /* No FPU */ - } -} - - -/*@} end of CMSIS_Core_FpuFunctions */ - - - -/* ########################## Cache functions #################################### */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_CacheFunctions Cache Functions - \brief Functions that configure Instruction and Data cache. - @{ - */ - -/* Cache Size ID Register Macros */ -#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) -#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) - - -/** - \brief Enable I-Cache - \details Turns on I-Cache - */ -__STATIC_INLINE void SCB_EnableICache (void) -{ - #if (__ICACHE_PRESENT == 1U) - __DSB(); - __ISB(); - SCB->ICIALLU = 0UL; /* invalidate I-Cache */ - SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ - __DSB(); - __ISB(); - #endif -} - - -/** - \brief Disable I-Cache - \details Turns off I-Cache - */ -__STATIC_INLINE void SCB_DisableICache (void) -{ - #if (__ICACHE_PRESENT == 1U) - __DSB(); - __ISB(); - SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ - SCB->ICIALLU = 0UL; /* invalidate I-Cache */ - __DSB(); - __ISB(); - #endif -} - - -/** - \brief Invalidate I-Cache - \details Invalidates I-Cache - */ -__STATIC_INLINE void SCB_InvalidateICache (void) -{ - #if (__ICACHE_PRESENT == 1U) - __DSB(); - __ISB(); - SCB->ICIALLU = 0UL; - __DSB(); - __ISB(); - #endif -} - - -/** - \brief Enable D-Cache - \details Turns on D-Cache - */ -__STATIC_INLINE void SCB_EnableDCache (void) -{ - #if (__DCACHE_PRESENT == 1U) - uint32_t ccsidr; - uint32_t sets; - uint32_t ways; - - SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ - __DSB(); - - ccsidr = SCB->CCSIDR; - - /* invalidate D-Cache */ - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - do { - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - do { - SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | - ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); - #if defined ( __CC_ARM ) - __schedule_barrier(); - #endif - } while (ways--); - } while(sets--); - __DSB(); - - SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ - - __DSB(); - __ISB(); - #endif -} - - -/** - \brief Disable D-Cache - \details Turns off D-Cache - */ -__STATIC_INLINE void SCB_DisableDCache (void) -{ - #if (__DCACHE_PRESENT == 1U) - uint32_t ccsidr; - uint32_t sets; - uint32_t ways; - - SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ - __DSB(); - - ccsidr = SCB->CCSIDR; - - SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ - - /* clean & invalidate D-Cache */ - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - do { - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - do { - SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | - ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); - #if defined ( __CC_ARM ) - __schedule_barrier(); - #endif - } while (ways--); - } while(sets--); - - __DSB(); - __ISB(); - #endif -} - - -/** - \brief Invalidate D-Cache - \details Invalidates D-Cache - */ -__STATIC_INLINE void SCB_InvalidateDCache (void) -{ - #if (__DCACHE_PRESENT == 1U) - uint32_t ccsidr; - uint32_t sets; - uint32_t ways; - - SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ - __DSB(); - - ccsidr = SCB->CCSIDR; - - /* invalidate D-Cache */ - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - do { - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - do { - SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | - ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); - #if defined ( __CC_ARM ) - __schedule_barrier(); - #endif - } while (ways--); - } while(sets--); - - __DSB(); - __ISB(); - #endif -} - - -/** - \brief Clean D-Cache - \details Cleans D-Cache - */ -__STATIC_INLINE void SCB_CleanDCache (void) -{ - #if (__DCACHE_PRESENT == 1U) - uint32_t ccsidr; - uint32_t sets; - uint32_t ways; - - SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ - __DSB(); - - ccsidr = SCB->CCSIDR; - - /* clean D-Cache */ - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - do { - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - do { - SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | - ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); - #if defined ( __CC_ARM ) - __schedule_barrier(); - #endif - } while (ways--); - } while(sets--); - - __DSB(); - __ISB(); - #endif -} - - -/** - \brief Clean & Invalidate D-Cache - \details Cleans and Invalidates D-Cache - */ -__STATIC_INLINE void SCB_CleanInvalidateDCache (void) -{ - #if (__DCACHE_PRESENT == 1U) - uint32_t ccsidr; - uint32_t sets; - uint32_t ways; - - SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ - __DSB(); - - ccsidr = SCB->CCSIDR; - - /* clean & invalidate D-Cache */ - sets = (uint32_t)(CCSIDR_SETS(ccsidr)); - do { - ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); - do { - SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | - ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); - #if defined ( __CC_ARM ) - __schedule_barrier(); - #endif - } while (ways--); - } while(sets--); - - __DSB(); - __ISB(); - #endif -} - - -/** - \brief D-Cache Invalidate by address - \details Invalidates D-Cache for the given address - \param[in] addr address (aligned to 32-byte boundary) - \param[in] dsize size of memory block (in number of bytes) -*/ -__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) -{ - #if (__DCACHE_PRESENT == 1U) - int32_t op_size = dsize; - uint32_t op_addr = (uint32_t)addr; - int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ - - __DSB(); - - while (op_size > 0) { - SCB->DCIMVAC = op_addr; - op_addr += linesize; - op_size -= linesize; - } - - __DSB(); - __ISB(); - #endif -} - - -/** - \brief D-Cache Clean by address - \details Cleans D-Cache for the given address - \param[in] addr address (aligned to 32-byte boundary) - \param[in] dsize size of memory block (in number of bytes) -*/ -__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) -{ - #if (__DCACHE_PRESENT == 1) - int32_t op_size = dsize; - uint32_t op_addr = (uint32_t) addr; - int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ - - __DSB(); - - while (op_size > 0) { - SCB->DCCMVAC = op_addr; - op_addr += linesize; - op_size -= linesize; - } - - __DSB(); - __ISB(); - #endif -} - - -/** - \brief D-Cache Clean and Invalidate by address - \details Cleans and invalidates D_Cache for the given address - \param[in] addr address (aligned to 32-byte boundary) - \param[in] dsize size of memory block (in number of bytes) -*/ -__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) -{ - #if (__DCACHE_PRESENT == 1U) - int32_t op_size = dsize; - uint32_t op_addr = (uint32_t) addr; - int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ - - __DSB(); - - while (op_size > 0) { - SCB->DCCIMVAC = op_addr; - op_addr += linesize; - op_size -= linesize; - } - - __DSB(); - __ISB(); - #endif -} - - -/*@} end of CMSIS_Core_CacheFunctions */ - - - -/* ################################## SysTick function ############################################ */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_SysTickFunctions SysTick Functions - \brief Functions that configure the System. - @{ - */ - -#if (__Vendor_SysTickConfig == 0U) - -/** - \brief System Tick Configuration - \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. - Counter is in free running mode to generate periodic interrupts. - \param [in] ticks Number of ticks between two interrupts. - \return 0 Function succeeded. - \return 1 Function failed. - \note When the variable __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) - { - return (1UL); /* Reload value impossible */ - } - - SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ - return (0UL); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** - \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** - \brief ITM Send Character - \details Transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - \param [in] ch Character to transmit. - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ - ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0U].u32 == 0UL) - { - __NOP(); - } - ITM->PORT[0U].u8 = (uint8_t)ch; - } - return (ch); -} - - -/** - \brief ITM Receive Character - \details Inputs a character via the external variable \ref ITM_RxBuffer. - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) -{ - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) - { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** - \brief ITM Check Character - \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) -{ - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) - { - return (0); /* no character available */ - } - else - { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM7_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/bsp/es32f0654/libraries/CMSIS/RTOS/Template/cmsis_os.h b/bsp/es32f0654/libraries/CMSIS/RTOS/Template/cmsis_os.h deleted file mode 100644 index 02930af3e6..0000000000 --- a/bsp/es32f0654/libraries/CMSIS/RTOS/Template/cmsis_os.h +++ /dev/null @@ -1,707 +0,0 @@ -/* ---------------------------------------------------------------------- - * $Date: 5. February 2013 - * $Revision: V1.02 - * - * Project: CMSIS-RTOS API - * Title: cmsis_os.h template header file - * - * Version 0.02 - * Initial Proposal Phase - * Version 0.03 - * osKernelStart added, optional feature: main started as thread - * osSemaphores have standard behavior - * osTimerCreate does not start the timer, added osTimerStart - * osThreadPass is renamed to osThreadYield - * Version 1.01 - * Support for C++ interface - * - const attribute removed from the osXxxxDef_t typedef's - * - const attribute added to the osXxxxDef macros - * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete - * Added: osKernelInitialize - * Version 1.02 - * Control functions for short timeouts in microsecond resolution: - * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec - * Removed: osSignalGet - *---------------------------------------------------------------------------- - * - * Copyright (c) 2013 ARM LIMITED - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - *---------------------------------------------------------------------------*/ - - -#ifndef _CMSIS_OS_H -#define _CMSIS_OS_H - -/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. -#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0]) - -/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. -#define osCMSIS_KERNEL 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0]) - -/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. -#define osKernelSystemId "KERNEL V1.00" ///< RTOS identification string - -/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. -#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available -#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available -#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available -#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available -#define osFeature_Signals 8 ///< maximum number of Signal Flags available per thread -#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function -#define osFeature_Wait 1 ///< osWait function: 1=available, 0=not available -#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available - -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - -// ==== Enumeration, structures, defines ==== - -/// Priority used for thread control. -/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. -typedef enum { - osPriorityIdle = -3, ///< priority: idle (lowest) - osPriorityLow = -2, ///< priority: low - osPriorityBelowNormal = -1, ///< priority: below normal - osPriorityNormal = 0, ///< priority: normal (default) - osPriorityAboveNormal = +1, ///< priority: above normal - osPriorityHigh = +2, ///< priority: high - osPriorityRealtime = +3, ///< priority: realtime (highest) - osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority -} osPriority; - -/// Timeout value. -/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. -#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value - -/// Status code values returned by CMSIS-RTOS functions. -/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. -typedef enum { - osOK = 0, ///< function completed; no error or event occurred. - osEventSignal = 0x08, ///< function completed; signal event occurred. - osEventMessage = 0x10, ///< function completed; message event occurred. - osEventMail = 0x20, ///< function completed; mail event occurred. - osEventTimeout = 0x40, ///< function completed; timeout occurred. - osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. - osErrorResource = 0x81, ///< resource not available: a specified resource was not available. - osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. - osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. - osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. - osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. - osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. - osErrorValue = 0x86, ///< value of a parameter is out of range. - osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. - os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. -} osStatus; - - -/// Timer type value for the timer definition. -/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. -typedef enum { - osTimerOnce = 0, ///< one-shot timer - osTimerPeriodic = 1 ///< repeating timer -} os_timer_type; - -/// Entry point of a thread. -/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. -typedef void (*os_pthread) (void const *argument); - -/// Entry point of a timer call back function. -/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. -typedef void (*os_ptimer) (void const *argument); - -// >>> the following data type definitions may shall adapted towards a specific RTOS - -/// Thread ID identifies the thread (pointer to a thread control block). -/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_cb *osThreadId; - -/// Timer ID identifies the timer (pointer to a timer control block). -/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_cb *osTimerId; - -/// Mutex ID identifies the mutex (pointer to a mutex control block). -/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_cb *osMutexId; - -/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). -/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_cb *osSemaphoreId; - -/// Pool ID identifies the memory pool (pointer to a memory pool control block). -/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_cb *osPoolId; - -/// Message ID identifies the message queue (pointer to a message queue control block). -/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_cb *osMessageQId; - -/// Mail ID identifies the mail queue (pointer to a mail queue control block). -/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_cb *osMailQId; - - -/// Thread Definition structure contains startup information of a thread. -/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. -typedef struct os_thread_def { - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - uint32_t instances; ///< maximum number of instances of that thread function - uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size -} osThreadDef_t; - -/// Timer Definition structure contains timer parameters. -/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. -typedef struct os_timer_def { - os_ptimer ptimer; ///< start address of a timer function -} osTimerDef_t; - -/// Mutex Definition structure contains setup information for a mutex. -/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mutex_def { - uint32_t dummy; ///< dummy value. -} osMutexDef_t; - -/// Semaphore Definition structure contains setup information for a semaphore. -/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. -typedef struct os_semaphore_def { - uint32_t dummy; ///< dummy value. -} osSemaphoreDef_t; - -/// Definition structure for memory block allocation. -/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. -typedef struct os_pool_def { - uint32_t pool_sz; ///< number of items (elements) in the pool - uint32_t item_sz; ///< size of an item - void *pool; ///< pointer to memory for pool -} osPoolDef_t; - -/// Definition structure for message queue. -/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_messageQ_def { - uint32_t queue_sz; ///< number of elements in the queue - uint32_t item_sz; ///< size of an item - void *pool; ///< memory array for messages -} osMessageQDef_t; - -/// Definition structure for mail queue. -/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. -typedef struct os_mailQ_def { - uint32_t queue_sz; ///< number of elements in the queue - uint32_t item_sz; ///< size of an item - void *pool; ///< memory array for mail -} osMailQDef_t; - -/// Event structure contains detailed information about an event. -/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. -/// However the struct may be extended at the end. -typedef struct { - osStatus status; ///< status code: event or error information - union { - uint32_t v; ///< message as 32-bit value - void *p; ///< message or mail as void pointer - int32_t signals; ///< signal flags - } value; ///< event value - union { - osMailQId mail_id; ///< mail id obtained by \ref osMailCreate - osMessageQId message_id; ///< message id obtained by \ref osMessageCreate - } def; ///< event definition -} osEvent; - - -// ==== Kernel Control Functions ==== - -/// Initialize the RTOS Kernel for creating objects. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. -osStatus osKernelInitialize (void); - -/// Start the RTOS Kernel. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. -osStatus osKernelStart (void); - -/// Check if the RTOS kernel is already started. -/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. -/// \return 0 RTOS is not started, 1 RTOS is started. -int32_t osKernelRunning(void); - -#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available - -/// Get the RTOS kernel system timer counter -/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS. -/// \return RTOS kernel system timer as 32-bit value -uint32_t osKernelSysTick (void); - -/// The RTOS kernel system timer frequency in Hz -/// \note Reflects the system timer setting and is typically defined in a configuration file. -#define osKernelSysTickFrequency 100000000 - -/// Convert a microseconds value to a RTOS kernel system timer value. -/// \param microsec time value in microseconds. -/// \return time value normalized to the \ref osKernelSysTickFrequency -#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) - -#endif // System Timer available - -// ==== Thread Management ==== - -/// Create a Thread Definition with function, priority, and stack requirements. -/// \param name name of the thread function. -/// \param priority initial priority of the thread function. -/// \param instances number of possible thread instances. -/// \param stacksz stack size (in bytes) requirements for the thread function. -/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, instances, stacksz) \ -extern const osThreadDef_t os_thread_def_##name -#else // define the object -#define osThreadDef(name, priority, instances, stacksz) \ -const osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (instances), (stacksz) } -#endif - -/// Access a Thread definition. -/// \param name name of the thread definition object. -/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osThread(name) \ -&os_thread_def_##name - -/// Create a thread and add it to Active Threads and set it to state READY. -/// \param[in] thread_def thread definition referenced with \ref osThread. -/// \param[in] argument pointer that is passed to the thread function as start argument. -/// \return thread ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. -osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); - -/// Return the thread ID of the current running thread. -/// \return thread ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. -osThreadId osThreadGetId (void); - -/// Terminate execution of a thread and remove it from Active Threads. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. -osStatus osThreadTerminate (osThreadId thread_id); - -/// Pass control to next thread that is in state \b READY. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. -osStatus osThreadYield (void); - -/// Change priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] priority new priority value for the thread function. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. -osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); - -/// Get current priority of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return current priority value of the thread function. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. -osPriority osThreadGetPriority (osThreadId thread_id); - - -// ==== Generic Wait Functions ==== - -/// Wait for Timeout (Time Delay). -/// \param[in] millisec time delay value -/// \return status code that indicates the execution status of the function. -osStatus osDelay (uint32_t millisec); - -#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available - -/// Wait for Signal, Message, Mail, or Timeout. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains signal, message, or mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. -osEvent osWait (uint32_t millisec); - -#endif // Generic Wait available - - -// ==== Timer Management Functions ==== -/// Define a Timer object. -/// \param name name of the timer object. -/// \param function name of the timer call back function. -/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osTimerDef(name, function) \ -extern const osTimerDef_t os_timer_def_##name -#else // define the object -#define osTimerDef(name, function) \ -const osTimerDef_t os_timer_def_##name = \ -{ (function) } -#endif - -/// Access a Timer definition. -/// \param name name of the timer object. -/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osTimer(name) \ -&os_timer_def_##name - -/// Create a timer. -/// \param[in] timer_def timer object referenced with \ref osTimer. -/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. -/// \param[in] argument argument to the timer call back function. -/// \return timer ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. -osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); - -/// Start or restart a timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \param[in] millisec time delay value of the timer. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. -osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); - -/// Stop the timer. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. -osStatus osTimerStop (osTimerId timer_id); - -/// Delete a timer that was created by \ref osTimerCreate. -/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. -osStatus osTimerDelete (osTimerId timer_id); - - -// ==== Signal Management ==== - -/// Set the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that should be set. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. -int32_t osSignalSet (osThreadId thread_id, int32_t signals); - -/// Clear the specified Signal Flags of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \param[in] signals specifies the signal flags of the thread that shall be cleared. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR. -/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. -int32_t osSignalClear (osThreadId thread_id, int32_t signals); - -/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. -/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event flag information or error code. -/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. -osEvent osSignalWait (int32_t signals, uint32_t millisec); - - -// ==== Mutex Management ==== - -/// Define a Mutex. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMutexDef(name) \ -extern const osMutexDef_t os_mutex_def_##name -#else // define the object -#define osMutexDef(name) \ -const osMutexDef_t os_mutex_def_##name = { 0 } -#endif - -/// Access a Mutex definition. -/// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMutex(name) \ -&os_mutex_def_##name - -/// Create and Initialize a Mutex object. -/// \param[in] mutex_def mutex definition referenced with \ref osMutex. -/// \return mutex ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. -osMutexId osMutexCreate (const osMutexDef_t *mutex_def); - -/// Wait until a Mutex becomes available. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. -osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); - -/// Release a Mutex that was obtained by \ref osMutexWait. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. -osStatus osMutexRelease (osMutexId mutex_id); - -/// Delete a Mutex that was created by \ref osMutexCreate. -/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. -osStatus osMutexDelete (osMutexId mutex_id); - - -// ==== Semaphore Management Functions ==== - -#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available - -/// Define a Semaphore object. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osSemaphoreDef(name) \ -extern const osSemaphoreDef_t os_semaphore_def_##name -#else // define the object -#define osSemaphoreDef(name) \ -const osSemaphoreDef_t os_semaphore_def_##name = { 0 } -#endif - -/// Access a Semaphore definition. -/// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osSemaphore(name) \ -&os_semaphore_def_##name - -/// Create and Initialize a Semaphore object used for managing resources. -/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. -/// \param[in] count number of available resources. -/// \return semaphore ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. -osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); - -/// Wait until a Semaphore token becomes available. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return number of available tokens, or -1 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); - -/// Release a Semaphore token. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); - -/// Delete a Semaphore that was created by \ref osSemaphoreCreate. -/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); - -#endif // Semaphore available - - -// ==== Memory Pool Management Functions ==== - -#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available - -/// \brief Define a Memory Pool. -/// \param name name of the memory pool. -/// \param no maximum number of blocks (objects) in the memory pool. -/// \param type data type of a single block (object). -/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osPoolDef(name, no, type) \ -extern const osPoolDef_t os_pool_def_##name -#else // define the object -#define osPoolDef(name, no, type) \ -const osPoolDef_t os_pool_def_##name = \ -{ (no), sizeof(type), NULL } -#endif - -/// \brief Access a Memory Pool definition. -/// \param name name of the memory pool -/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osPool(name) \ -&os_pool_def_##name - -/// Create and Initialize a memory pool. -/// \param[in] pool_def memory pool definition referenced with \ref osPool. -/// \return memory pool ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. -osPoolId osPoolCreate (const osPoolDef_t *pool_def); - -/// Allocate a memory block from a memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolAlloc (osPoolId pool_id); - -/// Allocate a memory block from a memory pool and set memory block to zero. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \return address of the allocated memory block or NULL in case of no memory available. -/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. -void *osPoolCAlloc (osPoolId pool_id); - -/// Return an allocated memory block back to a specific memory pool. -/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. -/// \param[in] block address of the allocated memory block that is returned to the memory pool. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. -osStatus osPoolFree (osPoolId pool_id, void *block); - -#endif // Memory Pool Management available - - -// ==== Message Queue Management Functions ==== - -#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available - -/// \brief Create a Message Queue Definition. -/// \param name name of the queue. -/// \param queue_sz maximum number of messages in the queue. -/// \param type data type of a single message element (for debugger). -/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMessageQDef(name, queue_sz, type) \ -extern const osMessageQDef_t os_messageQ_def_##name -#else // define the object -#define osMessageQDef(name, queue_sz, type) \ -const osMessageQDef_t os_messageQ_def_##name = \ -{ (queue_sz), sizeof (type) } -#endif - -/// \brief Access a Message Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMessageQ(name) \ -&os_messageQ_def_##name - -/// Create and Initialize a Message Queue. -/// \param[in] queue_def queue definition referenced with \ref osMessageQ. -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return message queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. -osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); - -/// Put a Message to a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] info message information. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. -osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); - -/// Get a Message or Wait for a Message from a Queue. -/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return event information that includes status code. -/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. -osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); - -#endif // Message Queues available - - -// ==== Mail Queue Management Functions ==== - -#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available - -/// \brief Create a Mail Queue Definition. -/// \param name name of the queue -/// \param queue_sz maximum number of messages in queue -/// \param type data type of a single message element -/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#if defined (osObjectsExternal) // object is external -#define osMailQDef(name, queue_sz, type) \ -extern const osMailQDef_t os_mailQ_def_##name -#else // define the object -#define osMailQDef(name, queue_sz, type) \ -const osMailQDef_t os_mailQ_def_##name = \ -{ (queue_sz), sizeof (type) } -#endif - -/// \brief Access a Mail Queue Definition. -/// \param name name of the queue -/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. -#define osMailQ(name) \ -&os_mailQ_def_##name - -/// Create and Initialize mail queue. -/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ -/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. -/// \return mail queue ID for reference by other functions or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. -osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); - -/// Allocate a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. -void *osMailAlloc (osMailQId queue_id, uint32_t millisec); - -/// Allocate a memory block from a mail and set memory block to zero. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return pointer to memory block that can be filled with mail or NULL in case of error. -/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. -void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); - -/// Put a mail to a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. -osStatus osMailPut (osMailQId queue_id, void *mail); - -/// Get a mail from a queue. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] millisec timeout value or 0 in case of no time-out -/// \return event that contains mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. -osEvent osMailGet (osMailQId queue_id, uint32_t millisec); - -/// Free a memory block from a mail. -/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. -/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. -/// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. -osStatus osMailFree (osMailQId queue_id, void *mail); - -#endif // Mail Queues available - - -#ifdef __cplusplus -} -#endif - -#endif // _CMSIS_OS_H diff --git a/bsp/es32f0654/libraries/CMSIS/index.html b/bsp/es32f0654/libraries/CMSIS/index.html deleted file mode 100644 index c6da0802b4..0000000000 --- a/bsp/es32f0654/libraries/CMSIS/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - -Redirect to the CMSIS main page after 0 seconds - - - - - - -If the automatic redirection is failing, click
    open CMSIS Documentation. - - - diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_acmp.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_acmp.h deleted file mode 100644 index 8c39f28af2..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_acmp.h +++ /dev/null @@ -1,374 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_acmp.h - * @brief Header file of ACMP module driver. - * - * @version V1.0 - * @date 13 Dec 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ********************************************************************************* - */ - -#ifndef __ALD_ACMP_H__ -#define __ALD_ACMP_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup ACMP - * @{ - */ - -/** @defgroup ACMP_Public_Types ACMP Public Types - * @{ - */ - -/** - * @brief Acmp interrupt - */ -typedef enum -{ - ACMP_IT_EDGE = (1U << 0), /**< Edge interrupt bit */ - ACMP_IT_WARMUP = (1U << 1), /**< Warm up interrupt bit */ -} acmp_it_t; - -/** - * @brief Acmp interrupt - */ -typedef enum -{ - ACMP_FLAG_EDGE = (1U << 0), /**< Edge interrupt flag */ - ACMP_FLAG_WARMUP = (1U << 1), /**< Warm up interrupt flag */ -} acmp_flag_t; - -/** - * @brief Acmp interrupt flag - */ -typedef enum -{ - ACMP_STATUS_EDGE = (1U << 0), /**< Edge interrupt flag */ - ACMP_STATUS_WARMUP = (1U << 1), /**< Warm up interrupt flag */ -} acmp_status_t; - -/** - * @brief Acmp positive input - */ -typedef enum -{ - ACMP_POS_CH0 = 0, /**< Channel 0 as positive input */ - ACMP_POS_CH1 = 1, /**< Channel 1 as positive input */ - ACMP_POS_CH2 = 2, /**< Channel 2 as positive input */ - ACMP_POS_CH3 = 3, /**< Channel 3 as positive input */ - ACMP_POS_CH4 = 4, /**< Channel 4 as positive input */ - ACMP_POS_CH5 = 5, /**< Channel 5 as positive input */ - ACMP_POS_CH6 = 6, /**< Channel 6 as positive input */ - ACMP_POS_CH7 = 7, /**< Channel 7 as positive input */ -} acmp_pos_input_t; - -/** - * @brief Acmp negative input - */ -typedef enum -{ - ACMP_NEG_CH0 = 0, /**< Channel 0 as negative input */ - ACMP_NEG_CH1 = 1, /**< Channel 1 as negative input */ - ACMP_NEG_CH2 = 2, /**< Channel 2 as negative input */ - ACMP_NEG_CH3 = 3, /**< Channel 3 as negative input */ - ACMP_NEG_CH4 = 4, /**< Channel 4 as negative input */ - ACMP_NEG_CH5 = 5, /**< Channel 5 as negative input */ - ACMP_NEG_CH6 = 6, /**< Channel 6 as negative input */ - ACMP_NEG_CH7 = 7, /**< Channel 7 as negative input */ - ACMP_NEG_1V25 = 8, /**< 1.25v as negative input */ - ACMP_NEG_2V5 = 9, /**< 2.5v as negative input */ - ACMP_NEG_VDD = 10, /**< VDD as negative input */ - ACMP_NEG_CAP = 11, /**< Capacitive as negative input */ - ACMP_NEG_DAC0_CH0 = 12, /**< DAC0 channel 0 as negative input */ - ACMP_NEG_DAC0_CH1 = 13, /**< DAC0 channel 1 as negative input */ -} acmp_neg_input_t; - -/** - * @brief Acmp mode - */ -typedef enum -{ - ACMP_ULTRA_LOW_POWER = 0, /**< Ultra low power mode */ - ACMP_LOW_POWER = 1, /**< Low power mode */ - ACMP_MIDDLE_POWER = 2, /**< Middle power mode */ - ACMP_HIGH_POWER = 3, /**< High power mode */ -} acmp_mode_t; - -/** - * @brief Acmp warm-up time - */ -typedef enum -{ - ACMP_4_PCLK = 0, /**< 4 hfperclk cycles */ - ACMP_8_PCLK = 1, /**< 4 hfperclk cycles */ - ACMP_16_PCLK = 2, /**< 4 hfperclk cycles */ - ACMP_32_PCLK = 3, /**< 4 hfperclk cycles */ - ACMP_64_PCLK = 4, /**< 4 hfperclk cycles */ - ACMP_128_PCLK = 5, /**< 4 hfperclk cycles */ - ACMP_256_PCLK = 6, /**< 4 hfperclk cycles */ - ACMP_512_PCLK = 7, /**< 4 hfperclk cycles */ -} acmp_warm_time_t; - -/** - * @brief Acmp hysteresis level - */ -typedef enum -{ - ACMP_HYST_0 = 0, /**< No hysteresis */ - ACMP_HYST_15 = 1, /**< 15mV hysteresis */ - ACMP_HYST_22 = 2, /**< 22mV hysteresis */ - ACMP_HYST_29 = 3, /**< 29mV hysteresis */ - ACMP_HYST_36 = 4, /**< 36mV hysteresis */ - ACMP_HYST_43 = 5, /**< 43mV hysteresis */ - ACMP_HYST_50 = 6, /**< 50mV hysteresis */ - ACMP_HYST_57 = 7, /**< 57mV hysteresis */ -} acmp_hystsel_t; - -/** - * @brief Acmp inactive state - */ -typedef enum -{ - ACMP_INACTVAL_LOW = 0, /**< The inactive value is 0 */ - ACMP_INACTVAL_HIGH = 1, /**< The inactive value is 1 */ -} acmp_inactval_t; - -/** - * @brief which edges set up interrupt - */ -typedef enum -{ - ACMP_EDGE_NONE = 0, /**< Disable EDGE interrupt */ - ACMP_EDGE_FALL = 1, /**< Falling edges set EDGE interrupt */ - ACMP_EDGE_RISE = 2, /**< rise edges set EDGE interrupt */ - ACMP_EDGE_ALL = 3, /**< Falling edges and rise edges set EDGE interrupt */ -} acmp_edge_t; - -/** - * @brief Acmp output function - */ -typedef enum -{ - ACMP_OUT_DISABLE = 0, /**< Disable acmp output */ - ACMP_OUT_ENABLE = 1, /**< Enable acmp output */ -} acmp_out_func_t; - -/** - * @brief Acmp warm-up interrupt function - */ -typedef enum -{ - ACMP_WARM_DISABLE = 0, /**< Disable acmp warm-up interrupt */ - ACMP_WARM_ENABLE = 1, /**< Enable acmp warm-up interrupt */ -} acmp_warm_it_func; - -/** - * @brief Acmp gpio output invert - */ -typedef enum -{ - ACMP_GPIO_NO_INV = 0, /**< Acmp output to gpio is not inverted */ - ACMP_GPIO_INV = 1, /**< Acmp output to gpio is inverted */ -} acmp_invert_t; - -/** - * @brief The location of the acmp i/o pin - */ -typedef enum -{ - ACMP_LOCATION_O = 0, /**< Location 0 */ - ACMP_LOCATION_1 = 1, /**< Location 1 */ - ACMP_LOCATION_2 = 2, /**< Location 2 */ -} acmp_location_t; - -/** - * @brief Acmp output config structure definition - */ -typedef struct -{ - acmp_out_func_t out_func; /**< Acmp output function */ - acmp_invert_t gpio_inv; /**< If invert gpio output */ - acmp_location_t location; /**< The location of acmp I/0 pin */ -} acmp_output_config_t; - -/** - * @brief Acmp init structure definition - */ -typedef struct -{ - acmp_mode_t mode; /**< Acmp operation mode */ - acmp_warm_time_t warm_time; /**< Acmp warm up time */ - acmp_hystsel_t hystsel; /**< Acmp hysteresis level */ - acmp_warm_it_func warm_func; /**< Acmp warm-up interrupt enable/disable */ - acmp_pos_input_t pos_port; /**< Acmp positive port select */ - acmp_neg_input_t neg_port; /**< Acmp negative port select */ - acmp_inactval_t inactval; /**< Acmp inavtive output value */ - acmp_edge_t edge; /** Select edges to set interrupt flag */ - uint8_t vdd_level; /** Select scaling factor for CDD reference level, MAX is 63 */ -} acmp_init_t; - -/** - * @brief ACMP Handle Structure definition - */ -typedef struct acmp_handle_s -{ - ACMP_TypeDef *perh; /**< Register base address */ - acmp_init_t init; /**< ACMP required parameters */ - lock_state_t lock; /**< Locking object */ - - void (*acmp_warmup_cplt_cbk)(struct acmp_handle_s *arg); /**< Acmp warm-up complete callback */ - void (*acmp_edge_cplt_cbk)(struct acmp_handle_s *arg); /**< Acmp edge trigger callback */ -} acmp_handle_t; -/** - * @} - */ - -/** @defgroup ACMP_Public_Macros ACMP Public Macros - * @{ - */ -#define ACMP_ENABLE(handle) (SET_BIT((handle)->perh->CON, ACMP_CON_EN_MSK)) -#define ACMP_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, ACMP_CON_EN_MSK)) -/** - * @} - */ - -/** @defgroup ACMP_Private_Macros ACMP Private Macros - * @{ - */ -#define IS_ACMP_TYPE(x) (((x) == ACMP0) || \ - ((x) == ACMP1)) -#define IS_ACMP_MODE_TYPE(x) (((x) == ACMP_ULTRA_LOW_POWER) || \ - ((x) == ACMP_LOW_POWER) || \ - ((x) == ACMP_MIDDLE_POWER) || \ - ((x) == ACMP_HIGH_POWER)) -#define IS_ACMP_IT_TYPE(x) (((x) == ACMP_IT_EDGE) || \ - ((x) == ACMP_IT_WARMUP)) -#define IS_ACMP_FLAG_TYPE(x) (((x) == ACMP_FLAG_EDGE) || \ - ((x) == ACMP_FLAG_WARMUP)) -#define IS_ACMP_STATUS_TYPE(x) (((x) == ACMP_STATUS_EDGE) || \ - ((x) == ACMP_STATUS_WARMUP)) -#define IS_ACMP_POS_INPUT_TYPE(x) (((x) == ACMP_POS_CH0) || \ - ((x) == ACMP_POS_CH1) || \ - ((x) == ACMP_POS_CH2) || \ - ((x) == ACMP_POS_CH3) || \ - ((x) == ACMP_POS_CH4) || \ - ((x) == ACMP_POS_CH5) || \ - ((x) == ACMP_POS_CH6) || \ - ((x) == ACMP_POS_CH7)) -#define IS_ACMP_NEG_INPUT_TYPE(x) (((x) == ACMP_NEG_CH0) || \ - ((x) == ACMP_NEG_CH1) || \ - ((x) == ACMP_NEG_CH2) || \ - ((x) == ACMP_NEG_CH3) || \ - ((x) == ACMP_NEG_CH4) || \ - ((x) == ACMP_NEG_CH5) || \ - ((x) == ACMP_NEG_CH6) || \ - ((x) == ACMP_NEG_CH7) || \ - ((x) == ACMP_NEG_1V25) || \ - ((x) == ACMP_NEG_2V5) || \ - ((x) == ACMP_NEG_VDD) || \ - ((x) == ACMP_NEG_CAP) || \ - ((x) == ACMP_NEG_DAC0_CH0) || \ - ((x) == ACMP_NEG_DAC0_CH1)) -#define IS_ACMP_WARM_UP_TIME_TYPE(x) (((x) == ACMP_4_PCLK) || \ - ((x) == ACMP_8_PCLK) || \ - ((x) == ACMP_16_PCLK) || \ - ((x) == ACMP_32_PCLK) || \ - ((x) == ACMP_64_PCLK) || \ - ((x) == ACMP_128_PCLK) || \ - ((x) == ACMP_256_PCLK) || \ - ((x) == ACMP_512_PCLK)) -#define IS_ACMP_HYSTSEL_TYPE(x) (((x) == ACMP_HYST_0) || \ - ((x) == ACMP_HYST_15) || \ - ((x) == ACMP_HYST_22) || \ - ((x) == ACMP_HYST_29) || \ - ((x) == ACMP_HYST_36) || \ - ((x) == ACMP_HYST_43) || \ - ((x) == ACMP_HYST_50) || \ - ((x) == ACMP_HYST_57)) -#define IS_ACMP_INACTVAL_TYPE(x) (((x) == ACMP_INACTVAL_LOW) || \ - ((x) == ACMP_INACTVAL_HIGH)) -#define IS_ACMP_EDGE_TYPE(x) (((x) == ACMP_EDGE_NONE) || \ - ((x) == ACMP_EDGE_FALL) || \ - ((x) == ACMP_EDGE_RISE) || \ - ((x) == ACMP_EDGE_ALL)) -#define IS_ACMP_OUT_FUNC_TYPE(x) (((x) == ACMP_OUT_DISABLE) || \ - ((x) == ACMP_OUT_ENABLE)) -#define IS_ACMP_INVERT_TYPE(x) (((x) == ACMP_GPIO_NO_INV) || \ - ((x) == ACMP_GPIO_INV)) -#define IS_ACMP_LOCATION_TYPE(x) (((x) == ACMP_LOCATION_O) || \ - ((x) == ACMP_LOCATION_1) || \ - ((x) == ACMP_LOCATION_2)) -#define IS_ACMP_WARM_FUNC_TYPE(x) (((x) == ACMP_WARM_DISABLE) || \ - ((x) == ACMP_WARM_ENABLE)) -/** - * @} - */ - -/** @addtogroup ACMP_Public_Functions - * @{ - */ - -/** @addtogroup ACMP_Public_Functions_Group1 - * @{ - */ -ald_status_t acmp_init(acmp_handle_t *hperh); - -/** - * @} - */ - -/** @addtogroup ACMP_Public_Functions_Group2 - * @{ - */ -ald_status_t acmp_interrupt_config(acmp_handle_t *hperh, acmp_it_t it, type_func_t state); -ald_status_t acmp_set_interrupt_mask(acmp_handle_t *hperh, acmp_it_t it); -it_status_t acmp_get_flag_status(acmp_handle_t *hperh, acmp_flag_t it); -ald_status_t acmp_clear_flag_status(acmp_handle_t *hperh, acmp_flag_t it); -flag_status_t acmp_get_status(acmp_handle_t *hperh, acmp_status_t flag); - -/** - * @} - */ - -/** @addtogroup ACMP_Public_Functions_Group3 - * @{ - */ -void acmp_irq_handle(acmp_handle_t *hperh); -ald_status_t acmp_out_config(acmp_handle_t *hperh, acmp_output_config_t *config); -uint8_t acmp_out_result(acmp_handle_t *hperh); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -extern "C" -} -#endif - -#endif diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_adc.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_adc.h deleted file mode 100644 index b4f4f029d1..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_adc.h +++ /dev/null @@ -1,585 +0,0 @@ -/** - ****************************************************************************** - * @file ald_adc.h - * @brief Header file of ADC Module library. - * - * @version V1.0 - * @date 15 Dec 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ****************************************************************************** - */ - -#ifndef __ALD_ADC_H__ -#define __ALD_ADC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" -#include "ald_dma.h" -#include "ald_pis.h" -#include "ald_timer.h" - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup ADC - * @{ - */ - -/** @defgroup ADC_Pubulic_Types ADC Pubulic Types - * @{ - */ - -/** - * @brief ADC State structures definition - */ -typedef enum -{ - ADC_STATE_RESET = 0x0, /**< ADC not yet initialized or disabled */ - ADC_STATE_READY = 0x1, /**< ADC peripheral ready for use */ - ADC_STATE_BUSY_INTERNAL = 0x2, /**< ADC is busy to internal process */ - ADC_STATE_TIMEOUT = 0x4, /**< TimeOut occurrence */ - ADC_STATE_ERROR = 0x10, /**< Internal error occurrence */ - ADC_STATE_NM_BUSY = 0x100, /**< Conversion on group normal is ongoing or can occur */ - ADC_STATE_NM_EOC = 0x200, /**< Conversion data available on group normal */ - ADC_STATE_IST_BUSY = 0x1000, /**< Conversion on group insert is ongoing or can occur */ - ADC_STATE_IST_EOC = 0x2000, /**< Conversion data available on group insert */ - ADC_STATE_AWD = 0x10000, /**< Out-of-window occurrence of analog watchdog */ -} adc_state_t; - -/** - *@brief ADC Error Code - */ -typedef enum -{ - ADC_ERROR_NONE = 0x0, /**< No error */ - ADC_ERROR_INTERNAL = 0x1, /**< ADC IP internal error*/ - ADC_ERROR_OVR = 0x2, /**< Overrun error */ - ADC_ERROR_DMA = 0x4, /**< DMA transfer error */ -} adc_error_t; - -/** - *@brief ADC data alignment - */ -typedef enum -{ - ADC_DATAALIGN_RIGHT = 0x0, /**< ADC data alignment right */ - ADC_DATAALIGN_LEFT = 0x1, /**< ADC data alignment left */ -} adc_align_t; - -/** - *@brief ADC scan mode - */ -typedef enum -{ - ADC_SCAN_DISABLE = 0x0, /**< ADC scan disable */ - ADC_SCAN_ENABLE = 0x1, /**< ADC scan enable */ -} adc_scan_t; - -/** - *@brief ADC config hannal trigger the EOC IT mode - */ -typedef enum -{ - ADC_NCHESEL_MODE_ALL = 0x0, /**< ADC set RCHE after convert sequence finish */ - ADC_NCHESEL_MODE_ONE = 0x1, /**< ADC set RCHE after one convert finish */ -} adc_nchesel_t; - -/** - *@brief ADC channels - */ -typedef enum -{ - ADC_CHANNEL_0 = 0x0, /**< ADC channel 0 */ - ADC_CHANNEL_1 = 0x1, /**< ADC channel 1 */ - ADC_CHANNEL_2 = 0x2, /**< ADC channel 2 */ - ADC_CHANNEL_3 = 0x3, /**< ADC channel 3 */ - ADC_CHANNEL_4 = 0x4, /**< ADC channel 4 */ - ADC_CHANNEL_5 = 0x5, /**< ADC channel 5 */ - ADC_CHANNEL_6 = 0x6, /**< ADC channel 6 */ - ADC_CHANNEL_7 = 0x7, /**< ADC channel 7 */ - ADC_CHANNEL_8 = 0x8, /**< ADC channel 8 */ - ADC_CHANNEL_9 = 0x9, /**< ADC channel 9 */ - ADC_CHANNEL_10 = 0xA, /**< ADC channel 10 */ - ADC_CHANNEL_11 = 0xB, /**< ADC channel 11 */ - ADC_CHANNEL_12 = 0xC, /**< ADC channel 12 */ - ADC_CHANNEL_13 = 0xD, /**< ADC channel 13 */ - ADC_CHANNEL_14 = 0xE, /**< ADC channel 14 */ - ADC_CHANNEL_15 = 0xF, /**< ADC channel 15 */ - ADC_CHANNEL_16 = 0x10, /**< ADC channel 16 */ - ADC_CHANNEL_17 = 0x11, /**< ADC channel 17 */ - ADC_CHANNEL_18 = 0x12, /**< ADC channel 18 */ - ADC_CHANNEL_19 = 0x13, /**< ADC channel 19 */ -} adc_channel_t; - -/** - *@brief ADC sampling times - */ -typedef enum -{ - ADC_SAMPLETIME_1 = 0x0, /**< ADC sampling times 1 clk */ - ADC_SAMPLETIME_2 = 0x1, /**< ADC sampling times 2 clk */ - ADC_SAMPLETIME_4 = 0x2, /**< ADC sampling times 4 clk */ - ADC_SAMPLETIME_15 = 0x3, /**< ADC sampling times 15 clk */ -} adc_samp_t; - -/** - *@brief ADC rank into normal group - */ -typedef enum -{ - ADC_NC_RANK_1 = 0x1, /**< ADC normal channel rank 1 */ - ADC_NC_RANK_2 = 0x2, /**< ADC normal channel rank 2 */ - ADC_NC_RANK_3 = 0x3, /**< ADC normal channel rank 3 */ - ADC_NC_RANK_4 = 0x4, /**< ADC normal channel rank 4 */ - ADC_NC_RANK_5 = 0x5, /**< ADC normal channel rank 5 */ - ADC_NC_RANK_6 = 0x6, /**< ADC normal channel rank 6 */ - ADC_NC_RANK_7 = 0x7, /**< ADC normal channel rank 7 */ - ADC_NC_RANK_8 = 0x8, /**< ADC normal channel rank 8 */ - ADC_NC_RANK_9 = 0x9, /**< ADC normal channel rank 9 */ - ADC_NC_RANK_10 = 0xA, /**< ADC normal channel rank 10 */ - ADC_NC_RANK_11 = 0xB, /**< ADC normal channel rank 11 */ - ADC_NC_RANK_12 = 0xC, /**< ADC normal channel rank 12 */ - ADC_NC_RANK_13 = 0xD, /**< ADC normal channel rank 13 */ - ADC_NC_RANK_14 = 0xE, /**< ADC normal channel rank 14 */ - ADC_NC_RANK_15 = 0xF, /**< ADC normal channel rank 15 */ - ADC_NC_RANK_16 = 0x10, /**< ADC normal channel rank 16 */ -} adc_nc_rank_t; - -/** - * @brief ADC rank into insert group - */ -typedef enum -{ - ADC_IH_RANK_1 = 0x1, /**< ADC insert channel rank 1 */ - ADC_IH_RANK_2 = 0x2, /**< ADC insert channel rank 2 */ - ADC_IH_RANK_3 = 0x3, /**< ADC insert channel rank 3 */ - ADC_IH_RANK_4 = 0x4, /**< ADC insert channel rank 4 */ -} adc_ih_rank_t; - -/** - * @brief ADC analog watchdog mode - */ -typedef enum -{ - ADC_ANAWTD_NONE = 0x0, /**< No watch dog */ - ADC_ANAWTD_SING_NM = 0x800200, /**< One normal channel watch dog */ - ADC_ANAWTD_SING_IST = 0x400200, /**< One inset channel Injec watch dog */ - ADC_ANAWTD_SING_NMIST = 0xC00200, /**< One normal and inset channel watch dog */ - ADC_ANAWTD_ALL_NM = 0x800000, /**< All normal channel watch dog */ - ADC_ANAWTD_ALL_IST = 0x400000, /**< All inset channel watch dog */ - ADC_ANAWTD_ALL_NMIST = 0xC00000, /**< All normal and inset channel watch dog */ -} adc_ana_wtd_t; - -/** - * @brief ADC Event type - */ -typedef enum -{ - ADC_AWD_EVENT = (1U << 0), /**< ADC analog watch dog event */ -} adc_event_type_t; - -/** - * @brief ADC interrupts definition - */ -typedef enum -{ - ADC_IT_NH = (1U << 5), /**< ADC it normal */ - ADC_IT_AWD = (1U << 6), /**< ADC it awd */ - ADC_IT_IH = (1U << 7), /**< ADC it insert */ - ADC_IT_OVR = (1U << 26), /**< ADC it overring */ -} adc_it_t; - -/** - * @brief ADC flags definition - */ -typedef enum -{ - ADC_FLAG_AWD = (1U << 0), /**perh->CON1, ADC_CON1_ADCEN_MSK)) -#define ADC_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON1, ADC_CON1_ADCEN_MSK)) -#define ADC_NH_TRIG_BY_SOFT(handle) (SET_BIT((handle)->perh->CON1, ADC_CON1_NCHTRG_MSK)) -#define ADC_IH_TRIG_BY_SOFT(handle) (SET_BIT((handle)->perh->CON1, ADC_CON1_ICHTRG_MSK)) -#define ADC_RESET_HANDLE_STATE(handle) ((handle)->state = ADC_STATE_RESET) -#define ADC_VREF_OUT_ENABLE(handle) (SET_BIT((handle)->perh->CCR, ADC_CCR_VREFOEN_MSK)) -#define ADC_VREF_OUT_DISABLE(handle) (CLEAR_BIT((handle)->perh->CCR, ADC_CCR_VREFOEN_MSK)) -/** - * @} - */ - -/** @defgroup ADC_Private_Macros ADC Private Macros - * @{ - */ -#define IS_ADC_IH_RANK_TYPE(x) ((x) <= ADC_IH_RANK_4) -#define IS_ADC_NC_RANK_TYPE(x) ((x) <= ADC_NC_RANK_16) -#define IS_ADC_SAMPLING_TIMES_TYPE(x) (((x) == ADC_SAMPLETIME_1) || \ - ((x) == ADC_SAMPLETIME_2) || \ - ((x) == ADC_SAMPLETIME_4) || \ - ((x) == ADC_SAMPLETIME_15)) -#define IS_ADC_CHANNELS_TYPE(x) ((x) <= ADC_CHANNEL_19) -#define IS_ADC_SCAN_MODE_TYPE(x) (((x) == ADC_SCAN_DISABLE) || \ - ((x) == ADC_SCAN_ENABLE) ) -#define IS_ADC_DATA_ALIGN_TYPE(x) (((x) == ADC_DATAALIGN_RIGHT) || \ - ((x) == ADC_DATAALIGN_LEFT)) -#define IS_ADC_ANALOG_WTD_MODE_TYPE(x) (((x) == ADC_ANAWTD_NONE) || \ - ((x) == ADC_ANAWTD_SING_NM) || \ - ((x) == ADC_ANAWTD_SING_IST) || \ - ((x) == ADC_ANAWTD_SING_NMIST) || \ - ((x) == ADC_ANAWTD_ALL_NM) || \ - ((x) == ADC_ANAWTD_ALL_IST) || \ - ((x) == ADC_ANAWTD_ALL_NMIST)) -#define IS_ADC_IT_TYPE(x) (((x) == ADC_IT_NH) || \ - ((x) == ADC_IT_AWD) || \ - ((x) == ADC_IT_IH) || \ - ((x) == ADC_IT_OVR )) -#define IS_ADC_FLAGS_TYPE(x) (((x) == ADC_FLAG_AWD) || \ - ((x) == ADC_FLAG_NH) || \ - ((x) == ADC_FLAG_IH) || \ - ((x) == ADC_FLAG_OVR) || \ - ((x) == ADC_FLAG_NHS) || \ - ((x) == ADC_FLAG_IHS)) -#define IS_ADC_CLK_DIV_TYPE(x) (((x) == ADC_CKDIV_1) || \ - ((x) == ADC_CKDIV_2) || \ - ((x) == ADC_CKDIV_4) || \ - ((x) == ADC_CKDIV_8) || \ - ((x) == ADC_CKDIV_16) || \ - ((x) == ADC_CKDIV_32) || \ - ((x) == ADC_CKDIV_64) || \ - ((x) == ADC_CKDIV_128)) -#define IS_ADC_NEG_REF_VOLTAGE_TYPE(x) (((x) == ADC_NEG_REF_VSS ) || \ - ((x) == ADC_NEG_REF_VREFN )) -#define IS_POS_REF_VOLTAGE_TYPE(x) (((x) == ADC_POS_REF_VDD) || \ - ((x) == ADC_POS_REF_2V) || \ - ((x) == ADC_POS_REF_VREEFP) || \ - ((x) == ADC_POS_REF_VREEFP_BUF)) -#define IS_ADC_NBR_OF_NM_TYPE(x) ((x) <= ADC_NM_NBR_16) -#define IS_ADC_NBR_OF_IST_TYPE(x) ((x) <= ADC_IST_NBR_4) -#define IS_ADC_DISC_NBR_TYPE(x) ((x) <= ADC_DISC_NBR_8) -#define IS_ADC_CONV_RES_TYPE(x) (((x) == ADC_CONV_RES_12) || \ - ((x) == ADC_CONV_RES_6) || \ - ((x) == ADC_CONV_RES_8) || \ - ((x) == ADC_CONV_RES_10)) -#define IS_ADC_TRIG_MODE_TYPE(x) (((x) == ADC_TRIG_SOFT) || \ - ((x) == ADC_TRIG_PIS) || \ - ((x) == ADC_TRIG_PIS_SOFT)) -#define IS_ADC_TYPE(x) (((x) == ADC0) || \ - ((x) == ADC1)) -#define IS_ADC_NCHESEL_MODE_TYPE(x) (((x) == ADC_NCHESEL_MODE_ALL) || \ - ((x) == ADC_NCHESEL_MODE_ONE)) -#define IS_ADC_EVENT_TYPE(x) ((x) == ADC_AWD_EVENT) -#define IS_ADC_IST_OFFSET_TYPE(x) ((x) <= 0xfff) -#define IS_HTR_TYPE(x) ((x) <= 0xfff) -#define IS_LTR_TYPE(x) ((x) <= 0xfff) -/** - * @} - */ - -/** @addtogroup ADC_Public_Functions - * @{ - */ - -/** @addtogroup ADC_Public_Functions_Group1 - * @{ - */ -ald_status_t adc_init(adc_handle_t *hperh); -ald_status_t adc_reset(adc_handle_t *hperh); -/** - * @} - */ - -/** @addtogroup ADC_Public_Functions_Group2 - * @{ - */ -ald_status_t adc_normal_start(adc_handle_t *hperh); -ald_status_t adc_normal_stop(adc_handle_t *hperh); -ald_status_t adc_normal_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout); -ald_status_t adc_poll_for_event(adc_handle_t *hperh, adc_event_type_t event_type, uint32_t timeout); -ald_status_t adc_normal_start_by_it(adc_handle_t *hperh); -ald_status_t adc_normal_stop_by_it(adc_handle_t *hperh); -#ifdef ALD_DMA -ald_status_t adc_start_by_dma(adc_handle_t *hperh, uint16_t *buf, uint16_t size, uint8_t channel); -ald_status_t adc_stop_by_dma(adc_handle_t *hperh); -ald_status_t adc_timer_trigger_adc_by_dma(adc_timer_config_t *config); -#endif -uint32_t adc_normal_get_value(adc_handle_t *hperh); -ald_status_t adc_insert_start(adc_handle_t *hperh); -ald_status_t adc_insert_stop(adc_handle_t *hperh); -ald_status_t adc_insert_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout); -ald_status_t adc_insert_start_by_it(adc_handle_t *hperh); -ald_status_t adc_insert_stop_by_it(adc_handle_t *hperh); -uint32_t adc_insert_get_value(adc_handle_t *hperh, adc_ih_rank_t ih_rank); -void adc_irq_handler(adc_handle_t *hperh); -/** - * @} - */ - -/** @addtogroup ADC_Public_Functions_Group3 - * @{ - */ -ald_status_t adc_normal_channel_config(adc_handle_t *hperh, adc_channel_conf_t *config); -ald_status_t adc_insert_channel_config(adc_handle_t *hperh, adc_ih_conf_t *config); -ald_status_t adc_analog_wdg_config(adc_handle_t *hperh, adc_analog_wdg_conf_t *config); -void adc_interrupt_config(adc_handle_t *hperh, adc_it_t it, type_func_t state); -it_status_t adc_get_it_status(adc_handle_t *hperh, adc_it_t it); -flag_status_t adc_get_flag_status(adc_handle_t *hperh, adc_flag_t flag); -void adc_clear_flag_status(adc_handle_t *hperh, adc_flag_t flag); -/** - * @} - */ - -/** @addtogroup ADC_Public_Functions_Group4 - * @{ - */ -uint32_t adc_get_state(adc_handle_t *hperh); -uint32_t adc_get_error(adc_handle_t *hperh); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -extern "C" -} -#endif - -#endif /* __ALD_ADC_H */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_can.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_can.h deleted file mode 100644 index ebe2e2a479..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_can.h +++ /dev/null @@ -1,485 +0,0 @@ -/** - ****************************************************************************** - * @file ald_can.h - * @brief Header file of CAN Module driver. - * - * @version V1.0 - * @date 16 Apr 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ****************************************************************************** - */ - -#ifndef __ALD_CAN_H -#define __ALD_CAN_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup CAN - * @{ - */ - -/** @defgroup CAN_Public_Types CAN Public Types - * @{ - */ -/** - * @brief ALD State structures definition - */ -typedef enum -{ - CAN_STATE_RESET = 0x00, /**< CAN not yet initialized or disabled */ - CAN_STATE_READY = 0x01, /**< CAN initialized and ready for use */ - CAN_STATE_BUSY = 0x02, /**< CAN process is ongoing */ - CAN_STATE_BUSY_TX = 0x11, /**< CAN process is ongoing */ - CAN_STATE_BUSY_RX = 0x21, /**< CAN process is ongoing */ - CAN_STATE_BUSY_TX_RX = 0x31, /**< CAN process is ongoing */ - CAN_STATE_TIMEOUT = 0x03, /**< CAN in Timeout state */ - CAN_STATE_ERROR = 0x04, /**< CAN error state */ -} can_state_t; - -/** - * @brief CAN Error Code - */ -typedef enum -{ - CAN_ERROR_NONE = 0x00, /**< No error */ - CAN_ERROR_EWG = 0x01, /**< EWG error */ - CAN_ERROR_EPV = 0x02, /**< EPV error */ - CAN_ERROR_BOF = 0x04, /**< BOF error */ - CAN_ERROR_STF = 0x08, /**< Stuff error */ - CAN_ERROR_FOR = 0x10, /**< Form error */ - CAN_ERROR_ACK = 0x20, /**< Acknowledgment error */ - CAN_ERROR_BR = 0x40, /**< Bit recessive */ - CAN_ERROR_BD = 0x80, /**< LEC dominant */ - CAN_ERROR_CRC = 0x100, /**< LEC transfer error */ -} can_error_t; - -/** - * @brief CAN Operating Mode - */ -typedef enum -{ - CAN_MODE_NORMAL = 0x00, /**< Normal mode */ - CAN_MODE_LOOPBACK = 0x01, /**< Loopback mode */ - CAN_MODE_SILENT = 0x02, /**< Silent mode */ - CAN_MODE_SILENT_LOOPBACK = 0x03, /**< Loopback combined with silent mode */ -} can_operate_mode_t; - -/** - * @brief CAN Synchronization Jump Width - */ -typedef enum -{ - CAN_SJW_1 = 0x0, /**< 1 time quantum */ - CAN_SJW_2 = 0x1, /**< 2 time quantum */ - CAN_SJW_3 = 0x2, /**< 3 time quantum */ - CAN_SJW_4 = 0x3, /**< 4 time quantum */ -} can_sjw_t; - -/** - * @brief CAN Time Quantum in Bit Segment 1 - */ -typedef enum -{ - CAN_SEG1_1 = 0x0, /**< 1 time quantum */ - CAN_SEG1_2 = 0x1, /**< 2 time quantum */ - CAN_SEG1_3 = 0x2, /**< 3 time quantum */ - CAN_SEG1_4 = 0x3, /**< 4 time quantum */ - CAN_SEG1_5 = 0x4, /**< 5 time quantum */ - CAN_SEG1_6 = 0x5, /**< 6 time quantum */ - CAN_SEG1_7 = 0x6, /**< 7 time quantum */ - CAN_SEG1_8 = 0x7, /**< 8 time quantum */ - CAN_SEG1_9 = 0x8, /**< 9 time quantum */ - CAN_SEG1_10 = 0x9, /**< 10 time quantum */ - CAN_SEG1_11 = 0xA, /**< 11 time quantum */ - CAN_SEG1_12 = 0xB, /**< 12 time quantum */ - CAN_SEG1_13 = 0xC, /**< 13 time quantum */ - CAN_SEG1_14 = 0xD, /**< 14 time quantum */ - CAN_SEG1_15 = 0xE, /**< 15 time quantum */ - CAN_SEG1_16 = 0xF, /**< 16 time quantum */ -} can_seg1_t; - -/** - * @brief CAN Time Quantum in Bit Segment 2 - */ -typedef enum -{ - CAN_SEG2_1 = 0x0, /**< 1 time quantum */ - CAN_SEG2_2 = 0x1, /**< 2 time quantum */ - CAN_SEG2_3 = 0x2, /**< 3 time quantum */ - CAN_SEG2_4 = 0x3, /**< 4 time quantum */ - CAN_SEG2_5 = 0x4, /**< 5 time quantum */ - CAN_SEG2_6 = 0x5, /**< 6 time quantum */ - CAN_SEG2_7 = 0x6, /**< 7 time quantum */ - CAN_SEG2_8 = 0x7, /**< 8 time quantum */ -} can_seg2_t; - -/** - * @brief CAN Filter Mode - */ -typedef enum -{ - CAN_FILTER_MODE_MASK = 0x0, /**< Identifier mask mode */ - CAN_FILTER_MODE_LIST = 0x1, /**< Identifier list mode */ -} can_filter_mode_t; - -/** - * @brief CAN Filter Scale - */ -typedef enum -{ - CAN_FILTER_SCALE_16 = 0x0, /**< Two 16-bit filters */ - CAN_FILTER_SCALE_32 = 0x1, /**< One 32-bit filter */ -} can_filter_scale_t; - -/** - * @brief CAN Filter fifo - */ -typedef enum -{ - CAN_FILTER_FIFO0 = 0x0, /**< FIFO 0 assignment for filter */ - CAN_FILTER_FIFO1 = 0x1, /**< FIFO 1 assignment for filter */ -} can_filter_fifo_t; - -/** - * @brief CAN Identifier Type - */ -typedef enum -{ - CAN_ID_STD = 0x0, /**< Standard Id */ - CAN_ID_EXT = 0x1, /**< Extended Id */ -} can_id_type_t; - -/** - * @brief CAN Remote Transmission Request - */ -typedef enum -{ - CAN_RTR_DATA = 0x0, /**< Data frame */ - CAN_RTR_REMOTE = 0x1, /**< Remote frame */ -} can_remote_req_t; - -/** - * @brief CAN Transmit Constants - */ -typedef enum -{ - CAN_TX_MAILBOX_0 = 0x0, /**< TX mailbox index 0 */ - CAN_TX_MAILBOX_1 = 0x1, /**< TX mailbox index 1 */ - CAN_TX_MAILBOX_2 = 0x2, /**< TX mailbox index 2 */ - CAN_TX_MAILBOX_NONE = 0x3, /**< MailBox can't be used */ -} can_tx_mailbox_t; - -/** - * @brief CAN Receive fifo Number - */ -typedef enum -{ - CAN_RX_FIFO0 = 0x0, /**< CAN fifo 0 used to receive */ - CAN_RX_FIFO1 = 0x1, /**< CAN fifo 1 used to receive */ -} can_rx_fifo_t; - -/** - * @brief CAN Flags - */ -typedef enum -{ - CAN_FLAG_SLAK = (1U << 1), /**< Sleep acknowledge flag */ - CAN_FLAG_WKU = (1U << 3), /**< Wake up flag */ - CAN_FLAG_SLAKI = (1U << 4), /**< Sleep acknowledge flag */ - CAN_FLAG_RQCP0 = (1U << 20) | (1U << 0), /**< Request MailBox0 flag */ - CAN_FLAG_TXOK0 = (1U << 20) | (1U << 1), /**< Transmission OK MailBox0 flag */ - CAN_FLAG_RQCP1 = (1U << 20) | (1U << 8), /**< Request MailBox1 flag */ - CAN_FLAG_TXOK1 = (1U << 20) | (1U << 9), /**< Transmission OK MailBox1 flag */ - CAN_FLAG_RQCP2 = (1U << 20) | (1U << 16), /**< Request MailBox2 flag */ - CAN_FLAG_TXOK2 = (1U << 20) | (1U << 17), /**< Transmission OK MailBox2 flag */ - CAN_FLAG_TME0 = (1U << 20) | (1U << 26), /**< Transmit mailbox 0 empty flag */ - CAN_FLAG_TME1 = (1U << 20) | (1U << 27), /**< Transmit mailbox 1 empty flag */ - CAN_FLAG_TME2 = (1U << 20) | (1U << 28), /**< Transmit mailbox 2 empty flag */ - CAN_FLAG_FF0 = (2U << 20) | (1U << 3), /**< FIFO 0 Full flag */ - CAN_FLAG_FOV0 = (2U << 20) | (1U << 4), /**< FIFO 0 Overrun flag */ - CAN_FLAG_FF1 = (3U << 20) | (1U << 3), /**< FIFO 1 Full flag */ - CAN_FLAG_FOV1 = (3U << 20) | (1U << 4), /**< FIFO 1 Overrun flag */ - CAN_FLAG_EWG = (4U << 20) | (1U << 0), /**< Error warning flag */ - CAN_FLAG_EPV = (4U << 20) | (1U << 1), /**< Error passive flag */ - CAN_FLAG_BOF = (4U << 20) | (1U << 2), /**< Bus-Off flag */ -} can_flag_t; - -/** - * @brief CAN Interrupts - */ -typedef enum -{ - CAN_IT_TME = (1U << 0), /**< Transmit mailbox empty interrupt bit */ - CAN_IT_FMP0 = (1U << 1), /**< FIFO0 message pending interrupt bit */ - CAN_IT_FF0 = (1U << 2), /**< FIFO0 full interrupt bit */ - CAN_IT_FOV0 = (1U << 3), /**< FIFO0 overrun interrupt bit */ - CAN_IT_FMP1 = (1U << 4), /**< FIFO1 message pending interrupt bit */ - CAN_IT_FF1 = (1U << 5), /**< FIFO1 full interrupt bit */ - CAN_IT_FOV1 = (1U << 6), /**< FIFO1 overrun interrupt bit */ - CAN_IT_EWG = (1U << 8), /**< Error warning interrupt bit */ - CAN_IT_EPV = (1U << 9), /**< Error passive interrupt bit */ - CAN_IT_BOF = (1U << 10), /**< Bus-off interrupt bit */ - CAN_IT_LEC = (1U << 11), /**< Last error code interrupt bit */ - CAN_IT_ERR = (1U << 15), /**< Error interrupt bit */ - CAN_IT_WKU = (1U << 16), /**< wake-up interrupt bit */ - CAN_IT_SLK = (1U << 17), /**< sleep interrupt bit */ -} can_it_t; - -/** - * @brief CAN filter configuration structure definition - */ -typedef struct -{ - uint32_t id_high; /**< Specifies the filter identification number */ - uint32_t id_low; /**< Specifies the filter identification number */ - uint32_t mask_id_high; /**< Specifies the filter mask number or identification number */ - uint32_t mask_id_low; /**< Specifies the filter mask number or identification number */ - can_filter_fifo_t fifo; /**< Specifies the fifo (0 or 1) which will be assigned to the filter. */ - uint32_t number; /**< Specifies the filter which will be initialized. */ - can_filter_mode_t mode; /**< Specifies the filter mode to be initialized. */ - can_filter_scale_t scale; /**< Specifies the filter scale. */ - type_func_t active; /**< Enable or disable the filter. */ - uint32_t bank_number; /**< Select the start slave bank filter. */ -} can_filter_t; - -/** - * @brief CAN init structure definition - */ -typedef struct -{ - uint32_t psc; /**< Specifies the length of a time quantum. */ - can_operate_mode_t mode; /**< Specifies the CAN operating mode. */ - can_sjw_t sjw; /**< Specifies the maximum number of time quanta the CAN hardware is - allowed to lengthen or shorten a bit to perform resynchronization. */ - can_seg1_t seg1; /**< Specifies the number of time quanta in Bit Segment 1. */ - can_seg2_t seg2; /**< Specifies the number of time quanta in Bit Segment 2. */ - type_func_t ttcm; /**< Enable or disable the time triggered communication mode. */ - type_func_t abom; /**< Enable or disable the automatic bus-off management. */ - type_func_t awk; /**< Enable or disable the automatic wake-up mode. */ - type_func_t artx; /**< Enable or disable the non-automatic retransmission mode. */ - type_func_t rfom; /**< Enable or disable the Receive fifo Locked mode. */ - type_func_t txmp; /**< Enable or disable the transmit fifo priority. */ -} can_init_t; - -/** - * @brief CAN Tx message structure definition - */ -typedef struct -{ - uint32_t std; /**< Specifies the standard identifier. */ - uint32_t ext; /**< Specifies the extended identifier. */ - can_id_type_t type; /**< Specifies the type of identifier for the message that will be transmitted. */ - can_remote_req_t rtr; /**< Specifies the type of frame for the message that will be transmitted. */ - uint32_t len; /**< Specifies the length of the frame that will be transmitted. */ - uint8_t data[8]; /**< Contains the data to be transmitted. */ -} can_tx_msg_t; - -/** - * @brief CAN Rx message structure definition - */ -typedef struct -{ - uint32_t std; /**< Specifies the standard identifier. */ - uint32_t ext; /**< Specifies the extended identifier. */ - can_id_type_t type; /**< Specifies the type of identifier for the message that will be received. */ - can_remote_req_t rtr; /**< Specifies the type of frame for the received message. */ - uint32_t len; /**< Specifies the length of the frame that will be received. */ - uint8_t data[8]; /**< Contains the data to be received. */ - uint32_t fmi; /**< Specifies the index of the filter the message stored in the mailbox passes through. */ - can_rx_fifo_t num; /**< Specifies the receive fifo number. */ -} can_rx_msg_t; - -/** - * @brief CAN handle Structure definition - */ -typedef struct can_handle_s -{ - CAN_TypeDef *perh; /**< Register base address */ - can_init_t init; /**< CAN required parameters */ - can_rx_msg_t *rx_msg; /**< Pointer to receive message */ - lock_state_t lock; /**< CAN locking object */ - can_state_t state; /**< CAN communication state */ - can_error_t err; /**< CAN Error code */ - - void (*tx_cplt_cbk)(struct can_handle_s *arg); /**< Tx completed callback */ - void (*rx_cplt_cbk)(struct can_handle_s *arg); /**< Rx completed callback */ - void (*error_cbk)(struct can_handle_s *arg); /**< error callback */ -} can_handle_t; -/** - * @} - */ - -/** @defgroup CAN_Public_Macro CAN Public Macros - * @{ - */ -#define CAN_RESET_HANDLE_STATE(x) ((x)->state = CAN_STATE_RESET) -#define CAN_RX_MSG_PENDING(x, y) (((y) == CAN_RX_FIFO0) ? \ - (READ_BIT((x)->perh->RXF0, CAN_RXF0_PEND_MSK)) : (READ_BIT((x)->perh->RXF1, CAN_RXF1_PEND_MSK))) -#define CAN_DBG_FREEZE(x, y) (MODIFY_REG((x)->perh->CON, CAN_CON_DBGSTP_MSK, (y) << CAN_CON_DBGSTP_POS)) -/** - * @} - */ - -/** @defgroup CAN_Private_Macros CAN Private Macros - * @{ - */ -#define IS_CAN_ALL(x) ((x) == CAN0) -#define IS_CAN_FILTER_NUMBER(x) ((x) <= 13) -#define IS_CAN_MODE(x) (((x) == CAN_MODE_NORMAL) || \ - ((x) == CAN_MODE_LOOPBACK) || \ - ((x) == CAN_MODE_SILENT) || \ - ((x) == CAN_MODE_SILENT_LOOPBACK)) -#define IS_CAN_SJW(x) (((x) == CAN_SJW_1) || \ - ((x) == CAN_SJW_2) || \ - ((x) == CAN_SJW_3) || \ - ((x) == CAN_SJW_4)) -#define IS_CAN_BS1(x) ((x) <= CAN_SEG1_16) -#define IS_CAN_BS2(x) ((x) <= CAN_SEG2_8) -#define IS_CAN_FILTER_MODE(x) (((x) == CAN_FILTER_MODE_MASK) || \ - ((x) == CAN_FILTER_MODE_LIST)) -#define IS_CAN_FILTER_SCALE(x) (((x) == CAN_FILTER_SCALE_16) || \ - ((x) == CAN_FILTER_SCALE_32)) -#define IS_CAN_FILTER_FIFO(x) (((x) == CAN_FILTER_FIFO0) || \ - ((x) == CAN_FILTER_FIFO1)) -#define IS_CAN_IDTYPE(x) (((x) == CAN_ID_STD) || \ - ((x) == CAN_ID_EXT)) -#define IS_CAN_RTR(x) (((x) == CAN_RTR_DATA) || ((x) == CAN_RTR_REMOTE)) -#define IS_CAN_FIFO(x) (((x) == CAN_RX_FIFO0) || ((x) == CAN_RX_FIFO1)) -#define IS_CAN_BANKNUMBER(x) ((x) <= 28) -#define IS_CAN_TX_MAILBOX(x) ((x) <= CAN_TX_MAILBOX_NONE) -#define IS_CAN_STDID(x) ((x) <= ((uint32_t)0x7FF)) -#define IS_CAN_EXTID(x) ((x) <= ((uint32_t)0x1FFFFFFF)) -#define IS_CAN_DATA_LEN(x) ((x) <= ((uint8_t)0x08)) -#define IS_CAN_PRESCALER(x) (((x) >= 1) && ((x) <= 1024)) -#define IS_CAN_GET_FLAG(x) (((x) == CAN_FLAG_SLAK) || \ - ((x) == CAN_FLAG_WKU) || \ - ((x) == CAN_FLAG_SLAKI) || \ - ((x) == CAN_FLAG_RQCP0) || \ - ((x) == CAN_FLAG_TXOK0) || \ - ((x) == CAN_FLAG_RQCP1) || \ - ((x) == CAN_FLAG_TXOK1) || \ - ((x) == CAN_FLAG_RQCP2) || \ - ((x) == CAN_FLAG_TXOK2) || \ - ((x) == CAN_FLAG_TME0) || \ - ((x) == CAN_FLAG_TME1) || \ - ((x) == CAN_FLAG_TME2) || \ - ((x) == CAN_FLAG_FF0) || \ - ((x) == CAN_FLAG_FOV0) || \ - ((x) == CAN_FLAG_FF1) || \ - ((x) == CAN_FLAG_FOV1) || \ - ((x) == CAN_FLAG_EWG) || \ - ((x) == CAN_FLAG_EPV) || \ - ((x) == CAN_FLAG_BOF)) -#define IS_CAN_CLEAR_FLAG(x) (((x) == CAN_FLAG_WKU) || \ - ((x) == CAN_FLAG_SLAKI) || \ - ((x) == CAN_FLAG_RQCP0) || \ - ((x) == CAN_FLAG_RQCP1) || \ - ((x) == CAN_FLAG_RQCP2) || \ - ((x) == CAN_FLAG_FF0) || \ - ((x) == CAN_FLAG_FOV0) || \ - ((x) == CAN_FLAG_FF1) || \ - ((x) == CAN_FLAG_FOV1)) -#define IS_CAN_IT(x) (((x) == CAN_IT_TME) || \ - ((x) == CAN_IT_FMP0) || \ - ((x) == CAN_IT_FF0) || \ - ((x) == CAN_IT_FOV0) || \ - ((x) == CAN_IT_FMP1) || \ - ((x) == CAN_IT_FF1) || \ - ((x) == CAN_IT_FOV1) || \ - ((x) == CAN_IT_EWG) || \ - ((x) == CAN_IT_EPV) || \ - ((x) == CAN_IT_BOF) || \ - ((x) == CAN_IT_LEC) || \ - ((x) == CAN_IT_ERR) || \ - ((x) == CAN_IT_WKU) || \ - ((x) == CAN_IT_SLK)) -#define CAN_TIMEOUT_VALUE 100 -#define CAN_STATE_TX_MASK (1U << 4) -#define CAN_STATE_RX_MASK (1U << 5) -/** - * @} - */ - -/** @addtogroup CAN_Public_Functions - * @{ - */ - -/** @addtogroup CAN_Public_Functions_Group1 - * @{ - */ -/* Initialization functions */ -void can_reset(can_handle_t *hperh); -ald_status_t can_init(can_handle_t *hperh); -ald_status_t can_filter_config(can_handle_t *hperh, can_filter_t *config); -/** - * @} - */ - -/** @addtogroup CAN_Public_Functions_Group2 - * @{ - */ -/* IO operation functions */ -ald_status_t can_send(can_handle_t *hperh, can_tx_msg_t *msg, uint32_t timeout); -ald_status_t can_send_by_it(can_handle_t *hperh, can_tx_msg_t *msg); -ald_status_t can_recv(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg, uint32_t timeout); -ald_status_t can_recv_by_it(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg); -/** - * @} - */ - -/** @addtogroup CAN_Public_Functions_Group3 - * @{ - */ -/* Control function */ -ald_status_t can_sleep(can_handle_t *hperh); -ald_status_t can_wake_up(can_handle_t *hperh); -void can_cancel_send(can_handle_t *hperh, can_tx_mailbox_t box); -void can_irq_handler(can_handle_t *hperh); -type_bool_t can_get_tx_status(can_handle_t *hperh, can_tx_mailbox_t box); -void can_interrupt_config(can_handle_t *hperh, can_it_t it, type_func_t state); -it_status_t can_get_it_status(can_handle_t *hperh, can_it_t it); -flag_status_t can_get_flag_status(can_handle_t *hperh, can_flag_t flag); -void can_clear_flag_status(can_handle_t *hperh, can_flag_t flag); -/** - * @} - */ - -/** @addtogroup CAN_Public_Functions_Group4 - * @{ - */ -/* State and Error functions */ -can_state_t can_get_state(can_handle_t *hperh); -can_error_t can_get_error(can_handle_t *hperh); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_CAN_H */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_cmu.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_cmu.h deleted file mode 100644 index ced2976ea8..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_cmu.h +++ /dev/null @@ -1,632 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_cmu.h - * @brief Header file of CMU module driver. - * - * @version V1.0 - * @date 22 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ******************************************************************************** - */ - -#ifndef __ALD_CMU_H__ -#define __ALD_CMU_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" -#include "ald_syscfg.h" - - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup CMU - * @{ - */ - -/** @defgroup CMU_Public_Macros CMU Public Macros - * @{ - */ -#define CMU_LOSC_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LOSC_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LRC_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LRC_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_ULRC_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(CMU->CLKENR, CMU_CLKENR_ULRCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_ULRC_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_ULRCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) - -/* Low power mode control */ -#define CMU_LP_LRC_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(CMU->LPENR, CMU_LPENR_LRCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LP_LRC_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(CMU->LPENR, CMU_LPENR_LRCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LP_LOSC_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(CMU->LPENR, CMU_LPENR_LOSCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LP_LOSC_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(CMU->LPENR, CMU_LPENR_LOSCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LP_HRC_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(CMU->LPENR, CMU_LPENR_HRCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LP_HRC_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(CMU->LPENR, CMU_LPENR_HRCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LP_HOSC_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(CMU->LPENR, CMU_LPENR_HOSCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define CMU_LP_HOSC_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(CMU->LPENR, CMU_LPENR_HOSCEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -/** - * @} - */ - - -/** @defgroup CMU_Public_Types CMU Public Types - * @{ - */ -/** - * @brief CMU state structure definition - */ -typedef enum -{ - CMU_CLOCK_HRC = 0x1, /**< HRC */ - CMU_CLOCK_LRC = 0x2, /**< LRC */ - CMU_CLOCK_LOSC = 0x3, /**< LOSC */ - CMU_CLOCK_PLL1 = 0x4, /**< PLL1 */ - CMU_CLOCK_HOSC = 0x5, /**< HOSC */ -} cmu_clock_t; - -/** - * @brief PLL1 output clock - */ -typedef enum -{ - CMU_PLL1_OUTPUT_32M = 0x0, /**< x8 (32MHz) */ - CMU_PLL1_OUTPUT_48M = 0x1, /**< x12 (48MHz) */ -} cmu_pll1_output_t; - -/** - * @brief PLL1 referance clock - */ -typedef enum -{ - CMU_PLL1_INPUT_HRC_6 = 0x0, /**< HRC / 6 */ - CMU_PLL1_INPUT_PLL2 = 0x1, /**< PLL2 */ - CMU_PLL1_INPUT_HOSC = 0x2, /**< HOSC / 1 */ - CMU_PLL1_INPUT_HOSC_2 = 0x3, /**< HOSC / 2 */ - CMU_PLL1_INPUT_HOSC_3 = 0x4, /**< HOSC / 3 */ - CMU_PLL1_INPUT_HOSC_4 = 0x5, /**< HOSC / 4 */ - CMU_PLL1_INPUT_HOSC_5 = 0x6, /**< HOSC / 5 */ - CMU_PLL1_INPUT_HOSC_6 = 0x7, /**< HOSC / 6 */ -} cmu_pll1_input_t; - -/** - * @brief HOSC range - */ -typedef enum -{ - CMU_HOSC_2M = 0x0, - CMU_HOSC_4M = 0x1, - CMU_HOSC_8M = 0x2, - CMU_HOSC_16M = 0x3, - CMU_HOSC_24M = 0x4, -} cmu_hosc_range_t; - -/** - * @brief Auto-calibrate input - */ -typedef enum -{ - CMU_AUTO_CALIB_INPUT_LOSE = 0x0, - CMU_AUTO_CALIB_INPUT_HOSE = 0x1, -} cmu_auto_calib_input_t; - -/** - * @brief Auto-calibrate output - */ -typedef enum -{ - CMU_AUTO_CALIB_OUTPUT_24M = 0x0, - CMU_AUTO_CALIB_OUTPUT_2M = 0x1, -} cmu_auto_calib_output_t; - -/** - * @brief Frequency division select bit - */ -typedef enum -{ - CMU_DIV_1 = 0x0, /**< Division by 1 */ - CMU_DIV_2 = 0x1, /**< Division by 2 */ - CMU_DIV_4 = 0x2, /**< Division by 4 */ - CMU_DIV_8 = 0x3, /**< Division by 8 */ - CMU_DIV_16 = 0x4, /**< Division by 16 */ - CMU_DIV_32 = 0x5, /**< Division by 32 */ - CMU_DIV_64 = 0x6, /**< Division by 64 */ - CMU_DIV_128 = 0x7, /**< Division by 128 */ - CMU_DIV_256 = 0x8, /**< Division by 256 */ - CMU_DIV_512 = 0x9, /**< Division by 512 */ - CMU_DIV_1024 = 0xA, /**< Division by 1024 */ - CMU_DIV_2048 = 0xB, /**< Division by 2048 */ - CMU_DIV_4096 = 0xC, /**< Division by 4096 */ -} cmu_div_t; - -/** - * @brief Bus type - */ -typedef enum -{ - CMU_HCLK_1 = 0x0, /**< AHB1 bus */ - CMU_SYS = 0x1, /**< SYS bus */ - CMU_PCLK_1 = 0x2, /**< APB1 bus */ - CMU_PCLK_2 = 0x3, /**< APB2 bus */ -} cmu_bus_t; - -/** - * @brief Output high clock select - */ -typedef enum -{ - CMU_OUTPUT_HIGH_SEL_HOSC = 0x0, /**< Select HOSC */ - CMU_OUTPUT_HIGH_SEL_LOSC = 0x1, /**< Select LOSC */ - CMU_OUTPUT_HIGH_SEL_HRC = 0x2, /**< Select HRC */ - CMU_OUTPUT_HIGH_SEL_LRC = 0x3, /**< Select LRC */ - CMU_OUTPUT_HIGH_SEL_HOSM = 0x4, /**< Select HOSM */ - CMU_OUTPUT_HIGH_SEL_PLL1 = 0x5, /**< Select PLL1 */ - CMU_OUTPUT_HIGH_SEL_PLL2 = 0x6, /**< Select PLL2 */ - CMU_OUTPUT_HIGH_SEL_SYSCLK = 0x7, /**< Select SYSCLK */ -} cmu_output_high_sel_t; - -/** - * @brief Output frequency division - */ -typedef enum -{ - CMU_OUTPUT_DIV_1 = 0x0, /**< Division by 1 */ - CMU_OUTPUT_DIV_2 = 0x1, /**< Division by 2 */ - CMU_OUTPUT_DIV_4 = 0x2, /**< Division by 4 */ - CMU_OUTPUT_DIV_8 = 0x3, /**< Division by 8 */ - CMU_OUTPUT_DIV_16 = 0x4, /**< Division by 16 */ - CMU_OUTPUT_DIV_32 = 0x5, /**< Division by 32 */ - CMU_OUTPUT_DIV_64 = 0x6, /**< Division by 64 */ - CMU_OUTPUT_DIV_128 = 0x7, /**< Division by 128 */ -} cmu_output_high_div_t; - -/** - * @brief Output low clock select - */ -typedef enum -{ - CMU_OUTPUT_LOW_SEL_LOSC = 0x0, /**< Select LOSC */ - CMU_OUTPUT_LOW_SEL_LRC = 0x1, /**< Select LRC */ - CMU_OUTPUT_LOW_SEL_LOSM = 0x2, /**< Select LOSM */ - CMU_OUTPUT_LOW_SEL_BUZZ = 0x3, /**< Select BUZZ */ - CMU_OUTPUT_LOW_SEL_ULRC = 0x4, /**< Select ULRC */ -} cmu_output_low_sel_t; - -/** - * @brief BUZZ frequency division - */ -typedef enum -{ - CMU_BUZZ_DIV_2 = 0x0, /**< Division by 2 */ - CMU_BUZZ_DIV_4 = 0x1, /**< Division by 4 */ - CMU_BUZZ_DIV_8 = 0x2, /**< Division by 8 */ - CMU_BUZZ_DIV_16 = 0x3, /**< Division by 16 */ - CMU_BUZZ_DIV_32 = 0x4, /**< Division by 32 */ - CMU_BUZZ_DIV_64 = 0x5, /**< Division by 64 */ - CMU_BUZZ_DIV_128 = 0x6, /**< Division by 128 */ - CMU_BUZZ_DIV_256 = 0x7, /**< Division by 256 */ -} cmu_buzz_div_t; - -/** - * @brief Low power peripheral clock select - */ -typedef enum -{ - CMU_LP_PERH_CLOCK_SEL_PCLK2 = 0x0, /**< Select PCLK2 */ - CMU_LP_PERH_CLOCK_SEL_PLL1 = 0x1, /**< Select PLL1 */ - CMU_LP_PERH_CLOCK_SEL_PLL2 = 0x2, /**< Select PLL2 */ - CMU_LP_PERH_CLOCK_SEL_HRC = 0x3, /**< Select HRC */ - CMU_LP_PERH_CLOCK_SEL_HOSC = 0x4, /**< Select HOSC */ - CMU_LP_PERH_CLOCK_SEL_LRC = 0x5, /**< Select LRC */ - CMU_LP_PERH_CLOCK_SEL_LOSC = 0x6, /**< Select LOSC */ - CMU_LP_PERH_CLOCK_SEL_ULRC = 0x7, /**< Select ULRC */ - CMU_LP_PERH_CLOCK_SEL_HRC_1M = 0x8, /**< Select HRC down to 1MHz */ - CMU_LP_PERH_CLOCK_SEL_HOSC_1M = 0x9, /**< Select HOSC down to 1MHz */ - CMU_LP_PERH_CLOCK_SEL_LOSM = 0xA, /**< Select LOSM */ - CMU_LP_PERH_CLOCK_SEL_HOSM = 0xB, /**< Select HOSM */ -} cmu_lp_perh_clock_sel_t; - -/** - * @brief LCD clock select - */ -typedef enum -{ - CMU_LCD_SEL_LOSM = 0x0, /**< Select LOSM */ - CMU_LCD_SEL_LOSC = 0x1, /**< Select LOSC */ - CMU_LCD_SEL_LRC = 0x2, /**< Select LRC */ - CMU_LCD_SEL_ULRC = 0x3, /**< Select ULRC */ - CMU_LCD_SEL_HRC_1M = 0x4, /**< Select HRC down to 1MHz */ - CMU_LCD_SEL_HOSC_1M = 0x5, /**< Select HOSC down to 1MHz */ -} cmu_lcd_clock_sel_t; - -/** - * @brief Peripheral clock enable/disable - */ -typedef enum -{ - CMU_PERH_GPIO = (1U << 0), /**< GPIO */ - CMU_PERH_CRC = (1U << 1), /**< CRC */ - CMU_PERH_CALC = (1U << 2), /**< CALC */ - CMU_PERH_CRYPT = (1U << 3), /**< CRYPT */ - CMU_PERH_TRNG = (1U << 4), /**< TRNG */ - CMU_PERH_PIS = (1U << 5), /**< PIS */ - CMU_PERH_TIM0 = (1U << 0) | (1U << 27), /**< TIM0 */ - CMU_PERH_TIM1 = (1U << 1) | (1U << 27), /**< TIM1 */ - CMU_PERH_TIM2 = (1U << 2) | (1U << 27), /**< TIM2 */ - CMU_PERH_TIM3 = (1U << 3) | (1U << 27), /**< TIM3 */ - CMU_PERH_TIM4 = (1U << 4) | (1U << 27), /**< TIM4 */ - CMU_PERH_TIM5 = (1U << 5) | (1U << 27), /**< TIM5 */ - CMU_PERH_TIM6 = (1U << 6) | (1U << 27), /**< TIM6 */ - CMU_PERH_TIM7 = (1U << 7) | (1U << 27), /**< TIM7 */ - CMU_PERH_UART0 = (1U << 8) | (1U << 27), /**< UART0 */ - CMU_PERH_UART1 = (1U << 9) | (1U << 27), /**< UART1 */ - CMU_PERH_UART2 = (1U << 10) | (1U << 27), /**< UART2 */ - CMU_PERH_UART3 = (1U << 11) | (1U << 27), /**< UART3 */ - CMU_PERH_USART0 = (1U << 12) | (1U << 27), /**< USART0 */ - CMU_PERH_USART1 = (1U << 13) | (1U << 27), /**< USART1 */ - CMU_PERH_SPI0 = (1U << 16) | (1U << 27), /**< SPI0 */ - CMU_PERH_SPI1 = (1U << 17) | (1U << 27), /**< SPI1 */ - CMU_PERH_SPI2 = (1U << 18) | (1U << 27), /**< SPI2 */ - CMU_PERH_I2C0 = (1U << 20) | (1U << 27), /**< I2C0 */ - CMU_PERH_I2C1 = (1U << 21) | (1U << 27), /**< I2C1 */ - CMU_PERH_CAN = (1U << 24) | (1U << 27), /**< CAN */ - CMU_PERH_LPTIM0 = (1U << 0) | (1U << 28), /**< LPTIM0 */ - CMU_PERH_LPUART0 = (1U << 2) | (1U << 28), /**< LPUART0 */ - CMU_PERH_ADC0 = (1U << 4) | (1U << 28), /**< ADC0 */ - CMU_PERH_ADC1 = (1U << 5) | (1U << 28), /**< ADC1 */ - CMU_PERH_ACMP0 = (1U << 6) | (1U << 28), /**< ACMP0 */ - CMU_PERH_ACMP1 = (1U << 7) | (1U << 28), /**< ACMP1 */ - CMU_PERH_OPAMP = (1U << 8) | (1U << 28), /**< OPAMP */ - CMU_PERH_DAC0 = (1U << 9) | (1U << 28), /**< DAC0 */ - CMU_PERH_WWDT = (1U << 12) | (1U << 28), /**< WWDT */ - CMU_PERH_LCD = (1U << 13) | (1U << 28), /**< LCD */ - CMU_PERH_IWDT = (1U << 14) | (1U << 28), /**< IWDT */ - CMU_PERH_RTC = (1U << 15) | (1U << 28), /**< RTC */ - CMU_PERH_TEMP = (1U << 16) | (1U << 28), /**< TEMP */ - CMU_PERH_BKPC = (1U << 17) | (1U << 28), /**< BKPC */ - CMU_PERH_BKRPAM = (1U << 18) | (1U << 28), /**< BKPRAM */ - CMU_PERH_DBGC = (1U << 19) | (1U << 28), /**< DBGC */ - CMU_PERH_ALL = (0x7FFFFFFF), /**< ALL */ -} cmu_perh_t; - -/** - * @brief CMU interrupt type - */ -typedef enum -{ - CMU_LOSC_STOP = 0x0, /**< LOSC STOP INTERRUPT */ - CMU_HOSC_STOP = 0x1, /**< HOSC STOP INTERRUPT */ - CMU_PLL1_UNLOCK = 0x2, /**< PLL1 UNLOCK INTERRUPT */ - CMU_LOSC_START = 0x3, /**< LOSC START INTERRUPT */ - CMU_HOSC_START = 0x4, /**< HOSC START INTERRUPT */ -} cmu_security_t; - -/** - * @brief CMU clock state type - */ -typedef enum -{ - CMU_CLOCK_STATE_HOSCACT = (1U << 0), /**< HOSC active */ - CMU_CLOCK_STATE_LOSCACT = (1U << 1), /**< LOSC active */ - CMU_CLOCK_STATE_HRCACT = (1U << 2), /**< HRC active */ - CMU_CLOCK_STATE_LRCACT = (1U << 3), /**< LRC active */ - CMU_CLOCK_STATE_ULRCACT = (1U << 4), /**< ULRC active */ - CMU_CLOCK_STATE_PLLACT = (1U << 8), /**< PLL active */ - CMU_CLOCK_STATE_HOSCRDY = (1U << 16), /**< HOSC ready */ - CMU_CLOCK_STATE_LOSCRDY = (1U << 17), /**< LOSC ready */ - CMU_CLOCK_STATE_HRCRDY = (1U << 18), /**< HRC ready */ - CMU_CLOCK_STATE_LRCRDY = (1U << 19), /**< LRC ready */ - CMU_CLOCK_STATE_PLLRDY = (1U << 24), /**< PLL ready */ -} cmu_clock_state_t; -/** - * @} - */ - -/** - * @defgroup CMU_Private_Macros CMU Private Macros - * @{ - */ -#define IS_CMU_CLOCK(x) (((x) == CMU_CLOCK_HRC) || \ - ((x) == CMU_CLOCK_LRC) || \ - ((x) == CMU_CLOCK_LOSC) || \ - ((x) == CMU_CLOCK_PLL1) || \ - ((x) == CMU_CLOCK_HOSC)) -#define IS_CMU_PLL1_OUTPUT(x) (((x) == CMU_PLL1_OUTPUT_32M) || \ - ((x) == CMU_PLL1_OUTPUT_48M)) -#define IS_CMU_PLL1_INPUT(x) (((x) == CMU_PLL1_INPUT_HRC_6) || \ - ((x) == CMU_PLL1_INPUT_PLL2) || \ - ((x) == CMU_PLL1_INPUT_HOSC) || \ - ((x) == CMU_PLL1_INPUT_HOSC_2) || \ - ((x) == CMU_PLL1_INPUT_HOSC_3) || \ - ((x) == CMU_PLL1_INPUT_HOSC_4) || \ - ((x) == CMU_PLL1_INPUT_HOSC_5) || \ - ((x) == CMU_PLL1_INPUT_HOSC_6)) -#define IS_CMU_HOSC_RANGE(x) (((x) == CMU_HOSC_2M) || \ - ((x) == CMU_HOSC_4M) || \ - ((x) == CMU_HOSC_8M) || \ - ((x) == CMU_HOSC_16M) || \ - ((x) == CMU_HOSC_24M)) -#define IS_CMU_DIV(x) (((x) == CMU_DIV_1) || \ - ((x) == CMU_DIV_2) || \ - ((x) == CMU_DIV_4) || \ - ((x) == CMU_DIV_8) || \ - ((x) == CMU_DIV_16) || \ - ((x) == CMU_DIV_32) || \ - ((x) == CMU_DIV_64) || \ - ((x) == CMU_DIV_128) || \ - ((x) == CMU_DIV_256) || \ - ((x) == CMU_DIV_512) || \ - ((x) == CMU_DIV_1024) || \ - ((x) == CMU_DIV_2048) || \ - ((x) == CMU_DIV_4096)) -#define IS_CMU_BUS(x) (((x) == CMU_HCLK_1) || \ - ((x) == CMU_SYS) || \ - ((x) == CMU_PCLK_1) || \ - ((x) == CMU_PCLK_2)) -#define IS_CMU_OUTPUT_HIGH_SEL(x) (((x) == CMU_OUTPUT_HIGH_SEL_HOSC) || \ - ((x) == CMU_OUTPUT_HIGH_SEL_LOSC) || \ - ((x) == CMU_OUTPUT_HIGH_SEL_HRC) || \ - ((x) == CMU_OUTPUT_HIGH_SEL_LRC) || \ - ((x) == CMU_OUTPUT_HIGH_SEL_HOSM) || \ - ((x) == CMU_OUTPUT_HIGH_SEL_PLL1) || \ - ((x) == CMU_OUTPUT_HIGH_SEL_PLL2) || \ - ((x) == CMU_OUTPUT_HIGH_SEL_SYSCLK)) -#define IS_CMU_OUTPUT_HIGH_DIV(x) (((x) == CMU_OUTPUT_DIV_1) || \ - ((x) == CMU_OUTPUT_DIV_2) || \ - ((x) == CMU_OUTPUT_DIV_4) || \ - ((x) == CMU_OUTPUT_DIV_8) || \ - ((x) == CMU_OUTPUT_DIV_16) || \ - ((x) == CMU_OUTPUT_DIV_32) || \ - ((x) == CMU_OUTPUT_DIV_64) || \ - ((x) == CMU_OUTPUT_DIV_128)) -#define IS_CMU_OUTPUT_LOW_SEL(x) (((x) == CMU_OUTPUT_LOW_SEL_LOSC) || \ - ((x) == CMU_OUTPUT_LOW_SEL_LRC ) || \ - ((x) == CMU_OUTPUT_LOW_SEL_LOSM) || \ - ((x) == CMU_OUTPUT_LOW_SEL_BUZZ) || \ - ((x) == CMU_OUTPUT_LOW_SEL_ULRC)) -#define IS_CMU_AUTO_CALIB_INPUT(x) (((x) == CMU_AUTO_CALIB_INPUT_LOSE) || \ - ((x) == CMU_AUTO_CALIB_INPUT_HOSE)) -#define IS_CMU_AUTO_CALIB_OUTPUT(x) (((x) == CMU_AUTO_CALIB_OUTPUT_24M) || \ - ((x) == CMU_AUTO_CALIB_OUTPUT_2M)) -#define IS_CMU_BUZZ_DIV(x) (((x) == CMU_BUZZ_DIV_2) || \ - ((x) == CMU_BUZZ_DIV_4) || \ - ((x) == CMU_BUZZ_DIV_8) || \ - ((x) == CMU_BUZZ_DIV_16) || \ - ((x) == CMU_BUZZ_DIV_32) || \ - ((x) == CMU_BUZZ_DIV_64) || \ - ((x) == CMU_BUZZ_DIV_128) || \ - ((x) == CMU_BUZZ_DIV_256)) -#define IS_CMU_LP_PERH_CLOCK_SEL(x) (((x) == CMU_LP_PERH_CLOCK_SEL_PCLK2) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_PLL1) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_PLL2) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_HRC) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_HOSC) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_LRC) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_LOSC) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_ULRC) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_HRC_1M) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_HOSC_1M) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_LOSM) || \ - ((x) == CMU_LP_PERH_CLOCK_SEL_HOSM)) -#define IS_CMU_LCD_CLOCK_SEL(x) (((x) == CMU_LCD_SEL_LOSM) || \ - ((x) == CMU_LCD_SEL_LOSC) || \ - ((x) == CMU_LCD_SEL_LRC) || \ - ((x) == CMU_LCD_SEL_ULRC) || \ - ((x) == CMU_LCD_SEL_HRC_1M) || \ - ((x) == CMU_LCD_SEL_HOSC_1M)) -#define IS_CMU_PERH(x) (((x) == CMU_PERH_GPIO) || \ - ((x) == CMU_PERH_CRC) || \ - ((x) == CMU_PERH_CALC) || \ - ((x) == CMU_PERH_CRYPT) || \ - ((x) == CMU_PERH_TRNG) || \ - ((x) == CMU_PERH_PIS) || \ - ((x) == CMU_PERH_TIM0) || \ - ((x) == CMU_PERH_TIM1) || \ - ((x) == CMU_PERH_TIM2) || \ - ((x) == CMU_PERH_TIM3) || \ - ((x) == CMU_PERH_TIM4) || \ - ((x) == CMU_PERH_TIM5) || \ - ((x) == CMU_PERH_TIM6) || \ - ((x) == CMU_PERH_TIM7) || \ - ((x) == CMU_PERH_UART0) || \ - ((x) == CMU_PERH_UART1) || \ - ((x) == CMU_PERH_UART2) || \ - ((x) == CMU_PERH_UART3) || \ - ((x) == CMU_PERH_USART0) || \ - ((x) == CMU_PERH_USART1) || \ - ((x) == CMU_PERH_SPI0) || \ - ((x) == CMU_PERH_SPI1) || \ - ((x) == CMU_PERH_SPI2) || \ - ((x) == CMU_PERH_I2C0) || \ - ((x) == CMU_PERH_I2C1) || \ - ((x) == CMU_PERH_CAN) || \ - ((x) == CMU_PERH_LPTIM0) || \ - ((x) == CMU_PERH_LPUART0) || \ - ((x) == CMU_PERH_ADC0) || \ - ((x) == CMU_PERH_ADC1) || \ - ((x) == CMU_PERH_ACMP0) || \ - ((x) == CMU_PERH_ACMP1) || \ - ((x) == CMU_PERH_OPAMP) || \ - ((x) == CMU_PERH_DAC0) || \ - ((x) == CMU_PERH_WWDT) || \ - ((x) == CMU_PERH_LCD) || \ - ((x) == CMU_PERH_IWDT) || \ - ((x) == CMU_PERH_RTC) || \ - ((x) == CMU_PERH_TEMP) || \ - ((x) == CMU_PERH_BKPC) || \ - ((x) == CMU_PERH_BKRPAM ) || \ - ((x) == CMU_PERH_DBGC) || \ - ((x) == CMU_PERH_ALL)) -#define IS_CMU_CLOCK_STATE(x) (((x) == CMU_CLOCK_STATE_HOSCACT) || \ - ((x) == CMU_CLOCK_STATE_LOSCACT) || \ - ((x) == CMU_CLOCK_STATE_HRCACT) || \ - ((x) == CMU_CLOCK_STATE_LRCACT) || \ - ((x) == CMU_CLOCK_STATE_ULRCACT) || \ - ((x) == CMU_CLOCK_STATE_PLLACT) || \ - ((x) == CMU_CLOCK_STATE_HOSCRDY) || \ - ((x) == CMU_CLOCK_STATE_LOSCRDY) || \ - ((x) == CMU_CLOCK_STATE_HRCRDY) || \ - ((x) == CMU_CLOCK_STATE_LRCRDY) || \ - ((x) == CMU_CLOCK_STATE_PLLRDY)) -/** - * @} - */ - -/** @addtogroup CMU_Public_Functions - * @{ - */ -/** @addtogroup CMU_Public_Functions_Group1 - * @{ - */ -/* System clock configure */ -ald_status_t cmu_clock_config_default(void); -ald_status_t cmu_clock_config(cmu_clock_t clk, uint32_t clock); -void cmu_pll1_config(cmu_pll1_input_t input, cmu_pll1_output_t output); -uint32_t cmu_get_clock(void); -int32_t cmu_auto_calib_clock(cmu_auto_calib_input_t input, cmu_auto_calib_output_t freq); -/** - * @} - */ - -/** @addtogroup CMU_Public_Functions_Group2 - * @{ - */ -/* BUS division control */ -void cmu_div_config(cmu_bus_t bus, cmu_div_t div); -uint32_t cmu_get_hclk1_clock(void); -uint32_t cmu_get_sys_clock(void); -uint32_t cmu_get_pclk1_clock(void); -uint32_t cmu_get_pclk2_clock(void); -/** - * @} - */ - -/** @addtogroup CMU_Public_Functions_Group3 - * @{ - */ -/* Clock safe configure */ -void cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status); -void cmu_losc_safe_config(type_func_t status); -void cmu_pll_safe_config(type_func_t status); -flag_status_t cmu_get_clock_state(cmu_clock_state_t sr); -void cmu_irq_cbk(cmu_security_t se); -/** - * @} - */ - -/** @addtogroup CMU_Public_Functions_Group4 - * @{ - */ -/* Clock output configure */ -void cmu_output_high_clock_config(cmu_output_high_sel_t sel, - cmu_output_high_div_t div, type_func_t status); -void cmu_output_low_clock_config(cmu_output_low_sel_t sel, type_func_t status); -/** - * @} - */ - -/** @addtogroup CMU_Public_Functions_Group5 - * @{ - */ -/* Peripheral Clock configure */ -void cmu_buzz_config(cmu_buzz_div_t div, uint16_t dat, type_func_t status); -void cmu_lptim0_clock_select(cmu_lp_perh_clock_sel_t clock); -void cmu_lpuart0_clock_select(cmu_lp_perh_clock_sel_t clock); -void cmu_lcd_clock_select(cmu_lcd_clock_sel_t clock); -void cmu_perh_clock_config(cmu_perh_t perh, type_func_t status); -/** - * @} - */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_CMU_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dma.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dma.h deleted file mode 100644 index 646ae02a67..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dma.h +++ /dev/null @@ -1,389 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_dma.h - * @brief DMA module Library. - * - * @version V1.0 - * @date 09 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ********************************************************************************* - */ - -#ifndef __ALD_DMA_H__ -#define __ALD_DMA_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" - - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup DMA - * @{ - */ - -/** - * @defgroup DMA_Public_Macros DMA Public Macros - * @{ - */ -#define DMA_CH_COUNT 6 -#define DMA_ERR 31 -/** - * @} - */ - -/** - * @defgroup DMA_Public_Types DMA Public Types - * @{ - */ - -/** - * @brief Input source to DMA channel - */ -typedef enum -{ - DMA_MSEL_NONE = 0x0, /**< NONE */ - DMA_MSEL_GPIO = 0x1, /**< GPIO */ - DMA_MSEL_CRYPT = 0x2, /**< CRYPT */ - DMA_MSEL_ACMP = 0x3, /**< ACMP */ - DMA_MSEL_DAC0 = 0x4, /**< DAC0 */ - DMA_MSEL_ADC0 = 0x6, /**< ADC0 */ - DMA_MSEL_CRC = 0x7, /**< CRC */ - DMA_MSEL_UART0 = 0x8, /**< UART0 */ - DMA_MSEL_UART1 = 0x9, /**< UART1 */ - DMA_MSEL_UART2 = 0xA, /**< UART2 */ - DMA_MSEL_UART3 = 0xB, /**< UART3 */ - DMA_MSEL_USART0 = 0xC, /**< USART0 */ - DMA_MSEL_USART1 = 0xD, /**< USART1 */ - DMA_MSEL_SPI0 = 0xE, /**< SPI0 */ - DMA_MSEL_SPI1 = 0xF, /**< SPI1 */ - DMA_MSEL_I2C0 = 0x10, /**< I2C0 */ - DMA_MSEL_I2C1 = 0x11, /**< I2C1 */ - DMA_MSEL_TIMER0 = 0x12, /**< TIMER0 */ - DMA_MSEL_TIMER1 = 0x13, /**< TIMER1 */ - DMA_MSEL_TIMER2 = 0x14, /**< TIMER2 */ - DMA_MSEL_TIMER3 = 0x15, /**< TIMER3 */ - DMA_MSEL_RTC = 0x16, /**< RTC */ - DMA_MSEL_LPTIM0 = 0x17, /**< LPTIM0 */ - DMA_MSEL_LPUART0 = 0x18, /**< LPUART0 */ - DMA_MSEL_DMA = 0x19, /**< DMA */ - DMA_MSEL_SPI2 = 0x1A, /**< SPI2 */ - DMA_MSEL_TIMER4 = 0x1B, /**< TIMER4 */ - DMA_MSEL_TIMER5 = 0x1C, /**< TIMER5 */ - DMA_MSEL_TIMER6 = 0x1D, /**< TIMER6 */ - DMA_MSEL_TIMER7 = 0x1E, /**< TIMER7 */ - DMA_MSEL_ADC1 = 0x1F, /**< ADC1 */ - DMA_MSEL_PIS = 0x20, /**< PIS */ - DMA_MSEL_TRNG = 0x21, /**< TRNG */ -} dma_msel_t; - -/** - * @brief Input signal to DMA channel - */ -typedef enum -{ - DMA_MSIGSEL_NONE = 0x0, /**< NONE */ - DMA_MSIGSEL_EXTI_0 = 0x0, /**< External interrupt 0 */ - DMA_MSIGSEL_EXTI_1 = 0x1, /**< External interrupt 1 */ - DMA_MSIGSEL_EXTI_2 = 0x2, /**< External interrupt 2 */ - DMA_MSIGSEL_EXTI_3 = 0x3, /**< External interrupt 3 */ - DMA_MSIGSEL_EXTI_4 = 0x4, /**< External interrupt 4 */ - DMA_MSIGSEL_EXTI_5 = 0x5, /**< External interrupt 5 */ - DMA_MSIGSEL_EXTI_6 = 0x6, /**< External interrupt 6 */ - DMA_MSIGSEL_EXTI_7 = 0x7, /**< External interrupt 7 */ - DMA_MSIGSEL_EXTI_8 = 0x8, /**< External interrupt 8 */ - DMA_MSIGSEL_EXTI_9 = 0x9, /**< External interrupt 9 */ - DMA_MSIGSEL_EXTI_10 = 0xA, /**< External interrupt 10 */ - DMA_MSIGSEL_EXTI_11 = 0xB, /**< External interrupt 11 */ - DMA_MSIGSEL_EXTI_12 = 0xC, /**< External interrupt 12 */ - DMA_MSIGSEL_EXTI_13 = 0xD, /**< External interrupt 13 */ - DMA_MSIGSEL_EXTI_14 = 0xE, /**< External interrupt 14 */ - DMA_MSIGSEL_EXTI_15 = 0xF, /**< External interrupt 15 */ - DMA_MSIGSEL_CRYPT_WRITE = 0x0, /**< CRYPT write mode */ - DMA_MSIGSEL_CRYPT_READ = 0x1, /**< CRYPT read mode */ - DMA_MSIGSEL_CALC_WRITE = 0x0, /**< CALC write mode */ - DMA_MSIGSEL_CALC_READ = 0x1, /**< CALC read mode */ - DMA_MSIGSEL_DAC0_CH0 = 0x0, /**< DAC0 channel 0 complete */ - DMA_MSIGSEL_DAC0_CH1 = 0x1, /**< DAC0 channel 1 complete */ - DMA_MSIGSEL_ADC = 0x0, /**< ADC mode */ - DMA_MSIGSEL_UART_TXEMPTY = 0x0, /**< UART transmit */ - DMA_MSIGSEL_UART_RNR = 0x1, /**< UART receive */ - DMA_MSIGSEL_USART_RNR = 0x0, /**< USART reveive */ - DMA_MSIGSEL_USART_TXEMPTY = 0x1, /**< USART transmit */ - DMA_MSIGSEL_SPI_RNR = 0x0, /**< SPI receive */ - DMA_MSIGSEL_SPI_TXEMPTY = 0x1, /**< SPI transmit */ - DMA_MSIGSEL_I2C_RNR = 0x0, /**< I2C receive */ - DMA_MSIGSEL_I2C_TXEMPTY = 0x1, /**< I2C transmit */ - DMA_MSIGSEL_TIMER_CH1 = 0x0, /**< TIM channal 1 */ - DMA_MSIGSEL_TIMER_CH2 = 0x1, /**< TIM channal 2 */ - DMA_MSIGSEL_TIMER_CH3 = 0x2, /**< TIM channal 3 */ - DMA_MSIGSEL_TIMER_CH4 = 0x3, /**< TIM channal 4 */ - DMA_MSIGSEL_TIMER_TRI = 0x4, /**< TIM trigger */ - DMA_MSIGSEL_TIMER_COMP = 0x5, /**< TIM compare */ - DMA_MSIGSEL_TIMER_UPDATE = 0x6, /**< TIM update */ - DMA_MSIGSEL_LPUART_RNR = 0x0, /**< LPUART receive */ - DMA_MSIGSEL_LPUART_TXEMPTY = 0x1, /**< LPUART transmit */ - DMA_MSIGSEL_PIS_CH0 = 0x0, /**< PIS channal 0 */ - DMA_MSIGSEL_PIS_CH1 = 0x1, /**< PIS channal 1 */ - DMA_MSIGSEL_PIS_CH2 = 0x2, /**< PIS channal 2 */ - DMA_MSIGSEL_PIS_CH3 = 0x3, /**< PIS channal 3 */ - DMA_MSIGSEL_PIS_CH4 = 0x4, /**< PIS channal 4 */ - DMA_MSIGSEL_PIS_CH5 = 0x5, /**< PIS channal 5 */ - DMA_MSIGSEL_PIS_CH6 = 0x6, /**< PIS channal 6 */ - DMA_MSIGSEL_PIS_CH7 = 0x7, /**< PIS channal 7 */ - DMA_MSIGSEL_PIS_CH8 = 0x8, /**< PIS channal 8 */ - DMA_MSIGSEL_PIS_CH9 = 0x9, /**< PIS channal 9 */ - DMA_MSIGSEL_PIS_CH10 = 0xA, /**< PIS channal 10 */ - DMA_MSIGSEL_PIS_CH11 = 0xB, /**< PIS channal 11 */ - DMA_MSIGSEL_PIS_CH12 = 0xC, /**< PIS channal 12 */ - DMA_MSIGSEL_PIS_CH13 = 0xD, /**< PIS channal 13 */ - DMA_MSIGSEL_PIS_CH14 = 0xE, /**< PIS channal 14 */ - DMA_MSIGSEL_PIS_CH15 = 0xF, /**< PIS channal 15 */ -} dma_msigsel_t; - -/** - * @brief DMA Descriptor control type - */ -typedef union -{ - struct - { - uint32_t cycle_ctrl : 3; /**< DMA operating mode @ref dma_cycle_ctrl_t */ - uint32_t next_useburst : 1; /**< Uses the alternate data structure when complete a DMA cycle */ - uint32_t n_minus_1 : 10; /**< Represent the total number of DMA transfers that DMA cycle contains. */ - uint32_t R_power : 4; /**< Control how many DMA transfers can occur before re-arbitrates. @ref dma_arbiter_config_t */ - uint32_t src_prot_ctrl : 3; /**< Control the state of HPROT when reads the source data. */ - uint32_t dst_prot_ctrl : 3; /**< Control the state of HPROT when writes the destination data */ - uint32_t src_size : 2; /**< Source data size @ref dma_data_size_t */ - uint32_t src_inc : 2; /**< Control the source address increment. @ref dma_data_inc_t */ - uint32_t dst_size : 2; /**< Destination data size. @ref dma_data_size_t */ - uint32_t dst_inc : 2; /**< Destination address increment. @ref dma_data_inc_t */ - }; - uint32_t word; -} dma_ctrl_t; - -/** - * @brief Channel control data structure - */ -typedef struct -{ - void *src; /**< Source data end pointer */ - void *dst; /**< Destination data end pointer */ - dma_ctrl_t ctrl; /**< Control data configuration @ref dma_ctrl_t */ - uint32_t use; /**< Reserve for user */ -} dma_descriptor_t; - -/** - * @brief data increment - */ -typedef enum -{ - DMA_DATA_INC_BYTE = 0x0, /**< Address increment by byte */ - DMA_DATA_INC_HALFWORD = 0x1, /**< Address increment by halfword */ - DMA_DATA_INC_WORD = 0x2, /**< Address increment by word */ - DMA_DATA_INC_NONE = 0x3, /**< No increment */ -} dma_data_inc_t; - -/** - * @brief Data size - */ -typedef enum -{ - DMA_DATA_SIZE_BYTE = 0x0, /**< Byte */ - DMA_DATA_SIZE_HALFWORD = 0x1, /**< Halfword */ - DMA_DATA_SIZE_WORD = 0x2, /**< Word */ -} dma_data_size_t; - -/** - * @brief The operating mode of the DMA cycle - */ -typedef enum -{ - DMA_CYCLE_CTRL_NONE = 0x0, /**< Stop */ - DMA_CYCLE_CTRL_BASIC = 0x1, /**< Basic */ - DMA_CYCLE_CTRL_AUTO = 0x2, /**< Auto-request */ - DMA_CYCLE_CTRL_PINGPONG = 0x3, /**< Ping-pong */ - DMA_CYCLE_CTRL_MEM_SCATTER_GATHER = 0x4, /**< Memory scatter/gather */ - DMA_CYCLE_CTRL_PER_SCATTER_GATHER = 0x6, /**< Peripheral scatter/gather */ -} dma_cycle_ctrl_t; - -/** - * @brief Control how many DMA transfers can occur - * before the controller re-arbitrates - */ -typedef enum -{ - DMA_R_POWER_1 = 0x0, /**< Arbitrates after each DMA transfer */ - DMA_R_POWER_2 = 0x1, /**< Arbitrates after 2 DMA transfer */ - DMA_R_POWER_4 = 0x2, /**< Arbitrates after 4 DMA transfer */ - DMA_R_POWER_8 = 0x3, /**< Arbitrates after 8 DMA transfer */ - DMA_R_POWER_16 = 0x4, /**< Arbitrates after 16 DMA transfer */ - DMA_R_POWER_32 = 0x5, /**< Arbitrates after 32 DMA transfer */ - DMA_R_POWER_64 = 0x6, /**< Arbitrates after 64 DMA transfer */ - DMA_R_POWER_128 = 0x7, /**< Arbitrates after 128 DMA transfer */ - DMA_R_POWER_256 = 0x8, /**< Arbitrates after 256 DMA transfer */ - DMA_R_POWER_512 = 0x9, /**< Arbitrates after 512 DMA transfer */ - DMA_R_POWER_1024 = 0xA, /**< Arbitrates after 1024 DMA transfer */ -} dma_arbiter_config_t; - -/** - * @brief Callback function pointer and param - */ -typedef struct -{ - void (*cplt_cbk)(void *arg); /**< DMA transfers complete callback */ - void (*err_cbk)(void *arg); /**< DMA occurs error callback */ - void *cplt_arg; /**< The parameter of cplt_cbk() */ - void *err_arg; /**< The parameter of err_cbk() */ -} dma_call_back_t; - -/** - * @brief DMA channal configure structure - */ -typedef struct -{ - void *src; /**< Source data begin pointer */ - void *dst; /**< Destination data begin pointer */ - uint16_t size; /**< The total number of DMA transfers that DMA cycle contains */ - dma_data_size_t data_width; /**< Data width, @ref dma_data_size_t */ - dma_data_inc_t src_inc; /**< Source increment type. @ref dma_data_inc_t */ - dma_data_inc_t dst_inc; /**< Destination increment type. @ref dma_data_inc_t */ - dma_arbiter_config_t R_power; /**< Control how many DMA transfers can occur before re-arbitrates. @ref dma_arbiter_config_t */ - type_func_t primary; /**< Use primary descriptor or alternate descriptor */ - type_func_t burst; /**< Uses the alternate data structure when complete a DMA cycle */ - type_func_t high_prio; /**< High priority or default priority */ - type_func_t iterrupt; /**< Enable/disable interrupt */ - dma_msel_t msel; /**< Input source to DMA channel @ref dma_msel_t */ - dma_msigsel_t msigsel; /**< Input signal to DMA channel @ref dma_msigsel_t */ - uint8_t channel; /**< Channel index */ -} dma_config_t; - -/** - * @brief DMA handle structure definition - */ -typedef struct -{ - DMA_TypeDef *perh; /**< DMA registers base address */ - dma_config_t config; /**< Channel configure structure. @ref dma_config_t */ - void (*cplt_cbk)(void *arg); /**< DMA transfers complete callback */ - void (*err_cbk)(void *arg); /**< DMA bus occurs error callback */ - void *cplt_arg; /**< The parameter of cplt_cbk() */ - void *err_arg; /**< The parameter of err_cbk() */ -} dma_handle_t; -/** - * @} - */ - -/** - * @defgroup DMA_Private_Macros DMA Private Macros - * @{ - */ -#define IS_DMA_MSEL_TYPE(x) ((x) <= DMA_MSEL_TRNG) -#define IS_DMA_MSIGSEL_TYPE(x) ((x) <= 0xF) -#define IS_DMA_DATAINC_TYPE(x) (((x) == DMA_DATA_INC_BYTE) || \ - ((x) == DMA_DATA_INC_HALFWORD) || \ - ((x) == DMA_DATA_INC_WORD) || \ - ((x) == DMA_DATA_INC_NONE)) -#define IS_DMA_DATASIZE_TYPE(x) (((x) == DMA_DATA_SIZE_BYTE) || \ - ((x) == DMA_DATA_SIZE_HALFWORD) || \ - ((x) == DMA_DATA_SIZE_WORD)) -#define IS_CYCLECTRL_TYPE(x) (((x) == DMA_CYCLE_CTRL_NONE) || \ - ((x) == DMA_CYCLE_CTRL_BASIC) || \ - ((x) == DMA_CYCLE_CTRL_AUTO) || \ - ((x) == DMA_CYCLE_CTRL_PINGPONG) || \ - ((x) == DMA_CYCLE_CTRL_MEM_SCATTER_GATHER) || \ - ((x) == DMA_CYCLE_CTRL_PER_SCATTER_GATHER)) -#define IS_DMA_ARBITERCONFIG_TYPE(x) (((x) == DMA_R_POWER_1) || \ - ((x) == DMA_R_POWER_2) || \ - ((x) == DMA_R_POWER_4) || \ - ((x) == DMA_R_POWER_8) || \ - ((x) == DMA_R_POWER_16) || \ - ((x) == DMA_R_POWER_32) || \ - ((x) == DMA_R_POWER_64) || \ - ((x) == DMA_R_POWER_128) || \ - ((x) == DMA_R_POWER_256) || \ - ((x) == DMA_R_POWER_512) || \ - ((x) == DMA_R_POWER_1024)) -#define IS_DMA(x) ((x) == DMA0) -#define IS_DMA_CHANNEL(x) ((x) <= 5) -#define IS_DMA_DATA_SIZE(x) ((x) <= 1024) -#define IS_DMA_IT_TYPE(x) (((x) <= 5) || ((x) == 31)) -/** - * @} - */ - -/** - * @addtogroup DMA_Public_Functions - * @{ - */ - -/** @addtogroup DMA_Public_Functions_Group1 - * @{ - */ -/* Initialization functions */ -extern void dma_reset(DMA_TypeDef *DMAx); -extern void dma_init(DMA_TypeDef *DMAx); -extern void dma_config_struct(dma_config_t *p); -/** - * @} - */ - - -/** @addtogroup DMA_Public_Functions_Group2 - * @{ - */ -/* Configure DMA channel functions */ -extern void dma_config_auto(dma_handle_t *hperh); -extern void dma_restart_auto(dma_handle_t *hperh, void *src, void *dst, uint16_t size); -extern void dma_config_auto_easy(DMA_TypeDef *DMAx, void *src, void *dst, - uint16_t size, uint8_t channel, void (*cbk)(void *arg)); -extern void dma_config_basic(dma_handle_t *hperh); -extern void dma_restart_basic(dma_handle_t *hperh, void *src, void *dst, uint16_t size); -extern void dma_config_basic_easy(DMA_TypeDef *DMAx, void *src, void *dst, uint16_t size, dma_msel_t msel, - dma_msigsel_t msigsel, uint8_t channel, void (*cbk)(void *arg)); -/** - * @} - */ - -/** @addtogroup DMA_Public_Functions_Group3 - * @{ - */ -/* DMA control functions */ -extern void dma_channel_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state); -extern void dma_interrupt_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state); -extern it_status_t dma_get_it_status(DMA_TypeDef *DMAx, uint8_t channel); -extern flag_status_t dma_get_flag_status(DMA_TypeDef *DMAx, uint8_t channel); -extern void dma_clear_flag_status(DMA_TypeDef *DMAx, uint8_t channel); -void dma0_irq_cbk(void); -/** - * @} - */ - -/** - * @} - */ - - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /*__ALD_DMA_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_gpio.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_gpio.h deleted file mode 100644 index 7e93a95751..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_gpio.h +++ /dev/null @@ -1,288 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_gpio.h - * @brief Header file of GPIO module driver - * - * @version V1.0 - * @date 07 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ********************************************************************************* - */ - -#ifndef __ALD_GPIO_H__ -#define __ALD_GPIO_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" - - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup GPIO - * @{ - */ - -/** - * @defgroup GPIO_Public_Macros GPIO Public Macros - * @{ - */ -#define GPIO_PIN_0 (1U << 0) -#define GPIO_PIN_1 (1U << 1) -#define GPIO_PIN_2 (1U << 2) -#define GPIO_PIN_3 (1U << 3) -#define GPIO_PIN_4 (1U << 4) -#define GPIO_PIN_5 (1U << 5) -#define GPIO_PIN_6 (1U << 6) -#define GPIO_PIN_7 (1U << 7) -#define GPIO_PIN_8 (1U << 8) -#define GPIO_PIN_9 (1U << 9) -#define GPIO_PIN_10 (1U << 10) -#define GPIO_PIN_11 (1U << 11) -#define GPIO_PIN_12 (1U << 12) -#define GPIO_PIN_13 (1U << 13) -#define GPIO_PIN_14 (1U << 14) -#define GPIO_PIN_15 (1U << 15) -#define GPIO_PIN_ALL (0xFFFF) -/** - * @} - */ - -/** - * @defgroup GPIO_Public_Types GPIO Public Types - * @{ - */ - -/** - * @brief GPIO mode - */ -typedef enum -{ - GPIO_MODE_CLOSE = 0x0, /**< Digital close Analog open */ - GPIO_MODE_INPUT = 0x1, /**< Input */ - GPIO_MODE_OUTPUT = 0x2, /**< Output */ -} gpio_mode_t; - -/** - * @brief GPIO open-drain or push-pull - */ -typedef enum -{ - GPIO_PUSH_PULL = 0x0, /**< Push-Pull */ - GPIO_OPEN_DRAIN = 0x2, /**< Open-Drain */ - GPIO_OPEN_SOURCE = 0x3, /**< Open-Source */ -} gpio_odos_t; - -/** - * @brief GPIO push-up or push-down - */ -typedef enum -{ - GPIO_FLOATING = 0x0,/**< Floating */ - GPIO_PUSH_UP = 0x1,/**< Push-Up */ - GPIO_PUSH_DOWN = 0x2,/**< Push-Down */ - GPIO_PUSH_UP_DOWN = 0x3,/**< Push-Up and Push-Down */ -} gpio_push_t; - -/** - * @brief GPIO output drive - */ -typedef enum -{ - GPIO_OUT_DRIVE_NORMAL = 0x0, /**< Normal current flow */ - GPIO_OUT_DRIVE_STRONG = 0x1, /**< Strong current flow */ -} gpio_out_drive_t; - -/** - * @brief GPIO filter - */ -typedef enum -{ - GPIO_FILTER_DISABLE = 0x0, /**< Disable filter */ - GPIO_FILTER_ENABLE = 0x1, /**< Enable filter */ -} gpio_filter_t; - -/** - * @brief GPIO type - */ -typedef enum -{ - GPIO_TYPE_CMOS = 0x0, /**< CMOS Type */ - GPIO_TYPE_TTL = 0x1, /**< TTL Type */ -} gpio_type_t; - -/** - * @brief GPIO functions - */ -typedef enum -{ - GPIO_FUNC_0 = 0, /**< function #0 */ - GPIO_FUNC_1 = 1, /**< function #1 */ - GPIO_FUNC_2 = 2, /**< function #2 */ - GPIO_FUNC_3 = 3, /**< function #3 */ - GPIO_FUNC_4 = 4, /**< function #4 */ - GPIO_FUNC_5 = 5, /**< function #5 */ - GPIO_FUNC_6 = 6, /**< function #6 */ - GPIO_FUNC_7 = 7, /**< function #7 */ -} gpio_func_t; - - -/** - * @brief GPIO Init Structure definition - */ -typedef struct -{ - gpio_mode_t mode; /**< Specifies the operating mode for the selected pins. - This parameter can be any value of @ref gpio_mode_t */ - gpio_odos_t odos; /**< Specifies the Open-Drain or Push-Pull for the selected pins. - This parameter can be a value of @ref gpio_odos_t */ - gpio_push_t pupd; /**< Specifies the Pull-up or Pull-Down for the selected pins. - This parameter can be a value of @ref gpio_push_t */ - gpio_out_drive_t odrv; /**< Specifies the output driver for the selected pins. - This parameter can be a value of @ref gpio_out_drive_t */ - gpio_filter_t flt; /**< Specifies the input filter for the selected pins. - This parameter can be a value of @ref gpio_filter_t */ - gpio_type_t type; /**< Specifies the type for the selected pins. - This parameter can be a value of @ref gpio_type_t */ - gpio_func_t func; /**< Specifies the function for the selected pins. - This parameter can be a value of @ref gpio_func_t */ -} gpio_init_t; - -/** - * @brief EXTI trigger style - */ -typedef enum -{ - EXTI_TRIGGER_RISING_EDGE = 0, /**< Rising edge trigger */ - EXTI_TRIGGER_TRAILING_EDGE = 1, /**< Trailing edge trigger */ - EXTI_TRIGGER_BOTH_EDGE = 2, /**< Rising and trailing edge trigger */ -} exti_trigger_style_t; - -/** - * @brief EXTI filter clock select - */ -typedef enum -{ - EXTI_FILTER_CLOCK_10K = 0, /**< cks = 10KHz */ - EXTI_FILTER_CLOCK_32K = 1, /**< cks = 32KHz */ -} exti_filter_clock_t; - -/** - * @brief EXTI Init Structure definition - */ -typedef struct -{ - type_func_t filter; /**< Enable filter. */ - exti_filter_clock_t cks; /**< Filter clock select. */ - uint8_t filter_time; /**< Filter duration */ -} exti_init_t; -/** - * @} - */ - -/** - * @defgroup GPIO_Private_Macros GPIO Private Macros - * @{ - */ -#define PIN_MASK 0xFFFF -#define UNLOCK_KEY 0x55AA - -#define IS_GPIO_PIN(x) ((((x) & (uint16_t)0x00) == 0) && ((x) != (uint16_t)0x0)) -#define IS_GPIO_PORT(GPIOx) ((GPIOx == GPIOA) || \ - (GPIOx == GPIOB) || \ - (GPIOx == GPIOC) || \ - (GPIOx == GPIOD) || \ - (GPIOx == GPIOE) || \ - (GPIOx == GPIOF) || \ - (GPIOx == GPIOG) || \ - (GPIOx == GPIOH)) -#define IS_GPIO_MODE(x) (((x) == GPIO_MODE_CLOSE) || \ - ((x) == GPIO_MODE_INPUT) || \ - ((x) == GPIO_MODE_OUTPUT)) -#define IS_GPIO_ODOS(x) (((x) == GPIO_PUSH_PULL) || \ - ((x) == GPIO_OPEN_DRAIN) || \ - ((x) == GPIO_OPEN_SOURCE)) -#define IS_GPIO_PUPD(x) (((x) == GPIO_FLOATING) || \ - ((x) == GPIO_PUSH_UP) || \ - ((x) == GPIO_PUSH_DOWN) || \ - ((x) == GPIO_PUSH_UP_DOWN)) -#define IS_GPIO_ODRV(x) (((x) == GPIO_OUT_DRIVE_NORMAL) || \ - ((x) == GPIO_OUT_DRIVE_STRONG)) -#define IS_GPIO_FLT(x) (((x) == GPIO_FILTER_DISABLE) || \ - ((x) == GPIO_FILTER_ENABLE)) -#define IS_GPIO_TYPE(x) (((x) == GPIO_TYPE_TTL) || \ - ((x) == GPIO_TYPE_CMOS)) -#define IS_TRIGGER_STYLE(x) (((x) == EXTI_TRIGGER_RISING_EDGE) || \ - ((x) == EXTI_TRIGGER_TRAILING_EDGE) || \ - ((x) == EXTI_TRIGGER_BOTH_EDGE)) -#define IS_EXTI_FLTCKS_TYPE(x) (((x) == EXTI_FILTER_CLOCK_10K) || \ - ((x) == EXTI_FILTER_CLOCK_32K)) -#define IS_GPIO_FUNC(x) ((x) <= 7) -/** - * @} - */ - -/** @addtogroup GPIO_Public_Functions - * @{ - */ - -/** @addtogroup GPIO_Public_Functions_Group1 - * @{ - */ -void gpio_init(GPIO_TypeDef *GPIOx, uint16_t pin, gpio_init_t *init); -void gpio_init_default(GPIO_TypeDef *GPIOx, uint16_t pin); -void gpio_func_default(GPIO_TypeDef *GPIOx); -void gpio_exti_init(GPIO_TypeDef *GPIOx, uint16_t pin, exti_init_t *init); -/** - * @} - */ - -/** @addtogroup GPIO_Public_Functions_Group2 - * @{ - */ -uint8_t gpio_read_pin(GPIO_TypeDef *GPIOx, uint16_t pin); -void gpio_write_pin(GPIO_TypeDef *GPIOx, uint16_t pin, uint8_t val); -void gpio_toggle_pin(GPIO_TypeDef *GPIOx, uint16_t pin); -void gpio_toggle_dir(GPIO_TypeDef *GPIOx, uint16_t pin); -void gpio_lock_pin(GPIO_TypeDef *GPIOx, uint16_t pin); -uint16_t gpio_read_port(GPIO_TypeDef *GPIOx); -void gpio_write_port(GPIO_TypeDef *GPIOx, uint16_t val); -/** - * @} - */ - -/** @addtogroup GPIO_Public_Functions_Group3 - * @{ - */ -void gpio_exti_interrupt_config(uint16_t pin, exti_trigger_style_t style, type_func_t status); -flag_status_t gpio_exti_get_flag_status(uint16_t pin); -void gpio_exti_clear_flag_status(uint16_t pin); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_GPIO_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_i2c.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_i2c.h deleted file mode 100644 index f20384d7e1..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_i2c.h +++ /dev/null @@ -1,534 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_i2c.h - * @brief Header file of I2C driver - * - * @version V1.0 - * @date 15 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ******************************************************************************** - */ - -#ifndef __ALD_I2C_H__ -#define __ALD_I2C_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" -#include "ald_dma.h" -#include "ald_cmu.h" - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup I2C - * @{ - */ - -/** @defgroup I2C_Public_Types I2C Public Types - * @{ - */ -/** - * @brief I2C Error Code - */ -typedef enum -{ - I2C_ERROR_NONE = 0x0, /**< No error */ - I2C_ERROR_BERR = 0x1, /**< Berr error */ - I2C_ERROR_ARLO = 0x2, /**< Arlo error */ - I2C_ERROR_AF = 0x4, /**< Af error */ - I2C_ERROR_OVR = 0x8, /**< Ovr error */ - I2C_ERROR_DMA = 0x10, /**< Dma error */ - I2C_ERROR_TIMEOUT = 0x20, /**< Timeout error */ -} i2c_error_t; - -/** - * @brief I2C state structure definition - */ -typedef enum -{ - I2C_STATE_RESET = 0x0, /**< Peripheral is not yet Initialized */ - I2C_STATE_READY = 0x1, /**< Peripheral Initialized and ready for use */ - I2C_STATE_BUSY = 0x2, /**< An internal process is ongoing */ - I2C_STATE_BUSY_TX = 0x3, /**< Data Transmission process is ongoing */ - I2C_STATE_BUSY_RX = 0x4, /**< Data Reception process is ongoing */ - I2C_STATE_TIMEOUT = 0x5, /**< timeout state */ - I2C_STATE_ERROR = 0x6, /**< Error */ -} i2c_state_t; - -/** - * @brief I2C Duty Cycle - */ -typedef enum -{ - I2C_DUTYCYCLE_2 = 0x0, /**< duty cycle is 2 */ - I2C_DUTYCYCLE_16_9 = 0x4000, /**< duty cycle is 16/9 */ -} i2c_duty_t; - -/** - * @brief I2C Addressing Mode - */ -typedef enum -{ - I2C_ADDR_7BIT = 0x1, /**< 7 bit address */ - I2C_ADDR_10BIT = 0x2, /**< 10 bit address */ -} i2c_addr_t; - -/** - * @brief I2C Dual Addressing Mode - */ -typedef enum -{ - I2C_DUALADDR_DISABLE = 0x0, /**< dual address is disable */ - I2C_DUALADDR_ENABLE = 0x1, /**< dual address is enable */ -} i2c_dual_addr_t; - -/** - * @brief I2C General Call Addressing mode - */ -typedef enum -{ - I2C_GENERALCALL_DISABLE = 0x0, /**< feneral call address is disable */ - I2C_GENERALCALL_ENABLE = 0x40, /**< feneral call address is enable */ -} i2c_general_addr_t; - -/** - * @brief I2C Nostretch Mode - */ -typedef enum -{ - I2C_NOSTRETCH_DISABLE = 0x0, /**< Nostretch disable */ - I2C_NOSTRETCH_ENABLE = 0x80, /**< Nostretch enable */ -} i2c_nostretch_t; - -/** - * @brief I2C Memory Address Size - */ -typedef enum -{ - I2C_MEMADD_SIZE_8BIT = 0x1, /**< 8 bit memory address size */ - I2C_MEMADD_SIZE_16BIT = 0x10 /**< 10 bit memory address size */ -} i2c_addr_size_t; - -/** - * @brief I2C Flag Definition - */ -typedef enum -{ - I2C_FLAG_SB = (1U << 0), - I2C_FLAG_ADDR = (1U << 1), - I2C_FLAG_BTF = (1U << 2), - I2C_FLAG_ADD10 = (1U << 3), - I2C_FLAG_STOPF = (1U << 4), - I2C_FLAG_RXNE = (1U << 6), - I2C_FLAG_TXE = (1U << 7), - I2C_FLAG_BERR = (1U << 8), - I2C_FLAG_ARLO = (1U << 9), - I2C_FLAG_AF = (1U << 10), - I2C_FLAG_OVR = (1U << 11), - I2C_FLAG_PECERR = (1U << 12), - I2C_FLAG_TIMEOUT = (1U << 14), - I2C_FLAG_SMBALERT = (1U << 15), - I2C_FLAG_MSL = (1U << 16), - I2C_FLAG_BUSY = (1U << 17), - I2C_FLAG_TRA = (1U << 18), - I2C_FLAG_GENCALL = (1U << 20), - I2C_FLAG_SMBDEFAULT = (1U << 21), - I2C_FLAG_SMBHOST = (1U << 22), - I2C_FLAG_DUALF = (1U << 23), -} i2c_flag_t; - -/** - * @brief I2C mode structure definition - */ -typedef enum -{ - I2C_MODE_NONE = 0x0, /**< No I2C communication on going */ - I2C_MODE_MASTER = 0x10, /**< I2C communication is in Master mode */ - I2C_MODE_SLAVE = 0x20, /**< I2C communication is in Slave mode */ - I2C_MODE_MEM = 0x40, /**< I2C communication is in Memory mode */ -} i2c_mode_t; - -/** - * @brief I2C Clock - */ -typedef enum -{ - I2C_STANDARD_MODE_MAX_CLK = 100000, /**< Standard mode clock */ - I2C_FAST_MODE_MAX_CLK = 400000, /**< Fast mode clock */ -} i2c_clock_t; - -/** - * @brief Interrupt Configuration Definition - */ -typedef enum -{ - I2C_IT_BUF = (1U << 10), /**< Buffer interrupt */ - I2C_IT_EVT = (1U << 9), /**< Event interrupt */ - I2C_IT_ERR = (1U << 8), /**< Error interrupt */ -} i2c_interrupt_t; - -/** - * @brief I2C CON1 Register - */ -typedef enum -{ - I2C_CON1_PEN = (1U << 0), /**< PEN BIT */ - I2C_CON1_PMOD = (1U << 1), /**< PMOD BIT */ - I2C_CON1_SMBMOD = (1U << 3), /**< SMBMOD BIT */ - I2C_CON1_ARPEN = (1U << 4), /**< ARPEN BIT */ - I2C_CON1_PECEN = (1U << 5), /**< PECEN BIT */ - I2C_CON1_GCEN = (1U << 6), /**< GCEN BIT */ - I2C_CON1_DISCS = (1U << 7), /**< DISCS BIT */ - I2C_CON1_START = (1U << 8), /**< START BIT */ - I2C_CON1_STOP = (1U << 9), /**< STOP BIT */ - I2C_CON1_ACKEN = (1U << 10), /**< ACKEN BIT */ - I2C_CON1_POSAP = (1U << 11), /**< POSAP BIT */ - I2C_CON1_TRPEC = (1U << 12), /**< TRPEC BIT */ - I2C_CON1_ALARM = (1U << 13), /**< ALARM BIT */ - I2C_CON1_SRST = (1U << 15), /**< SRST BIT */ -} i2c_con1_t; - -/** - * @brief I2C CON2 Register - */ -typedef enum -{ - I2C_CON2_CLKF = 0x3F, /**< CLKF BITS */ - I2C_CON2_CLKF_0 = (1U << 0), /**< CLKF_0 BIT */ - I2C_CON2_CLKF_1 = (1U << 1), /**< CLKF_1 BIT */ - I2C_CON2_CLKF_2 = (1U << 2), /**< CLKF_2 BIT */ - I2C_CON2_CLKF_3 = (1U << 3), /**< CLKF_3 BIT */ - I2C_CON2_CLKF_4 = (1U << 4), /**< CLKF_4 BIT */ - I2C_CON2_CLKF_5 = (1U << 5), /**< CLKF_5 BIT */ - I2C_CON2_ERRIE = (1U << 8), /**< ERRIE BIT */ - I2C_CON2_EVTIE = (1U << 9), /**< EVTIE BIT */ - I2C_CON2_BUFIE = (1U << 10), /**< BUFIE BIT */ - I2C_CON2_DMAEN = (1U << 11), /**< DMAEN BIT */ - I2C_CON2_LDMA = (1U << 12), /**< LDMA BIT */ -} i2c_con2_t; - -/** - * @brief I2C ADDR1 Register - */ -typedef enum -{ - I2C_ADDR1_ADDH0 = (1U << 0), /**< ADDH0 BIT */ - I2C_ADDR1_ADDH1 = (1U << 1), /**< ADDH1 BIT */ - I2C_ADDR1_ADDH2 = (1U << 2), /**< ADDH2 BIT */ - I2C_ADDR1_ADDH3 = (1U << 3), /**< ADDH3 BIT */ - I2C_ADDR1_ADDH4 = (1U << 4), /**< ADDH4 BIT */ - I2C_ADDR1_ADDH5 = (1U << 5), /**< ADDH5 BIT */ - I2C_ADDR1_ADDH6 = (1U << 6), /**< ADDH6 BIT */ - I2C_ADDR1_ADDH7 = (1U << 7), /**< ADDH7 BIT */ - I2C_ADDR1_ADDH8 = (1U << 8), /**< ADDH8 BIT */ - I2C_ADDR1_ADDH9 = (1U << 9), /**< ADDH9 BIT */ - I2C_ADDR1_ADDTYPE = (1U << 15), /**< ADDTYPE BIT */ -} i2c_addr1_t; - -/** - * @brief I2C ADDR2 Register - */ -typedef enum -{ - I2C_ADDR2_DUALEN = (1U << 0), /**< DUALEN BIT */ - I2C_ADDR2_ADD = (1U << 1), /**< ADD BIT */ -} i2c_addr2_t; - -/** - * @brief I2C STAT1 Register - */ -typedef enum -{ - I2C_STAT1_SB = (1U << 0), /**< SB BIT */ - I2C_STAT1_ADDR = (1U << 1), /**< ADDR BIT */ - I2C_STAT1_BTC = (1U << 2), /**< BTC BIT */ - I2C_STAT1_SENDADD10 = (1U << 3), /**< SENDADD10 BIT */ - I2C_STAT1_DETSTP = (1U << 4), /**< DETSTP BIT */ - I2C_STAT1_RXBNE = (1U << 6), /**< RXBNE BIT */ - I2C_STAT1_TXBE = (1U << 7), /**< TXBE BIT */ - I2C_STAT1_BUSERR = (1U << 8), /**< BUSERR BIT */ - I2C_STAT1_LARB = (1U << 9), /**< LARB BIT */ - I2C_STAT1_ACKERR = (1U << 10), /**< ACKERR BIT */ - I2C_STAT1_ROUERR = (1U << 11), /**< ROUERR BIT */ - I2C_STAT1_PECERR = (1U << 12), /**< PECERR BIT */ - I2C_STAT1_SMBTO = (1U << 14), /**< SMBTO BIT */ - I2C_STAT1_SMBALARM = (1U << 15), /**< SMBALARM BIT */ -} i2c_stat1_t; - -/** - * @brief I2C STAT2 Register - */ -typedef enum -{ - I2C_STAT2_MASTER = (1U << 0), /**< MASTER BIT */ - I2C_STAT2_BSYF = (1U << 1), /**< BSYF BIT */ - I2C_STAT2_TRF = (1U << 2), /**< TRF BIT */ - I2C_STAT2_RXGCF = (1U << 4), /**< RXGCF BIT */ - I2C_STAT2_SMBDEF = (1U << 5), /**< SMBDEF BIT */ - I2C_STAT2_SMBHH = (1U << 6), /**< SMBHH BIT */ - I2C_STAT2_DUALF = (1U << 7), /**< DMF BIT */ - I2C_STAT2_PECV = (1U << 8), /**< PECV BIT */ -} i2c_stat2_t; - -/** - * @brief I2C CKCFG Register - */ -typedef enum -{ - I2C_CKCFG_CLKSET = 0xFFF, /**< CLKSET BITS */ - I2C_CKCFG_DUTY = (1U << 14), /**< DUTY BIT */ - I2C_CKCFG_CLKMOD = (1U << 15), /**< CLKMOD BIT */ -} i2c_ckcfg_t; - -/** - * @brief I2C RT Register - */ -typedef enum -{ - I2C_RT_RISET = 0x3F, /**< RISET BITS */ -} i2c_trise_t; - -/** - * @brief I2C Configuration Structure definition - */ -typedef struct -{ - uint32_t clk_speed; /**< Specifies the clock frequency */ - i2c_duty_t duty; /**< Specifies the I2C fast mode duty cycle */ - uint32_t own_addr1; /**< Specifies the first device own address */ - i2c_addr_t addr_mode; /**< Specifies addressing mode */ - i2c_dual_addr_t dual_addr; /**< Specifies if dual addressing mode is selected */ - uint32_t own_addr2; /**< Specifies the second device own address */ - i2c_general_addr_t general_call; /**< Specifies if general call mode is selected */ - i2c_nostretch_t no_stretch; /**< Specifies if nostretch mode is selected */ -} i2c_init_t; - -/** - * @brief I2C handle Structure definition - */ -typedef struct i2c_handle_s -{ - I2C_TypeDef *perh; /**< I2C registers base address */ - i2c_init_t init; /**< I2C communication parameters */ - uint8_t *p_buff; /**< Pointer to I2C transfer buffer */ - uint16_t xfer_size; /**< I2C transfer size */ - __IO uint16_t xfer_count; /**< I2C transfer counter */ -#ifdef ALD_DMA - dma_handle_t hdmatx; /**< I2C Tx DMA handle parameters */ - dma_handle_t hdmarx; /**< I2C Rx DMA handle parameters */ -#endif - lock_state_t lock; /**< I2C locking object */ - __IO i2c_state_t state; /**< I2C communication state */ - __IO i2c_mode_t mode; /**< I2C communication mode */ - __IO uint32_t error_code; /**< I2C Error code */ - - void (*master_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Master Tx completed callback */ - void (*master_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Master Rx completed callback */ - void (*slave_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Slave Tx completed callback */ - void (*slave_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Slave Rx completed callback */ - void (*mem_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Tx to Memory completed callback */ - void (*mem_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Rx from Memory completed callback */ - void (*error_callback)(struct i2c_handle_s *arg); /**< Error callback */ -} i2c_handle_t; - -/** - * @} - */ - -/** @defgroup I2C_Public_Macro I2C Public Macros - * @{ - */ -#define I2C_RESET_HANDLE_STATE(x) ((x)->state = I2C_STATE_RESET) -#define I2C_CLEAR_ADDRFLAG(x) \ -do { \ - __IO uint32_t tmpreg; \ - tmpreg = (x)->perh->STAT1; \ - tmpreg = (x)->perh->STAT2; \ - UNUSED(tmpreg); \ -} while (0) -#define __I2C_CLEAR_STOPFLAG(x) \ -do { \ - __IO uint32_t tmpreg; \ - tmpreg = (x)->perh->STAT1; \ - tmpreg = SET_BIT((x)->perh->CON1, I2C_CON1_PEN); \ - UNUSED(tmpreg); \ -} while (0) -#define I2C_ENABLE(x) (SET_BIT((x)->perh->CON1, I2C_CON1_PEN_MSK)) -#define I2C_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, I2C_CON1_PEN_MSK)) -/** - * @} - */ - -/** @defgroup I2C_Private_Macro I2C Private Macros - * @{ - */ -#define IS_I2C_TYPE(x) (((x) == I2C0) || \ - ((x) == I2C1)) -#define IS_I2C_ADDRESSING_MODE(x) (((x) == I2C_ADDR_7BIT) || \ - ((x) == I2C_ADDR_10BIT)) -#define IS_I2C_DUAL_ADDRESS(x) (((x) == I2C_DUALADDR_DISABLE) || \ - ((x) == I2C_DUALADDR_ENABLE)) -#define IS_I2C_GENERAL_CALL(x) (((x) == I2C_GENERALCALL_DISABLE) || \ - ((x) == I2C_GENERALCALL_ENABLE)) -#define IS_I2C_MEMADD_size(x) (((x) == I2C_MEMADD_SIZE_8BIT) || \ - ((x) == I2C_MEMADD_SIZE_16BIT)) -#define IS_I2C_NO_STRETCH(x) (((x) == I2C_NOSTRETCH_DISABLE) || \ - ((x) == I2C_NOSTRETCH_ENABLE)) -#define IS_I2C_OWN_ADDRESS1(x) (((x) & (uint32_t)(0xFFFFFC00)) == 0) -#define IS_I2C_OWN_ADDRESS2(x) (((x) & (uint32_t)(0xFFFFFF01)) == 0) -#define IS_I2C_CLOCK_SPEED(x) (((x) > 0) && ((x) <= I2C_FAST_MODE_MAX_CLK)) -#define IS_I2C_DUTY_CYCLE(x) (((x) == I2C_DUTYCYCLE_2) || \ - ((x) == I2C_DUTYCYCLE_16_9)) -#define IS_I2C_IT_TYPE(x) (((x) == I2C_IT_BUF) || \ - ((x) == I2C_IT_EVT) || \ - ((x) == I2C_IT_ERR)) -#define IS_I2C_FLAG(x) (((x) == I2C_FLAG_SB) || \ - ((x) == I2C_FLAG_ADDR) || \ - ((x) == I2C_FLAG_BTF) || \ - ((x) == I2C_FLAG_ADD10) || \ - ((x) == I2C_FLAG_STOPF) || \ - ((x) == I2C_FLAG_RXNE) || \ - ((x) == I2C_FLAG_TXE) || \ - ((x) == I2C_FLAG_BERR) || \ - ((x) == I2C_FLAG_ARLO) || \ - ((x) == I2C_FLAG_AF) || \ - ((x) == I2C_FLAG_OVR) || \ - ((x) == I2C_FLAG_PECERR) || \ - ((x) == I2C_FLAG_TIMEOUT) || \ - ((x) == I2C_FLAG_SMBALERT) || \ - ((x) == I2C_FLAG_MSL) || \ - ((x) == I2C_FLAG_BUSY) || \ - ((x) == I2C_FLAG_TRA) || \ - ((x) == I2C_FLAG_GENCALL) || \ - ((x) == I2C_FLAG_SMBDEFAULT) || \ - ((x) == I2C_FLAG_SMBHOST) || \ - ((x) == I2C_FLAG_DUALF)) - -#define I2C_FREQ_RANGE(x) ((x) / 1000000) -#define I2C_RISE_TIME(x, u) (((u) <= I2C_STANDARD_MODE_MAX_CLK) ? ((x) + 1) :\ - ((((x) * 300) / 1000) + 1)) -#define I2C_SPEED_STANDARD(x, y) (((((x) / ((y) << 1)) & I2C_CKCFG_CLKSET) < 4) ? 4:\ - ((x) / ((y) << 1))) -#define I2C_SPEED_FAST(x, y, z) (((z) == I2C_DUTYCYCLE_2) ? ((x) / ((y) * 3)) :\ - (((x) / ((y) * 25)) | I2C_DUTYCYCLE_16_9)) -#define I2C_SPEED(x, y, z) (((y) <= 100000) ? (I2C_SPEED_STANDARD((x), (y))) :\ - ((I2C_SPEED_FAST((x), (y), (z)) & I2C_CKCFG_CLKSET) == 0) ? 1 : \ - ((I2C_SPEED_FAST((x), (y), (z))) | I2C_CKCFG_CLKMOD)) -#define I2C_MEM_ADD_MSB(x) ((uint8_t)((uint16_t)(((uint16_t)((x) &\ - (uint16_t)(0xFF00))) >> 8))) -#define I2C_MEM_ADD_LSB(x) ((uint8_t)((uint16_t)((x) & (uint16_t)(0x00FF)))) -#define I2C_7BIT_ADD_WRITE(x) ((uint8_t)((x) & (~I2C_ADDR1_ADDH0))) -#define I2C_7BIT_ADD_READ(x) ((uint8_t)((x) | I2C_ADDR1_ADDH0)) -#define I2C_10BIT_ADDRESS(x) ((uint8_t)((uint16_t)((x) & (uint16_t)(0x00FF)))) -#define I2C_10BIT_HEADER_WRITE(x) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((x) &\ - (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF0)))) -#define I2C_10BIT_HEADER_READ(x) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((x) &\ - (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF1)))) -/** - * @} - */ - -/** @addtogroup I2C_Public_Functions - * @{ - */ - -/** @addtogroup I2C_Public_Functions_Group1 - * @{ - */ -ald_status_t i2c_init(i2c_handle_t *hperh); -ald_status_t i2c_reset(i2c_handle_t *hperh); - -/** - * @} - */ - -/** @addtogroup I2C_Public_Functions_Group2 - * @{ - */ -/** Blocking mode: Polling */ -ald_status_t i2c_master_send(i2c_handle_t *hperh, uint16_t dev_addr, - uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t i2c_master_recv(i2c_handle_t *hperh, uint16_t dev_addr, - uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t i2c_slave_send(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t i2c_slave_recv(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t i2c_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, - i2c_addr_size_t add_size, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t i2c_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, - i2c_addr_size_t add_size, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t i2c_is_device_ready(i2c_handle_t *hperh, uint16_t dev_addr, uint32_t trials, uint32_t timeout); - -/** Non-Blocking mode: Interrupt */ -ald_status_t i2c_master_send_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint16_t size); -ald_status_t i2c_master_recv_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint16_t size); -ald_status_t i2c_slave_send_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t i2c_slave_recv_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t i2c_mem_write_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, - i2c_addr_size_t add_size, uint8_t *buf, uint16_t size); -ald_status_t i2c_mem_read_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, - i2c_addr_size_t add_size, uint8_t *buf, uint16_t size); - -#ifdef ALD_DMA -/** Non-Blocking mode: DMA */ -ald_status_t i2c_master_send_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, - uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t i2c_master_recv_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, - uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t i2c_slave_send_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t i2c_slave_recv_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t i2c_mem_write_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size, - uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t i2c_mem_read_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, - i2c_addr_size_t add_size, uint8_t *buf, uint16_t size, uint8_t channel); -#endif -/** - * @} - */ - -/** @addtogroup I2C_Public_Functions_Group3 - * @{ - */ -i2c_state_t i2c_get_state(i2c_handle_t *hperh); -uint32_t i2c_get_error(i2c_handle_t *hperh); -flag_status_t i2c_get_flag_status(i2c_handle_t *hperh, i2c_flag_t flag); -flag_status_t i2c_get_it_status(i2c_handle_t *hperh, i2c_interrupt_t it); -void i2c_clear_flag_status(i2c_handle_t *hperh, i2c_flag_t flag); -/** - * @} - */ - -/** @addtogroup I2C_Public_Functions_Group4 - * @{ - */ -void i2c_interrupt_config(i2c_handle_t *hperh, i2c_interrupt_t it, type_func_t state); -void i2c_ev_irq_handler(i2c_handle_t *hperh); -void i2c_er_irq_handler(i2c_handle_t *hperh); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_I2C_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pis.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pis.h deleted file mode 100644 index 3b7c12cf0f..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pis.h +++ /dev/null @@ -1,633 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_pis.h - * @brief Header file of PIS driver. - * - * @version V1.0 - * @date 27 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ********************************************************************************* - */ - -#ifndef __ALD_PIS_H__ -#define __ALD_PIS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" - - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup PIS - * @{ - */ - -/** @defgroup PIS_Public_Types PIS Public Types - * @{ - */ - -/** - * @brief Producer entry - */ -typedef enum -{ - PIS_NON = 0x0, /**< No async */ - PIS_GPIO_PIN0 = 0x10, /**< Pin0, level,support async */ - PIS_GPIO_PIN1 = 0x11, /**< Pin1, level,support async */ - PIS_GPIO_PIN2 = 0x12, /**< Pin2, level,support async */ - PIS_GPIO_PIN3 = 0x13, /**< Pin3, level,support async */ - PIS_GPIO_PIN4 = 0x14, /**< Pin4, level,support async */ - PIS_GPIO_PIN5 = 0x15, /**< Pin5, level,support async */ - PIS_GPIO_PIN6 = 0x16, /**< Pin6, level,support async */ - PIS_GPIO_PIN7 = 0x17, /**< Pin7, level,support async */ - PIS_GPIO_PIN8 = 0x18, /**< Pin8, level,support async */ - PIS_GPIO_PIN9 = 0x19, /**< Pin9, level,support async */ - PIS_GPIO_PIN10 = 0x1a, /**< Pin10, level,support async */ - PIS_GPIO_PIN11 = 0x1b, /**< Pin11, level,support async */ - PIS_GPIO_PIN12 = 0x1c, /**< Pin12, level,support async */ - PIS_GPIO_PIN13 = 0x1d, /**< Pin13, level,support async */ - PIS_GPIO_PIN14 = 0x1e, /**< Pin14, level,support async */ - PIS_GPIO_PIN15 = 0x1f, /**< Pin15, level,support async */ - PIS_ACMP_OUT0 = 0x30, /**< Acmp0 output, level,support async */ - PIS_ACMP_OUT1 = 0x31, /**< Acmp1 output, level,support async */ - PIS_DAC0_CH0 = 0x40, /**< Dac0 channel 0, pclk2 pulse,support async */ - PIS_DAC0_CH1 = 0x41, /**< Dac0 channel 1, pclk2 pulse,support async */ - PIS_ADC0_INJECT = 0x60, /**< Adc0 inject, pclk2 pulse,support async */ - PIS_ADC0_REGULAT = 0x61, /**< Adc0 regulat, pclk2 pulse,support async */ - PIS_ADC0_WINDOW = 0x62, /**< Adc0 window, no have */ - PIS_LVD = 0x70, /**< Lvd, level,support async */ - PIS_UART0_ASY_SEND = 0x80, /**< Uart0 asy send, pulse,support async */ - PIS_UART0_ASY_RECV = 0x81, /**< Uart0 asy recv, pulse,support async */ - PIS_UART0_IRDAOUT = 0x82, /**< Uart0 irdaout, level,support async */ - PIS_UART0_RTSOUT = 0x83, /**< Uart0 rtsout, level,support async */ - PIS_UART0_TXOUT = 0x84, /**< Uart0 txout, level,support async */ - PIS_UART0_SYN_SEND = 0x85, /**< Uart0 syn send, pulse,support async */ - PIS_UART0_SYN_RECV = 0x86, /**< Uart0 syn recv, pulse,support async */ - PIS_UART1_ASY_SEND = 0x90, /**< Uart1 asy send, pulse,support async */ - PIS_UART1_ASY_RECV = 0x91, /**< Uart1 asy recv, pulse,support async */ - PIS_UART1_IRDA = 0x92, /**< Uart1 irdaout, level,support async */ - PIS_UART1_RTS = 0x93, /**< Uart1 rtsout, level,support async */ - PIS_UART1_TXOUT = 0x94, /**< Uart1 txout, level,support async */ - PIS_UART1_SYN_SEND = 0x95, /**< Uart1 syn send, pulse,support async */ - PIS_UART1_SYN_RECV = 0x96, /**< Uart1 syn recv, pulse,support async */ - PIS_UART2_ASY_SEND = 0xa0, /**< Uart2 asy send, pulse,support async */ - PIS_UART2_ASY_RECV = 0xa1, /**< Uart2 asy recv, pulse,support async */ - PIS_UART2_IRDA = 0xa2, /**< Uart2 irdaout, level,support async */ - PIS_UART2_RTS = 0xa3, /**< Uart2 rtsout, level,support async */ - PIS_UART2_TXOUT = 0xa4, /**< Uart2 txout, level,support async */ - PIS_UART2_SYN_SEND = 0xa5, /**< Uart2 syn send, pulse,support async */ - PIS_UART2_SYN_RECV = 0xa6, /**< Uart2 syn recv, pulse,support async */ - PIS_UART3_ASY_SEND = 0xb1, /**< Uart3 asy send, pulse,support async */ - PIS_UART3_ASY_RECV = 0xb2, /**< Uart3 asy recv, pulse,support async */ - PIS_UART3_IRDA = 0xb3, /**< Uart3 irdaout, level,support async */ - PIS_UART3_RTS = 0xb4, /**< Uart3 rtsout, level,support async */ - PIS_UART3_TXOUT = 0xb5, /**< Uart3 txout, level,support async */ - PIS_UART3_SYN_SEND = 0xb6, /**< Uart3 syn send, pulse,support async */ - PIS_UART3_SYN_RECV = 0xb7, /**< Uart3 syn recv, pulse,support async */ - PIS_EUART0_RECV = 0xc0, /**< Euart0 recv, plck1 pulse */ - PIS_EUART0_SEND = 0xc1, /**< Euart0 send, plck1 pulse */ - PIS_EUART0_TXOUT = 0xc2, /**< Euart0 txout, plck1 level */ - PIS_EUART1_RECV = 0xd0, /**< Euart1 recv, plck1 pulse */ - PIS_EUART1_SEND = 0xd1, /**< Euart1 send, plck1 pulse */ - PIS_EUART1_TXOUT = 0xd2, /**< Euart1 txout, plck1 level */ - PIS_SPI0_RECV = 0xe0, /**< Spi0 recv, plck1 pulse */ - PIS_SPI0_SEND = 0xe1, /**< Spi0 send, plck1 pulse */ - PIS_SPI0_NE = 0xe2, /**< Spi0 ne, plck1 level */ - PIS_SPI1_RECV = 0xf0, /**< Spi1 recv, plck1 pulse */ - PIS_SPI1_SEND = 0xf1, /**< Spi1 send, plck1 pulse */ - PIS_SPI1_NE = 0xf2, /**< Spi1 ne, plck1 level */ - PIS_I2C0_RECV = 0x100, /**< I2c0 recv, plck1 level */ - PIS_I2C0_SEND = 0x101, /**< I2c0 send, plck1 level */ - PIS_I2C1_RECV = 0x110, /**< I2c1 recv, plck1 level */ - PIS_I2C1_SEND = 0x111, /**< I2c1 send, plck1 level */ - PIS_TIMER0_UPDATA = 0x120, /**< Timer0 updata, plck1 pulse */ - PIS_TIMER0_TRIG = 0x121, /**< Timer0 trig, plck1 pulse */ - PIS_TIMER0_INPUT = 0x122, /**< Timer0 input, plck1 pulse */ - PIS_TIMER0_OUTPUT = 0x123, /**< Timer0 output, plck1 pulse */ - PIS_TIMER1_UPDATA = 0x130, /**< Timer1 updata, plck1 pulse */ - PIS_TIMER1_TRIG = 0x131, /**< Timer1 trig, plck1 pulse */ - PIS_TIMER1_INPUT = 0x132, /**< Timer1 input, plck1 pulse */ - PIS_TIMER1_OUTPUT = 0x133, /**< Timer1 output, plck1 pulse */ - PIS_TIMER2_UPDATA = 0x140, /**< Timer2 updata, plck1 pulse */ - PIS_TIMER2_TRIG = 0x141, /**< Timer2 trig, plck1 pulse */ - PIS_TIMER2_INPUT = 0x142, /**< Timer2 input, plck1 pulse */ - PIS_TIMER2_OUTPUT = 0x143, /**< Timer2 output, plck1 pulse */ - PIS_TIMER3_UPDATA = 0x150, /**< Timer0 updata, plck1 pulse */ - PIS_TIMER3_TRIG = 0x151, /**< Timer0 trig, plck1 pulse */ - PIS_TIMER3_INPUT = 0x152, /**< Timer0 input, plck1 pulse */ - PIS_TIMER3_OUTPUT = 0x153, /**< Timer0 output, plck1 pulse */ - PIS_RTC_CLOCK = 0x160, /**< Rtc clock, pulse,support async */ - PIS_RTC_ALARM = 0x161, /**< Rtc alarm, pulse,support async */ - PIS_LPTIM0_SYN_UPDATA = 0x170, /**< Lptimer0 syn updata, pulse,support async */ - PIS_LPTIM0_ASY_UPDATA = 0x171, /**< Lptimer0 asy updata, pulse,support async */ - PIS_LPUART0_ASY_RECV = 0x180, /**< Lpuart0 asy recv, pulse,support async */ - PIS_LPUART0_ASY_SEND = 0x181, /**< Lpuart0 asy send, pulse,support async */ - PIS_LPUART0_SYN_RECV = 0x182, /**< Lpuart0 syn recv, pulse,support async */ - PIS_LPUART0_SYN_SEND = 0x183, /**< Lpuart0 syn recv, pulse,support async */ - PIS_DMA = 0x190, /**< Dma, pulse,support async */ - PIS_ADC1_INJECT = 0x1a0, /**< Adc1 inject, pclk2 pulse,support async */ - PIS_ADC1_REGULAT = 0x1a1, /**< Adc1 regulat, pclk2 pulse,support async */ - PIS_ADC1_WINDOW = 0x1a2, /**< Adc1 window, no have */ -} pis_src_t; - -/** - * @brief Consumer entry - */ -typedef enum -{ - PIS_CH0_TIMER0_BRKIN = 0x4000, /**< Timer0 brkin */ - PIS_CH0_SPI1_CLK = 0xF010, /**< Spi1 clk */ - PIS_CH0_LPTIM0_EXT0 = 0x0030, /**< Lptimer0 ext0 */ - PIS_CH0_ADC1_NORMAL = 0x0030, /**< Adc1 normal */ - PIS_CH1_TIMER0_CH1IN = 0x0001, /**< Timer0 ch1in */ - PIS_CH1_TIMER2_CH1IN = 0x0101, /**< Timer2 ch1in */ - PIS_CH1_TIMER3_CH1IN = 0x8101, /**< Timer3 ch1in */ - PIS_CH1_LPTIM0_EXT1 = 0x0031, /**< Lptime0 ext1 */ - PIS_CH1_UART0_RX_IRDA = 0x0011, /**< Uart0 rx irda */ - PIS_CH1_ADC1_INSERT = 0x0031, /**< Adc1 insert */ - PIS_CH2_TIMER0_CH2IN = 0x1002, /**< Timer0 ch2in */ - PIS_CH2_TIMER2_CH2IN = 0x1102, /**< Timer2 ch2in */ - PIS_CH2_TIMER3_CH2IN = 0x9102, /**< Timer3 ch2in */ - PIS_CH2_LPTIM0_EXT2 = 0x0032, /**< Lptime0 ext2 */ - PIS_CH2_UART1_RX_IRDA = 0x1012, /**< Uart1 rx irda */ - PIS_CH3_TIMER0_CH3IN = 0x2003, /**< Timer0 ch3in */ - PIS_CH3_LPTIM0_EXT3 = 0x0033, /**< Lptime0 ext3 */ - PIS_CH3_UART2_RX_IRDA = 0x2013, /**< Uart2 rx irda */ - PIS_CH4_TIMER0_CH4IN = 0x0004, /**< Timer0 ch4in */ - PIS_CH4_TIMER0_ITR0 = 0x0034, /**< Timer0 itr0 */ - PIS_CH4_TIMER2_ITR0 = 0x0034, /**< Timer2 itr0 */ - PIS_CH4_TIMER3_ITR0 = 0x0034, /**< Timer3 itr0 */ - PIS_CH4_LPTIM0_EXT4 = 0x4034, /**< Lptime0 ext4 */ - PIS_CH4_UART3_RX_IRDA = 0x3014, /**< Uart3 rx irda */ - PIS_CH5_SPI0_RX = 0xC015, /**< Spi0 rx */ - PIS_CH5_LPTIM0_EXT5 = 0x0035, /**< Lptime0 ext5 */ - PIS_CH5_EUART0_RX = 0x6015, /**< Euart0 rx */ - PIS_CH5_TIMER0_ITR1 = 0x0035, /**< Timer0 itr1 */ - PIS_CH5_TIMER2_ITR1 = 0x0035, /**< Timer2 itr1 */ - PIS_CH5_TIMER3_ITR1 = 0x0035, /**< Timer3 itr1 */ - PIS_CH6_SPI0_CLK = 0xD016, /**< Spi0 clk */ - PIS_CH6_ADC0_NORMAL = 0x0036, /**< Adc0 normal */ - PIS_CH6_LPTIM0_EXT6 = 0x0036, /**< Lptime0 ext6 */ - PIS_CH6_EUART1_RX = 0x7016, /**< Euart1 rx */ - PIS_CH6_TIMER0_ITR2 = 0x0036, /**< Timer0 itr2 */ - PIS_CH6_TIMER2_ITR2 = 0x0036, /**< Timer2 itr2 */ - PIS_CH6_TIMER3_ITR2 = 0x0036, /**< Timer3 itr2 */ - PIS_CH6_DAC_CH1 = 0x0036, /**< Dac channel 1 */ - PIS_CH7_SPI1_RX = 0xE017, /**< Spi1 rx */ - PIS_CH7_ADC0_INSERT = 0x0037, /**< Adc0 insert */ - PIS_CH7_LPTIM0_EXT7 = 0x0037, /**< Lptime0 ext7 */ - PIS_CH7_DMA = 0x0037, /**< Dma */ - PIS_CH7_TIMER0_ITR3 = 0x0037, /**< Timer0 itr3 */ - PIS_CH7_TIMER2_ITR3 = 0x0037, /**< Timer2 itr3 */ - PIS_CH7_TIMER3_ITR3 = 0x0037, /**< Timer3 itr3 */ - PIS_CH7_LPUART_RX = 0x8017, /**< Lpuart rx */ - PIS_CH7_DAC_CH0 = 0x0037, /**< Dac channel 0 */ -} pis_trig_t; - -/** - * @brief Clock select - */ -typedef enum -{ - PIS_CLK_PCLK1 = 0, /**< Pclock1 */ - PIS_CLK_PCLK2 = 1, /**< Pclock2 */ - PIS_CLK_SYS = 2, /**< Sys clock */ - PIS_CLK_LP = 3, /**< Low power clock */ -} pis_clock_t; - -/** - * @brief Level select - */ -typedef enum -{ - PIS_EDGE_NONE = 0, /**< None edge */ - PIS_EDGE_UP = 1, /**< Up edge */ - PIS_EDGE_DOWN = 2, /**< Down edge */ - PIS_EDGE_UP_DOWN = 3, /**< Up and down edge */ -} pis_edge_t; - -/** - * @brief Output style - */ -typedef enum -{ - PIS_OUT_LEVEL = 0, /**< Level */ - PIS_OUT_PULSE = 1, /**< Pulse */ -} pis_output_t; -/** - * @brief Sync select - */ -typedef enum -{ - PIS_SYN_DIRECT = 0, /**< Direct */ - PIS_SYN_ASY_PCLK1 = 1, /**< Asy pclk1 */ - PIS_SYN_ASY_PCLK2 = 2, /**< Asy pclk2 */ - PIS_SYN_ASY_PCLK = 3, /**< Asy pclk */ - PIS_SYN_PCLK2_PCLK1 = 4, /**< Pclk2 to pclk1 */ - PIS_SYN_PCLK1_PCLK2 = 5, /**< Pclk1 to pclk2 */ - PIS_SYN_PCLK12_SYS = 6, /**< Pclk1 or pclk2 to sysclk */ -} pis_syncsel_t; - -/** - * @brief Pis channel - */ -typedef enum -{ - PIS_CH_0 = 0, /**< Channel 0 */ - PIS_CH_1 = 1, /**< Channel 1 */ - PIS_CH_2 = 2, /**< Channel 2 */ - PIS_CH_3 = 3, /**< Channel 3 */ - PIS_CH_4 = 4, /**< Channel 4 */ - PIS_CH_5 = 5, /**< Channel 5 */ - PIS_CH_6 = 6, /**< Channel 6 */ - PIS_CH_7 = 7, /**< Channel 7 */ -} pis_ch_t; - -/** - * @brief Pis output channel - */ -typedef enum -{ - PIS_OUT_CH_0 = 0, /**< Channel 0 */ - PIS_OUT_CH_1 = 1, /**< Channel 1 */ - PIS_OUT_CH_2 = 2, /**< Channel 2 */ - PIS_OUT_CH_3 = 3, /**< Channel 3 */ -} pis_out_ch_t; - -/** - * @brief Indirect value,no care of it. - */ -typedef enum -{ - PIS_CON_0 = 0, /**< Con 0 */ - PIS_CON_1 = 1, /**< Con 1 */ - PIS_CON_NONE = 2, /**< None */ -} pis_con_t; - -/** - * @brief Indirect value,no care of it. - */ -typedef union -{ - struct - { - uint8_t ch : 4; /**< Channel */ - uint8_t con : 4; /**< Contorl */ - uint8_t shift : 8; /**< Shift */ - }; - uint16_t HalfWord; -} pis_divide_t; - -/** - * @brief PIS state structures definition - */ -typedef enum -{ - PIS_STATE_RESET = 0x00, /**< Peripheral is not initialized */ - PIS_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ - PIS_STATE_BUSY = 0x02, /**< An internal process is ongoing */ - PIS_STATE_TIMEOUT = 0x03, /**< Timeout state */ - PIS_STATE_ERROR = 0x04, /**< Error */ -} pis_state_t; - -/** - * @brief PIS modulate target - */ -typedef enum -{ - PIS_UART0_TX = 0, /**< Modulate uart0 tx */ - PIS_UART1_TX = 1, /**< Modulate uart1 tx */ - PIS_UART2_TX = 2, /**< Modulate uart2 tx */ - PIS_UART3_TX = 3, /**< Modulate uart3 tx */ - PIS_LPUART0_TX = 4, /**< Modulate lpuart0 tx */ -} pis_modu_targ_t; - -/** - * @brief PIS modulate level - */ -typedef enum -{ - PIS_LOW_LEVEL = 0, /**< Modulate low level */ - PIS_HIGH_LEVEL = 1, /**< Modulate high level */ -} pis_modu_level_t; - -/** - * @brief PIS modulate source - */ -typedef enum -{ - PIS_SRC_NONE = 0, /**< Stop modulate */ - PIS_SRC_TIMER0 = 1, /**< Modulate source is TIMER0 */ - PIS_SRC_TIMER1 = 2, /**< Modulate source is TIMER1 */ - PIS_SRC_TIMER2 = 3, /**< Modulate source is TIMER2 */ - PIS_SRC_TIMER3 = 4, /**< Modulate source is TIMER3 */ - PIS_SRC_TIMER6 = 5, /**< Modulate source is TIMER6 */ - PIS_SRC_TIMER7 = 6, /**< Modulate source is TIMER7 */ - PIS_SRC_LPTIM0 = 7, /**< Modulate source is LPTIM0 */ - PIS_SRC_BUZ = 8, /**< Modulate source is buz */ -} pis_modu_src_t; - -/** - * @brief PIS modulate channel - */ -typedef enum -{ - PIS_TIMER_CH1 = 0, /**< Src is TIMERx and choose channel 1 */ - PIS_TIMER_CH2 = 1, /**< Src is TIMERx and choose channel 2 */ - PIS_TIMER_CH3 = 2, /**< Src is TIMERx and choose channel 3 */ - PIS_TIMER_CH4 = 3, /**< Src is TIMERx and choose channel 4 */ -} pis_modu_channel_t; - -/** - * @brief PIS init structure definition - */ -typedef struct -{ - pis_src_t producer_src; /**< Producer entry */ - pis_clock_t producer_clk; /**< Producer module clock */ - pis_edge_t producer_edge; /**< Producer module pin output edge */ - pis_trig_t consumer_trig; /**< Consumer entry */ - pis_clock_t consumer_clk; /**< Consumer clock */ -} pis_init_t; - -/** - * @brief PIS modulate config structure definition - */ -typedef struct -{ - pis_modu_targ_t target; /**< Modulate target */ - pis_modu_level_t level; /**< Modulate level */ - pis_modu_src_t src; /**< Modulate src */ - pis_modu_channel_t channel; /**< Modulate channel */ -} pis_modulate_config_t; - -/** - * @brief PIS Handle Structure definition - */ -typedef struct pis_handle_s -{ - PIS_TypeDef *perh; /**< Register base address */ - pis_init_t init; /**< PIS required parameters */ - pis_ch_t consumer_ch; /**< Indirect value, no care of it */ - pis_con_t consumer_con; /**< Indirect value, no care of it */ - uint8_t consumer_pos; /**< Indirect value, no care of it */ - uint32_t check_info; /**< When destroy a handle ,user need check whether is right that ready to destroy */ - lock_state_t lock; /**< Locking object */ - pis_state_t state; /**< PIS operation state */ -} pis_handle_t; -/** - * @} - */ - - -/** @defgroup PIS_Private_Macros PIS Private Macros - * @{ - */ -#define IS_PIS(x) (((x) == PIS)) -#define IS_PIS_SRC(x) (((x) == PIS_NON) || \ - ((x) == PIS_GPIO_PIN0) || \ - ((x) == PIS_GPIO_PIN1) || \ - ((x) == PIS_GPIO_PIN2) || \ - ((x) == PIS_GPIO_PIN3) || \ - ((x) == PIS_GPIO_PIN4) || \ - ((x) == PIS_GPIO_PIN5) || \ - ((x) == PIS_GPIO_PIN6) || \ - ((x) == PIS_GPIO_PIN7) || \ - ((x) == PIS_GPIO_PIN8) || \ - ((x) == PIS_GPIO_PIN9) || \ - ((x) == PIS_GPIO_PIN10) || \ - ((x) == PIS_GPIO_PIN11) || \ - ((x) == PIS_GPIO_PIN12) || \ - ((x) == PIS_GPIO_PIN13) || \ - ((x) == PIS_GPIO_PIN14) || \ - ((x) == PIS_GPIO_PIN15) || \ - ((x) == PIS_ACMP_OUT0) || \ - ((x) == PIS_ACMP_OUT1) || \ - ((x) == PIS_DAC0_CH1) || \ - ((x) == PIS_ACMP_OUT1) || \ - ((x) == PIS_ADC0_INJECT) || \ - ((x) == PIS_ADC0_REGULAT) || \ - ((x) == PIS_ADC0_WINDOW) || \ - ((x) == PIS_LVD) || \ - ((x) == PIS_UART0_ASY_SEND) || \ - ((x) == PIS_UART0_ASY_RECV) || \ - ((x) == PIS_UART0_IRDAOUT) || \ - ((x) == PIS_UART0_RTSOUT) || \ - ((x) == PIS_UART0_TXOUT) || \ - ((x) == PIS_UART0_SYN_SEND) || \ - ((x) == PIS_UART0_SYN_RECV) || \ - ((x) == PIS_UART1_ASY_SEND) || \ - ((x) == PIS_UART1_ASY_RECV) || \ - ((x) == PIS_UART1_IRDA) || \ - ((x) == PIS_UART1_RTS) || \ - ((x) == PIS_UART1_TXOUT) || \ - ((x) == PIS_UART1_SYN_SEND) || \ - ((x) == PIS_UART1_SYN_RECV) || \ - ((x) == PIS_UART2_ASY_SEND) || \ - ((x) == PIS_UART2_ASY_RECV) || \ - ((x) == PIS_UART2_IRDA) || \ - ((x) == PIS_UART2_RTS) || \ - ((x) == PIS_UART2_TXOUT) || \ - ((x) == PIS_UART2_SYN_SEND) || \ - ((x) == PIS_UART2_SYN_RECV) || \ - ((x) == PIS_UART3_ASY_SEND) || \ - ((x) == PIS_UART3_ASY_RECV) || \ - ((x) == PIS_UART3_IRDA) || \ - ((x) == PIS_UART3_RTS) || \ - ((x) == PIS_UART3_TXOUT) || \ - ((x) == PIS_UART3_SYN_SEND) || \ - ((x) == PIS_UART3_SYN_RECV) || \ - ((x) == PIS_EUART0_RECV) || \ - ((x) == PIS_EUART0_SEND) || \ - ((x) == PIS_EUART0_TXOUT) || \ - ((x) == PIS_EUART1_RECV) || \ - ((x) == PIS_EUART1_SEND) || \ - ((x) == PIS_EUART1_TXOUT) || \ - ((x) == PIS_SPI0_RECV) || \ - ((x) == PIS_SPI0_SEND) || \ - ((x) == PIS_SPI0_NE) || \ - ((x) == PIS_SPI1_RECV) || \ - ((x) == PIS_SPI1_SEND) || \ - ((x) == PIS_SPI1_NE) || \ - ((x) == PIS_I2C0_RECV) || \ - ((x) == PIS_I2C0_SEND) || \ - ((x) == PIS_I2C1_RECV) || \ - ((x) == PIS_I2C1_SEND) || \ - ((x) == PIS_TIMER0_UPDATA) || \ - ((x) == PIS_TIMER0_TRIG) || \ - ((x) == PIS_TIMER0_INPUT) || \ - ((x) == PIS_TIMER0_OUTPUT) || \ - ((x) == PIS_TIMER1_UPDATA) || \ - ((x) == PIS_TIMER1_TRIG) || \ - ((x) == PIS_TIMER1_INPUT) || \ - ((x) == PIS_TIMER1_OUTPUT) || \ - ((x) == PIS_TIMER2_UPDATA) || \ - ((x) == PIS_TIMER2_TRIG) || \ - ((x) == PIS_TIMER2_INPUT) || \ - ((x) == PIS_TIMER2_OUTPUT) || \ - ((x) == PIS_TIMER3_UPDATA) || \ - ((x) == PIS_TIMER3_TRIG) || \ - ((x) == PIS_TIMER3_INPUT) || \ - ((x) == PIS_TIMER3_OUTPUT) || \ - ((x) == PIS_RTC_CLOCK) || \ - ((x) == PIS_RTC_ALARM) || \ - ((x) == PIS_LPTIM0_SYN_UPDATA) || \ - ((x) == PIS_LPTIM0_ASY_UPDATA) || \ - ((x) == PIS_LPUART0_ASY_RECV) || \ - ((x) == PIS_LPUART0_ASY_SEND) || \ - ((x) == PIS_LPUART0_SYN_RECV) || \ - ((x) == PIS_LPUART0_SYN_SEND) || \ - ((x) == PIS_DMA) || \ - ((x) == PIS_ADC1_INJECT) || \ - ((x) == PIS_ADC1_REGULAT) || \ - ((x) == PIS_ADC1_WINDOW)) -#define IS_PIS_TRIG(x) (((x) == PIS_CH0_TIMER0_BRKIN) || \ - ((x) == PIS_CH0_SPI1_CLK) || \ - ((x) == PIS_CH0_LPTIM0_EXT0) || \ - ((x) == PIS_CH0_ADC1_NORMAL) || \ - ((x) == PIS_CH1_TIMER0_CH1IN) || \ - ((x) == PIS_CH1_TIMER2_CH1IN) || \ - ((x) == PIS_CH1_TIMER3_CH1IN) || \ - ((x) == PIS_CH1_UART0_RX_IRDA) || \ - ((x) == PIS_CH1_LPTIM0_EXT1) || \ - ((x) == PIS_CH1_ADC1_INSERT) || \ - ((x) == PIS_CH2_TIMER0_CH2IN) || \ - ((x) == PIS_CH2_TIMER2_CH2IN) || \ - ((x) == PIS_CH2_TIMER3_CH2IN) || \ - ((x) == PIS_CH2_LPTIM0_EXT2) || \ - ((x) == PIS_CH2_UART1_RX_IRDA) || \ - ((x) == PIS_CH3_TIMER0_CH3IN) || \ - ((x) == PIS_CH3_LPTIM0_EXT3) || \ - ((x) == PIS_CH3_UART2_RX_IRDA) || \ - ((x) == PIS_CH4_TIMER0_CH4IN) || \ - ((x) == PIS_CH4_TIMER0_ITR0) || \ - ((x) == PIS_CH4_TIMER2_ITR0) || \ - ((x) == PIS_CH4_TIMER3_ITR0) || \ - ((x) == PIS_CH4_LPTIM0_EXT4) || \ - ((x) == PIS_CH4_UART3_RX_IRDA) || \ - ((x) == PIS_CH5_SPI0_RX) || \ - ((x) == PIS_CH5_LPTIM0_EXT5) || \ - ((x) == PIS_CH5_EUART0_RX) || \ - ((x) == PIS_CH5_TIMER0_ITR1) || \ - ((x) == PIS_CH5_TIMER2_ITR1) || \ - ((x) == PIS_CH5_TIMER3_ITR1) || \ - ((x) == PIS_CH6_SPI0_CLK) || \ - ((x) == PIS_CH6_ADC0_NORMAL) || \ - ((x) == PIS_CH6_LPTIM0_EXT6) || \ - ((x) == PIS_CH6_EUART1_RX) || \ - ((x) == PIS_CH6_TIMER0_ITR2) || \ - ((x) == PIS_CH6_TIMER2_ITR2) || \ - ((x) == PIS_CH6_TIMER3_ITR2) || \ - ((x) == PIS_CH6_DAC_CH1) || \ - ((x) == PIS_CH7_SPI1_RX) || \ - ((x) == PIS_CH7_ADC0_INSERT) || \ - ((x) == PIS_CH7_LPTIM0_EXT7) || \ - ((x) == PIS_CH7_DMA) || \ - ((x) == PIS_CH7_TIMER0_ITR3) || \ - ((x) == PIS_CH7_TIMER2_ITR3) || \ - ((x) == PIS_CH7_TIMER3_ITR3) || \ - ((x) == PIS_CH7_DAC_CH0) || \ - ((x) == PIS_CH7_LPUART_RX)) -#define IS_PIS_CLOCK(x) (((x) == PIS_CLK_PCLK1) || \ - ((x) == PIS_CLK_PCLK2) || \ - ((x) == PIS_CLK_SYS) || \ - ((x) == PIS_CLK_LP)) -#define IS_PIS_EDGE(x) (((x) == PIS_EDGE_NONE) || \ - ((x) == PIS_EDGE_UP) || \ - ((x) == PIS_EDGE_DOWN) || \ - ((x) == PIS_EDGE_UP_DOWN)) -#define IS_PIS_OUTPUT(x) (((x) == PIS_OUT_LEVEL) || \ - ((x) == PIS_OUT_PULSE)) -#define IS_PIS_OUPUT_CH(x) (((x) == PIS_OUT_CH_0) || \ - ((x) == PIS_OUT_CH_1) || \ - ((x) == PIS_OUT_CH_2) || \ - ((x) == PIS_OUT_CH_3)) -#define IS_PIS_MODU_TARGET(x) (((x) == PIS_UART0_TX) || \ - ((x) == PIS_UART1_TX) || \ - ((x) == PIS_UART2_TX) || \ - ((x) == PIS_UART3_TX) || \ - ((x) == PIS_LPUART0_TX)) -#define IS_PIS_MODU_LEVEL(x) (((x) == PIS_LOW_LEVEL) || \ - ((x) == PIS_HIGH_LEVEL)) -#define IS_PIS_MODU_SRC(x) (((x) == PIS_SRC_NONE) || \ - ((x) == PIS_SRC_TIMER0) || \ - ((x) == PIS_SRC_TIMER1) || \ - ((x) == PIS_SRC_TIMER2) || \ - ((x) == PIS_SRC_TIMER3) || \ - ((x) == PIS_SRC_TIMER6) || \ - ((x) == PIS_SRC_TIMER7) || \ - ((x) == PIS_SRC_LPTIM0) || \ - ((x) == PIS_SRC_BUZ)) -#define IS_PIS_MODU_CHANNEL(x) (((x) == PIS_TIMER_CH1) || \ - ((x) == PIS_TIMER_CH2) || \ - ((x) == PIS_TIMER_CH3) || \ - ((x) == PIS_TIMER_CH4)) -/** - * @} - */ - -/** @addtogroup PIS_Public_Functions - * @{ - */ - -/** @addtogroup PIS_Public_Functions_Group1 - * @{ - */ -ald_status_t pis_create(pis_handle_t *hperh); -ald_status_t pis_destroy(pis_handle_t *hperh); -/** - * @} - */ - -/** @addtogroup PIS_Public_Functions_Group2 - * @{ - */ -ald_status_t pis_output_start(pis_handle_t *hperh, pis_out_ch_t ch); -ald_status_t pis_output_stop(pis_handle_t *hperh, pis_out_ch_t ch); -/** - * @} - */ - -/** @addtogroup PIS_Public_Functions_Group3 - * @{ - */ -pis_state_t pis_get_state(pis_handle_t *hperh); -/** - * @} - */ - -/** @addtogroup PIS_Public_Functions_Group4 - * @{ - */ -ald_status_t pis_modu_config(pis_handle_t *hperh, pis_modulate_config_t *config); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_PIS_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pmu.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pmu.h deleted file mode 100644 index c7e3327e59..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pmu.h +++ /dev/null @@ -1,241 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_pmu.h - * @brief Header file of PMU module driver. - * - * @version V1.0 - * @date 04 Dec 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ******************************************************************************** - */ - -#ifndef __ALD_PMU_H__ -#define __ALD_PMU_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" -#include "ald_syscfg.h" - - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup PMU - * @{ - */ - -/** @defgroup PMU_Public_Macros PMU Public Macros - * @{ - */ -#define PMU_SRAM0_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(PMU->PWRCR, BIT(PMU_PWRCR_SRAM_POSS)); \ - SYSCFG_LOCK(); \ -} while (0) -#define PMU_SRAM0_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(PMU->PWRCR, BIT(PMU_PWRCR_SRAM_POSS));\ - SYSCFG_LOCK(); \ -} while (0) -#define PMU_SRAM1_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(PMU->PWRCR, BIT(PMU_PWRCR_SRAM_POSE)); \ - SYSCFG_LOCK(); \ -} while (0) -#define PMU_SRAM1_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(PMU->PWRCR, BIT(PMU_PWRCR_SRAM_POSE));\ - SYSCFG_LOCK(); \ -} while (0) -#define PMU_BXCAN_ENABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(PMU->PWRCR, PMU_PWRCR_BXCAN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) -#define PMU_BXCAN_DISABLE() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(PMU->PWRCR, PMU_PWRCR_BXCAN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) - -#define PMU_GET_LVD_STATUS() (READ_BITS(PMU->LVDCR, PMU_LVDCR_LVDO_MSK, PMU_LVDCR_LVDO_POS)) -/** - * @} - */ - - -/** @defgroup PMU_Public_Types PMU Public Types - * @{ - */ -/** - * @brief Standby wakeup port select - */ -typedef enum -{ - PMU_STANDBY_PORT_SEL_PA0 = 0x0, /**< PA0 */ - PMU_STANDBY_PORT_SEL_PA1 = 0x1, /**< PA1 */ - PMU_STANDBY_PORT_SEL_PA2 = 0x2, /**< PA2 */ - PMU_STANDBY_PORT_SEL_PA3 = 0x3, /**< PA3 */ - PMU_STANDBY_PORT_SEL_PA4 = 0x4, /**< PA4 */ - PMU_STANDBY_PORT_SEL_PA5 = 0x5, /**< PA5 */ - PMU_STANDBY_PORT_SEL_PA6 = 0x6, /**< PA6 */ - PMU_STANDBY_PORT_SEL_PA7 = 0x7, /**< PA7 */ - PMU_STANDBY_PORT_NONE = 0xF, /**< NONE */ -} pmu_standby_wakeup_sel_t; - -/** - * @brief Low power mode - */ -typedef enum -{ - PMU_LP_STOP1 = 0x0, /**< Stop1 */ - PMU_LP_STOP2 = 0x1, /**< Stop2 */ - PMU_LP_STANDBY = 0x2, /**< Standby */ -} pmu_lp_mode_t; - -typedef enum -{ - PMU_SR_WUF = (1U << 0), - PMU_SR_STANDBYF = (1U << 1), -} pmu_status_t; - -/** - * @brief LVD voltage select - */ -typedef enum -{ - PMU_LVD_VOL_SEL_2_0 = 0x0, /**< 2.0V ~ 2.05V */ - PMU_LVD_VOL_SEL_2_1 = 0x1, /**< 2.1V ~ 2.15V */ - PMU_LVD_VOL_SEL_2_2 = 0x2, /**< 2.2V ~ 2.25V */ - PMU_LVD_VOL_SEL_2_4 = 0x3, /**< 2.4V ~ 2.45V */ - PMU_LVD_VOL_SEL_2_6 = 0x4, /**< 2.6V ~ 2.65V */ - PMU_LVD_VOL_SEL_2_8 = 0x5, /**< 2.8V ~ 2.85V */ - PMU_LVD_VOL_SEL_3_0 = 0x6, /**< 3.0V ~ 3.05V */ - PMU_LVD_VOL_SEL_3_6 = 0x7, /**< 3.6V ~ 3.65V */ - PMU_LVD_VOL_SEL_4_0 = 0x8, /**< 4.0V ~ 4.05V */ - PMU_LVD_VOL_SEL_4_6 = 0x9, /**< 4.6V ~ 4.65V */ - PMU_LVD_VOL_SEL_2_3 = 0xA, /**< 2.3V ~ 2.35V */ - PMU_LVD_VOL_SEL_EXT = 0xF, /**< Select external input. It must be 1.2V */ -} pmu_lvd_voltage_sel_t; - -/** - * @brief LVD trigger mode - */ -typedef enum -{ - PMU_LVD_TRIGGER_RISING_EDGE = 0x0, /**< Rising edge */ - PMU_LVD_TRIGGER_FALLING_EDGE = 0x1, /**< Falling edge */ - PMU_LVD_TRIGGER_HIGH_LEVEL = 0x2, /**< High level */ - PMU_LVD_TRIGGER_LOW_LEVEL = 0x3, /**< Low level */ - PMU_LVD_TRIGGER_RISING_FALLING = 0x4, /**< Rising and falling edge */ -} pmu_lvd_trigger_mode_t; - -/** - * @} - */ - -/** - * @defgroup PMU_Private_Macros PMU Private Macros - * @{ - */ -#define IS_PMU_STANDBY_PORT_SEL(x) (((x) == PMU_STANDBY_PORT_SEL_PA0) || \ - ((x) == PMU_STANDBY_PORT_SEL_PA1) || \ - ((x) == PMU_STANDBY_PORT_SEL_PA2) || \ - ((x) == PMU_STANDBY_PORT_SEL_PA3) || \ - ((x) == PMU_STANDBY_PORT_SEL_PA4) || \ - ((x) == PMU_STANDBY_PORT_SEL_PA5) || \ - ((x) == PMU_STANDBY_PORT_SEL_PA6) || \ - ((x) == PMU_STANDBY_PORT_SEL_PA7) || \ - ((x) == PMU_STANDBY_PORT_NONE)) -#define IS_PMU_LP_MODE(x) (((x) == PMU_LP_STOP1) || \ - ((x) == PMU_LP_STOP2) || \ - ((x) == PMU_LP_STANDBY)) -#define IS_PMU_STATUS(x) (((x) == PMU_SR_WUF) || \ - ((x) == PMU_SR_STANDBYF)) -#define IS_PMU_LVD_VOL_SEL(x) (((x) == PMU_LVD_VOL_SEL_2_0) || \ - ((x) == PMU_LVD_VOL_SEL_2_1) || \ - ((x) == PMU_LVD_VOL_SEL_2_2) || \ - ((x) == PMU_LVD_VOL_SEL_2_4) || \ - ((x) == PMU_LVD_VOL_SEL_2_6) || \ - ((x) == PMU_LVD_VOL_SEL_2_8) || \ - ((x) == PMU_LVD_VOL_SEL_3_0) || \ - ((x) == PMU_LVD_VOL_SEL_3_6) || \ - ((x) == PMU_LVD_VOL_SEL_4_0) || \ - ((x) == PMU_LVD_VOL_SEL_4_6) || \ - ((x) == PMU_LVD_VOL_SEL_2_3) || \ - ((x) == PMU_LVD_VOL_SEL_EXT)) -#define IS_PMU_LVD_TRIGGER_MODE(x) (((x) == PMU_LVD_TRIGGER_RISING_EDGE) || \ - ((x) == PMU_LVD_TRIGGER_FALLING_EDGE) || \ - ((x) == PMU_LVD_TRIGGER_HIGH_LEVEL) || \ - ((x) == PMU_LVD_TRIGGER_LOW_LEVEL) || \ - ((x) == PMU_LVD_TRIGGER_RISING_FALLING)) -/** - * @} - */ - -/** @addtogroup PMU_Public_Functions - * @{ - */ -/** @addtogroup PMU_Public_Functions_Group1 - * @{ - */ -/* Low power mode select */ -__STATIC_INLINE__ void __sleep() -{ - __WFI(); -} - -__STATIC_INLINE__ void __sleep_deep() -{ - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - __WFI(); -} - -void pmu_stop1_enter(void); -void pmu_stop2_enter(void); -void pmu_standby_enter(pmu_standby_wakeup_sel_t port); -flag_status_t pmu_get_status(pmu_status_t sr); -void pmu_clear_status(pmu_status_t sr); -/** - * @} - */ -/** @addtogroup PMU_Public_Functions_Group2 - * @{ - */ -/* LVD configure */ -void pmu_lvd_config(pmu_lvd_voltage_sel_t sel, pmu_lvd_trigger_mode_t mode, type_func_t state); -void lvd_irq_cbk(void); -/** - * @} - */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_PMU_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rmu.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rmu.h deleted file mode 100644 index 22b8fd21a1..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rmu.h +++ /dev/null @@ -1,265 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_rmu.h - * @brief Header file of RMU module driver. - * - * @version V1.0 - * @date 04 Dec 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ******************************************************************************** - */ - -#ifndef __ALD_RMU_H__ -#define __ALD_RMU_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup RMU - * @{ - */ - -/** @defgroup RMU_Public_Types RMU Public Types - * @{ - */ -/** - * @brief RMU BOR fliter - */ -typedef enum -{ - RMU_BORFLT_1 = 0x1, /**< 1 cycle */ - RMU_BORFLT_2 = 0x2, /**< 2 cycles */ - RMU_BORFLT_3 = 0x3, /**< 3 cycles */ - RMU_BORFLT_4 = 0x4, /**< 4 cycles */ - RMU_BORFLT_5 = 0x5, /**< 5 cycles */ - RMU_BORFLT_6 = 0x6, /**< 6 cycles */ - RMU_BORFLT_7 = 0x7, /**< 7 cycles */ -} rmu_bor_filter_t; - -/** - * @brief RMU BOR voltage - */ -typedef enum -{ - RMU_VOL_1_7 = 0x0, /**< 1.7V */ - RMU_VOL_2_0 = 0x1, /**< 2.0V */ - RMU_VOL_2_1 = 0x2, /**< 2.1V */ - RMU_VOL_2_2 = 0x3, /**< 2.2V */ - RMU_VOL_2_3 = 0x4, /**< 2.3V */ - RMU_VOL_2_4 = 0x5, /**< 2.4V */ - RMU_VOL_2_5 = 0x6, /**< 2.5V */ - RMU_VOL_2_6 = 0x7, /**< 2.6V */ - RMU_VOL_2_8 = 0x8, /**< 2.8V */ - RMU_VOL_3_0 = 0x9, /**< 3.0V */ - RMU_VOL_3_1 = 0xA, /**< 3.1V */ - RMU_VOL_3_3 = 0xB, /**< 3.3V */ - RMU_VOL_3_6 = 0xC, /**< 3.6V */ - RMU_VOL_3_7 = 0xD, /**< 3.7V */ - RMU_VOL_4_0 = 0xE, /**< 4.0V */ - RMU_VOL_4_3 = 0xF, /**< 4.3V */ -} rmu_bor_vol_t; - -/** - * @brief RMU reset status - */ -typedef enum -{ - RMU_RST_POR = (1U << 0), /**< POR */ - RMU_RST_WAKEUP = (1U << 1), /**< WAKEUP */ - RMU_RST_BOR = (1U << 2), /**< BOR */ - RMU_RST_NMRST = (1U << 3), /**< NMRST */ - RMU_RST_IWDT = (1U << 4), /**< IWDT */ - RMU_RST_WWDT = (1U << 5), /**< WWDT */ - RMU_RST_LOCKUP = (1U << 6), /**< LOCKUP */ - RMU_RST_CHIP = (1U << 7), /**< CHIP */ - RMU_RST_MCU = (1U << 8), /**< MCU */ - RMU_RST_CPU = (1U << 9), /**< CPU */ - RMU_RST_CFG = (1U << 10), /**< CFG */ - RMU_RST_CFGERR = (1U << 16), /**< CFG Error */ -} rmu_state_t; - -/** - * @brief RMU periperal select bit - */ -typedef enum -{ - RMU_PERH_GPIO = (1U << 0), /**< AHB1: GPIO */ - RMU_PERH_CRC = (1U << 1), /**< AHB1: CRC */ - RMU_PERH_CALC = (1U << 2), /**< AHB1: CALC */ - RMU_PERH_CRYPT = (1U << 3), /**< AHB1: CRYPT */ - RMU_PERH_TRNG = (1U << 4), /**< AHB1: TRNG */ - RMU_PERH_PIS = (1U << 5), /**< AHB1: PIS */ - RMU_PERH_CHIP = (1U << 0) | (1U << 27), /**< AHB2: CHIP */ - RMU_PERH_CPU = (1U << 1) | (1U << 27), /**< AHB2: CPU */ - RMU_PERH_TIM0 = (1U << 0) | (1U << 28), /**< APB1: TIM0 */ - RMU_PERH_TIM1 = (1U << 1) | (1U << 28), /**< APB1: TIM1 */ - RMU_PERH_TIM2 = (1U << 2) | (1U << 28), /**< APB1: TIM2 */ - RMU_PERH_TIM3 = (1U << 3) | (1U << 28), /**< APB1: TIM3 */ - RMU_PERH_TIM4 = (1U << 4) | (1U << 28), /**< APB1: TIM4 */ - RMU_PERH_TIM5 = (1U << 5) | (1U << 28), /**< APB1: TIM5 */ - RMU_PERH_TIM6 = (1U << 6) | (1U << 28), /**< APB1: TIM6 */ - RMU_PERH_TIM7 = (1U << 7) | (1U << 28), /**< APB1: TIM7 */ - RMU_PERH_UART0 = (1U << 8) | (1U << 28), /**< APB1: UART0 */ - RMU_PERH_UART1 = (1U << 9) | (1U << 28), /**< APB1: UART1 */ - RMU_PERH_UART2 = (1U << 10) | (1U << 28), /**< APB1: UART2 */ - RMU_PERH_UART3 = (1U << 11) | (1U << 28), /**< APB1: UART3 */ - RMU_PERH_USART0 = (1U << 12) | (1U << 28), /**< APB1: EUART0 */ - RMU_PERH_USART1 = (1U << 13) | (1U << 28), /**< APB1: EUART1 */ - RMU_PERH_SPI0 = (1U << 16) | (1U << 28), /**< APB1: SPI0 */ - RMU_PERH_SPI1 = (1U << 17) | (1U << 28), /**< APB1: SPI1 */ - RMU_PERH_SPI2 = (1U << 18) | (1U << 28), /**< APB1: SPI2 */ - RMU_PERH_I2C0 = (1U << 20) | (1U << 28), /**< APB1: I2C0 */ - RMU_PERH_I2C1 = (1U << 21) | (1U << 28), /**< APB1: I2C1 */ - RMU_PERH_CAN0 = (1U << 24) | (1U << 28), /**< APB1: CAN0 */ - RMU_PERH_LPTIM0 = (1U << 0) | (1U << 29), /**< APB2: LPTIM0 */ - RMU_PERH_LPUART0 = (1U << 2) | (1U << 29), /**< APB2: LPUART */ - RMU_PERH_ADC0 = (1U << 4) | (1U << 29), /**< APB2: ADC0 */ - RMU_PERH_ADC1 = (1U << 5) | (1U << 29), /**< APB2: ADC1 */ - RMU_PERH_ACMP0 = (1U << 6) | (1U << 29), /**< APB2: ACMP0 */ - RMU_PERH_ACMP1 = (1U << 7) | (1U << 29), /**< APB2: ACMP1 */ - RMU_PERH_OPAMP = (1U << 8) | (1U << 29), /**< APB2: OPAMP */ - RMU_PERH_DAC0 = (1U << 9) | (1U << 29), /**< APB2: DAC0 */ - RMU_PERH_WWDT = (1U << 12) | (1U << 29), /**< APB2: WWDT */ - RMU_PERH_LCD = (1U << 13) | (1U << 29), /**< APB2: LCD */ - RMU_PERH_IWDT = (1U << 14) | (1U << 29), /**< APB2: IWDT */ - RMU_PERH_RTC = (1U << 15) | (1U << 29), /**< APB2: RTC */ - RMU_PERH_TEMP = (1U << 16) | (1U << 29), /**< APB2: TEMP */ - RMU_PERH_BKPC = (1U << 17) | (1U << 29), /**< APB2: BKPC */ - RMU_PERH_BKPRAM = (1U << 18) | (1U << 29), /**< APB2: BKPRAM */ -} rmu_peripheral_t; -/** - * @} - */ - -/** - * @defgroup RMU_Private_Macros RMU Private Macros - * @{ - */ -#define IS_RMU_BORFLT(x) (((x) == RMU_BORFLT_1) || \ - ((x) == RMU_BORFLT_2) || \ - ((x) == RMU_BORFLT_3) || \ - ((x) == RMU_BORFLT_4) || \ - ((x) == RMU_BORFLT_5) || \ - ((x) == RMU_BORFLT_6) || \ - ((x) == RMU_BORFLT_7)) -#define IS_RMU_BORVOL(x) (((x) == RMU_VOL_1_7) || \ - ((x) == RMU_VOL_2_0) || \ - ((x) == RMU_VOL_2_1) || \ - ((x) == RMU_VOL_2_2) || \ - ((x) == RMU_VOL_2_3) || \ - ((x) == RMU_VOL_2_4) || \ - ((x) == RMU_VOL_2_5) || \ - ((x) == RMU_VOL_2_6) || \ - ((x) == RMU_VOL_2_8) || \ - ((x) == RMU_VOL_3_0) || \ - ((x) == RMU_VOL_3_1) || \ - ((x) == RMU_VOL_3_3) || \ - ((x) == RMU_VOL_3_6) || \ - ((x) == RMU_VOL_3_7) || \ - ((x) == RMU_VOL_4_0) || \ - ((x) == RMU_VOL_4_3)) -#define IS_RMU_STATE(x) (((x) == RMU_RST_POR) || \ - ((x) == RMU_RST_WAKEUP) || \ - ((x) == RMU_RST_BOR) || \ - ((x) == RMU_RST_NMRST) || \ - ((x) == RMU_RST_IWDT) || \ - ((x) == RMU_RST_WWDT) || \ - ((x) == RMU_RST_LOCKUP) || \ - ((x) == RMU_RST_CHIP) || \ - ((x) == RMU_RST_MCU) || \ - ((x) == RMU_RST_CPU) || \ - ((x) == RMU_RST_CFG) || \ - ((x) == RMU_RST_CFGERR)) -#define IS_RMU_STATE_CLEAR(x) (((x) == RMU_RST_POR) || \ - ((x) == RMU_RST_WAKEUP) || \ - ((x) == RMU_RST_BOR) || \ - ((x) == RMU_RST_NMRST) || \ - ((x) == RMU_RST_IWDT) || \ - ((x) == RMU_RST_WWDT) || \ - ((x) == RMU_RST_LOCKUP) || \ - ((x) == RMU_RST_CHIP) || \ - ((x) == RMU_RST_MCU) || \ - ((x) == RMU_RST_CPU) || \ - ((x) == RMU_RST_CFG)) -#define IS_RMU_PERH(x) (((x) == RMU_PERH_GPIO) || \ - ((x) == RMU_PERH_CRC) || \ - ((x) == RMU_PERH_CALC) || \ - ((x) == RMU_PERH_CRYPT) || \ - ((x) == RMU_PERH_TRNG) || \ - ((x) == RMU_PERH_PIS) || \ - ((x) == RMU_PERH_CHIP) || \ - ((x) == RMU_PERH_CPU) || \ - ((x) == RMU_PERH_TIM0) || \ - ((x) == RMU_PERH_TIM1) || \ - ((x) == RMU_PERH_TIM2) || \ - ((x) == RMU_PERH_TIM3) || \ - ((x) == RMU_PERH_TIM4) || \ - ((x) == RMU_PERH_TIM5) || \ - ((x) == RMU_PERH_TIM6) || \ - ((x) == RMU_PERH_TIM7) || \ - ((x) == RMU_PERH_UART0) || \ - ((x) == RMU_PERH_UART1) || \ - ((x) == RMU_PERH_UART2) || \ - ((x) == RMU_PERH_UART3) || \ - ((x) == RMU_PERH_USART0) || \ - ((x) == RMU_PERH_USART1) || \ - ((x) == RMU_PERH_SPI0) || \ - ((x) == RMU_PERH_SPI1) || \ - ((x) == RMU_PERH_SPI2) || \ - ((x) == RMU_PERH_I2C0) || \ - ((x) == RMU_PERH_I2C1) || \ - ((x) == RMU_PERH_CAN0) || \ - ((x) == RMU_PERH_LPTIM0) || \ - ((x) == RMU_PERH_LPUART0) || \ - ((x) == RMU_PERH_ADC0) || \ - ((x) == RMU_PERH_ADC1) || \ - ((x) == RMU_PERH_ACMP0) || \ - ((x) == RMU_PERH_ACMP1) || \ - ((x) == RMU_PERH_OPAMP) || \ - ((x) == RMU_PERH_DAC0) || \ - ((x) == RMU_PERH_WWDT) || \ - ((x) == RMU_PERH_LCD) || \ - ((x) == RMU_PERH_IWDT) || \ - ((x) == RMU_PERH_RTC) || \ - ((x) == RMU_PERH_TEMP) || \ - ((x) == RMU_PERH_BKPC) || \ - ((x) == RMU_PERH_BKPRAM)) -/** - * @} - */ - -/** @addtogroup RMU_Public_Functions - * @{ - */ -void rmu_bor_config(rmu_bor_filter_t flt, rmu_bor_vol_t vol, type_func_t state); -flag_status_t rmu_get_reset_status(rmu_state_t state); -void rmu_clear_reset_status(rmu_state_t state); -void rmu_reset_periperal(rmu_peripheral_t perh); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_RMU_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rtc.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rtc.h deleted file mode 100644 index 9d0bce383f..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rtc.h +++ /dev/null @@ -1,699 +0,0 @@ -/** - ****************************************************************************** - * @file ald_rtc.h - * @brief Header file of RTC Module driver. - * - * @version V1.0 - * @date 16 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ******************************************************************************* - */ - -#ifndef __ALD_RTC_H__ -#define __ALD_RTC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" - - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup RTC - * @{ - */ - -/** @defgroup RTC_Public_Types RTC Public Types - * @{ - */ - -/** - * @brief Hours format - */ -typedef enum -{ - RTC_HOUR_FORMAT_24 = 0x0, /**< 24-hours format */ - RTC_HOUR_FORMAT_12 = 0x1, /**< 12-hours format */ -} rtc_hour_format_t; - -/** - * @brief Output mode - */ -typedef enum -{ - RTC_OUTPUT_DISABLE = 0x0, /**< Disable output */ - RTC_OUTPUT_ALARM_A = 0x1, /**< Output alarm_a signal */ - RTC_OUTPUT_ALARM_B = 0x2, /**< Output alarm_b signal */ - RTC_OUTPUT_WAKEUP = 0x3, /**< Output wakeup signal */ -} rtc_output_select_t; - -/** - * @brief Output polarity - */ -typedef enum -{ - RTC_OUTPUT_POLARITY_HIGH = 0x0, /**< Polarity is high */ - RTC_OUTPUT_POLARITY_LOW = 0x0, /**< Polarity is low */ -} rtc_output_polarity_t; - -/** - * @brief Initialization structure - */ -typedef struct -{ - rtc_hour_format_t hour_format; /**< Hours format */ - uint32_t asynch_pre_div; /**< Asynchronous predivider value */ - uint32_t synch_pre_div; /**< Synchronous predivider value */ - rtc_output_select_t output; /**< Output signal type */ - rtc_output_polarity_t output_polarity; /**< Output polarity */ -} rtc_init_t; - -/** - * @brief Source select - */ -typedef enum -{ - RTC_SOURCE_LOSC = 0x0, /**< LOSC */ - RTC_SOURCE_LRC = 0x1, /**< LRC */ - RTC_SOURCE_HRC_DIV_1M = 0x2, /**< HRC divide to 1MHz */ - RTC_SOURCE_HOSC_DIV_1M = 0x3, /**< HOSC divide to 1MHz */ -} rtc_source_sel_t; - -/** - * @brief Time structure - */ -typedef struct -{ - uint8_t hour; /**< Hours */ - uint8_t minute; /**< Minutes */ - uint8_t second; /**< Seconds */ - uint16_t sub_sec; /**< Sub-seconds */ -} rtc_time_t; - -/** - * @brief Date structure - */ -typedef struct -{ - uint8_t week; /**< Weeks */ - uint8_t day; /**< days */ - uint8_t month; /**< months */ - uint8_t year; /**< years */ -} rtc_date_t; - -/** - * @brief Data format - */ -typedef enum -{ - RTC_FORMAT_DEC = 0, - RTC_FORMAT_BCD = 1, -} rtc_format_t; - -/** - * @brief Index of alarm - */ -typedef enum -{ - RTC_ALARM_A = 0x0, /**< Alarm-A */ - RTC_ALARM_B = 0x1, /**< Alarm-B */ -} rtc_alarm_idx_t; - -/** - * @brief Alarm mask - */ -typedef enum -{ - RTC_ALARM_MASK_NONE = 0x0, /**< Mask is disable */ - RTC_ALARM_MASK_WEEK_DAY = (1U << 30), /**< Mask week or day */ - RTC_ALARM_MASK_HOUR = (1U << 23), /**< Mask hour */ - RTC_ALARM_MASK_MINUTE = (1U << 15), /**< Mask minute */ - RTC_ALARM_MASK_SECOND = (1U << 7), /**< Mask second */ - RTC_ALARM_MASK_ALL = 0x40808080, /**< Mask all */ -} rtc_alarm_mask_t; - -/** - * @brief Alarm sub-second mask - */ -typedef enum -{ - RTC_ALARM_SS_MASK_NONE = 0xF, /**< Mask is disable */ - RTC_ALARM_SS_MASK_14_1 = 0x1, /**< Mask bit(1-14) */ - RTC_ALARM_SS_MASK_14_2 = 0x2, /**< Mask bit(2-14) */ - RTC_ALARM_SS_MASK_14_3 = 0x3, /**< Mask bit(3-14) */ - RTC_ALARM_SS_MASK_14_4 = 0x4, /**< Mask bit(4-14) */ - RTC_ALARM_SS_MASK_14_5 = 0x5, /**< Mask bit(5-14) */ - RTC_ALARM_SS_MASK_14_6 = 0x6, /**< Mask bit(6-14) */ - RTC_ALARM_SS_MASK_14_7 = 0x7, /**< Mask bit(7-14) */ - RTC_ALARM_SS_MASK_14_8 = 0x8, /**< Mask bit(8-14) */ - RTC_ALARM_SS_MASK_14_9 = 0x9, /**< Mask bit(9-14) */ - RTC_ALARM_SS_MASK_14_10 = 0xA, /**< Mask bit(10-14) */ - RTC_ALARM_SS_MASK_14_11 = 0xB, /**< Mask bit(11-14) */ - RTC_ALARM_SS_MASK_14_12 = 0xC, /**< Mask bit(12-14) */ - RTC_ALARM_SS_MASK_14_13 = 0xD, /**< Mask bit(13-14) */ - RTC_ALARM_SS_MASK_14 = 0xE, /**< Mask bit14 */ - RTC_ALARM_SS_MASK_ALL = 0x0, /**< Mask bit(0-14) */ -} rtc_sub_second_mask_t; - -/** - * @brief Alarm select week or day */ -typedef enum -{ - RTC_SELECT_DAY = 0x0, /**< Alarm select day */ - RTC_SELECT_WEEK = 0x1, /**< Alarm select week */ -} rtc_week_day_sel_t; - -/** - * @brief Alarm structure - */ -typedef struct -{ - rtc_alarm_idx_t idx; /**< Index of alarm */ - rtc_time_t time; /**< Time structure */ - uint32_t mask; /**< Alarm mask */ - rtc_sub_second_mask_t ss_mask; /**< Alarm sub-second mask */ - rtc_week_day_sel_t sel; /**< Select week or day */ - - union - { - uint8_t week; /**< Alarm select week */ - uint8_t day; /**< Alarm select day */ - }; -} rtc_alarm_t; - -/** - * @brief Time stamp signel select - */ -typedef enum -{ - RTC_TS_SIGNAL_SEL_TAMPER0 = 0, /**< Select tamper0 */ - RTC_TS_SIGNAL_SEL_TAMPER1 = 1, /**< Select tamper1 */ -} rtc_ts_signal_sel_t; - -/** - * @brief Time stamp trigger style - */ -typedef enum -{ - RTC_TS_RISING_EDGE = 0, /**< Rising edge */ - RTC_TS_FALLING_EDGE = 1, /**< Falling edge */ -} rtc_ts_trigger_style_t; - -/** - * @brief Index of tamper - */ -typedef enum -{ - RTC_TAMPER_0 = 0, /**< Tamper0 */ - RTC_TAMPER_1 = 1, /**< Tamper1 */ -} rtc_tamper_idx_t; - -/** - * @brief Tamper trigger type - */ -typedef enum -{ - RTC_TAMPER_TRIGGER_LOW = 0, /**< High trigger */ - RTC_TAMPER_TRIGGER_HIGH = 1, /**< Low trigger */ -} rtc_tamper_trigger_t; - -/** - * @brief Tamper sampling frequency - */ -typedef enum -{ - RTC_TAMPER_SAMPLING_FREQ_32768 = 0, /**< RTCCLK / 32768 */ - RTC_TAMPER_SAMPLING_FREQ_16384 = 1, /**< RTCCLK / 16384 */ - RTC_TAMPER_SAMPLING_FREQ_8192 = 2, /**< RTCCLK / 8192 */ - RTC_TAMPER_SAMPLING_FREQ_4096 = 3, /**< RTCCLK / 4096 */ - RTC_TAMPER_SAMPLING_FREQ_2048 = 4, /**< RTCCLK / 2048 */ - RTC_TAMPER_SAMPLING_FREQ_1024 = 5, /**< RTCCLK / 1024 */ - RTC_TAMPER_SAMPLING_FREQ_512 = 6, /**< RTCCLK / 512 */ - RTC_TAMPER_SAMPLING_FREQ_256 = 7, /**< RTCCLK / 256 */ -} rtc_tamper_sampling_freq_t; - -/** - * @brief Tamper filter time - */ -typedef enum -{ - RTC_TAMPER_DURATION_1 = 0, /**< Duration 1 sampling */ - RTC_TAMPER_DURATION_2 = 1, /**< Duration 2 sampling */ - RTC_TAMPER_DURATION_4 = 2, /**< Duration 4 sampling */ - RTC_TAMPER_DURATION_8 = 3, /**< Duration 8 sampling */ -} rtc_tamper_duration_t; - -/** - * @brief Tamper structure - */ -typedef struct -{ - rtc_tamper_idx_t idx; /**< Index of tamper */ - rtc_tamper_trigger_t trig; /**< Trigger type */ - rtc_tamper_sampling_freq_t freq; /**< Sampling frequency */ - rtc_tamper_duration_t dur; /**< Filter time */ - type_func_t ts; /**< Enable/Disable trigger time stamp event */ -} rtc_tamper_t; - -/** - * @brief Wake-up clock - */ -typedef enum -{ - RTC_WAKEUP_CLOCK_DIV_16 = 0, /**< RTCCLK / 16 */ - RTC_WAKEUP_CLOCK_DIV_8 = 1, /**< RTCCLK / 8 */ - RTC_WAKEUP_CLOCK_DIV_4 = 2, /**< RTCCLK / 4 */ - RTC_WAKEUP_CLOCK_DIV_2 = 3, /**< RTCCLK / 2 */ - RTC_WAKEUP_CLOCK_1HZ = 4, /**< 1Hz */ - RTC_WAKEUP_CLOCK_1HZ_PULS = 6, /**< 1Hz and WUT + 65536 */ -} rtc_wakeup_clock_t; - -/** - * @brief RTC clock output type - */ -typedef enum -{ - RTC_CLOCK_OUTPUT_32768 = 0, /**< 32768Hz */ - RTC_CLOCK_OUTPUT_1024 = 1, /**< 1024Hz */ - RTC_CLOCK_OUTPUT_32 = 2, /**< 32Hz */ - RTC_CLOCK_OUTPUT_1 = 3, /**< 1Hz */ - RTC_CLOCK_OUTPUT_CAL_1 = 4, /**< 1Hz after calibration */ - RTC_CLOCK_OUTPUT_EXA_1 = 5, /**< Exact 1Hz */ -} rtc_clock_output_t; - -/** - * @ Calibration frequency - */ -typedef enum -{ - RTC_CALI_FREQ_10_SEC = 0, /**< Calibrate every 10 seconds */ - RTC_CALI_FREQ_20_SEC = 1, /**< Calibrate every 20 seconds */ - RTC_CALI_FREQ_1_MIN = 2, /**< Calibrate every 1 minute */ - RTC_CALI_FREQ_2_MIN = 3, /**< Calibrate every 2 minutes */ - RTC_CALI_FREQ_5_MIN = 4, /**< Calibrate every 5 minutes */ - RTC_CALI_FREQ_10_MIN = 5, /**< Calibrate every 10 minutes */ - RTC_CALI_FREQ_20_MIN = 6, /**< Calibrate every 20 minutes */ - RTC_CALI_FREQ_1_SEC = 7, /**< Calibrate every 1 second */ -} rtc_cali_freq_t; - -/** - * @brief Temperature compensate type - */ -typedef enum -{ - RTC_CALI_TC_NONE = 0, /**< Temperature compensate disable */ - RTC_CALI_TC_AUTO_BY_HW = 1, /**< Temperature compensate by hardware */ - RTC_CALI_TC_AUTO_BY_SF = 2, /**< Temperature compensate by software */ - RTC_CALI_TC_AUTO_BY_HW_SF = 3, /**< Temperature compensate by hardware, trigger by software */ -} rtc_cali_tc_t; - -/** - * @ Calculate frequency - */ -typedef enum -{ - RTC_CALI_CALC_FREQ_10_SEC = 0, /**< Calculate every 10 seconds */ - RTC_CALI_CALC_FREQ_20_SEC = 1, /**< Calculate every 20 seconds */ - RTC_CALI_CALC_FREQ_1_MIN = 2, /**< Calculate every 1 minute */ - RTC_CALI_CALC_FREQ_2_MIN = 3, /**< Calculate every 2 minutes */ - RTC_CALI_CALC_FREQ_5_MIN = 4, /**< Calculate every 5 minutes */ - RTC_CALI_CALC_FREQ_10_MIN = 5, /**< Calculate every 10 minutes */ - RTC_CALI_CALC_FREQ_20_MIN = 6, /**< Calculate every 20 minutes */ - RTC_CALI_CALC_FREQ_1_HOUR = 7, /**< Calculate every 1 hour */ -} rtc_cali_calc_freq_t; - -/** - * @brief Calibration algorithm - */ -typedef enum -{ - RTC_CALI_CALC_4 = 0, /**< 4-polynomial */ - RTC_CALI_CALC_2 = 1, /**< 2-parabola */ -} rtc_cali_calc_t; - -/** - * @brief Calibration structure - */ -typedef struct -{ - rtc_cali_freq_t cali_freq; /**< calibrate frequency */ - rtc_cali_tc_t tc; /**< Temperature compensate type */ - rtc_cali_calc_freq_t calc_freq; /**< Calculate frequency */ - rtc_cali_calc_t calc; /**< algorithm */ - type_func_t acc; /**< Enable/Disable decimal accumulate */ -} rtc_cali_t; - -/** - * @brief Interrupt type - */ -typedef enum -{ - RTC_IT_SEC = (1U << 0), /**< Second */ - RTC_IT_MIN = (1U << 1), /**< Minute */ - RTC_IT_HR = (1U << 2), /**< Hour */ - RTC_IT_DAY = (1U << 3), /**< Day */ - RTC_IT_MON = (1U << 4), /**< Month */ - RTC_IT_YR = (1U << 5), /**< Year */ - RTC_IT_ALMA = (1U << 8), /**< Alarm-A */ - RTC_IT_ALMB = (1U << 9), /**< Alarm-B */ - RTC_IT_TS = (1U << 10), /**< Time stamp */ - RTC_IT_TSOV = (1U << 11), /**< Time stamp overflow */ - RTC_IT_TP0 = (1U << 12), /**< Tamper-0 */ - RTC_IT_TP1 = (1U << 13), /**< Tamper-1 */ - RTC_IT_RSC = (1U << 16), /**< Synchronous complete */ - RTC_IT_SFC = (1U << 17), /**< Shift complete */ - RTC_IT_WU = (1U << 18), /**< Wake-up */ - RTC_IT_TCC = (1U << 24), /**< Temperature compensate complete */ - RTC_IT_TCE = (1U << 25), /**< Temperature compensate error */ -} rtc_it_t; - -/** - * @brief Interrupt flag - */ -typedef enum -{ - RTC_IF_SEC = (1U << 0), /**< Second */ - RTC_IF_MIN = (1U << 1), /**< Minute */ - RTC_IF_HR = (1U << 2), /**< Hour */ - RTC_IF_DAY = (1U << 3), /**< Day */ - RTC_IF_MON = (1U << 4), /**< Month */ - RTC_IF_YR = (1U << 5), /**< Year */ - RTC_IF_ALMA = (1U << 8), /**< Alarm-A */ - RTC_IF_ALMB = (1U << 9), /**< Alarm-B */ - RTC_IF_TS = (1U << 10), /**< Time stamp */ - RTC_IF_TSOV = (1U << 11), /**< Time stamp overflow */ - RTC_IF_TP0 = (1U << 12), /**< Tamper-0 */ - RTC_IF_TP1 = (1U << 13), /**< Tamper-1 */ - RTC_IF_RSC = (1U << 16), /**< Synchronous complete */ - RTC_IF_SFC = (1U << 17), /**< Shift complete */ - RTC_IF_WU = (1U << 18), /**< Wake-up */ - RTC_IF_TCC = (1U << 24), /**< Temperature compensate complete */ - RTC_IF_TCE = (1U << 25), /**< Temperature compensate error */ -} rtc_flag_t; -/** - * @} - */ - -/** @defgroup RTC_Public_Macro RTC Public Macros - * @{ - */ -#define RTC_UNLOCK() (WRITE_REG(RTC->WPR, 0x55AAAA55)) -#define RTC_LOCK() (WRITE_REG(RTC->WPR, 0x0)) -#define RTC_BY_PASS_ENABLE() \ -do { \ - RTC_UNLOCK(); \ - SET_BIT(RTC->CON, RTC_CON_SHDBP_MSK); \ - RTC_LOCK(); \ -} while (0) -#define RTC_BY_PASS_DISABLE() \ -do { \ - RTC_UNLOCK(); \ - CLEAR_BIT(RTC->CON, RTC_CON_SHDBP_MSK); \ - RTC_LOCK(); \ -} while (0) -#define RTC_SUMMER_TIME_ENABLE() \ -do { \ - RTC_UNLOCK(); \ - SET_BIT(RTC->CON, RTC_CON_ADD1H_MSK); \ - RTC_LOCK(); \ -} while (0) -#define RTC_SUMMER_TIME_DISABLE() \ -do { \ - RTC_UNLOCK(); \ - CLEAR_BIT(RTC->CON, RTC_CON_ADD1H_MSK); \ - RTC_LOCK(); \ -} while (0) -#define RTC_WINTER_TIME_ENABLE() \ -do { \ - RTC_UNLOCK(); \ - SET_BIT(RTC->CON, RTC_CON_SUB1H_MSK); \ - RTC_LOCK(); \ -} while (0) -#define RTC_WINTER_TIME_DISABLE() \ -do { \ - RTC_UNLOCK(); \ - CLEAR_BIT(RTC->CON, RTC_CON_SUB1H_MSK); \ - RTC_LOCK(); \ -} while (0) -/** - * @} - */ - -/** @defgroup CAN_Private_Macros CAN Private Macros - * @{ - */ -#define RTC_CALI_UNLOCK() (WRITE_REG(RTC->CALWPR, 0x699655AA)) -#define RTC_CALI_LOCK() (WRITE_REG(RTC->CALWPR, 0x0)) -#define ALARM_MASK_ALL 0x40808080 -#define RTC_TIMEOUT_VALUE 100 - -#define IS_SHIFT_SUB_SS(x) ((x) < (1U << 15)) -#define IS_RTC_HOUR_FORMAT(x) (((x) == RTC_HOUR_FORMAT_24) || \ - ((x) == RTC_HOUR_FORMAT_12)) -#define IS_RTC_OUTPUT_SEL(x) (((x) == RTC_OUTPUT_DISABLE) || \ - ((x) == RTC_OUTPUT_ALARM_A) || \ - ((x) == RTC_OUTPUT_ALARM_B) || \ - ((x) == RTC_OUTPUT_WAKEUP)) -#define IS_RTC_OUTPUT_POLARITY(x) (((x) == RTC_OUTPUT_POLARITY_HIGH) || \ - ((x) == RTC_OUTPUT_POLARITY_LOW)) -#define IS_RTC_SOURCE_SEL(x) (((x) == RTC_SOURCE_LOSC) || \ - ((x) == RTC_SOURCE_LRC) || \ - ((x) == RTC_SOURCE_HRC_DIV_1M ) || \ - ((x) == RTC_SOURCE_HOSC_DIV_1M)) -#define IS_RTC_ALARM(x) (((x) == RTC_ALARM_A) || \ - ((x) == RTC_ALARM_B)) -#define IS_RTC_ALARM_SEL(x) (((x) == RTC_SELECT_DAY) || \ - ((x) == RTC_SELECT_WEEK)) -#define IS_RTC_ALARM_MASK(x) (((x) == RTC_ALARM_MASK_NONE) || \ - ((x) == RTC_ALARM_MASK_WEEK_DAY) || \ - ((x) == RTC_ALARM_MASK_HOUR) || \ - ((x) == RTC_ALARM_MASK_MINUTE) || \ - ((x) == RTC_ALARM_MASK_SECOND) || \ - ((x) == RTC_ALARM_MASK_ALL)) -#define IS_RTC_ALARM_SS_MASK(x) (((x) == RTC_ALARM_SS_MASK_NONE) || \ - ((x) == RTC_ALARM_SS_MASK_14_1) || \ - ((x) == RTC_ALARM_SS_MASK_14_2) || \ - ((x) == RTC_ALARM_SS_MASK_14_3) || \ - ((x) == RTC_ALARM_SS_MASK_14_4) || \ - ((x) == RTC_ALARM_SS_MASK_14_5) || \ - ((x) == RTC_ALARM_SS_MASK_14_6) || \ - ((x) == RTC_ALARM_SS_MASK_14_7) || \ - ((x) == RTC_ALARM_SS_MASK_14_8) || \ - ((x) == RTC_ALARM_SS_MASK_14_9) || \ - ((x) == RTC_ALARM_SS_MASK_14_10) || \ - ((x) == RTC_ALARM_SS_MASK_14_11) || \ - ((x) == RTC_ALARM_SS_MASK_14_12) || \ - ((x) == RTC_ALARM_SS_MASK_14_13) || \ - ((x) == RTC_ALARM_SS_MASK_14) || \ - ((x) == RTC_ALARM_SS_MASK_ALL)) -#define IS_RTC_TS_SIGNAL(x) (((x) == RTC_TS_SIGNAL_SEL_TAMPER0) || \ - ((x) == RTC_TS_SIGNAL_SEL_TAMPER1)) -#define IS_RTC_TS_STYLE(x) (((x) == RTC_TS_RISING_EDGE) || \ - ((x) == RTC_TS_FALLING_EDGE)) -#define IS_RTC_FORMAT(x) (((x) == RTC_FORMAT_DEC) || \ - ((x) == RTC_FORMAT_BCD)) -#define IS_RTC_TAMPER(x) (((x) == RTC_TAMPER_0) || \ - ((x) == RTC_TAMPER_1)) -#define IS_RTC_TAMPER_TRIGGER(x) (((x) == RTC_TAMPER_TRIGGER_LOW) || \ - ((x) == RTC_TAMPER_TRIGGER_HIGH)) -#define IS_RTC_TAMPER_SAMPLING_FREQ(x) (((x) == RTC_TAMPER_SAMPLING_FREQ_32768) || \ - ((x) == RTC_TAMPER_SAMPLING_FREQ_16384) || \ - ((x) == RTC_TAMPER_SAMPLING_FREQ_8192) || \ - ((x) == RTC_TAMPER_SAMPLING_FREQ_4096) || \ - ((x) == RTC_TAMPER_SAMPLING_FREQ_2048) || \ - ((x) == RTC_TAMPER_SAMPLING_FREQ_1024) || \ - ((x) == RTC_TAMPER_SAMPLING_FREQ_512) || \ - ((x) == RTC_TAMPER_SAMPLING_FREQ_256)) -#define IS_RTC_TAMPER_DURATION(x) (((x) == RTC_TAMPER_DURATION_1) || \ - ((x) == RTC_TAMPER_DURATION_2) || \ - ((x) == RTC_TAMPER_DURATION_4) || \ - ((x) == RTC_TAMPER_DURATION_8)) -#define IS_RTC_WAKEUP_CLOCK(x) (((x) == RTC_WAKEUP_CLOCK_DIV_16) || \ - ((x) == RTC_WAKEUP_CLOCK_DIV_8) || \ - ((x) == RTC_WAKEUP_CLOCK_DIV_4) || \ - ((x) == RTC_WAKEUP_CLOCK_DIV_2) || \ - ((x) == RTC_WAKEUP_CLOCK_1HZ) || \ - ((x) == RTC_WAKEUP_CLOCK_1HZ_PULS)) -#define IS_RTC_CLOCK_OUTPUT(x) (((x) == RTC_CLOCK_OUTPUT_32768) || \ - ((x) == RTC_CLOCK_OUTPUT_1024) || \ - ((x) == RTC_CLOCK_OUTPUT_32) || \ - ((x) == RTC_CLOCK_OUTPUT_1) || \ - ((x) == RTC_CLOCK_OUTPUT_CAL_1) || \ - ((x) == RTC_CLOCK_OUTPUT_EXA_1)) -#define IS_RTC_CALI_FREQ(x) (((x) == RTC_CALI_FREQ_10_SEC) || \ - ((x) == RTC_CALI_FREQ_20_SEC) || \ - ((x) == RTC_CALI_FREQ_1_MIN) || \ - ((x) == RTC_CALI_FREQ_2_MIN) || \ - ((x) == RTC_CALI_FREQ_5_MIN) || \ - ((x) == RTC_CALI_FREQ_10_MIN) || \ - ((x) == RTC_CALI_FREQ_20_MIN) || \ - ((x) == RTC_CALI_FREQ_1_SEC)) -#define IS_RTC_CALI_TC(x) (((x) == RTC_CALI_TC_NONE) || \ - ((x) == RTC_CALI_TC_AUTO_BY_HW) || \ - ((x) == RTC_CALI_TC_AUTO_BY_SF) || \ - ((x) == RTC_CALI_TC_AUTO_BY_HW_SF)) -#define IS_RTC_CALC_FREQ(x) (((x) == RTC_CALI_CALC_FREQ_10_SEC) || \ - ((x) == RTC_CALI_CALC_FREQ_20_SEC) || \ - ((x) == RTC_CALI_CALC_FREQ_1_MIN) || \ - ((x) == RTC_CALI_CALC_FREQ_2_MIN) || \ - ((x) == RTC_CALI_CALC_FREQ_5_MIN) || \ - ((x) == RTC_CALI_CALC_FREQ_10_MIN) || \ - ((x) == RTC_CALI_CALC_FREQ_20_MIN) || \ - ((x) == RTC_CALI_CALC_FREQ_1_HOUR)) -#define IS_RTC_CALI_CALC(x) (((x) == RTC_CALI_CALC_4) || \ - ((x) == RTC_CALI_CALC_2)) -#define IS_RTC_IT(x) (((x) == RTC_IT_SEC) || \ - ((x) == RTC_IT_MIN) || \ - ((x) == RTC_IT_HR) || \ - ((x) == RTC_IT_DAY) || \ - ((x) == RTC_IT_MON) || \ - ((x) == RTC_IT_YR) || \ - ((x) == RTC_IT_ALMA) || \ - ((x) == RTC_IT_ALMB) || \ - ((x) == RTC_IT_TS) || \ - ((x) == RTC_IT_TSOV) || \ - ((x) == RTC_IT_TP0) || \ - ((x) == RTC_IT_TP1) || \ - ((x) == RTC_IT_RSC) || \ - ((x) == RTC_IT_SFC) || \ - ((x) == RTC_IT_WU) || \ - ((x) == RTC_IT_TCC) || \ - ((x) == RTC_IT_TCE)) -#define IS_RTC_IF(x) (((x) == RTC_IF_SEC) || \ - ((x) == RTC_IF_MIN) || \ - ((x) == RTC_IF_HR) || \ - ((x) == RTC_IF_DAY) || \ - ((x) == RTC_IF_MON) || \ - ((x) == RTC_IF_YR) || \ - ((x) == RTC_IF_ALMA) || \ - ((x) == RTC_IF_ALMB) || \ - ((x) == RTC_IF_TS) || \ - ((x) == RTC_IF_TSOV) || \ - ((x) == RTC_IF_TP0) || \ - ((x) == RTC_IF_TP1) || \ - ((x) == RTC_IF_RSC) || \ - ((x) == RTC_IF_SFC) || \ - ((x) == RTC_IF_WU) || \ - ((x) == RTC_IF_TCC) || \ - ((x) == RTC_IF_TCE)) -#define IS_RTC_SECOND(x) ((x) < 60) -#define IS_RTC_MINUTE(x) ((x) < 60) -#define IS_RTC_HOUR(x) ((x) < 24) -#define IS_RTC_DAY(x) (((x) > 0) && ((x) < 32)) -#define IS_RTC_MONTH(x) (((x) > 0) && ((x) < 13)) -#define IS_RTC_YEAR(x) ((x) < 100) -/** - * @} - */ - -/** @addtogroup RTC_Public_Functions - * @{ - */ - -/** @addtogroup RTC_Public_Functions_Group1 - * @{ - */ -/* Initialization functions */ -void rtc_reset(void); -void rtc_init(rtc_init_t *init); -void rtc_source_selcet(rtc_source_sel_t sel); -/** - * @} - */ -/** @addtogroup RTC_Public_Functions_Group2 - * @{ - */ -/* Time and date operation functions */ -ald_status_t rtc_set_time(rtc_time_t *time, rtc_format_t format); -ald_status_t rtc_set_date(rtc_date_t *date, rtc_format_t format); -void rtc_get_time(rtc_time_t *time, rtc_format_t format); -void rtc_get_date(rtc_date_t *date, rtc_format_t format); -int32_t rtc_get_date_time(rtc_date_t *date, rtc_time_t *time, rtc_format_t format); -/** - * @} - */ -/** @addtogroup RTC_Public_Functions_Group3 - * @{ - */ -/* Alarm functions */ -void rtc_set_alarm(rtc_alarm_t *alarm, rtc_format_t format); -void rtc_get_alarm(rtc_alarm_t *alarm, rtc_format_t format); -/** - * @} - */ -/** @addtogroup RTC_Public_Functions_Group4 - * @{ - */ -/* Time stamp functions */ -void rtc_set_time_stamp(rtc_ts_signal_sel_t sel, rtc_ts_trigger_style_t style); -void rtc_cancel_time_stamp(void); -void rtc_get_time_stamp(rtc_time_t *ts_time, rtc_date_t *ts_date, rtc_format_t format); -/** - * @} - */ -/** @addtogroup RTC_Public_Functions_Group5 - * @{ - */ -/* Tamper functions */ -void rtc_set_tamper(rtc_tamper_t *tamper); -void rtc_cancel_tamper(rtc_tamper_idx_t idx); -/** - * @} - */ -/** @addtogroup RTC_Public_Functions_Group6 - * @{ - */ -/* Wakeup functions */ -void rtc_set_wakeup(rtc_wakeup_clock_t clock, uint16_t value); -void rtc_cancel_wakeup(void); -uint16_t rtc_get_wakeup_timer_value(void); -/** - * @} - */ -/** @addtogroup RTC_Public_Functions_Group7 - * @{ - */ -/* Clock output functions */ -ald_status_t rtc_set_clock_output(rtc_clock_output_t clock); -void rtc_cancel_clock_output(void); -/** - * @} - */ -/** @addtogroup RTC_Public_Functions_Group8 - * @{ - */ -/* Control functions */ -void rtc_interrupt_config(rtc_it_t it, type_func_t state); -void rtc_alarm_cmd(rtc_alarm_idx_t idx, type_func_t state); -ald_status_t rtc_set_shift(type_func_t add_1s, uint16_t sub_ss); -void rtc_set_cali(rtc_cali_t *config); -void rtc_cancel_cali(void); -ald_status_t rtc_get_cali_status(void); -void rtc_write_temp(uint16_t temp); -it_status_t rtc_get_it_status(rtc_it_t it); -flag_status_t rtc_get_flag_status(rtc_flag_t flag); -void rtc_clear_flag_status(rtc_flag_t flag); -/** - * @} - */ -/** - * @} - */ -/** - * @} - */ -/** - * @} - */ -#ifdef __cplusplus -} -#endif -#endif diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_spi.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_spi.h deleted file mode 100644 index 467e92b07f..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_spi.h +++ /dev/null @@ -1,377 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_spi.c - * @brief Header file of SPI module driver. - * - * @version V1.0 - * @date 13 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ********************************************************************************* - */ - -#ifndef __ALD_SPI_H__ -#define __ALD_SPI_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" -#include "ald_dma.h" - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup SPI - * @{ - */ - -/** @defgroup SPI_Public_Types SPI Public Types - * @{ - */ - -/** - * @brief clock phase - */ -typedef enum -{ - SPI_CPHA_FIRST = 0, /**< Transiting data in the first edge */ - SPI_CPHA_SECOND = 1, /**< Transiting data in the seconde edge */ -} spi_cpha_t; - -/** - * @brief clock polarity - */ -typedef enum -{ - SPI_CPOL_LOW = 0, /**< Polarity hold low when spi-bus is idle */ - SPI_CPOL_HIGH = 1, /**< Polarity hold high when spi-bus is idle */ -} spi_cpol_t; - -/** - * @brief master selection - */ -typedef enum -{ - SPI_MODE_SLAVER = 0, /**< Slave mode */ - SPI_MODE_MASTER = 1, /**< Master mode */ -} spi_mode_t; - -/** - * @brief baud rate control - */ -typedef enum -{ - SPI_BAUD_2 = 0, /**< fpclk/2 */ - SPI_BAUD_4 = 1, /**< fpclk/4 */ - SPI_BAUD_8 = 2, /**< fpclk/8 */ - SPI_BAUD_16 = 3, /**< fpclk/16 */ - SPI_BAUD_32 = 4, /**< fpclk/32 */ - SPI_BAUD_64 = 5, /**< fpclk/64 */ - SPI_BAUD_128 = 6, /**< fpclk/128 */ - SPI_BAUD_256 = 7, /**< fpclk/256 */ -} spi_baud_t; - -/** - * @brief frame format - */ -typedef enum -{ - SPI_FIRSTBIT_MSB = 0, /**< MSB transmitted first */ - SPI_FIRSTBIT_LSB = 1, /**< LSB transmitted first */ -} spi_firstbit_t; - -/** - * @brief data frame format - */ -typedef enum -{ - SPI_DATA_SIZE_8 = 0, /**< 8-bit data frame format is selected for transmission/reception */ - SPI_DATA_SIZE_16 = 1, /**< 16-bit data frame format is selected for transmission/reception */ -} spi_datasize_t; - -/** - * @brief interrupt control - */ -typedef enum -{ - SPI_IT_ERR = (1U << 5), /**< error interrupt */ - SPI_IT_RXBNE = (1U << 6), /**< rx buffer not empty interrupt */ - SPI_IT_TXBE = (1U << 7), /**< tx buffer empty interrupt */ -} spi_it_t; - -/** - * @brief interrupt flag - */ -typedef enum -{ - SPI_IF_RXBNE = (1U << 0), /**< receive buffer not empty */ - SPI_IF_TXBE = (1U << 1), /**< transmit buffer empty */ - SPI_IF_CRCERR = (1U << 4), /**< crc error flag */ - SPI_IF_MODF = (1U << 5), /**< mode fault */ - SPI_IF_OVE = (1U << 6), /**< overrun flag */ - SPI_IF_BUSY = (1U << 7), /**< busy flag */ -} spi_flag_t; - -/** - * @brief SPI error status - */ -typedef enum -{ - SPI_ERROR_NONE = 0, /**< none */ - SPI_ERROR_MODF = 1, /**< mode fault */ - SPI_ERROR_CRC = 2, /**< crc error */ - SPI_ERROR_OVE = 4, /**< overrun error */ - SPI_ERROR_DMA = 8, /**< dma error */ - SPI_ERROR_FLAG = 0x10, /**< interrupt flag error */ -} spi_error_t; - - - -/** - * @brief SPI state structures definition - */ -typedef enum -{ - SPI_STATE_RESET = 0x00, /**< Peripheral is not initialized */ - SPI_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ - SPI_STATE_BUSY = 0x02, /**< an internal process is ongoing */ - SPI_STATE_BUSY_TX = 0x11, /**< transmit is ongoing */ - SPI_STATE_BUSY_RX = 0x21, /**< receive is ongoing */ - SPI_STATE_BUSY_TX_RX = 0x31, /**< transmit and receive are ongoing */ - SPI_STATE_TIMEOUT = 0x03, /**< Timeout state */ - SPI_STATE_ERROR = 0x04, /**< Error */ -} spi_state_t; - - -/** - * @brief SPI direction definition - */ -typedef enum -{ - SPI_DIRECTION_2LINES = 0, /**< 2 lines */ - SPI_DIRECTION_2LINES_RXONLY = 1, /**< 2 lines only rx */ - SPI_DIRECTION_1LINE = 2, /**< 1 line */ - SPI_DIRECTION_1LINE_RX = 3, /**< 1 line only rx */ -} spi_direction_t; - -/** - * @brief SPI dma request definition - */ -typedef enum -{ - SPI_DMA_REQ_TX = 0, /**< TX dma request */ - SPI_DMA_REQ_RX = 1, /**< RX dma request */ -} spi_dma_req_t; - -/** - * @brief SPI TXE/RXNE status definition - */ -typedef enum -{ - SPI_SR_TXBE = 0, /**< SR.TXE set */ - SPI_SR_RXBNE = 1, /**< SR.RXNE set */ - SPI_SR_TXBE_RXBNE = 2, /**< SR.TXE and SR.RXNE set */ -} spi_sr_status_t; - -/** - * @brief SPI init structure definition - */ -typedef struct -{ - spi_mode_t mode; /**< SPI mode */ - spi_direction_t dir; /**< SPI direction */ - spi_datasize_t data_size; /**< SPI data size */ - spi_baud_t baud; /**< SPI baudrate prescaler */ - spi_cpha_t phase; /**< SPI clock phase */ - spi_cpol_t polarity; /**< SPI clock polarity */ - spi_firstbit_t first_bit; /**< SPI first bit */ - type_func_t ss_en; /**< SPI ssm enable or disable */ - type_func_t crc_calc; /**< SPI crc calculation */ - uint16_t crc_poly; /**< SPI crc polynomial */ -} spi_init_t; - -/** - * @brief SPI handle structure definition - */ -typedef struct spi_handle_s -{ - SPI_TypeDef *perh; /**< SPI registers base address */ - spi_init_t init; /**< SPI communication parameters */ - uint8_t *tx_buf; /**< Pointer to SPI Tx transfer buffer */ - uint16_t tx_size; /**< SPI Tx transfer size */ - uint16_t tx_count; /**< SPI Tx transfer counter */ - uint8_t *rx_buf; /**< Pointer to SPI Rx transfer buffer */ - uint16_t rx_size; /**< SPI Rx Transfer size */ - uint16_t rx_count; /**< SPI Rx Transfer Counter */ -#ifdef ALD_DMA - dma_handle_t hdmatx; /**< SPI Tx DMA handle parameters */ - dma_handle_t hdmarx; /**< SPI Rx DMA handle parameters */ -#endif - lock_state_t lock; /**< Locking object */ - spi_state_t state; /**< SPI communication state */ - uint32_t err_code; /**< SPI error code */ - - void (*tx_cplt_cbk)(struct spi_handle_s *arg); /**< Tx completed callback */ - void (*rx_cplt_cbk)(struct spi_handle_s *arg); /**< Rx completed callback */ - void (*tx_rx_cplt_cbk)(struct spi_handle_s *arg); /**< Tx & Rx completed callback */ - void (*err_cbk)(struct spi_handle_s *arg); /**< error callback */ -} spi_handle_t; -/** - * @} - */ - -/** @defgroup SPI_Public_Macros SPI Public Macros - * @{ - */ -#define SPI_RESET_HANDLE_STATE(x) ((x)->state = SPI_STATE_RESET) -#define SPI_ENABLE(x) ((x)->perh->CON1 |= (1 << SPI_CON1_SPIEN_POS)) -#define SPI_DISABLE(x) ((x)->perh->CON1 &= ~(1 << SPI_CON1_SPIEN_POS)) -#define SPI_CRC_RESET(x) \ -do { \ - CLEAR_BIT((x)->perh->CON1, SPI_CON1_CRCEN_MSK); \ - SET_BIT((x)->perh->CON1, SPI_CON1_CRCEN_MSK); \ -} while (0) -#define SPI_CRCNEXT_ENABLE(x) (SET_BIT((x)->perh->CON1, SPI_CON1_NXTCRC_MSK)) -#define SPI_CRCNEXT_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_NXTCRC_MSK)) -#define SPI_RXONLY_ENABLE(x) (SET_BIT((x)->perh->CON1, SPI_CON1_RXO_MSK)) -#define SPI_RXONLY_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_RXO_MSK)) -#define SPI_1LINE_TX(x) (SET_BIT((x)->perh->CON1, SPI_CON1_BIDOEN_MSK)) -#define SPI_1LINE_RX(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_BIDOEN_MSK)) -#define SPI_SSI_HIGH(x) (SET_BIT((x)->perh->CON1, SPI_CON1_SSOUT_MSK)) -#define SPI_SSI_LOW(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_SSOUT_MSK)) -#define SPI_SSOE_ENABLE(x) (SET_BIT((x)->perh->CON2, SPI_CON2_NSSOE_MSK)) -#define SPI_SSOE_DISABLE(x) (CLEAR_BIT((x)->perh->CON2, SPI_CON2_NSSOE_MSK)) -/** - * @} - */ - -/** @defgroup SPI_Private_Macros SPI Private Macros - * @{ - */ -#define IS_SPI(x) (((x) == SPI0) || \ - ((x) == SPI1) || \ - ((x) == SPI2)) -#define IS_SPI_CPHA(x) (((x) == SPI_CPHA_FIRST) || \ - ((x) == SPI_CPHA_SECOND)) -#define IS_SPI_CPOL(x) (((x) == SPI_CPOL_LOW) || \ - ((x) == SPI_CPOL_HIGH)) -#define IS_SPI_MODE(x) (((x) == SPI_MODE_SLAVER) || \ - ((x) == SPI_MODE_MASTER)) -#define IS_SPI_BAUD(x) (((x) == SPI_BAUD_2) || \ - ((x) == SPI_BAUD_4) || \ - ((x) == SPI_BAUD_8) || \ - ((x) == SPI_BAUD_16) || \ - ((x) == SPI_BAUD_32) || \ - ((x) == SPI_BAUD_64) || \ - ((x) == SPI_BAUD_128) || \ - ((x) == SPI_BAUD_256)) -#define IS_SPI_DATASIZE(x) (((x) == SPI_DATA_SIZE_8) || \ - ((x) == SPI_DATA_SIZE_16)) -#define IS_SPI_BIDOE(x) (((x) == SPI_BID_RX) || \ - ((x) == SPI_BID_TX)) -#define IS_SPI_BIDMODE(x) (((x) == SPI_BIDMODE_DUAL) || \ - ((x) == SPI_BIDMODE_SOLE)) -#define IS_SPI_DIRECTION(x) (((x) == SPI_DIRECTION_2LINES) || \ - ((x) == SPI_DIRECTION_2LINES_RXONLY) || \ - ((x) == SPI_DIRECTION_1LINE) || \ - ((x) == SPI_DIRECTION_1LINE_RX)) -#define IS_SPI_DMA_REQ(x) (((x) == SPI_DMA_REQ_TX) || \ - ((x) == SPI_DMA_REQ_RX)) -#define IS_SPI_SR_STATUS(x) (((x) == SPI_SR_TXBE) || \ - ((x) == SPI_SR_RXBNE) || \ - ((x) == SPI_SR_TXBE_RXBNE)) -#define IS_SPI_IT(x) (((x) == SPI_IT_ERR) || \ - ((x) == SPI_IT_RXBNE) || \ - ((x) == SPI_IT_TXBE)) -#define IS_SPI_IF(x) (((x) == SPI_IF_RXBNE) || \ - ((x) == SPI_IF_TXBE) || \ - ((x) == SPI_IF_CRCERR) || \ - ((x) == SPI_IF_MODF) || \ - ((x) == SPI_IF_OVE) || \ - ((x) == SPI_IF_BUSY)) -/** - * @} - */ - -/** @addtogroup SPI_Public_Functions - * @{ - */ - -/** @addtogroup SPI_Public_Functions_Group1 - * @{ - */ - -ald_status_t spi_init(spi_handle_t *hperh); -void spi_reset(spi_handle_t *hperh); -/** - * @} - */ - -/** @addtogroup SPI_Public_Functions_Group2 - * @{ - */ -int32_t spi_send_byte_fast(spi_handle_t *hperh, uint8_t data); -uint8_t spi_recv_byte_fast(spi_handle_t *hperh); -ald_status_t spi_send(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t spi_send_recv(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout); -ald_status_t spi_send_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t spi_recv_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t spi_send_recv_by_it(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size); -#ifdef ALD_DMA -ald_status_t spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel); -ald_status_t spi_dma_pause(spi_handle_t *hperh); -ald_status_t spi_dma_resume(spi_handle_t *hperh); -ald_status_t spi_dma_stop(spi_handle_t *hperh); -#endif -/** - * @} - */ - -/** @addtogroup SPI_Public_Functions_Group3 - * @{ - */ -void spi_irq_handle(spi_handle_t *hperh); -void spi_interrupt_config(spi_handle_t *hperh, spi_it_t it, type_func_t state); -void spi_speed_config(spi_handle_t *hperh, spi_baud_t speed); -void spi_dma_req_config(spi_handle_t *hperh, spi_dma_req_t req, type_func_t state); -it_status_t spi_get_it_status(spi_handle_t *hperh, spi_it_t it); -flag_status_t spi_get_flag_status(spi_handle_t *hperh, spi_flag_t flag); -void spi_clear_flag_status(spi_handle_t *hperh, spi_flag_t flag); -/** - * @} - */ - -/** @addtogroup SPI_Public_Functions_Group4 - * @{ - */ -spi_state_t spi_get_state(spi_handle_t *hperh); -uint32_t spi_get_error(spi_handle_t *hperh); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -} -#endif -#endif diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_temp.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_temp.h deleted file mode 100644 index b9d5c15d15..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_temp.h +++ /dev/null @@ -1,203 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_temp.h - * @brief Header file of TEMP module driver. - * - * @version V1.0 - * @date 15 Dec 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ******************************************************************************** - */ - -#ifndef __ALD_TEMP_H__ -#define __ALD_TEMP_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" - - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup TEMP - * @{ - */ - -/** @defgroup TEMP_Public_Macros TEMP Public Macros - * @{ - */ -#define TEMP_LOCK() (WRITE_REG(TEMP->WPR, 0x0)) -#define TEMP_UNLOCK() (WRITE_REG(TEMP->WPR, 0xA55A9669)) -#define TEMP_ENABLE() \ -do { \ - TEMP_UNLOCK(); \ - SET_BIT(TEMP->CR, TEMP_CR_EN_MSK); \ - TEMP_LOCK(); \ -} while (0) -#define TEMP_DISABLE() \ -do { \ - TEMP_UNLOCK(); \ - CLEAR_BIT(TEMP->CR, TEMP_CR_EN_MSK); \ - TEMP_LOCK(); \ -} while (0) -#define TEMP_REQ_ENABLE() \ -do { \ - TEMP_UNLOCK(); \ - SET_BIT(TEMP->CR, TEMP_CR_REQEN_MSK); \ - TEMP_LOCK(); \ -} while (0) -#define TEMP_REQ_DISABLE() \ -do { \ - TEMP_UNLOCK(); \ - CLEAR_BIT(TEMP->CR, TEMP_CR_REQEN_MSK); \ - TEMP_LOCK(); \ -} while (0) -#define TEMP_CTN_ENABLE() \ -do { \ - TEMP_UNLOCK(); \ - SET_BIT(TEMP->CR, TEMP_CR_CTN_MSK); \ - TEMP_LOCK(); \ -} while (0) -#define TEMP_CTN_DISABLE() \ -do { \ - TEMP_UNLOCK(); \ - CLEAR_BIT(TEMP->CR, TEMP_CR_CTN_MSK); \ - TEMP_LOCK(); \ -} while (0) -#define TEMP_RESET() \ -do { \ - TEMP_UNLOCK(); \ - SET_BIT(TEMP->CR, TEMP_CR_RST_MSK); \ - TEMP_LOCK(); \ -} while (0) -/** - * @} - */ - -/** @defgroup TEMP_Public_Types TEMP Public Types - * @{ - */ -/** - * @brief Temperature update time - */ -typedef enum -{ - TEMP_UPDATE_CYCLE_3 = 0x3, /**< 3 Cycles */ - TEMP_UPDATE_CYCLE_4 = 0x4, /**< 4 Cycles */ - TEMP_UPDATE_CYCLE_5 = 0x5, /**< 5 Cycles */ - TEMP_UPDATE_CYCLE_6 = 0x6, /**< 6 Cycles */ - TEMP_UPDATE_CYCLE_7 = 0x7, /**< 7 Cycles */ -} temp_update_cycle_t; - -/** - * @brief Temperature output mode - */ -typedef enum -{ - TEMP_OUTPUT_MODE_200 = 0x0, /**< 200 cycles update one temperature */ - TEMP_OUTPUT_MODE_400 = 0x1, /**< 400 cycles update one temperature */ - TEMP_OUTPUT_MODE_800 = 0x2, /**< 800 cycles update one temperature */ - TEMP_OUTPUT_MODE_1600 = 0x3, /**< 1600 cycles update one temperature */ - TEMP_OUTPUT_MODE_3200 = 0x4, /**< 3200 cycles update one temperature */ -} temp_output_mode_t; - -/** - * @brief Source select - */ -typedef enum -{ - TEMP_SOURCE_LOSC = 0x0, /**< LOSC */ - TEMP_SOURCE_LRC = 0x1, /**< LRC */ - TEMP_SOURCE_HRC_DIV_1M = 0x2, /**< HRC divide to 1MHz */ - TEMP_SOURCE_HOSC_DIV_1M = 0x3, /**< HOSC divide to 1MHz */ -} temp_source_sel_t; - - -/** - * @brief TEMP init structure definition - */ -typedef struct -{ - temp_update_cycle_t cycle; /**< Temperature update time */ - temp_output_mode_t mode; /**< Temperature output mode */ - uint8_t ctn; /**< Continue mode */ - uint8_t psc; /**< Perscaler */ -} temp_init_t; - -/** - * @brief Define callback function type - */ -typedef void (*temp_cbk)(uint16_t value, ald_status_t status); -/** - * @} - */ - -/** - * @defgroup TEMP_Private_Macros TEMP Private Macros - * @{ - */ -#define IS_TEMP_UPDATE_CYCLE(x) (((x) == TEMP_UPDATE_CYCLE_3) || \ - ((x) == TEMP_UPDATE_CYCLE_4) || \ - ((x) == TEMP_UPDATE_CYCLE_5) || \ - ((x) == TEMP_UPDATE_CYCLE_6) || \ - ((x) == TEMP_UPDATE_CYCLE_7)) -#define IS_TEMP_OUTPUT_MODE(x) (((x) == TEMP_OUTPUT_MODE_200) || \ - ((x) == TEMP_OUTPUT_MODE_400) || \ - ((x) == TEMP_OUTPUT_MODE_800) || \ - ((x) == TEMP_OUTPUT_MODE_1600) || \ - ((x) == TEMP_OUTPUT_MODE_3200)) -#define IS_TEMP_SOURCE_SEL(x) (((x) == TEMP_SOURCE_LOSC) || \ - ((x) == TEMP_SOURCE_LRC) || \ - ((x) == TEMP_SOURCE_HRC_DIV_1M ) || \ - ((x) == TEMP_SOURCE_HOSC_DIV_1M)) -/** - * @} - */ - -/** @addtogroup TEMP_Public_Functions - * @{ - */ -/** @addtogroup TEMP_Public_Functions_Group1 - * @{ - */ -/* Initialization functions */ -extern void temp_init(temp_init_t *init); -extern void temp_source_selcet(temp_source_sel_t sel); -/** - * @} - */ -/** @addtogroup TEMP_Public_Functions_Group2 - * @{ - */ -/* Control functions */ -extern ald_status_t temp_get_value(uint16_t *temp); -extern void temp_get_value_by_it(temp_cbk cbk); -void temp_irq_handle(void); -/** - * @} - */ -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_TEMP_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_timer.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_timer.h deleted file mode 100644 index 6eaf44da44..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_timer.h +++ /dev/null @@ -1,1130 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_timer.h - * @brief TIMER module driver. - * This is the common part of the TIMER initialization - * - * @version V1.0 - * @date 06 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ********************************************************************************* - */ - -#ifndef __ALD_TIMER_H__ -#define __ALD_TIMER_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" -#include "ald_dma.h" - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup TIMER - * @{ - */ - -/** @defgroup TIMER_Public_Types TIMER Public Types - * @{ - */ - -/** - * @brief TIMER counter mode - */ -typedef enum -{ - TIMER_CNT_MODE_UP = 0, /**< Counter mode up */ - TIMER_CNT_MODE_DOWN = 1, /**< Counter mode down */ - TIMER_CNT_MODE_CENTER1 = 2, /**< Counter mode center1 */ - TIMER_CNT_MODE_CENTER2 = 3, /**< Counter mode center2 */ - TIMER_CNT_MODE_CENTER3 = 4, /**< Counter mode center3 */ -} timer_cnt_mode_t; - -/** - * @brief TIMER clock division - */ -typedef enum -{ - TIMER_CLOCK_DIV1 = 0, /**< No prescaler is used */ - TIMER_CLOCK_DIV2 = 1, /** Clock is divided by 2 */ - TIMER_CLOCK_DIV4 = 2, /** Clock is divided by 4 */ -} timer_clock_division_t; - -/** - * @brief TIMER output compare and PWM modes - */ -typedef enum -{ - TIMER_OC_MODE_TIMERING = 0, /**< Output compare mode is timering */ - TIMER_OC_MODE_ACTIVE = 1, /**< Output compare mode is active */ - TIMER_OC_MODE_INACTIVE = 2, /**< Output compare mode is inactive */ - TIMER_OC_MODE_TOGGLE = 3, /**< Output compare mode is toggle */ - TIMER_OC_MODE_FORCE_INACTIVE = 4, /**< Output compare mode is force inactive */ - TIMER_OC_MODE_FORCE_ACTIVE = 5, /**< Output compare mode is force active */ - TIMER_OC_MODE_PWM1 = 6, /**< Output compare mode is pwm1 */ - TIMER_OC_MODE_PWM2 = 7, /**< Output compare mode is pwm2 */ -} timer_oc_mode_t; - -/** - * @brief TIMER output compare polarity - */ -typedef enum -{ - TIMER_OC_POLARITY_HIGH = 0, /**< Output compare polarity is high */ - TIMER_OC_POLARITY_LOW = 1, /**< Output compare polarity is low */ -} timer_oc_polarity_t; - -/** - * @brief TIMER complementary output compare polarity - */ -typedef enum -{ - TIMER_OCN_POLARITY_HIGH = 0, /**< Complementary output compare polarity is high */ - TIMER_OCN_POLARITY_LOW = 1, /**< Complementary output compare polarity is low */ -} timer_ocn_polarity_t; - -/** - * @brief TIMER output compare idle state - */ -typedef enum -{ - TIMER_OC_IDLE_RESET = 0, /**< Output compare idle state is reset */ - TIMER_OC_IDLE_SET = 1, /**< Output compare idle state is set */ -} timer_oc_idle_t; - -/** - * @brief TIMER complementary output compare idle state - */ -typedef enum -{ - TIMER_OCN_IDLE_RESET = 0, /**< Complementary output compare idle state is reset */ - TIMER_OCN_IDLE_SET = 1, /**< Complementary output compare idle state is set */ -} timer_ocn_idle_t; - -/** - * @brief TIMER channel - */ -typedef enum -{ - TIMER_CHANNEL_1 = 0, /**< Channel 1 */ - TIMER_CHANNEL_2 = 1, /**< Channel 2 */ - TIMER_CHANNEL_3 = 2, /**< Channel 3 */ - TIMER_CHANNEL_4 = 4, /**< Channel 4 */ - TIMER_CHANNEL_ALL = 0xF, /**< All channel */ -} timer_channel_t; - -/** - * @brief TIMER one pulse mode - */ -typedef enum -{ - TIMER_OP_MODE_REPEAT = 0, /**< Repetitive */ - TIMER_OP_MODE_SINGLE = 1, /**< single */ -} timer_op_mode_t; - -/** - * @brief TIMER one pulse output channel - */ -typedef enum -{ - TIMER_OP_OUTPUT_CHANNEL_1 = 0, /**< One pulse output channal 1 */ - TIMER_OP_OUTPUT_CHANNEL_2 = 1, /**< One pulse output channal 2 */ -} timer_op_output_channel_t; - -/** - * @brief TIMER time base configuration structure definition - */ -typedef struct -{ - uint32_t prescaler; /**< Specifies the prescaler value used to divide the TIMER clock. */ - timer_cnt_mode_t mode; /**< Specifies the counter mode. */ - uint32_t period; /**< Specifies the period value to be loaded into ARR at the next update event. */ - timer_clock_division_t clk_div; /**< Specifies the clock division.*/ - uint32_t re_cnt; /**< Specifies the repetition counter value. */ -} timer_base_init_t; - -/** - * @brief TIMER output compare configuration structure definition - */ -typedef struct -{ - timer_oc_mode_t oc_mode; /**< Specifies the TIMER mode. */ - uint32_t pulse; /**< Specifies the pulse value to be loaded into the Capture Compare Register. */ - timer_oc_polarity_t oc_polarity; /**< Specifies the output polarity. */ - timer_ocn_polarity_t ocn_polarity; /**< Specifies the complementary output polarity. */ - type_func_t oc_fast_en; /**< Specifies the Fast mode state. */ - timer_oc_idle_t oc_idle; /**< Specifies the TIMER Output Compare pin state during Idle state. */ - timer_ocn_idle_t ocn_idle; /**< Specifies the TIMER Output Compare pin state during Idle state. */ -} timer_oc_init_t; - -/** - * @brief State structures definition - */ -typedef enum -{ - TIMER_STATE_RESET = 0x00, /**< Peripheral not yet initialized or disabled */ - TIMER_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ - TIMER_STATE_BUSY = 0x02, /**< An internal process is ongoing */ - TIMER_STATE_TIMEREOUT = 0x03, /**< Timeout state */ - TIMER_STATE_ERROR = 0x04, /**< Reception process is ongoing */ -} timer_state_t; - -/** - * @brief Active channel structures definition - */ -typedef enum -{ - TIMER_ACTIVE_CHANNEL_1 = 0x01, /**< The active channel is 1 */ - TIMER_ACTIVE_CHANNEL_2 = 0x02, /**< The active channel is 2 */ - TIMER_ACTIVE_CHANNEL_3 = 0x04, /**< The active channel is 3 */ - TIMER_ACTIVE_CHANNEL_4 = 0x08, /**< The active channel is 4 */ - TIMER_ACTIVE_CHANNEL_CLEARED = 0x00, /**< All active channels cleared */ -} timer_active_channel_t; - -/** - * @brief TIMER time base handle structure definition - */ -typedef struct timer_handle_s -{ - TIMER_TypeDef *perh; /**< Register base address */ - timer_base_init_t init; /**< TIMER Time Base required parameters */ - timer_active_channel_t ch; /**< Active channel */ - lock_state_t lock; /**< Locking object */ - timer_state_t state; /**< TIMER operation state */ - - void (*period_elapse_cbk)(struct timer_handle_s *arg); /**< Period elapse callback */ - void (*delay_elapse_cbk)(struct timer_handle_s *arg); /**< Delay_elapse callback */ - void (*capture_cbk)(struct timer_handle_s *arg); /**< Capture callback */ - void (*pwm_pulse_finish_cbk)(struct timer_handle_s *arg); /**< PWM_pulse_finish callback */ - void (*trigger_cbk)(struct timer_handle_s *arg); /**< Trigger callback */ - void (*break_cbk)(struct timer_handle_s *arg); /**< Break callback */ - void (*com_cbk)(struct timer_handle_s *arg); /**< commutation callback */ - void (*error_cbk)(struct timer_handle_s *arg); /**< Error callback */ -} timer_handle_t; - - -/** - * @brief TIMER encoder mode - */ -typedef enum -{ - TIMER_ENC_MODE_TI1 = 1, /**< encoder mode 1 */ - TIMER_ENC_MODE_TI2 = 2, /**< encoder mode 2 */ - TIMER_ENC_MODE_TI12 = 3, /**< encoder mode 3 */ -} timer_encoder_mode_t; - -/** - * @brief TIMER input capture polarity - */ -typedef enum -{ - TIMER_IC_POLARITY_RISE = 0, /**< Input capture polarity rising */ - TIMER_IC_POLARITY_FALL = 1, /**< Input capture polarity falling */ - TIMER_IC_POLARITY_BOTH = 3, /**< Input capture polarity rising and falling */ -} timer_ic_polarity_t; - -/** - *@brief TIMER input capture selection - */ -typedef enum -{ - TIMER_IC_SEL_DIRECT = 1, /**< IC1 -- TI1 */ - TIMER_IC_SEL_INDIRECT = 2, /**< IC1 -- TI2 */ - TIMER_IC_SEL_TRC = 3, /**< IC1 -- TRC */ -} timer_ic_select_t; - -/** - * @brief TIMER input capture prescaler - */ -typedef enum -{ - TIMER_IC_PSC_DIV1 = 0, /**< Capture performed once every 1 events */ - TIMER_IC_PSC_DIV2 = 1, /**< Capture performed once every 2 events */ - TIMER_IC_PSC_DIV4 = 2, /**< Capture performed once every 4 events */ - TIMER_IC_PSC_DIV8 = 3, /**< Capture performed once every 4 events */ -} timer_ic_prescaler_t; - -/** - * @brief TIMER encoder configuration structure definition - */ -typedef struct -{ - timer_encoder_mode_t mode; /**< Specifies the encoder mode */ - timer_ic_polarity_t ic1_polarity; /**< Specifies the active edge of the input signal */ - timer_ic_select_t ic1_sel; /**< Specifies the input */ - timer_ic_prescaler_t ic1_psc; /**< Specifies the Input Capture Prescaler */ - uint32_t ic1_filter; /**< Specifies the input capture filter */ - timer_ic_polarity_t ic2_polarity; /**< Specifies the active edge of the input signal */ - timer_ic_select_t ic2_sel; /**< Specifies the input */ - timer_ic_prescaler_t ic2_psc; /**< Specifies the Input Capture Prescaler */ - uint32_t ic2_filter; /**< Specifies the input capture filter */ -} timer_encoder_init_t; - -/** - * @brief TIMER input capture configuration structure definition - */ -typedef struct -{ - timer_ic_polarity_t polarity; /**< Specifies the active edge of the input signal */ - timer_ic_select_t sel; /**< Specifies the input */ - timer_ic_prescaler_t psc; /**< Specifies the Input Capture Prescaler */ - uint32_t filter; /**< Specifies the input capture filter */ -} timer_ic_init_t; - -/** - * @brief TIMER one pulse mode configuration structure definition - */ -typedef struct -{ - timer_oc_mode_t mode; /**< Specifies the TIMER mode */ - uint16_t pulse; /**< Specifies the pulse value */ - timer_oc_polarity_t oc_polarity; /**< Specifies the output polarity */ - timer_ocn_polarity_t ocn_polarity; /**< Specifies the complementary output polarity */ - timer_oc_idle_t oc_idle; /**< Specifies the TIMER Output Compare pin state during Idle state */ - timer_ocn_idle_t ocn_idle; /**< Specifies the TIMER Output Compare pin state during Idle state */ - timer_ic_polarity_t polarity; /**< Specifies the active edge of the input signal */ - timer_ic_select_t sel; /**< Specifies the input */ - uint32_t filter; /**< Specifies the input capture filter */ -} timer_one_pulse_init_t; - -/** @brief TIMER clear input source - */ -typedef enum -{ - TIMER_INPUT_NONE = 0, /**< Clear input none */ - TIMER_INPUT_ETR = 1, /**< Clear input etr */ -} timer_clear_input_source_t; - -/** @brief TIMER clear input polarity - */ -typedef enum -{ - TIMER_POLARITY_NO_INV = 0, /**< Polarity for ETRx pin */ - TIMER_POLARITY_INV = 1, /**< Polarity for ETRx pin */ -} timer_clear_input_polarity_t; - -/** @brief TIMER clear input polarity - */ -typedef enum -{ - TIMER_ETR_PSC_DIV1 = 0, /**< No prescaler is used */ - TIMER_ETR_PSC_DIV2 = 1, /**< ETR input source is divided by 2 */ - TIMER_ETR_PSC_DIV4 = 2, /**< ETR input source is divided by 4 */ - TIMER_ETR_PSC_DIV8 = 3, /**< ETR input source is divided by 8 */ -} timer_etr_psc_t; - -/** - * @brief TIMER clear input configuration handle structure definition - */ -typedef struct -{ - type_func_t state; /**< TIMER clear Input state */ - timer_clear_input_source_t source; /**< TIMER clear Input sources */ - timer_clear_input_polarity_t polarity; /**< TIMER Clear Input polarity */ - timer_etr_psc_t psc; /**< TIMER Clear Input prescaler */ - uint32_t filter; /**< TIMER Clear Input filter */ -} timer_clear_input_config_t; - -/** @brief TIMER clock source - */ -typedef enum -{ - TIMER_SRC_ETRMODE2 = 0, /**< Clock source is etr mode2 */ - TIMER_SRC_INTER = 1, /**< Clock source is etr internal */ - TIMER_SRC_ITR0 = 2, /**< Clock source is etr itr0 */ - TIMER_SRC_ITR1 = 3, /**< Clock source is etr itr1 */ - TIMER_SRC_ITR2 = 4, /**< Clock source is etr itr2 */ - TIMER_SRC_ITR3 = 5, /**< Clock source is etr itr3 */ - TIMER_SRC_TI1ED = 6, /**< Clock source is etr ti1ed */ - TIMER_SRC_TI1 = 7, /**< Clock source is etr ti1 */ - TIMER_SRC_TI2 = 8, /**< Clock source is etr ti2 */ - TIMER_SRC_ETRMODE1 = 9, /**< Clock source is etr mode1 */ -} timer_clock_source_t; - -/** @brief TIMER clock polarity - */ -typedef enum -{ - TIMER_CLK_POLARITY_INV = 1, /**< Polarity for ETRx clock sources */ - TIMER_CLK_POLARITY_NO_INV = 0, /**< Polarity for ETRx clock sources */ - TIMER_CLK_POLARITY_RISE = 0, /**< Polarity for TIx clock sources */ - TIMER_CLK_POLARITY_FALL = 1, /**< Polarity for TIx clock sources */ - TIMER_CLK_POLARITY_BOTH = 3, /**< Polarity for TIx clock sources */ -} timer_clock_polarity_t; - -/** - * @brief TIMER clock config structure definition - */ -typedef struct -{ - timer_clock_source_t source; /**< TIMER clock sources */ - timer_clock_polarity_t polarity; /**< TIMER clock polarity */ - timer_etr_psc_t psc; /**< TIMER clock prescaler */ - uint32_t filter; /**< TIMER clock filter */ -} timer_clock_config_t; - -/** - * @brief TIMER slave mode - */ -typedef enum -{ - TIMER_MODE_DISABLE = 0, /**< Slave mode is disable */ - TIMER_MODE_ENC1 = 1, /**< Slave mode is encoder1 */ - TIMER_MODE_ENC2 = 2, /**< Slave mode is encoder2 */ - TIMER_MODE_ENC3 = 3, /**< Slave mode is encoder3 */ - TIMER_MODE_RESET = 4, /**< Slave mode is reset */ - TIMER_MODE_GATED = 5, /**< Slave mode is gated */ - TIMER_MODE_TRIG = 6, /**< Slave mode is trigger */ - TIMER_MODE_EXTERNAL1 = 7, /**< Slave mode is external1 */ -} timer_slave_mode_t; - -/** - * @brief TIMER ts definition - */ -typedef enum -{ - TIMER_TS_ITR0 = 0, /**< ITR0 */ - TIMER_TS_ITR1 = 1, /**< ITR1 */ - TIMER_TS_ITR2 = 2, /**< ITR2 */ - TIMER_TS_ITR3 = 3, /**< ITR3 */ - TIMER_TS_TI1F_ED = 4, /**< TI1F_ED */ - TIMER_TS_TI1FP1 = 5, /**< TI1FP1 */ - TIMER_TS_TI2FP2 = 6, /**< TI2FP2 */ - TIMER_TS_ETRF = 7, /**< ETRF */ -} timer_ts_t; - -/** - * @brief TIMER slave configuration structure definition - */ -typedef struct -{ - timer_slave_mode_t mode; /**< Slave mode selection */ - timer_ts_t input; /**< Input Trigger source */ - timer_clock_polarity_t polarity; /**< Input Trigger polarity */ - timer_etr_psc_t psc; /**< Input trigger prescaler */ - uint32_t filter; /**< Input trigger filter */ -} timer_slave_config_t; - -/** - * @brief TIMER hall sensor configuretion structure definition - */ -typedef struct -{ - timer_ic_polarity_t polarity; /**< Specifies the active edge of the input signal */ - timer_ic_prescaler_t psc; /**< Specifies the Input Capture Prescaler */ - uint32_t filter; /**< Specifies the input capture filter [0x0, 0xF] */ - uint32_t delay; /**< Specifies the pulse value to be loaded into the register [0x0, 0xFFFF] */ -} timer_hall_sensor_init_t; - -/** - * @brief TIMER lock level - */ -typedef enum -{ - TIMER_LOCK_LEVEL_OFF = 0, /**< Lock off */ - TIMER_LOCK_LEVEL_1 = 1, /**< Lock level 1 */ - TIMER_LOCK_LEVEL_2 = 2, /**< Lock level 2 */ - TIMER_LOCK_LEVEL_3 = 3, /**< Lock level 3 */ -} timer_lock_level_t; - -/** - * @brief TIMER break polarity - */ -typedef enum -{ - TIMER_BREAK_POLARITY_LOW = 0, /**< LOW */ - TIMER_BREAK_POLARITY_HIGH = 1, /**< HIGH */ -} timer_break_polarity_t; - -/** - * @brief TIMER break and dead time configuretion structure definition - */ -typedef struct -{ - type_func_t off_run; /**< Enalbe/Disable off state in run mode */ - type_func_t off_idle; /**< Enalbe/Disable off state in idle mode */ - timer_lock_level_t lock_level; /**< Lock level */ - uint32_t dead_time; /**< Dead time, [0x0, 0xFF] */ - type_func_t break_state; /**< Break state */ - timer_break_polarity_t polarity; /**< Break input polarity */ - type_func_t auto_out; /**< Enalbe/Disable automatic output */ -} timer_break_dead_time_t; - -/** - * @brief TIMER commutation event channel configuretion structure definition - */ -typedef struct -{ - type_func_t en; /**< Enalbe/Disable the channel */ - type_func_t n_en; /**< Enalbe/Disable the complementary channel */ - timer_oc_mode_t mode; /**< Mode of the channel */ -} timer_channel_config_t; - -/** - * @brief TIMER commutation event configuretion structure definition - */ -typedef struct -{ - timer_channel_config_t ch[3]; /**< Configure of channel */ -} timer_com_channel_config_t; - -/** - * @brief TIMER master mode selection - */ -typedef enum -{ - TIMER_TRGO_RESET = 0, /**< RESET */ - TIMER_TRGO_ENABLE = 1, /**< ENABLE */ - TIMER_TRGO_UPDATE = 2, /**< UPDATE */ - TIMER_TRGO_OC1 = 3, /**< OC1 */ - TIMER_TRGO_OC1REF = 4, /**< OC1REF */ - TIMER_TRGO_OC2REF = 5, /**< OC2REF */ - TIMER_TRGO_OC3REF = 6, /**< OC3REF */ - TIMER_TRGO_OC4REF = 7, /**< OC4REF */ -} timer_master_mode_sel_t; - -/** - * @brief TIMER master configuretion structure definition - */ -typedef struct -{ - timer_master_mode_sel_t sel; /**< Specifies the active edge of the input signal */ - type_func_t master_en; /**< Master/Slave mode selection */ -} timer_master_config_t; - -/** - * @brief Specifies the event source - */ -typedef enum -{ - TIMER_SRC_UPDATE = (1U << 0), /**< Event source is update */ - TIMER_SRC_CC1 = (1U << 1), /**< Event source is channel1 */ - TIMER_SRC_CC2 = (1U << 2), /**< Event source is channel2 */ - TIMER_SRC_CC3 = (1U << 3), /**< Event source is channel3 */ - TIMER_SRC_CC4 = (1U << 4), /**< Event source is channel4 */ - TIMER_SRC_COM = (1U << 5), /**< Event source is compare */ - TIMER_SRC_TRIG = (1U << 6), /**< Event source is trigger */ - TIMER_SRC_BREAK = (1U << 7), /**< Event source is break */ -} timer_event_source_t; - -/** - * @brief TIMER interrupt definition - */ -typedef enum -{ - TIMER_IT_UPDATE = (1U << 0), /**< Update interrupt bit */ - TIMER_IT_CC1 = (1U << 1), /**< Channel1 interrupt bit */ - TIMER_IT_CC2 = (1U << 2), /**< Channel2 interrupt bit */ - TIMER_IT_CC3 = (1U << 3), /**< Channel3 interrupt bit */ - TIMER_IT_CC4 = (1U << 4), /**< Channel4 interrupt bit */ - TIMER_IT_COM = (1U << 5), /**< compare interrupt bit */ - TIMER_IT_TRIGGER = (1U << 6), /**< Trigger interrupt bit */ - TIMER_IT_BREAK = (1U << 7), /**< Break interrupt bit */ -} timer_it_t; - -/** - * @brief TIMER DMA request - */ -typedef enum -{ - TIMER_DMA_UPDATE = (1U << 8), /**< DMA request from update */ - TIMER_DMA_CC1 = (1U << 9), /**< DMA request from channel1 */ - TIMER_DMA_CC2 = (1U << 10), /**< DMA request from channel2 */ - TIMER_DMA_CC3 = (1U << 11), /**< DMA request from channel3 */ - TIMER_DMA_CC4 = (1U << 12), /**< DMA request from channel4 */ - TIMER_DMA_COM = (1U << 13), /**< DMA request from compare */ - TIMER_DMA_TRIGGER = (1U << 14), /**< DMA request from trigger */ -} timer_dma_req_t; - -/** - * @brief TIMER flag definition - */ -typedef enum -{ - TIMER_FLAG_UPDATE = (1U << 0), /**< Update interrupt flag */ - TIMER_FLAG_CC1 = (1U << 1), /**< Channel1 interrupt flag */ - TIMER_FLAG_CC2 = (1U << 2), /**< Channel2 interrupt flag */ - TIMER_FLAG_CC3 = (1U << 3), /**< Channel3 interrupt flag */ - TIMER_FLAG_CC4 = (1U << 4), /**< Channel4 interrupt flag */ - TIMER_FLAG_COM = (1U << 5), /**< Compare interrupt flag */ - TIMER_FLAG_TRIGGER = (1U << 6), /**< Trigger interrupt flag */ - TIMER_FLAG_BREAK = (1U << 7), /**< Break interrupt flag */ - TIMER_FLAG_CC1OF = (1U << 9), /**< Channel1 override state flag */ - TIMER_FLAG_CC2OF = (1U << 10), /**< Channel2 override state flag */ - TIMER_FLAG_CC3OF = (1U << 11), /**< Channel3 override state flag */ - TIMER_FLAG_CC4OF = (1U << 12), /**< Channel4 override state flag */ -} timer_flag_t; -/** - * @} - */ - -/** @defgroup TIMER_Public_Macros TIMER Public Macros - * @{ - */ -#define CCER_CCxE_MASK ((1U << 0) | (1U << 4) | (1U << 8) | (1U << 12)) -#define CCER_CCxNE_MASK ((1U << 2) | (1U << 6) | (1U << 10)) - -/** - * @brief Reset TIMER handle state - */ -#define TIMER_RESET_HANDLE_STATE(hperh) ((hperh)->state = TIMER_STATE_RESET) - -/** - * @brief Enable the TIMER peripheral. - */ -#define TIMER_ENABLE(hperh) (SET_BIT((hperh)->perh->CON1, TIMER_CON1_CNTEN_MSK)) - -/** - * @brief Enable the TIMER main output. - */ -#define TIMER_MOE_ENABLE(hperh) (SET_BIT((hperh)->perh->BDCFG, TIMER_BDCFG_GOEN_MSK)) - -/** - * @brief Disable the TIMER peripheral. - */ -#define TIMER_DISABLE(hperh) \ -do { \ - if ((((hperh)->perh->CCEP & CCER_CCxE_MASK) == 0) \ - && (((hperh)->perh->CCEP & CCER_CCxNE_MASK) == 0)) \ - CLEAR_BIT((hperh)->perh->CON1, TIMER_CON1_CNTEN_MSK); \ -} while (0) - -/** - * @brief Disable the TIMER main output. - * @note The Main Output Enable of a timer instance is disabled only if - * all the CCx and CCxN channels have been disabled - */ -#define TIMER_MOE_DISABLE(hperh) \ -do { \ - if ((((hperh)->perh->CCEP & CCER_CCxE_MASK) == 0) \ - && (((hperh)->perh->CCEP & CCER_CCxNE_MASK) == 0)) \ - CLEAR_BIT((hperh)->perh->BDCFG, TIMER_BDCFG_GOEN_MSK); \ -} while (0) - -/** - * @brief Sets the TIMER autoreload register value on runtime without calling - * another time any Init function. - */ -#define TIMER_SET_AUTORELOAD(handle, AUTORELOAD) \ -do { \ - (handle)->perh->AR = (AUTORELOAD); \ - (handle)->init.period = (AUTORELOAD); \ -} while (0) - -/** - * @brief Gets the TIMER autoreload register value on runtime - */ -#define TIMER_GET_AUTORELOAD(handle) ((handle)->perh->AR) - -/** - * @brief Gets the TIMER count register value on runtime - */ -#define TIMER_GET_CNT(handle) ((handle)->perh->COUNT) - -/** - * @brief Gets the TIMER count direction value on runtime - */ -#define TIMER_GET_DIR(handle) (READ_BITS((handle)->perh->CON1, TIMER_CON1_DIRSEL_MSK, TIMER_CON1_DIRSEL_POS)) - -/** - * @brief CCx DMA request sent when CCx event occurs - */ -#define TIMER_CCx_DMA_REQ_CCx(handle) (CLEAR_BIT((handle)->perh->CON2, TIMER_CON2_CCDMASEL_MSK)) - -/** - * @brief CCx DMA request sent when update event occurs - */ -#define TIMER_CCx_DMA_REQ_UPDATE(handle) (SET_BIT((handle)->perh->CON2, TIMER_CON2_CCDMASEL_MSK)) - -/** - * @brief Enable channel - * @param handle: TIMER handle - * @param ch: Must be one of this: - * TIMER_CHANNEL_1 - * TIMER_CHANNEL_2 - * TIMER_CHANNEL_3 - * TIMER_CHANNEL_4 - */ -#define TIMER_CCx_ENABLE(handle, ch) (((ch) == TIMER_CHANNEL_4) ? \ -(SET_BIT((handle)->perh->CCEP, TIMER_CCEP_CC4POL_MSK)) : (WRITE_REG(((handle)->perh->CCEP), (((handle)->perh->CCEP) | (1 << ((ch) << 2)))))) - -/** - * @brief Disable channel - * @param handle: TIMER handle - * @param ch: Must be one of this: - * TIMER_CHANNEL_1 - * TIMER_CHANNEL_2 - * TIMER_CHANNEL_3 - * TIMER_CHANNEL_4 - */ -#define TIMER_CCx_DISABLE(handle, ch) (((ch) == TIMER_CHANNEL_4) ? \ -(CLEAR_BIT((handle)->perh->CCEP, TIMER_CCEP_CC4EN_MSK)) : ((handle)->perh->CCEP &= ~(1 << ((ch) << 2)))) - -/** - * @brief Enable complementary channel - * @param handle: TIMER handle - * @param ch: Must be one of this: - * TIMER_CHANNEL_1 - * TIMER_CHANNEL_2 - * TIMER_CHANNEL_3 - */ -#define TIMER_CCxN_ENABLE(handle, ch) ((handle)->perh->CCEP |= (1 << (((ch) << 2) + 2))) - -/** - * @brief Disable complementary channel - * @param handle: TIMER handle - * @param ch: Must be one of this: - * TIMER_CHANNEL_1 - * TIMER_CHANNEL_2 - * TIMER_CHANNEL_3 - */ -#define TIMER_CCxN_DISABLE(handle, ch) ((handle)->perh->CCEP &= ~(1 << (((ch) << 2) + 2))) -/** - * @} - */ - -/** @defgroup TIMER_Private_Macros TIMER Private Macros - * @{ - */ -#define IS_TIMER_INSTANCE(x) (((x) == TIMER0) || \ - ((x) == TIMER1) || \ - ((x) == TIMER2) || \ - ((x) == TIMER3) || \ - ((x) == TIMER4) || \ - ((x) == TIMER5) || \ - ((x) == TIMER6) || \ - ((x) == TIMER7)) -#define IS_ADTIMER_INSTANCE(x) ((x) == TIMER0) -#define IS_TIMER_XOR_INSTANCE(x) (((x) == TIMER0) || ((x) == TIMER6)) -#define IS_TIMER_COM_EVENT_INSTANCE(x) (((x) == TIMER0) || \ - ((x) == TIMER2) || \ - ((x) == TIMER3)) -#define IS_TIMER_CC2_INSTANCE(x) (((x) == TIMER0) || \ - ((x) == TIMER2) || \ - ((x) == TIMER3) || \ - ((x) == TIMER6)) -#define IS_TIMER_CC4_INSTANCE(x) (((x) == TIMER0) || \ - ((x) == TIMER6)) -#define IS_TIMER_BREAK_INSTANCE(x) (((x) == TIMER0) || \ - ((x) == TIMER2) || \ - ((x) == TIMER3)) -#define IS_TIMER_PWM_INPUT_INSTANCE(x, y) ((((x) == TIMER0) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2))) || \ - (((x) == TIMER2) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2))) || \ - (((x) == TIMER3) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2))) || \ - (((x) == TIMER6) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2)))) -#define IS_TIMER_CCX_INSTANCE(x, y) ((((x) == TIMER0) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2) || \ - ((y) == TIMER_CHANNEL_3) || \ - ((y) == TIMER_CHANNEL_4))) || \ - (((x) == TIMER2) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2))) || \ - (((x) == TIMER3) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2))) || \ - (((x) == TIMER6) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2) || \ - ((y) == TIMER_CHANNEL_3) || \ - ((y) == TIMER_CHANNEL_4)))) -#define IS_TIMER_CCXN_INSTANCE(x, y) ((((x) == TIMER0) || \ - ((x) == TIMER2) || \ - ((x) == TIMER3)) && \ - (((y) == TIMER_CHANNEL_1) || \ - ((y) == TIMER_CHANNEL_2) || \ - ((y) == TIMER_CHANNEL_3) || \ - ((y) == TIMER_CHANNEL_4))) -#define IS_TIMER_REPETITION_COUNTER_INSTANCE(x) (((x) == TIMER0) || \ - ((x) == TIMER2) || \ - ((x) == TIMER3)) -#define IS_TIMER_CLOCK_DIVISION_INSTANCE(x) IS_TIMER_CC2_INSTANCE(x) -#define IS_TIMER_COUNTER_MODE(x) (((x) == TIMER_CNT_MODE_UP) || \ - ((x) == TIMER_CNT_MODE_DOWN) || \ - ((x) == TIMER_CNT_MODE_CENTER1) || \ - ((x) == TIMER_CNT_MODE_CENTER2) || \ - ((x) == TIMER_CNT_MODE_CENTER3)) -#define IS_TIMER_CLOCK_DIVISION(x) (((x) == TIMER_CLOCK_DIV1) || \ - ((x) == TIMER_CLOCK_DIV2) || \ - ((x) == TIMER_CLOCK_DIV4)) -#define IS_TIMER_PWM_MODE(x) (((x) == TIMER_OC_MODE_PWM1) || \ - ((x) == TIMER_OC_MODE_PWM2)) -#define IS_TIMER_OC_MODE(x) (((x) == TIMER_OC_MODE_TIMERING) || \ - ((x) == TIMER_OC_MODE_ACTIVE) || \ - ((x) == TIMER_OC_MODE_INACTIVE) || \ - ((x) == TIMER_OC_MODE_TOGGLE) || \ - ((x) == TIMER_OC_MODE_FORCE_ACTIVE) || \ - ((x) == TIMER_OC_MODE_FORCE_INACTIVE) || \ - ((x) == TIMER_OC_MODE_PWM1) || \ - ((x) == TIMER_OC_MODE_PWM2)) -#define IS_TIMER_OC_POLARITY(x) (((x) == TIMER_OC_POLARITY_HIGH) || \ - ((x) == TIMER_OC_POLARITY_LOW)) -#define IS_TIMER_OCN_POLARITY(x) (((x) == TIMER_OCN_POLARITY_HIGH) || \ - ((x) == TIMER_OCN_POLARITY_LOW)) -#define IS_TIMER_OCIDLE_STATE(x) (((x) == TIMER_OC_IDLE_RESET) || \ - ((x) == TIMER_OC_IDLE_SET)) -#define IS_TIMER_OCNIDLE_STATE(x) (((x) == TIMER_OCN_IDLE_RESET) || \ - ((x) == TIMER_OCN_IDLE_SET)) -#define IS_TIMER_CHANNELS(x) (((x) == TIMER_CHANNEL_1) || \ - ((x) == TIMER_CHANNEL_2) || \ - ((x) == TIMER_CHANNEL_3) || \ - ((x) == TIMER_CHANNEL_4) || \ - ((x) == TIMER_CHANNEL_ALL)) -#define IS_TIMER_OP_MODE(x) (((x) == TIMER_OP_MODE_REPEAT) || \ - ((x) == TIMER_OP_MODE_SINGLE)) -#define IS_TIMER_OP_OUTPUT_CH(x) (((x) == TIMER_OP_OUTPUT_CHANNEL_1) || \ - ((x) == TIMER_OP_OUTPUT_CHANNEL_2)) -#define IS_TIMER_ENCODER_MODE(x) (((x) == TIMER_ENC_MODE_TI1) || \ - ((x) == TIMER_ENC_MODE_TI2) || \ - ((x) == TIMER_ENC_MODE_TI12)) -#define IS_TIMER_IC_POLARITY(x) (((x) == TIMER_IC_POLARITY_RISE) || \ - ((x) == TIMER_IC_POLARITY_FALL) || \ - ((x) == TIMER_IC_POLARITY_BOTH)) -#define IS_TIMER_IC_SELECT(x) (((x) == TIMER_IC_SEL_DIRECT) || \ - ((x) == TIMER_IC_SEL_INDIRECT) || \ - ((x) == TIMER_IC_SEL_TRC)) -#define IS_TIMER_IC_PSC(x) (((x) == TIMER_IC_PSC_DIV1) || \ - ((x) == TIMER_IC_PSC_DIV2) || \ - ((x) == TIMER_IC_PSC_DIV4) || \ - ((x) == TIMER_IC_PSC_DIV8)) -#define IS_TIMER_IC_FILTER(x) ((x) <= 0xF) -#define IS_TIMER_DEAD_TIMERE(x) ((x) <= 0xFF) -#define IS_TIMER_CLEAR_INPUT_SOURCE(x) (((x) == TIMER_INPUT_NONE) || \ - ((x) == TIMER_INPUT_ETR)) -#define IS_TIMER_CLEAR_INPUT_POLARITY(x) (((x) == TIMER_POLARITY_NO_INV) || \ - ((x) == TIMER_POLARITY_INV)) -#define IS_TIMER_ETR_PSC(x) (((x) == TIMER_ETR_PSC_DIV1) || \ - ((x) == TIMER_ETR_PSC_DIV2) || \ - ((x) == TIMER_ETR_PSC_DIV4) || \ - ((x) == TIMER_ETR_PSC_DIV8)) -#define IS_TIMER_CLOCK_SOURCE(x) (((x) == TIMER_SRC_ETRMODE2) || \ - ((x) == TIMER_SRC_INTER) || \ - ((x) == TIMER_SRC_ITR0) || \ - ((x) == TIMER_SRC_ITR1) || \ - ((x) == TIMER_SRC_ITR2) || \ - ((x) == TIMER_SRC_ITR3) || \ - ((x) == TIMER_SRC_TI1ED) || \ - ((x) == TIMER_SRC_TI1) || \ - ((x) == TIMER_SRC_TI2) || \ - ((x) == TIMER_SRC_ETRMODE1)) -#define IS_TIMER_CLOCK_POLARITY(x) (((x) == TIMER_CLK_POLARITY_INV) || \ - ((x) == TIMER_CLK_POLARITY_NO_INV) || \ - ((x) == TIMER_CLK_POLARITY_RISE) || \ - ((x) == TIMER_CLK_POLARITY_FALL) || \ - ((x) == TIMER_CLK_POLARITY_BOTH)) -#define IS_TIMER_SLAVE_MODE(x) (((x) == TIMER_MODE_DISABLE) || \ - ((x) == TIMER_MODE_ENC1) || \ - ((x) == TIMER_MODE_ENC2) || \ - ((x) == TIMER_MODE_ENC3) || \ - ((x) == TIMER_MODE_RESET) || \ - ((x) == TIMER_MODE_GATED) || \ - ((x) == TIMER_MODE_TRIG) || \ - ((x) == TIMER_MODE_EXTERNAL1)) -#define IS_TIMER_EVENT_SOURCE(x) (((x) == TIMER_SRC_UPDATE) || \ - ((x) == TIMER_SRC_CC1) || \ - ((x) == TIMER_SRC_CC2) || \ - ((x) == TIMER_SRC_CC3) || \ - ((x) == TIMER_SRC_CC4) || \ - ((x) == TIMER_SRC_COM) || \ - ((x) == TIMER_SRC_TRIG) || \ - ((x) == TIMER_SRC_BREAK)) -#define IS_TIMER_TS(x) (((x) == TIMER_TS_ITR0) || \ - ((x) == TIMER_TS_ITR1) || \ - ((x) == TIMER_TS_ITR2) || \ - ((x) == TIMER_TS_ITR3) || \ - ((x) == TIMER_TS_TI1F_ED) || \ - ((x) == TIMER_TS_TI1FP1) || \ - ((x) == TIMER_TS_TI2FP2) || \ - ((x) == TIMER_TS_ETRF)) -#define IS_TIMER_CLOCK_LEVEL(x) (((x) == TIMER_LOCK_LEVEL_OFF) || \ - ((x) == TIMER_LOCK_LEVEL_1) || \ - ((x) == TIMER_LOCK_LEVEL_2) || \ - ((x) == TIMER_LOCK_LEVEL_3)) -#define IS_TIMER_BREAK_POLARITY(x) (((x) == TIMER_BREAK_POLARITY_LOW) || \ - ((x) == TIMER_BREAK_POLARITY_HIGH)) -#define IS_TIMER_MASTER_MODE_SEL(x) (((x) == TIMER_TRGO_RESET) || \ - ((x) == TIMER_TRGO_ENABLE) || \ - ((x) == TIMER_TRGO_UPDATE) || \ - ((x) == TIMER_TRGO_OC1) || \ - ((x) == TIMER_TRGO_OC1REF) || \ - ((x) == TIMER_TRGO_OC2REF) || \ - ((x) == TIMER_TRGO_OC3REF) || \ - ((x) == TIMER_TRGO_OC4REF)) -#define IS_TIMER_IT(x) (((x) == TIMER_IT_UPDATE) || \ - ((x) == TIMER_IT_CC1) || \ - ((x) == TIMER_IT_CC2) || \ - ((x) == TIMER_IT_CC3) || \ - ((x) == TIMER_IT_CC4) || \ - ((x) == TIMER_IT_COM) || \ - ((x) == TIMER_IT_TRIGGER) || \ - ((x) == TIMER_IT_BREAK)) -#define IS_TIMER_DMA_REQ(x) (((x) == TIMER_DMA_UPDATE) || \ - ((x) == TIMER_DMA_CC1) || \ - ((x) == TIMER_DMA_CC2) || \ - ((x) == TIMER_DMA_CC3) || \ - ((x) == TIMER_DMA_CC4) || \ - ((x) == TIMER_DMA_COM) || \ - ((x) == TIMER_DMA_TRIGGER)) -#define IS_TIMER_FLAG(x) (((x) == TIMER_FLAG_UPDATE) || \ - ((x) == TIMER_FLAG_CC1) || \ - ((x) == TIMER_FLAG_CC2) || \ - ((x) == TIMER_FLAG_CC3) || \ - ((x) == TIMER_FLAG_CC4) || \ - ((x) == TIMER_FLAG_COM) || \ - ((x) == TIMER_FLAG_TRIGGER) || \ - ((x) == TIMER_FLAG_BREAK) || \ - ((x) == TIMER_FLAG_CC1OF) || \ - ((x) == TIMER_FLAG_CC2OF) || \ - ((x) == TIMER_FLAG_CC3OF) || \ - ((x) == TIMER_FLAG_CC4OF)) -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions - * @{ - */ -/** @addtogroup TIMER_Public_Functions_Group1 - * @{ - */ -/* Time Base functions */ -ald_status_t timer_base_init(timer_handle_t *hperh); -void timer_base_reset(timer_handle_t *hperh); -void timer_base_start(timer_handle_t *hperh); -void timer_base_stop(timer_handle_t *hperh); -void timer_base_start_by_it(timer_handle_t *hperh); -void timer_base_stop_by_it(timer_handle_t *hperh); -#ifdef ALD_DMA -ald_status_t timer_base_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, - uint16_t *buf, uint32_t len, uint8_t dma_ch); -void timer_base_stop_by_dma(timer_handle_t *hperh); -#endif -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group2 - * @{ - */ -/* Timer Output Compare functions */ -ald_status_t timer_oc_init(timer_handle_t *hperh); -void timer_oc_start(timer_handle_t *hperh, timer_channel_t ch); -void timer_oc_stop(timer_handle_t *hperh, timer_channel_t ch); -void timer_oc_start_by_it(timer_handle_t *hperh, timer_channel_t ch); -void timer_oc_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); -#ifdef ALD_DMA -ald_status_t timer_oc_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, - dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch); -void timer_oc_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); -#endif -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group3 - * @{ - */ -/* Timer PWM functions */ -ald_status_t timer_pwm_init(timer_handle_t *hperh); -void timer_pwm_start(timer_handle_t *hperh, timer_channel_t ch); -void timer_pwm_stop(timer_handle_t *hperh, timer_channel_t ch); -void timer_pwm_start_by_it(timer_handle_t *hperh, timer_channel_t ch); -void timer_pwm_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); -void timer_pwm_set_freq(timer_handle_t *hperh, uint16_t freq); -void timer_pwm_set_duty(timer_handle_t *hperh, timer_channel_t ch, uint16_t duty); -void timer_pwm_set_input(timer_handle_t *hperh, timer_channel_t ch); -#ifdef ALD_DMA -ald_status_t timer_pwm_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, - dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch); -void timer_pwm_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); -#endif -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group4 - * @{ - */ -/* Timer Input Capture functions */ -ald_status_t timer_ic_init(timer_handle_t *hperh); -void timer_ic_start(timer_handle_t *hperh, timer_channel_t ch); -void timer_ic_stop(timer_handle_t *hperh, timer_channel_t ch); -void timer_ic_start_by_it(timer_handle_t *hperh, timer_channel_t ch); -void timer_ic_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); -#ifdef ALD_DMA -ald_status_t timer_ic_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, - dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch); -void timer_ic_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); -#endif -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group5 - * @{ - */ -/* Timer One Pulse functions */ -ald_status_t timer_one_pulse_init(timer_handle_t *hperh, timer_op_mode_t mode); -void timer_one_pulse_start(timer_handle_t *hperh, timer_op_output_channel_t ch); -void timer_one_pulse_stop(timer_handle_t *hperh, timer_op_output_channel_t ch); -void timer_one_pulse_start_by_it(timer_handle_t *hperh, timer_op_output_channel_t ch); -void timer_one_pulse_stop_by_it(timer_handle_t *hperh, timer_op_output_channel_t ch); -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group6 - * @{ - */ -/* Timer encoder functions */ -ald_status_t timer_encoder_init(timer_handle_t *hperh, timer_encoder_init_t *config); -void timer_encoder_start(timer_handle_t *hperh, timer_channel_t ch); -void timer_encoder_stop(timer_handle_t *hperh, timer_channel_t ch); -void timer_encoder_start_by_it(timer_handle_t *hperh, timer_channel_t ch); -void timer_encoder_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); -#ifdef ALD_DMA -ald_status_t timer_encoder_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, - dma_handle_t *hdma1, dma_handle_t *hdma2, uint16_t *buf1, - uint16_t *buf2, uint32_t len, uint8_t dma_ch1, uint8_t dma_ch2); -void timer_encoder_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); -#endif -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group7 - * @{ - */ -/* Timer hall sensor functions */ -ald_status_t timer_hall_sensor_init(timer_handle_t *hperh, timer_hall_sensor_init_t *config); -void timer_hall_sensor_start(timer_handle_t *hperh); -void timer_hall_sensor_stop(timer_handle_t *hperh); -void timer_hall_sensor_start_by_it(timer_handle_t *hperh); -void timer_hall_sensor_stop_by_it(timer_handle_t *hperh); -#ifdef ALD_DMA -ald_status_t timer_hall_sensor_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, - uint16_t *buf, uint32_t len, uint8_t dma_ch); -void timer_hall_sensor_stop_by_dma(timer_handle_t *hperh); -#endif -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group8 - * @{ - */ -/* Timer complementary output compare functions */ -void timer_ocn_start(timer_handle_t *hperh, timer_channel_t ch); -void timer_ocn_stop(timer_handle_t *hperh, timer_channel_t ch); -void timer_ocn_start_by_it(timer_handle_t *hperh, timer_channel_t ch); -void timer_ocn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); -#ifdef ALD_DMA -ald_status_t timer_ocn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, - timer_channel_t ch, uint16_t *buf, uint32_t len, uint8_t dma_ch); -void timer_ocn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); -#endif -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group9 - * @{ - */ -/* Timer complementary PWM functions */ -void timer_pwmn_start(timer_handle_t *hperh, timer_channel_t ch); -void timer_pwmn_stop(timer_handle_t *hperh, timer_channel_t ch); -void timer_pwmn_start_by_it(timer_handle_t *hperh, timer_channel_t ch); -void timer_pwmn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); -#ifdef ALD_DMA -ald_status_t timer_pwmn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, - timer_channel_t ch, uint16_t *buf, uint32_t len, uint8_t dma_ch); -void timer_pwmn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); -#endif -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group10 - * @{ - */ -/* Timer complementary one pulse functions */ -void timer_one_pulse_n_start(timer_handle_t *hperh, timer_channel_t ch); -void timer_one_pulse_n_stop(timer_handle_t *hperh, timer_channel_t ch); -void timer_one_pulse_n_start_by_it(timer_handle_t *hperh, timer_channel_t ch); -void timer_one_pulse_n_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group11 - * @{ - */ -/* Control functions */ -ald_status_t timer_oc_config_channel(timer_handle_t *hperh, timer_oc_init_t *config, timer_channel_t ch); -ald_status_t timer_ic_config_channel(timer_handle_t *hperh, timer_ic_init_t *config, timer_channel_t ch); -ald_status_t timer_one_pulse_config_channel(timer_handle_t *hperh, timer_one_pulse_init_t *config, - timer_channel_t ch_out, timer_channel_t ch_in); -ald_status_t timer_config_oc_ref_clear(timer_handle_t *hperh, timer_clear_input_config_t *config, timer_channel_t ch); -ald_status_t timer_config_clock_source(timer_handle_t *hperh, timer_clock_config_t *config); -ald_status_t timer_config_ti1_input(timer_handle_t *hperh, uint32_t ti1_select); -ald_status_t timer_slave_config_sync(timer_handle_t *hperh, timer_slave_config_t *config); -ald_status_t timer_slave_config_sync_by_it(timer_handle_t *hperh, timer_slave_config_t *config); -ald_status_t timer_generate_event(timer_handle_t *hperh, timer_event_source_t event); -uint32_t timer_read_capture_value(timer_handle_t *hperh, timer_channel_t ch); -void timer_set_output_mode(timer_handle_t *hperh, timer_oc_mode_t mode, timer_channel_t ch); -void timer_com_change_config(timer_handle_t *hperh, timer_com_channel_config_t *config); -void timer_com_event_config(timer_handle_t *hperh, timer_ts_t ts, type_func_t trgi); -void timer_com_event_config_it(timer_handle_t *hperh, timer_ts_t ts, type_func_t trgi); -void timer_break_dead_time_config(timer_handle_t *hperh, timer_break_dead_time_t *config); -void timer_master_sync_config(timer_handle_t *hperh, timer_master_config_t *config); -void timer_irq_handle(timer_handle_t *hperh); -void timer_dma_req_config(timer_handle_t *hperh, timer_dma_req_t req, type_func_t state); -void timer_interrupt_config(timer_handle_t *hperh, timer_it_t it, type_func_t state); -it_status_t timer_get_it_status(timer_handle_t *hperh, timer_it_t it); -flag_status_t timer_get_flag_status(timer_handle_t *hperh, timer_flag_t flag); -void timer_clear_flag_status(timer_handle_t *hperh, timer_flag_t flag); -/** - * @} - */ - -/** @addtogroup TIMER_Public_Functions_Group12 - * @{ - */ -/* State functions */ -timer_state_t timer_get_state(timer_handle_t *hperh); -/** - * @} - */ -/** - * @} - */ - -/** - * @} - */ -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_TIMER_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_uart.h b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_uart.h deleted file mode 100644 index 0d8b189931..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_uart.h +++ /dev/null @@ -1,478 +0,0 @@ -/** - ********************************************************************************* - * - * @file ald_uart.h - * @brief Header file of UART module library. - * - * @version V1.0 - * @date 21 Nov 2017 - * @author AE Team - * @note - * - * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. - * - ********************************************************************************* - */ - -#ifndef __ALD_UART_H__ -#define __ALD_UART_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "utils.h" -#include "ald_dma.h" - - -/** @addtogroup ES32FXXX_ALD - * @{ - */ - -/** @addtogroup UART - * @{ - */ - -/** - * @defgroup UART_Public_Macros UART Public Macros - * @{ - */ -#define UART_RX_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_RXEN_MSK)) -#define UART_RX_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_RXEN_MSK)) -#define UART_BRR_WRITE_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_BRWEN_MSK)) -#define UART_BRR_WRITE_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_BRWEN_MSK)) -#define UART_RX_TIMEOUT_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_RTOEN_MSK)) -#define UART_RX_TIMEOUT_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_RTOEN_MSK)) -#define UART_MSB_FIRST_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_MSBFIRST_MSK)) -#define UART_MSB_FIRST_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_MSBFIRST_MSK)) -#define UART_DATA_INV_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_DATAINV_MSK)) -#define UART_DATA_INV_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_DATAINV_MSK)) -#define UART_RX_INV_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_RXINV_MSK)) -#define UART_RX_INV_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_RXINV_MSK)) -#define UART_TX_INV_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_TXINV_MSK)) -#define UART_TX_INV_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_TXINV_MSK)) -#define UART_TX_RX_SWAP_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_SWAP_MSK)) -#define UART_TX_RX_SWAP_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_SWAP_MSK)) -#define UART_HDSEL_ENABLE(hperh) (SET_BIT((hperh)->perh->MCR, UART_MCR_HDSEL_MSK)) -#define UART_HDSEL_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->MCR, UART_MCR_HDSEL_MSK)) -#define UART_FIFO_TX_RESET(hperh) (SET_BIT((hperh)->perh->FCR, UART_FCR_TFRST_MSK)) -#define UART_FIFO_RX_RESET(hperh) (SET_BIT((hperh)->perh->FCR, UART_FCR_RFRST_MSK)) -#define UART_LPBMOD_ENABLE(hperh) (SET_BIT((hperh)->perh->MCR, UART_MCR_LBEN_MSK)) -#define UART_LPBMOD_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->MCR, UART_MCR_LBEN_MSK)) -#define UART_AUTOBR_ENABLE(hperh) (SET_BIT((hperh)->perh->MCR, UART_MCR_ABREN_MSK)) -#define UART_AUTOBR_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->MCR, UART_MCR_ABREN_MSK)) -#define UART_AUTOBR_RESTART(hperh) (SET_BIT((hperh)->perh->MCR, UART_MCR_ABRRS_MSK)) -#define UART_GET_BRR_VALUE(hperh) (READ_REG((hperh)->perh->BRR)) -#define UART_SET_TIMEOUT_VALUE(x, y) (MODIFY_REG((x)->perh->RTOR, UART_RTOR_RTO_MSK, (y) << UART_RTOR_RTO_POSS)) -/** - * @} - */ - -/** @defgroup UART_Public_Types UART Public Types - * @{ - */ -/** - * @brief UART word length - */ -typedef enum -{ - UART_WORD_LENGTH_5B = 0x0, /**< 5-bits */ - UART_WORD_LENGTH_6B = 0x1, /**< 6-bits */ - UART_WORD_LENGTH_7B = 0x2, /**< 7-bits */ - UART_WORD_LENGTH_8B = 0x3, /**< 8-bits */ -} uart_word_length_t; - -/** - * @brief UART stop bits - */ -typedef enum -{ - UART_STOP_BITS_1 = 0x0, /**< 1-bits */ - UART_STOP_BITS_2 = 0x1, /**< 2-bits */ - UART_STOP_BITS_0_5 = 0x0, /**< 0.5-bits, using smartcard mode */ - UART_STOP_BITS_1_5 = 0x1, /**< 1.5-bits, using smartcard mode */ -} uart_stop_bits_t; - -/** - * @brief UART parity - */ -typedef enum -{ - UART_PARITY_NONE = 0x0, /**< Not parity */ - UART_PARITY_ODD = 0x1, /**< Odd parity */ - UART_PARITY_EVEN = 0x3, /**< Even parity */ -} uart_parity_t; - -/** - * @brief UART mode - */ -typedef enum -{ - UART_MODE_UART = 0x0, /**< UART */ - UART_MODE_LIN = 0x1, /**< LIN */ - UART_MODE_IrDA = 0x2, /**< IrDA */ - UART_MODE_RS485 = 0x3, /**< RS485 */ - UART_MODE_HDSEL = 0x4, /**< Single-wire half-duplex */ -} uart_mode_t; - -/** - * @brief UART hardware flow control - */ -typedef enum -{ - UART_HW_FLOW_CTL_DISABLE = 0x0, /**< Auto-flow-control disable */ - UART_HW_FLOW_CTL_ENABLE = 0x1, /**< Auto-flow-control enable */ -} uart_hw_flow_ctl_t; - -/** - * @brief ALD UART state - */ -typedef enum -{ - UART_STATE_RESET = 0x00, /**< Peripheral is not initialized */ - UART_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ - UART_STATE_BUSY = 0x02, /**< an internal process is ongoing */ - UART_STATE_BUSY_TX = 0x11, /**< Data Transmission process is ongoing */ - UART_STATE_BUSY_RX = 0x21, /**< Data Reception process is ongoing */ - UART_STATE_BUSY_TX_RX = 0x31, /**< Data Transmission Reception process is ongoing */ - UART_STATE_TIMEOUT = 0x03, /**< Timeout state */ - UART_STATE_ERROR = 0x04, /**< Error */ -} uart_state_t; - -/** - * @brief UART error codes - */ -typedef enum -{ - UART_ERROR_NONE = ((uint32_t)0x00), /**< No error */ - UART_ERROR_PE = ((uint32_t)0x01), /**< Parity error */ - UART_ERROR_NE = ((uint32_t)0x02), /**< Noise error */ - UART_ERROR_FE = ((uint32_t)0x04), /**< frame error */ - UART_ERROR_ORE = ((uint32_t)0x08), /**< Overrun error */ - UART_ERROR_DMA = ((uint32_t)0x10), /**< DMA transfer error */ -} uart_error_t; - -/** - * @brief UART init structure definition - */ -typedef struct -{ - uint32_t baud; /**< Specifies the uart communication baud rate */ - uart_word_length_t word_length; /**< Specifies the number of data bits transmitted or received in a frame */ - uart_stop_bits_t stop_bits; /**< Specifies the number of stop bits transmitted */ - uart_parity_t parity; /**< Specifies the parity mode */ - uart_mode_t mode; /**< Specifies uart mode */ - uart_hw_flow_ctl_t fctl; /**< Specifies wether the hardware flow control mode is enabled or disabled */ -} uart_init_t; - -/** - * @brief UART handle structure definition - */ -typedef struct uart_handle_s -{ - UART_TypeDef *perh; /**< UART registers base address */ - uart_init_t init; /**< UART communication parameters */ - uint8_t *tx_buf; /**< Pointer to UART Tx transfer Buffer */ - uint16_t tx_size; /**< UART Tx Transfer size */ - uint16_t tx_count; /**< UART Tx Transfer Counter */ - uint8_t *rx_buf; /**< Pointer to UART Rx transfer Buffer */ - uint16_t rx_size; /**< UART Rx Transfer size */ - uint16_t rx_count; /**< UART Rx Transfer Counter */ -#ifdef ALD_DMA - dma_handle_t hdmatx; /**< UART Tx DMA Handle parameters */ - dma_handle_t hdmarx; /**< UART Rx DMA Handle parameters */ -#endif - lock_state_t lock; /**< Locking object */ - uart_state_t state; /**< UART communication state */ - uart_error_t err_code; /**< UART Error code */ - - void (*tx_cplt_cbk)(struct uart_handle_s *arg); /**< Tx completed callback */ - void (*rx_cplt_cbk)(struct uart_handle_s *arg); /**< Rx completed callback */ - void (*error_cbk)(struct uart_handle_s *arg); /**< error callback */ -} uart_handle_t; - -/** - * @brief UART RS485 configure structure definition - */ -typedef struct -{ - type_func_t normal; /**< Normal mode */ - type_func_t dir; /**< Auto-direction mode */ - type_func_t invert; /**< Address detection invert */ - uint8_t addr; /**< Address for compare */ -} uart_rs485_config_t; - -/** - * @brief LIN detection break length - */ -typedef enum -{ - LIN_BREAK_LEN_10B = 0x0, /**< 10-bit break */ - LIN_BREAK_LEN_11B = 0x1, /**< 11-bit break */ -} uart_lin_break_len_t; - -/** - * @brief UART TXFIFO size - */ -typedef enum -{ - UART_TXFIFO_EMPTY = 0x0, /**< Empty */ - UART_TXFIFO_2BYTE = 0x1, /**< 2-Bytes */ - UART_TXFIFO_4BYTE = 0x2, /**< 4-Bytes */ - UART_TXFIFO_8BYTE = 0x3, /**< 8-Bytes */ -} uart_txfifo_t; - -/** - * @brief UART RXFIFO size - */ -typedef enum -{ - UART_RXFIFO_1BYTE = 0x0, /**< 1-Byte */ - UART_RXFIFO_4BYTE = 0x1, /**< 4-Bytes */ - UART_RXFIFO_8BYTE = 0x2, /**< 8-Bytes */ - UART_RXFIFO_14BYTE = 0x3, /**< 14-Bytes */ -} uart_rxfifo_t; - -/** - * @brief UART auto-baud mode - */ -typedef enum -{ - UART_ABRMOD_1_TO_0 = 0x0, /**< Detect bit0:1, bit1:0 */ - UART_ABRMOD_1 = 0x1, /**< Detect bit0:1 */ - UART_ABRMOD_0_TO_1 = 0x2, /**< Detect bit0:0, bit1:1 */ -} uart_auto_baud_mode_t; - -/** - * @brief UART status types - */ -typedef enum -{ - UART_STATUS_DR = (1U << 0), /**< Data ready */ - UART_STATUS_OE = (1U << 1), /**< Overrun error */ - UART_STATUS_PE = (1U << 2), /**< Parity error */ - UART_STATUS_FE = (1U << 3), /**< Framing error */ - UART_STATUS_BI = (1U << 4), /**< Break interrupt */ - UART_STATUS_TBEM = (1U << 5), /**< Transmit buffer empty */ - UART_STATUS_TEM = (1U << 6), /**< Transmitter empty */ - UART_STATUS_RFE = (1U << 7), /**< Reveiver FIFO data error */ - UART_STATUS_BUSY = (1U << 8), /**< UART busy */ - UART_STATUS_TFNF = (1U << 9), /**< Transmit FIFO not full */ - UART_STATUS_TFEM = (1U << 10), /**< Transmit FIFO not empty */ - UART_STATUS_RFNE = (1U << 11), /**< Receive FIFO not empty */ - UART_STATUS_RFF = (1U << 12), /**< Receive FIFO full */ - UART_STATUS_DCTS = (1U << 14), /**< Delta clear to send */ - UART_STATUS_CTS = (1U << 15), /**< Clear to send */ -} uart_status_t; - -/** - * @brief UART interrupt types - */ -typedef enum -{ - UART_IT_RXRD = (1U << 0), /**< Receive data available */ - UART_IT_TXS = (1U << 1), /**< Tx empty status */ - UART_IT_RXS = (1U << 2), /**< Rx line status */ - UART_IT_MDS = (1U << 3), /**< Modem status */ - UART_IT_RTO = (1U << 4), /**< Receiver timeout */ - UART_IT_BZ = (1U << 5), /**< Busy status */ - UART_IT_ABE = (1U << 6), /**< Auto-baud rate detection end */ - UART_IT_ABTO = (1U << 7), /**< Auto-baud rate detection timeout */ - UART_IT_LINBK = (1U << 8), /**< Lin break detection */ - UART_IT_TC = (1U << 9), /**< Transmission complete */ - UART_IT_EOB = (1U << 10), /**< End of block */ - UART_IT_CM = (1U << 11), /**< Character match */ -} uart_it_t; - -/** - * @brief UART flags types - */ -typedef enum -{ - UART_IF_RXRD = (1U << 0), /**< Receive data available */ - UART_IF_TXS = (1U << 1), /**< Tx empty status */ - UART_IF_RXS = (1U << 2), /**< Rx line status */ - UART_IF_MDS = (1U << 3), /**< Modem status */ - UART_IF_RTO = (1U << 4), /**< Receiver timeout */ - UART_IF_BZ = (1U << 5), /**< Busy status */ - UART_IF_ABE = (1U << 6), /**< Auto-baud rate detection end */ - UART_IF_ABTO = (1U << 7), /**< Auto-baud rate detection timeout */ - UART_IF_LINBK = (1U << 8), /**< Lin break detection */ - UART_IF_TC = (1U << 9), /**< Transmission complete */ - UART_IF_EOB = (1U << 10), /**< End of block */ - UART_IF_CM = (1U << 11), /**< Character match */ -} uart_flag_t; -/** - * @} - */ - -/** @defgroup UART_Private_Macros UART Private Macros - * @{ - */ -#define IS_UART_ALL(x) (((x) == UART0) || \ - ((x) == UART1) || \ - ((x) == UART2) || \ - ((x) == UART3)) -#define IS_UART_WORD_LENGTH(x) (((x) == UART_WORD_LENGTH_5B) || \ - ((x) == UART_WORD_LENGTH_6B) || \ - ((x) == UART_WORD_LENGTH_7B) || \ - ((x) == UART_WORD_LENGTH_8B)) -#define IS_UART_STOPBITS(x) (((x) == UART_STOP_BITS_1) || \ - ((x) == UART_STOP_BITS_2) || \ - ((x) == UART_STOP_BITS_0_5) || \ - ((x) == UART_STOP_BITS_1_5)) -#define IS_UART_PARITY(x) (((x) == UART_PARITY_NONE) || \ - ((x) == UART_PARITY_ODD) || \ - ((x) == UART_PARITY_EVEN)) -#define IS_UART_MODE(x) (((x) == UART_MODE_UART) || \ - ((x) == UART_MODE_LIN) || \ - ((x) == UART_MODE_IrDA) || \ - ((x) == UART_MODE_RS485) || \ - ((x) == UART_MODE_HDSEL)) -#define IS_UART_HARDWARE_FLOW_CONTROL(x) \ - (((x) == UART_HW_FLOW_CTL_DISABLE) || \ - ((x) == UART_HW_FLOW_CTL_ENABLE)) -#define IS_UART_LIN_BREAK_LEN(x) (((x) == LIN_BREAK_LEN_10B) || \ - ((x) == LIN_BREAK_LEN_11B)) -#define IS_UART_TXFIFO_TYPE(x) (((x) == UART_TXFIFO_EMPTY) || \ - ((x) == UART_TXFIFO_2BYTE) || \ - ((x) == UART_TXFIFO_4BYTE) || \ - ((x) == UART_TXFIFO_8BYTE)) -#define IS_UART_RXFIFO_TYPE(x) (((x) == UART_RXFIFO_1BYTE) || \ - ((x) == UART_RXFIFO_4BYTE) || \ - ((x) == UART_RXFIFO_8BYTE) || \ - ((x) == UART_RXFIFO_14BYTE)) -#define IS_UART_AUTO_BAUD_MODE(x) (((x) == UART_ABRMOD_1_TO_0) || \ - ((x) == UART_ABRMOD_1) || \ - ((x) == UART_ABRMOD_0_TO_1)) -#define IS_UART_STATUS(x) (((x) == UART_STATUS_DR) || \ - ((x) == UART_STATUS_OE) || \ - ((x) == UART_STATUS_PE) || \ - ((x) == UART_STATUS_FE) || \ - ((x) == UART_STATUS_BI) || \ - ((x) == UART_STATUS_TBEM) || \ - ((x) == UART_STATUS_TEM) || \ - ((x) == UART_STATUS_RFE) || \ - ((x) == UART_STATUS_BUSY) || \ - ((x) == UART_STATUS_TFNF) || \ - ((x) == UART_STATUS_TFEM) || \ - ((x) == UART_STATUS_RFNE) || \ - ((x) == UART_STATUS_RFF) || \ - ((x) == UART_STATUS_DCTS) || \ - ((x) == UART_STATUS_CTS)) -#define IS_UART_IT(x) (((x) == UART_IT_RXRD) || \ - ((x) == UART_IT_TXS) || \ - ((x) == UART_IT_RXS) || \ - ((x) == UART_IT_MDS) || \ - ((x) == UART_IT_RTO) || \ - ((x) == UART_IT_BZ) || \ - ((x) == UART_IT_ABE) || \ - ((x) == UART_IT_ABTO) || \ - ((x) == UART_IT_LINBK) || \ - ((x) == UART_IT_TC) || \ - ((x) == UART_IT_EOB) || \ - ((x) == UART_IT_CM)) -#define IS_UART_IF(x) (((x) == UART_IF_RXRD) || \ - ((x) == UART_IF_TXS) || \ - ((x) == UART_IF_RXS) || \ - ((x) == UART_IF_MDS) || \ - ((x) == UART_IF_RTO) || \ - ((x) == UART_IF_BZ) || \ - ((x) == UART_IF_ABE) || \ - ((x) == UART_IF_ABTO) || \ - ((x) == UART_IF_LINBK) || \ - ((x) == UART_IF_TC) || \ - ((x) == UART_IF_EOB) || \ - ((x) == UART_IF_CM)) -#define IS_UART_BAUDRATE(x) (((x) > 0) && ((x) < 0x44AA21)) -#define IS_UART_DATA(x) ((x) <= 0x1FF) - -#define UART_STATE_TX_MASK (1U << 4) -#define UART_STATE_RX_MASK (1U << 5) -/** - * @} - */ - -/** @addtogroup UART_Public_Functions - * @{ - */ - -/** @addtogroup UART_Public_Functions_Group1 - * @{ - */ -/* Initialization functions */ -void uart_init(uart_handle_t *hperh); -void uart_reset(uart_handle_t *hperh); -void uart_rs485_config(uart_handle_t *hperh, uart_rs485_config_t *config); -/** - * @} - */ - -/** @addtogroup UART_Public_Functions_Group2 - * @{ - */ -/* IO operation functions */ -ald_status_t uart_send(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t uart_recv(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t uart_send_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t uart_recv_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size); -#ifdef ALD_DMA -ald_status_t uart_send_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t uart_recv_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t uart_dma_pause(uart_handle_t *hperh); -ald_status_t uart_dma_resume(uart_handle_t *hperh); -ald_status_t uart_dma_stop(uart_handle_t *hperh); -#endif -void uart_irq_handle(uart_handle_t *hperh); -/** - * @} - */ - -/** @addtogroup UART_Public_Functions_Group3 - * @{ - */ -/* Peripheral Control functions */ -void uart_interrupt_config(uart_handle_t *hperh, uart_it_t it, type_func_t state); -void uart_dma_req_config(uart_handle_t *hperh, type_func_t state); -void uart_tx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t level); -void uart_rx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t level); -void uart_lin_send_break(uart_handle_t *hperh); -void uart_lin_detect_break_len_config(uart_handle_t *hperh, uart_lin_break_len_t len); -void uart_auto_baud_config(uart_handle_t *hperh, uart_auto_baud_mode_t mode); -ald_status_t uart_rs485_send_addr(uart_handle_t *hperh, uint16_t addr, uint32_t timeout); -it_status_t uart_get_it_status(uart_handle_t *hperh, uart_it_t it); -flag_status_t uart_get_status(uart_handle_t *hperh, uart_status_t status); -flag_status_t uart_get_flag_status(uart_handle_t *hperh, uart_flag_t flag); -flag_status_t uart_get_mask_flag_status(uart_handle_t *hperh, uart_flag_t flag); -void uart_clear_flag_status(uart_handle_t *hperh, uart_flag_t flag); -/** - * @} - */ - -/** @addtogroup UART_Public_Functions_Group4 - * @{ - */ -/* Peripheral State and Errors functions */ -uart_state_t uart_get_state(uart_handle_t *hperh); -uint32_t uart_get_error(uart_handle_t *hperh); -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ALD_UART_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/ReleaseNote.html b/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/ReleaseNote.html deleted file mode 100644 index a57c58046d..0000000000 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/ReleaseNote.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - -ReleaseNote -

    ES32F065x MD Release Note

    -

    V1.00 2018-12-26

    -
      -
    1. First release
    2. - -
    -

     

    - - \ No newline at end of file diff --git a/bsp/es32f0654/.config b/bsp/essemi/es32f0654/.config similarity index 69% rename from bsp/es32f0654/.config rename to bsp/essemi/es32f0654/.config index 9853f9b6d0..56a52e8087 100644 --- a/bsp/es32f0654/.config +++ b/bsp/essemi/es32f0654/.config @@ -7,6 +7,7 @@ # RT-Thread Kernel # CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_SMP is not set CONFIG_RT_ALIGN_SIZE=4 # CONFIG_RT_THREAD_PRIORITY_8 is not set @@ -63,7 +64,8 @@ CONFIG_RT_USING_DEVICE=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart2" -CONFIG_RT_VER_NUM=0x40001 +CONFIG_RT_VER_NUM=0x40002 +# CONFIG_RT_USING_CPU_FFS is not set # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set # @@ -108,6 +110,7 @@ CONFIG_FINSH_ARG_MAX=10 # CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_PIPE_BUFSZ=512 +# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set CONFIG_RT_USING_SERIAL=y # CONFIG_RT_SERIAL_USING_DMA is not set CONFIG_RT_SERIAL_RB_BUFSZ=64 @@ -120,7 +123,6 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set -# CONFIG_RT_USING_MTD is not set # CONFIG_RT_USING_PM is not set # CONFIG_RT_USING_RTC is not set # CONFIG_RT_USING_SDIO is not set @@ -128,10 +130,10 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_SENSOR is not set - -# -# Using WiFi -# +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set # CONFIG_RT_USING_WIFI is not set # @@ -145,6 +147,7 @@ CONFIG_RT_USING_PIN=y # # CONFIG_RT_USING_LIBC is not set # CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_LIBC_USING_TIME is not set # # Network @@ -156,14 +159,14 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_SAL is not set # -# light weight TCP/IP stack +# Network interface device # -# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_NETDEV is not set # -# Modbus master and slave stack +# light weight TCP/IP stack # -# CONFIG_RT_USING_MODBUS is not set +# CONFIG_RT_USING_LWIP is not set # # AT commands @@ -178,7 +181,6 @@ CONFIG_RT_USING_PIN=y # # Utilities # -# CONFIG_RT_USING_LOGTRACE is not set # CONFIG_RT_USING_RYM is not set # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set @@ -192,10 +194,13 @@ CONFIG_RT_USING_PIN=y # # CONFIG_PKG_USING_PAHOMQTT is not set # CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set # CONFIG_PKG_USING_MONGOOSE is not set # CONFIG_PKG_USING_WEBTERMINAL is not set # CONFIG_PKG_USING_CJSON is not set # CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set @@ -213,10 +218,14 @@ CONFIG_RT_USING_PIN=y # Wiced WiFi # # CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set # CONFIG_PKG_USING_COAP is not set # CONFIG_PKG_USING_NOPOLL is not set # CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set # CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set # # IoT Cloud @@ -225,6 +234,21 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_GAGENT_CLOUD is not set # CONFIG_PKG_USING_ALI_IOTKIT is not set # CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOTHUB is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set # # security packages @@ -245,6 +269,9 @@ CONFIG_RT_USING_PIN=y # # CONFIG_PKG_USING_OPENMV is not set # CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set # # tools packages @@ -253,6 +280,12 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_EASYFLASH is not set # CONFIG_PKG_USING_EASYLOGGER is not set # CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set # # system packages @@ -266,17 +299,42 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_SQLITE is not set # CONFIG_PKG_USING_RTI is not set # CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_CMSIS is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set # # peripheral libraries and drivers # -# CONFIG_PKG_USING_STM32F4_HAL is not set -# CONFIG_PKG_USING_STM32F4_DRIVERS is not set +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set # CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_SHT2X is not set -# CONFIG_PKG_USING_AHT10 is not set -# CONFIG_PKG_USING_AP3216C is not set # CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_LCD_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set # # miscellaneous packages @@ -287,13 +345,15 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_MINILZO is not set # CONFIG_PKG_USING_QUICKLZ is not set # CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set # CONFIG_PKG_USING_CANFESTIVAL is not set # CONFIG_PKG_USING_ZLIB is not set # CONFIG_PKG_USING_DSTR is not set - -# -# sample package -# +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set # # samples: kernel and components samples @@ -302,11 +362,15 @@ CONFIG_RT_USING_PIN=y # CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set # CONFIG_PKG_USING_NETWORK_SAMPLES is not set # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set - -# -# example package: hello -# # CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_UKAL is not set CONFIG_SOC_ES32F0654LT=y # @@ -350,7 +414,6 @@ CONFIG_BSP_USING_UART2=y # HWtimer Drivers # # CONFIG_BSP_USING_HWTIMER0 is not set -# CONFIG_BSP_USING_HWTIMER1 is not set # CONFIG_BSP_USING_HWTIMER2 is not set # CONFIG_BSP_USING_HWTIMER3 is not set diff --git a/bsp/es32f0654/Kconfig b/bsp/essemi/es32f0654/Kconfig similarity index 94% rename from bsp/es32f0654/Kconfig rename to bsp/essemi/es32f0654/Kconfig index 188eb5bfc0..2d3814dfe9 100644 --- a/bsp/es32f0654/Kconfig +++ b/bsp/essemi/es32f0654/Kconfig @@ -8,7 +8,7 @@ config BSP_DIR config RTT_DIR string option env="RTT_ROOT" - default "../.." + default "../../.." config PKGS_DIR string diff --git a/bsp/es32f0654/README.md b/bsp/essemi/es32f0654/README.md similarity index 98% rename from bsp/es32f0654/README.md rename to bsp/essemi/es32f0654/README.md index 8111adeda5..120cf0f479 100644 --- a/bsp/es32f0654/README.md +++ b/bsp/essemi/es32f0654/README.md @@ -40,6 +40,7 @@ ES-PDS-ES32F0654-V1.1 | UART | 支持 | UART0/1/2/3 | | SPI | 支持 | SPI0/1 | | I2C | 支持 | I2C0/1 | +| CAN | 支持 | CAN0 | | PWM | 支持 | PWM0/1/2/3 | | TIMER | 支持 | TIMER0/1/2/3 | | RTC | 支持 | RTC | diff --git a/bsp/es32f0654/SConscript b/bsp/essemi/es32f0654/SConscript similarity index 100% rename from bsp/es32f0654/SConscript rename to bsp/essemi/es32f0654/SConscript diff --git a/bsp/es32f0654/SConstruct b/bsp/essemi/es32f0654/SConstruct similarity index 94% rename from bsp/es32f0654/SConstruct rename to bsp/essemi/es32f0654/SConstruct index ac79195833..e75d75371b 100644 --- a/bsp/es32f0654/SConstruct +++ b/bsp/essemi/es32f0654/SConstruct @@ -5,7 +5,7 @@ import rtconfig if os.getenv('RTT_ROOT'): RTT_ROOT = os.getenv('RTT_ROOT') else: - RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] try: diff --git a/bsp/es32f0654/applications/SConscript b/bsp/essemi/es32f0654/applications/SConscript similarity index 100% rename from bsp/es32f0654/applications/SConscript rename to bsp/essemi/es32f0654/applications/SConscript diff --git a/bsp/es32f0654/applications/main.c b/bsp/essemi/es32f0654/applications/main.c similarity index 100% rename from bsp/es32f0654/applications/main.c rename to bsp/essemi/es32f0654/applications/main.c diff --git a/bsp/es32f0654/drivers/Kconfig b/bsp/essemi/es32f0654/drivers/Kconfig similarity index 95% rename from bsp/es32f0654/drivers/Kconfig rename to bsp/essemi/es32f0654/drivers/Kconfig index f7a64ea678..888308497a 100644 --- a/bsp/es32f0654/drivers/Kconfig +++ b/bsp/essemi/es32f0654/drivers/Kconfig @@ -56,6 +56,13 @@ menu "Hardware Drivers Config" default n endmenu + menu "CAN Drivers" + config BSP_USING_CAN + bool "Enable CAN BUS PA11/PA12(RX/TX)" + select RT_USING_CAN + default n + endmenu + menu "PWM Drivers" config BSP_USING_PWM0 bool "Using PWM0 PA08/PA09/PA10/PA11" diff --git a/bsp/es32f0654/drivers/SConscript b/bsp/essemi/es32f0654/drivers/SConscript similarity index 94% rename from bsp/es32f0654/drivers/SConscript rename to bsp/essemi/es32f0654/drivers/SConscript index a5ecf863ab..ad5cf3c783 100644 --- a/bsp/es32f0654/drivers/SConscript +++ b/bsp/essemi/es32f0654/drivers/SConscript @@ -23,6 +23,10 @@ if GetDepend('BSP_USING_SPI0') or GetDepend('BSP_USING_SPI1'): if GetDepend('BSP_USING_I2C0') or GetDepend('BSP_USING_I2C1'): src += ['drv_i2c.c'] +# add can driver code +if GetDepend('BSP_USING_CAN'): + src += ['drv_can.c'] + # add spi flash driver code if GetDepend('BSP_USING_SPI_FLASH'): src += ['drv_spiflash.c'] diff --git a/bsp/es32f0654/drivers/board.c b/bsp/essemi/es32f0654/drivers/board.c similarity index 89% rename from bsp/es32f0654/drivers/board.c rename to bsp/essemi/es32f0654/drivers/board.c index 46b3d472a0..94b259e485 100644 --- a/bsp/es32f0654/drivers/board.c +++ b/bsp/essemi/es32f0654/drivers/board.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-01-23 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -43,10 +44,10 @@ void NVIC_Configuration(void) void SystemClock_Config(void) { /* hosc 12MHz, from hosc/3 pll to 48MHz */ - cmu_pll1_config(CMU_PLL1_INPUT_HOSC_3, CMU_PLL1_OUTPUT_48M); + ald_cmu_pll1_config(CMU_PLL1_INPUT_HOSC_3, CMU_PLL1_OUTPUT_48M); /* MCLK 48MHz*/ - cmu_clock_config(CMU_CLOCK_PLL1, 48000000); + ald_cmu_clock_config(CMU_CLOCK_PLL1, 48000000); } /******************************************************************************* @@ -59,14 +60,14 @@ void SystemClock_Config(void) void SysTick_Configuration(void) { /* ticks = sysclk / RT_TICK_PER_SECOND */ - SysTick_Config(cmu_get_sys_clock() / RT_TICK_PER_SECOND); + SysTick_Config(ald_cmu_get_sys_clock() / RT_TICK_PER_SECOND); } /** * This is the timer interrupt service routine. * */ -void systick_irq_cbk(void) +void SysTick_Handler(void) { /* enter interrupt */ rt_interrupt_enter(); @@ -113,7 +114,7 @@ void rt_hw_us_delay(rt_uint32_t us) unsigned int start, now, delta, reload, us_tick; start = SysTick->VAL; reload = SysTick->LOAD; - us_tick = cmu_get_sys_clock() / 1000000UL; + us_tick = ald_cmu_get_sys_clock() / 1000000UL; do { now = SysTick->VAL; diff --git a/bsp/es32f0654/drivers/board.h b/bsp/essemi/es32f0654/drivers/board.h similarity index 100% rename from bsp/es32f0654/drivers/board.h rename to bsp/essemi/es32f0654/drivers/board.h diff --git a/bsp/es32f0654/drivers/drv_adc.c b/bsp/essemi/es32f0654/drivers/drv_adc.c similarity index 71% rename from bsp/es32f0654/drivers/drv_adc.c rename to bsp/essemi/es32f0654/drivers/drv_adc.c index 9a90e4d394..81a269d5c3 100644 --- a/bsp/es32f0654/drivers/drv_adc.c +++ b/bsp/essemi/es32f0654/drivers/drv_adc.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-04-03 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -58,67 +59,67 @@ static adc_channel_t es32f0_adc_get_channel(rt_uint32_t channel) { case 0: es32f0_channel = ADC_CHANNEL_0; - gpio_init(GPIOC, GPIO_PIN_0, &gpio_initstruct); + ald_gpio_init(GPIOC, GPIO_PIN_0, &gpio_initstruct); break; case 1: es32f0_channel = ADC_CHANNEL_1; - gpio_init(GPIOC, GPIO_PIN_1, &gpio_initstruct); + ald_gpio_init(GPIOC, GPIO_PIN_1, &gpio_initstruct); break; case 2: es32f0_channel = ADC_CHANNEL_2; - gpio_init(GPIOC, GPIO_PIN_2, &gpio_initstruct); + ald_gpio_init(GPIOC, GPIO_PIN_2, &gpio_initstruct); break; case 3: es32f0_channel = ADC_CHANNEL_3; - gpio_init(GPIOC, GPIO_PIN_3, &gpio_initstruct); + ald_gpio_init(GPIOC, GPIO_PIN_3, &gpio_initstruct); break; case 4: es32f0_channel = ADC_CHANNEL_4; - gpio_init(GPIOA, GPIO_PIN_0, &gpio_initstruct); + ald_gpio_init(GPIOA, GPIO_PIN_0, &gpio_initstruct); break; case 5: es32f0_channel = ADC_CHANNEL_5; - gpio_init(GPIOA, GPIO_PIN_1, &gpio_initstruct); + ald_gpio_init(GPIOA, GPIO_PIN_1, &gpio_initstruct); break; case 6: es32f0_channel = ADC_CHANNEL_6; - gpio_init(GPIOA, GPIO_PIN_2, &gpio_initstruct); + ald_gpio_init(GPIOA, GPIO_PIN_2, &gpio_initstruct); break; case 7: es32f0_channel = ADC_CHANNEL_7; - gpio_init(GPIOA, GPIO_PIN_3, &gpio_initstruct); + ald_gpio_init(GPIOA, GPIO_PIN_3, &gpio_initstruct); break; case 8: es32f0_channel = ADC_CHANNEL_8; - gpio_init(GPIOA, GPIO_PIN_4, &gpio_initstruct); + ald_gpio_init(GPIOA, GPIO_PIN_4, &gpio_initstruct); break; case 9: es32f0_channel = ADC_CHANNEL_9; - gpio_init(GPIOA, GPIO_PIN_5, &gpio_initstruct); + ald_gpio_init(GPIOA, GPIO_PIN_5, &gpio_initstruct); break; case 10: es32f0_channel = ADC_CHANNEL_10; - gpio_init(GPIOA, GPIO_PIN_6, &gpio_initstruct); + ald_gpio_init(GPIOA, GPIO_PIN_6, &gpio_initstruct); break; case 11: es32f0_channel = ADC_CHANNEL_11; - gpio_init(GPIOA, GPIO_PIN_7, &gpio_initstruct); + ald_gpio_init(GPIOA, GPIO_PIN_7, &gpio_initstruct); break; case 12: es32f0_channel = ADC_CHANNEL_12; - gpio_init(GPIOC, GPIO_PIN_4, &gpio_initstruct); + ald_gpio_init(GPIOC, GPIO_PIN_4, &gpio_initstruct); break; case 13: es32f0_channel = ADC_CHANNEL_13; - gpio_init(GPIOC, GPIO_PIN_5, &gpio_initstruct); + ald_gpio_init(GPIOC, GPIO_PIN_5, &gpio_initstruct); break; case 14: es32f0_channel = ADC_CHANNEL_14; - gpio_init(GPIOB, GPIO_PIN_0, &gpio_initstruct); + ald_gpio_init(GPIOB, GPIO_PIN_0, &gpio_initstruct); break; case 15: es32f0_channel = ADC_CHANNEL_15; - gpio_init(GPIOB, GPIO_PIN_1, &gpio_initstruct); + ald_gpio_init(GPIOB, GPIO_PIN_1, &gpio_initstruct); break; case 16: es32f0_channel = ADC_CHANNEL_16; @@ -139,21 +140,21 @@ static adc_channel_t es32f0_adc_get_channel(rt_uint32_t channel) static rt_err_t es32f0_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value) { adc_handle_t *_hadc = (adc_handle_t *)device->parent.user_data; - adc_channel_conf_t nm_config; + adc_nch_conf_t nm_config; RT_ASSERT(device != RT_NULL); RT_ASSERT(value != RT_NULL); /* config adc channel */ nm_config.channel = es32f0_adc_get_channel(channel); - nm_config.rank = ADC_NC_RANK_1; - nm_config.sampling_time = ADC_SAMPLETIME_4; - adc_normal_channel_config(_hadc, &nm_config); + nm_config.rank = ADC_NCH_RANK_1; + nm_config.samp_time = ADC_SAMPLETIME_4; + ald_adc_normal_channel_config(_hadc, &nm_config); - adc_normal_start(_hadc); + ald_adc_normal_start(_hadc); - if (adc_normal_poll_for_conversion(_hadc, 5000) == OK) - *value = adc_normal_get_value(_hadc); + if (ald_adc_normal_poll_for_conversion(_hadc, 5000) == OK) + *value = ald_adc_normal_get_value(_hadc); return RT_EOK; } @@ -172,17 +173,16 @@ int rt_hw_adc_init(void) /* adc function initialization */ _h_adc0.perh = ADC0; _h_adc0.init.data_align = ADC_DATAALIGN_RIGHT; - _h_adc0.init.scan_mode = ADC_SCAN_DISABLE; + _h_adc0.init.scan_mode = DISABLE; _h_adc0.init.cont_mode = DISABLE; - _h_adc0.init.conv_nbr = ADC_NM_NBR_1; - _h_adc0.init.disc_mode = DISABLE; + _h_adc0.init.disc_mode = ADC_ALL_DISABLE; _h_adc0.init.disc_nbr = ADC_DISC_NBR_1; _h_adc0.init.conv_res = ADC_CONV_RES_10; _h_adc0.init.clk_div = ADC_CKDIV_128; - _h_adc0.init.nche_mode = ADC_NCHESEL_MODE_ALL; + _h_adc0.init.nche_sel = ADC_NCHESEL_MODE_ALL; _h_adc0.init.neg_ref = ADC_NEG_REF_VSS; _h_adc0.init.pos_ref = ADC_POS_REF_VDD; - adc_init(&_h_adc0); + ald_adc_init(&_h_adc0); rt_hw_adc_register(&_device_adc0, "adc0", &es32f0_adc_ops, &_h_adc0); diff --git a/bsp/es32f0654/drivers/drv_adc.h b/bsp/essemi/es32f0654/drivers/drv_adc.h similarity index 100% rename from bsp/es32f0654/drivers/drv_adc.h rename to bsp/essemi/es32f0654/drivers/drv_adc.h diff --git a/bsp/essemi/es32f0654/drivers/drv_can.c b/bsp/essemi/es32f0654/drivers/drv_can.c new file mode 100644 index 0000000000..0524fdaf07 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/drv_can.c @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-11-09 wangyq the first version + */ + +#include "drv_can.h" + +#ifdef BSP_USING_CAN + +static struct es32f0_can can; + +/* attention !!! baud calculation example: Pclk / ((sjw + seg1 + seg2) * psc) 48 / ((1 + 3 + 2) * 8) = 1MHz */ +static const struct es32f0_baud_rate_tab can_baud_rate_tab[] = +{ + {CAN1MBaud, 8}, + {CAN800kBaud, 10}, + {CAN500kBaud, 16}, + {CAN250kBaud, 32}, + {CAN125kBaud, 64}, + {CAN100kBaud, 80}, + {CAN50kBaud, 160}, + {CAN20kBaud, 400}, + {CAN10kBaud, 800} +}; + +static rt_uint32_t get_can_baud_index(rt_uint32_t baud) +{ + rt_uint32_t len, index; + + len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]); + for (index = 0; index < len; index++) + { + if (can_baud_rate_tab[index].baud_rate == baud) + return index; + } + + return 0; /* default baud is CAN1MBaud */ +} + +static rt_err_t _can_config(struct rt_can_device *can_device, struct can_configure *cfg) +{ + struct es32f0_can *drv_can; + rt_uint32_t baud_index; + + RT_ASSERT(can_device); + RT_ASSERT(cfg); + drv_can = (struct es32f0_can *)can_device->parent.user_data; + RT_ASSERT(drv_can); + + drv_can->CanHandle.perh = CAN0; + drv_can->CanHandle.init.ttcm = DISABLE; + drv_can->CanHandle.init.abom = ENABLE; + drv_can->CanHandle.init.awk = DISABLE; + drv_can->CanHandle.init.artx = DISABLE; + drv_can->CanHandle.init.rfom = DISABLE; + drv_can->CanHandle.init.txmp = ENABLE; + + switch (cfg->mode) + { + case RT_CAN_MODE_NORMAL: + drv_can->CanHandle.init.mode = CAN_MODE_NORMAL; + break; + case RT_CAN_MODE_LISEN: + drv_can->CanHandle.init.mode = CAN_MODE_SILENT; + break; + case RT_CAN_MODE_LOOPBACK: + drv_can->CanHandle.init.mode = CAN_MODE_LOOPBACK; + break; + case RT_CAN_MODE_LOOPBACKANLISEN: + drv_can->CanHandle.init.mode = CAN_MODE_SILENT_LOOPBACK; + break; + } + + baud_index = get_can_baud_index(cfg->baud_rate); + drv_can->CanHandle.init.sjw = CAN_SJW_1; + drv_can->CanHandle.init.seg1 = CAN_SEG1_3; + drv_can->CanHandle.init.seg2 = CAN_SEG2_2; + drv_can->CanHandle.init.psc = can_baud_rate_tab[baud_index].config_data; + /* init can */ + if (ald_can_init(&drv_can->CanHandle) != OK) + { + return -RT_ERROR; + } + /* default filter config */ + ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig); + + return RT_EOK; +} + +static rt_err_t _can_control(struct rt_can_device *can_device, int cmd, void *arg) +{ + rt_uint32_t argval; + struct es32f0_can *drv_can; + struct rt_can_filter_config *filter_cfg; + + RT_ASSERT(can_device != RT_NULL); + drv_can = (struct es32f0_can *)can_device->parent.user_data; + RT_ASSERT(drv_can != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + argval = (rt_uint32_t) arg; + if (argval == RT_DEVICE_FLAG_INT_RX) + { + ald_can_interrupt_config(&drv_can->CanHandle, (can_it_t)(CAN_IT_FP0 | CAN_IT_FF0 | CAN_IT_FOV0 | + CAN_IT_FP1 | CAN_IT_FF1 | CAN_IT_FOV1), DISABLE); + } + else if (argval == RT_DEVICE_FLAG_INT_TX) + { + ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_TXM, DISABLE); + } + else if (argval == RT_DEVICE_CAN_INT_ERR) + { + ald_can_interrupt_config(&drv_can->CanHandle, (can_it_t)(CAN_IT_WARN | CAN_IT_PERR | CAN_IT_BOF | + CAN_IT_PRERR | CAN_IT_ERR), DISABLE); + } + break; + case RT_DEVICE_CTRL_SET_INT: + argval = (rt_uint32_t) arg; + if (argval == RT_DEVICE_FLAG_INT_RX) + { + NVIC_SetPriority(CAN0_IRQn, 1); + NVIC_EnableIRQ(CAN0_IRQn); + + ald_can_interrupt_config(&drv_can->CanHandle, (can_it_t)(CAN_IT_FP0 | CAN_IT_FP1), ENABLE); + } + else if (argval == RT_DEVICE_FLAG_INT_TX) + { + NVIC_SetPriority(CAN0_IRQn, 1); + NVIC_EnableIRQ(CAN0_IRQn); + + ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_TXM, ENABLE); + } + else if (argval == RT_DEVICE_CAN_INT_ERR) + { + NVIC_SetPriority(CAN0_IRQn, 1); + NVIC_EnableIRQ(CAN0_IRQn); + + ald_can_interrupt_config(&drv_can->CanHandle, (can_it_t)(CAN_IT_WARN | CAN_IT_PERR | CAN_IT_BOF | + CAN_IT_PRERR | CAN_IT_ERR), ENABLE); + } + break; + case RT_CAN_CMD_SET_FILTER: + if (RT_NULL == arg) + { + /* default filter config */ + ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig); + } + else + { + filter_cfg = (struct rt_can_filter_config *)arg; + /* get default filter */ + for (int i = 0; i < filter_cfg->count; i++) + { + drv_can->FilterConfig.number = filter_cfg->items[i].hdr; + drv_can->FilterConfig.id_high = (filter_cfg->items[i].id >> 13) & 0xFFFF; + drv_can->FilterConfig.id_low = ((filter_cfg->items[i].id << 3) | + (filter_cfg->items[i].ide << 2) | + (filter_cfg->items[i].rtr << 1)) & 0xFFFF; + drv_can->FilterConfig.mask_id_high = (filter_cfg->items[i].mask >> 16) & 0xFFFF; + drv_can->FilterConfig.mask_id_low = filter_cfg->items[i].mask & 0xFFFF; + drv_can->FilterConfig.mode = (can_filter_mode_t)filter_cfg->items[i].mode; + /* Filter conf */ + ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig); + } + } + break; + case RT_CAN_CMD_SET_MODE: + argval = (rt_uint32_t) arg; + if (argval != RT_CAN_MODE_NORMAL && + argval != RT_CAN_MODE_LISEN && + argval != RT_CAN_MODE_LOOPBACK && + argval != RT_CAN_MODE_LOOPBACKANLISEN) + { + return -RT_ERROR; + } + if (argval != drv_can->device.config.mode) + { + drv_can->device.config.mode = argval; + return _can_config(&drv_can->device, &drv_can->device.config); + } + break; + case RT_CAN_CMD_SET_BAUD: + argval = (rt_uint32_t) arg; + if (argval != CAN1MBaud && + argval != CAN800kBaud && + argval != CAN500kBaud && + argval != CAN250kBaud && + argval != CAN125kBaud && + argval != CAN100kBaud && + argval != CAN50kBaud && + argval != CAN20kBaud && + argval != CAN10kBaud) + { + return -RT_ERROR; + } + if (argval != drv_can->device.config.baud_rate) + { + drv_can->device.config.baud_rate = argval; + return _can_config(&drv_can->device, &drv_can->device.config); + } + break; + case RT_CAN_CMD_SET_PRIV: + argval = (rt_uint32_t) arg; + if (argval != RT_CAN_MODE_PRIV && + argval != RT_CAN_MODE_NOPRIV) + { + return -RT_ERROR; + } + if (argval != drv_can->device.config.privmode) + { + drv_can->device.config.privmode = argval; + return _can_config(&drv_can->device, &drv_can->device.config); + } + break; + case RT_CAN_CMD_GET_STATUS: + { + rt_uint32_t errtype; + errtype = drv_can->CanHandle.perh->ERRSTAT; + drv_can->device.status.rcverrcnt = errtype >> 24; + drv_can->device.status.snderrcnt = (errtype >> 16 & 0xFF); + drv_can->device.status.lasterrtype = errtype & 0x70; + drv_can->device.status.errcode = errtype & 0x07; + + rt_memcpy(arg, &drv_can->device.status, sizeof(drv_can->device.status)); + } + break; + } + + return RT_EOK; +} + +static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num) +{ + can_handle_t *h_can; + h_can = &((struct es32f0_can *) can->parent.user_data)->CanHandle; + struct rt_can_msg *pmsg = (struct rt_can_msg *) buf; + can_tx_msg_t txheader = {0}; + can_state_t state = h_can->state; + + /* Check the parameters */ + RT_ASSERT(IS_CAN_DATA_LEN(pmsg->len)); + + if ((state == CAN_STATE_READY) || + (state == CAN_STATE_BUSY_RX)) + { + /*check select mailbox is empty */ + switch (1 << box_num) + { + case CAN_TX_MAILBOX_0: + if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM0) != SET) + { + /* Change CAN state */ + h_can->state = CAN_STATE_ERROR; + /* Return function status */ + return -RT_ERROR; + } + break; + case CAN_TX_MAILBOX_1: + if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM1) != SET) + { + /* Change CAN state */ + h_can->state = CAN_STATE_ERROR; + /* Return function status */ + return -RT_ERROR; + } + break; + case CAN_TX_MAILBOX_2: + if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM2) != SET) + { + /* Change CAN state */ + h_can->state = CAN_STATE_ERROR; + /* Return function status */ + return -RT_ERROR; + } + break; + default: + RT_ASSERT(0); + break; + } + + if (RT_CAN_STDID == pmsg->ide) + { + txheader.type = CAN_ID_STD; + RT_ASSERT(IS_CAN_STDID(pmsg->id)); + txheader.std = pmsg->id; + } + else + { + txheader.type = CAN_ID_EXT; + RT_ASSERT(IS_CAN_EXTID(pmsg->id)); + txheader.ext = pmsg->id; + } + + if (RT_CAN_DTR == pmsg->rtr) + { + txheader.rtr = CAN_RTR_DATA; + } + else + { + txheader.rtr = CAN_RTR_REMOTE; + } + /* clear TIR */ + h_can->perh->TxMailBox[box_num].TXID &= CAN_TXID0_TXMREQ_MSK; + /* Set up the Id */ + if (RT_CAN_STDID == pmsg->ide) + { + h_can->perh->TxMailBox[box_num].TXID |= (txheader.std << CAN_TXID0_STDID_POSS) | txheader.rtr; + } + else + { + h_can->perh->TxMailBox[box_num].TXID |= (txheader.ext << CAN_TXID0_EXID_POSS) | txheader.type | txheader.rtr; + } + /* Set up the DLC */ + h_can->perh->TxMailBox[box_num].TXFCON = pmsg->len & 0x0FU; + /* Set up the data field */ + WRITE_REG(h_can->perh->TxMailBox[box_num].TXDH, + ((uint32_t)pmsg->data[7] << CAN_TXDH0_BYTE7_POSS) | + ((uint32_t)pmsg->data[6] << CAN_TXDH0_BYTE6_POSS) | + ((uint32_t)pmsg->data[5] << CAN_TXDH0_BYTE5_POSS) | + ((uint32_t)pmsg->data[4] << CAN_TXDH0_BYTE4_POSS)); + WRITE_REG(h_can->perh->TxMailBox[box_num].TXDL, + ((uint32_t)pmsg->data[3] << CAN_TXDL0_BYTE3_POSS) | + ((uint32_t)pmsg->data[2] << CAN_TXDL0_BYTE2_POSS) | + ((uint32_t)pmsg->data[1] << CAN_TXDL0_BYTE1_POSS) | + ((uint32_t)pmsg->data[0] << CAN_TXDL0_BYTE0_POSS)); + /* Request transmission */ + SET_BIT(h_can->perh->TxMailBox[box_num].TXID, CAN_TXID0_TXMREQ_MSK); + + return RT_EOK; + } + else + { + /* Update error code */ + h_can->err |= 0x00040000U; + + return -RT_ERROR; + } +} + +static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo) +{ + can_handle_t *h_can; + struct rt_can_msg *pmsg; + can_rx_msg_t rxheader = {0}; + + RT_ASSERT(can); + + h_can = &((struct es32f0_can *)can->parent.user_data)->CanHandle; + pmsg = (struct rt_can_msg *) buf; + + /* get data */ + if (ald_can_recv(h_can, (can_rx_fifo_t)fifo, &rxheader, 0xFFFF) != OK) + return -RT_ERROR; + pmsg->data[0] = rxheader.data[0]; + pmsg->data[1] = rxheader.data[1]; + pmsg->data[2] = rxheader.data[2]; + pmsg->data[3] = rxheader.data[3]; + pmsg->data[4] = rxheader.data[4]; + pmsg->data[5] = rxheader.data[5]; + pmsg->data[6] = rxheader.data[6]; + pmsg->data[7] = rxheader.data[7]; + + /* get id */ + if (CAN_ID_STD == rxheader.type) + { + pmsg->ide = RT_CAN_STDID; + pmsg->id = rxheader.std; + } + else + { + pmsg->ide = RT_CAN_EXTID; + pmsg->id = rxheader.ext; + } + /* get type */ + if (CAN_RTR_DATA == rxheader.rtr) + { + pmsg->rtr = RT_CAN_DTR; + } + else + { + pmsg->rtr = RT_CAN_RTR; + } + /* get len */ + pmsg->len = rxheader.len; + /* get hdr */ + pmsg->hdr = (rxheader.fmi + 1) >> 1; + + return RT_EOK; +} + + +static const struct rt_can_ops _can_ops = +{ + _can_config, + _can_control, + _can_sendmsg, + _can_recvmsg, +}; + +static void _can_rx_isr(struct rt_can_device *can, rt_uint32_t fifo) +{ + can_handle_t *h_can; + RT_ASSERT(can); + h_can = &((struct es32f0_can *) can->parent.user_data)->CanHandle; + + switch (fifo) + { + case CAN_RX_FIFO0: + /* Check Overrun flag for FIFO0 */ + if (ald_can_get_flag_status(h_can, CAN_FLAG_FOV0) && ald_can_get_it_status(h_can, CAN_IT_FOV0)) + { + /* Clear FIFO0 Overrun Flag */ + ald_can_clear_flag_status(h_can, CAN_FLAG_FOV0); + rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8); + } + /* RX interrupt */ + else + { + /* save to user list */ + rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8); + + /* Clear FIFO0 rx Flag */ + SET_BIT(h_can->perh->RXF0, CAN_RXF0_FREE_MSK); + } + break; + case CAN_RX_FIFO1: + /* Check Overrun flag for FIFO1 */ + if (ald_can_get_flag_status(h_can, CAN_FLAG_FOV1) && ald_can_get_it_status(h_can, CAN_IT_FOV1)) + { + /* Clear FIFO1 Overrun Flag */ + ald_can_clear_flag_status(h_can, CAN_FLAG_FOV1); + rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8); + } + /* RX interrupt */ + else + { + /* save to user list */ + rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8); + + /* Clear FIFO0 rx Flag */ + SET_BIT(h_can->perh->RXF1, CAN_RXF1_FREE_MSK); + } + break; + } +} + +/** + * @brief This function handles CAN interrupts. + */ +void CAN0_Handler(void) +{ + rt_interrupt_enter(); + + rt_uint32_t errtype; + can_handle_t *h_can; + h_can = &can.CanHandle; + + /* RX FIFO0 interrupt */ + if ((ald_can_get_it_status(h_can, CAN_IT_FP0)) && (CAN_RX_MSG_PENDING(h_can, CAN_RX_FIFO0) != 0)) + { + _can_rx_isr(&can.device, CAN_RX_FIFO0); + } + + /* RX FIFO1 interrupt */ + if ((ald_can_get_it_status(h_can, CAN_IT_FP1)) && (CAN_RX_MSG_PENDING(h_can, CAN_RX_FIFO1) != 0)) + { + _can_rx_isr(&can.device, CAN_RX_FIFO1); + } + + /* TX interrupt. transmit fifo0/1/2 is empty can trigger this interrupt */ + if (ald_can_get_flag_status(h_can, CAN_FLAG_M0REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM)) + { + if (ald_can_get_flag_status(h_can, CAN_FLAG_M0TXC)) + { + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 0 << 8); + } + else + { + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 0 << 8); + } + /* Clear transmission status flag M0REQC */ + ald_can_clear_flag_status(h_can, CAN_FLAG_M0REQC); + } + else if (ald_can_get_flag_status(h_can, CAN_FLAG_M1REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM)) + { + if (ald_can_get_flag_status(h_can, CAN_FLAG_M1TXC)) + { + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 1 << 8); + } + else + { + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 1 << 8); + } + ald_can_clear_flag_status(h_can, CAN_FLAG_M1REQC); + } + else if (ald_can_get_flag_status(h_can, CAN_FLAG_M2REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM)) + { + if (ald_can_get_flag_status(h_can, CAN_FLAG_M2REQC)) + { + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 2 << 8); + } + else + { + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 2 << 8); + } + ald_can_clear_flag_status(h_can, CAN_FLAG_M2REQC); + } + + /* CAN error interrupt */ + if (ald_can_get_flag_status(h_can, CAN_FLAG_ERR) && ald_can_get_it_status(h_can, CAN_IT_ERR)) + { + errtype = h_can->perh->ERRSTAT; + switch ((errtype & 0x70) >> 4) + { + case RT_CAN_BUS_BIT_PAD_ERR: + can.device.status.bitpaderrcnt++; + break; + case RT_CAN_BUS_FORMAT_ERR: + can.device.status.formaterrcnt++; + break; + case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */ + can.device.status.ackerrcnt++; + if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC)) + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 0 << 8); + else if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC)) + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 1 << 8); + else if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC)) + rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 2 << 8); + break; + case RT_CAN_BUS_IMPLICIT_BIT_ERR: + case RT_CAN_BUS_EXPLICIT_BIT_ERR: + can.device.status.biterrcnt++; + break; + case RT_CAN_BUS_CRC_ERR: + can.device.status.crcerrcnt++; + break; + } + + can.device.status.lasterrtype = errtype & 0x70; + can.device.status.rcverrcnt = errtype >> 24; + can.device.status.snderrcnt = (errtype >> 16 & 0xFF); + can.device.status.errcode = errtype & 0x07; + h_can->perh->IFC |= CAN_IFC_ERRIFC_MSK; + } + + rt_interrupt_leave(); +} + +int rt_hw_can_init(void) +{ + gpio_init_t h_gpio; + struct can_configure config = CANDEFAULTCONFIG; + + config.privmode = RT_CAN_MODE_NOPRIV; + config.ticks = 50; +#ifdef RT_CAN_USING_HDR + config.maxhdr = 14; +#endif + + /* Initialize can common pin */ + h_gpio.odos = GPIO_PUSH_PULL; + h_gpio.pupd = GPIO_PUSH_UP; + h_gpio.odrv = GPIO_OUT_DRIVE_NORMAL; + h_gpio.flt = GPIO_FILTER_DISABLE; + h_gpio.type = GPIO_TYPE_TTL; + h_gpio.func = GPIO_FUNC_4; + + /* Initialize can rx pin */ + h_gpio.mode = GPIO_MODE_INPUT; + ald_gpio_init(GPIOA, GPIO_PIN_11, &h_gpio); + + /* Initialize can tx pin */ + h_gpio.mode = GPIO_MODE_OUTPUT; + ald_gpio_init(GPIOA, GPIO_PIN_12, &h_gpio); + + /* config default filter */ + can_filter_t filter = {0}; + filter.id_high = 0x0000; + filter.id_low = 0x0000; + filter.mask_id_high = 0x0000; + filter.mask_id_low = 0x0000; + filter.fifo = CAN_FILTER_FIFO0; + filter.number = 0; + filter.mode = CAN_FILTER_MODE_MASK; + filter.scale = CAN_FILTER_SCALE_32; + filter.active = ENABLE; + filter.bank_number = 14; + + can.FilterConfig = filter; + can.device.config = config; + /* register CAN1 device */ + rt_hw_can_register(&can.device, "can", &_can_ops, &can); + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_can_init); + +#endif /* BSP_USING_CAN */ diff --git a/bsp/essemi/es32f0654/drivers/drv_can.h b/bsp/essemi/es32f0654/drivers/drv_can.h new file mode 100644 index 0000000000..798a3a8653 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/drv_can.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-11-09 wangyq the first version + */ + +#ifndef DRV_CAN_H__ +#define DRV_CAN_H__ + +#include +#include +#include + +#include +#include + +struct es32f0_baud_rate_tab +{ + rt_uint32_t baud_rate; + rt_uint32_t config_data; +}; + +/* es32f0 can device */ +struct es32f0_can +{ + can_handle_t CanHandle; + can_filter_t FilterConfig; + struct rt_can_device device; /* inherit from can device */ +}; + +int rt_hw_can_init(void); + +#endif /*DRV_CAN_H__ */ diff --git a/bsp/es32f0654/drivers/drv_gpio.c b/bsp/essemi/es32f0654/drivers/drv_gpio.c similarity index 93% rename from bsp/es32f0654/drivers/drv_gpio.c rename to bsp/essemi/es32f0654/drivers/drv_gpio.c index 4374772ede..680860757f 100644 --- a/bsp/es32f0654/drivers/drv_gpio.c +++ b/bsp/essemi/es32f0654/drivers/drv_gpio.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-01-23 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -167,7 +168,7 @@ void es32f0_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) { return; } - gpio_write_pin(index->gpio, index->pin, value); + ald_gpio_write_pin(index->gpio, index->pin, value); } int es32f0_pin_read(rt_device_t dev, rt_base_t pin) @@ -180,7 +181,7 @@ int es32f0_pin_read(rt_device_t dev, rt_base_t pin) { return value; } - value = gpio_read_pin(index->gpio, index->pin); + value = ald_gpio_read_pin(index->gpio, index->pin); return value; } @@ -233,7 +234,7 @@ void es32f0_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) gpio_initstruct.pupd = GPIO_FLOATING; gpio_initstruct.odos = GPIO_OPEN_DRAIN; } - gpio_init(index->gpio, index->pin, &gpio_initstruct); + ald_gpio_init(index->gpio, index->pin, &gpio_initstruct); } rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint16_t gpio_pin) @@ -360,7 +361,7 @@ rt_err_t es32f0_pin_irq_enable(struct rt_device *device, rt_base_t pin, return RT_ENOSYS; } irqmap = &pin_irq_map[irqindex]; - gpio_exti_init(index->gpio, index->pin, &exti_initstruct); + ald_gpio_exti_init(index->gpio, index->pin, &exti_initstruct); /* Configure GPIO_InitStructure */ gpio_initstruct.mode = GPIO_MODE_INPUT; gpio_initstruct.func = GPIO_FUNC_1; @@ -368,18 +369,18 @@ rt_err_t es32f0_pin_irq_enable(struct rt_device *device, rt_base_t pin, { case PIN_IRQ_MODE_RISING: gpio_initstruct.pupd = GPIO_PUSH_DOWN; - gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_RISING_EDGE, ENABLE); + ald_gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_RISING_EDGE, ENABLE); break; case PIN_IRQ_MODE_FALLING: gpio_initstruct.pupd = GPIO_PUSH_UP; - gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_TRAILING_EDGE, ENABLE); + ald_gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_TRAILING_EDGE, ENABLE); break; case PIN_IRQ_MODE_RISING_FALLING: gpio_initstruct.pupd = GPIO_FLOATING; - gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_BOTH_EDGE, ENABLE); + ald_gpio_exti_interrupt_config(index->pin, EXTI_TRIGGER_BOTH_EDGE, ENABLE); break; } - gpio_init(index->gpio, index->pin, &gpio_initstruct); + ald_gpio_init(index->gpio, index->pin, &gpio_initstruct); NVIC_EnableIRQ(irqmap->irqno); rt_hw_interrupt_enable(level); } @@ -412,7 +413,7 @@ const static struct rt_pin_ops _es32f0_pin_ops = int rt_hw_pin_init(void) { int result; - cmu_perh_clock_config(CMU_PERH_GPIO, ENABLE); + ald_cmu_perh_clock_config(CMU_PERH_GPIO, ENABLE); result = rt_device_pin_register("pin", &_es32f0_pin_ops, RT_NULL); return result; } @@ -439,9 +440,9 @@ rt_inline void pin_irq_hdr(uint16_t GPIO_Pin) void GPIO_EXTI_Callback(uint16_t GPIO_Pin) { - if (gpio_exti_get_flag_status(GPIO_Pin) != RESET) + if (ald_gpio_exti_get_flag_status(GPIO_Pin) != RESET) { - gpio_exti_clear_flag_status(GPIO_Pin); + ald_gpio_exti_clear_flag_status(GPIO_Pin); pin_irq_hdr(GPIO_Pin); } } diff --git a/bsp/es32f0654/drivers/drv_gpio.h b/bsp/essemi/es32f0654/drivers/drv_gpio.h similarity index 100% rename from bsp/es32f0654/drivers/drv_gpio.h rename to bsp/essemi/es32f0654/drivers/drv_gpio.h diff --git a/bsp/es32f0654/drivers/drv_hwtimer.c b/bsp/essemi/es32f0654/drivers/drv_hwtimer.c similarity index 77% rename from bsp/es32f0654/drivers/drv_hwtimer.c rename to bsp/essemi/es32f0654/drivers/drv_hwtimer.c index 6eceab627b..4d7614a323 100644 --- a/bsp/es32f0654/drivers/drv_hwtimer.c +++ b/bsp/essemi/es32f0654/drivers/drv_hwtimer.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-3-19 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -30,12 +31,12 @@ static struct es32f0_hwtimer_dev hwtimer0; void BS16T0_Handler(void) { - timer_clear_flag_status(hwtimer0.hwtimer_periph, TIMER_FLAG_UPDATE); + ald_timer_clear_flag_status(hwtimer0.hwtimer_periph, TIMER_FLAG_UPDATE); rt_device_hwtimer_isr(&hwtimer0.parent); if (HWTIMER_MODE_ONESHOT == hwtimer0.parent.mode) { - timer_base_stop(hwtimer0.hwtimer_periph); + ald_timer_base_stop(hwtimer0.hwtimer_periph); } } #endif @@ -46,15 +47,15 @@ static struct es32f0_hwtimer_dev hwtimer1; void BS16T1_UART2_Handler(void) { /* if BS16T1 it */ - if (timer_get_it_status(hwtimer1.hwtimer_periph, TIMER_IT_UPDATE) && - timer_get_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE)) + if (ald_timer_get_it_status(hwtimer1.hwtimer_periph, TIMER_IT_UPDATE) && + ald_timer_get_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE)) { - timer_clear_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE); + ald_timer_clear_flag_status(hwtimer1.hwtimer_periph, TIMER_FLAG_UPDATE); rt_device_hwtimer_isr(&hwtimer1.parent); if (HWTIMER_MODE_ONESHOT == hwtimer1.parent.mode) { - timer_base_stop(hwtimer1.hwtimer_periph); + ald_timer_base_stop(hwtimer1.hwtimer_periph); } } } @@ -66,15 +67,15 @@ static struct es32f0_hwtimer_dev hwtimer2; void BS16T2_UART3_Handler(void) { /* if BS16T2 it */ - if (timer_get_it_status(hwtimer2.hwtimer_periph, TIMER_IT_UPDATE) && - timer_get_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE)) + if (ald_timer_get_it_status(hwtimer2.hwtimer_periph, TIMER_IT_UPDATE) && + ald_timer_get_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE)) { - timer_clear_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE); + ald_timer_clear_flag_status(hwtimer2.hwtimer_periph, TIMER_FLAG_UPDATE); rt_device_hwtimer_isr(&hwtimer2.parent); if (HWTIMER_MODE_ONESHOT == hwtimer2.parent.mode) { - timer_base_stop(hwtimer2.hwtimer_periph); + ald_timer_base_stop(hwtimer2.hwtimer_periph); } } } @@ -86,15 +87,15 @@ static struct es32f0_hwtimer_dev hwtimer3; void BS16T3_DAC0_Handler(void) { /* if BS16T3 it */ - if (timer_get_it_status(hwtimer3.hwtimer_periph, TIMER_IT_UPDATE) && - timer_get_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE)) + if (ald_timer_get_it_status(hwtimer3.hwtimer_periph, TIMER_IT_UPDATE) && + ald_timer_get_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE)) { - timer_clear_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE); + ald_timer_clear_flag_status(hwtimer3.hwtimer_periph, TIMER_FLAG_UPDATE); rt_device_hwtimer_isr(&hwtimer3.parent); if (HWTIMER_MODE_ONESHOT == hwtimer3.parent.mode) { - timer_base_stop(hwtimer3.hwtimer_periph); + ald_timer_base_stop(hwtimer3.hwtimer_periph); } } } @@ -116,13 +117,13 @@ static void es32f0_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state) if (1 == state) { - timer_base_init(hwtimer->hwtimer_periph); - timer_interrupt_config(hwtimer->hwtimer_periph, TIMER_IT_UPDATE, ENABLE); + ald_timer_base_init(hwtimer->hwtimer_periph); + ald_timer_interrupt_config(hwtimer->hwtimer_periph, TIMER_IT_UPDATE, ENABLE); NVIC_EnableIRQ(hwtimer->IRQn); } - hwtimer->parent.freq = cmu_get_pclk1_clock(); - es32f0_hwtimer_info.maxfreq = cmu_get_pclk1_clock(); - es32f0_hwtimer_info.minfreq = cmu_get_pclk1_clock(); + hwtimer->parent.freq = ald_cmu_get_pclk1_clock(); + es32f0_hwtimer_info.maxfreq = ald_cmu_get_pclk1_clock(); + es32f0_hwtimer_info.minfreq = ald_cmu_get_pclk1_clock(); } static rt_err_t es32f0_hwtimer_start(rt_hwtimer_t *timer, @@ -134,7 +135,7 @@ static rt_err_t es32f0_hwtimer_start(rt_hwtimer_t *timer, RT_ASSERT(hwtimer != RT_NULL); WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt); - timer_base_start(hwtimer->hwtimer_periph); + ald_timer_base_start(hwtimer->hwtimer_periph); return RT_EOK; } @@ -145,7 +146,7 @@ static void es32f0_hwtimer_stop(rt_hwtimer_t *timer) RT_ASSERT(hwtimer != RT_NULL); - timer_base_stop(hwtimer->hwtimer_periph); + ald_timer_base_stop(hwtimer->hwtimer_periph); } static rt_uint32_t es32f0_hwtimer_count_get(rt_hwtimer_t *timer) @@ -174,14 +175,14 @@ static rt_err_t es32f0_hwtimer_control(rt_hwtimer_t *timer, { case HWTIMER_CTRL_FREQ_SET: freq = *(rt_uint32_t *)args; - if (freq != cmu_get_pclk1_clock()) + if (freq != ald_cmu_get_pclk1_clock()) { ret = -RT_ERROR; } break; case HWTIMER_CTRL_STOP: - timer_base_stop(hwtimer->hwtimer_periph); + ald_timer_base_stop(hwtimer->hwtimer_periph); break; default: diff --git a/bsp/es32f0654/drivers/drv_hwtimer.h b/bsp/essemi/es32f0654/drivers/drv_hwtimer.h similarity index 100% rename from bsp/es32f0654/drivers/drv_hwtimer.h rename to bsp/essemi/es32f0654/drivers/drv_hwtimer.h diff --git a/bsp/es32f0654/drivers/drv_i2c.c b/bsp/essemi/es32f0654/drivers/drv_i2c.c similarity index 86% rename from bsp/es32f0654/drivers/drv_i2c.c rename to bsp/essemi/es32f0654/drivers/drv_i2c.c index ce726ae7ad..c40902047f 100644 --- a/bsp/es32f0654/drivers/drv_i2c.c +++ b/bsp/essemi/es32f0654/drivers/drv_i2c.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-01-24 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -45,10 +46,10 @@ static void _i2c_init(void) _h_i2c0.init.general_call = I2C_GENERALCALL_DISABLE; _h_i2c0.init.no_stretch = I2C_NOSTRETCH_ENABLE; - i2c_reset(&_h_i2c0); - i2c_init(&_h_i2c0); + ald_i2c_reset(&_h_i2c0); + ald_i2c_init(&_h_i2c0); /* I2C0_SCL->PB8, I2C0_SDA->PB9 */ - gpio_init(GPIOB, GPIO_PIN_8 | GPIO_PIN_9, &gpio_instruct); + ald_gpio_init(GPIOB, GPIO_PIN_8 | GPIO_PIN_9, &gpio_instruct); #endif #ifdef BSP_USING_I2C1 @@ -61,10 +62,10 @@ static void _i2c_init(void) _h_i2c1.init.general_call = I2C_GENERALCALL_DISABLE; _h_i2c1.init.no_stretch = I2C_NOSTRETCH_ENABLE; - i2c_reset(&_h_i2c1); - i2c_init(&_h_i2c1); + ald_i2c_reset(&_h_i2c1); + ald_i2c_init(&_h_i2c1); /* I2C1_SCL->PB10, I2C1_SDA->PB11 */ - gpio_init(GPIOB, GPIO_PIN_10 | GPIO_PIN_11, &gpio_instruct); + ald_gpio_init(GPIOB, GPIO_PIN_10 | GPIO_PIN_11, &gpio_instruct); #endif } @@ -81,7 +82,7 @@ static rt_size_t es32f0_master_xfer(struct rt_i2c_bus_device *bus, msg = &msgs[i]; if (msg->flags & RT_I2C_RD) { - if (i2c_master_recv(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0) + if (ald_i2c_master_recv(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0) { i2c_dbg("i2c bus write failed,i2c bus stop!\n"); goto out; @@ -89,7 +90,7 @@ static rt_size_t es32f0_master_xfer(struct rt_i2c_bus_device *bus, } else { - if (i2c_master_send(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0) + if (ald_i2c_master_send(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0) { i2c_dbg("i2c bus write failed,i2c bus stop!\n"); goto out; diff --git a/bsp/es32f0654/drivers/drv_i2c.h b/bsp/essemi/es32f0654/drivers/drv_i2c.h similarity index 100% rename from bsp/es32f0654/drivers/drv_i2c.h rename to bsp/essemi/es32f0654/drivers/drv_i2c.h diff --git a/bsp/essemi/es32f0654/drivers/drv_pm.c b/bsp/essemi/es32f0654/drivers/drv_pm.c new file mode 100644 index 0000000000..821d3bc843 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/drv_pm.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-04-08 wangyq the first version + * 2019-11-01 wangyq adapt to the new power management interface + */ + +#include +#include +#include +#include + +#ifdef RT_USING_PM + +static void uart_console_reconfig(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + rt_device_control(rt_console_get_device(), RT_DEVICE_CTRL_CONFIG, &config); +} + +/** + * This function will put ES32F033x into sleep mode. + * + * @param pm pointer to power manage structure + */ +static void sleep(struct rt_pm *pm, uint8_t mode) +{ + switch (mode) + { + case PM_SLEEP_MODE_NONE: + break; + + case PM_SLEEP_MODE_IDLE: + //__WFI(); + break; + + case PM_SLEEP_MODE_LIGHT: + /* Enter SLEEP Mode, Main regulator is ON */ + ald_pmu_stop1_enter(); + break; + + case PM_SLEEP_MODE_DEEP: + /* Enter STOP 2 mode */ + ald_pmu_stop2_enter(); + break; + + case PM_SLEEP_MODE_STANDBY: + /* Enter STANDBY mode */ + ald_pmu_stop2_enter(); + break; + + case PM_SLEEP_MODE_SHUTDOWN: + /* Enter SHUTDOWNN mode */ + ald_pmu_stop2_enter(); + break; + + default: + RT_ASSERT(0); + break; + } +} + +static uint8_t run_speed[PM_RUN_MODE_MAX][2] = +{ + {48, 0}, + {48, 1}, + {24, 2}, + {2, 3}, +}; + +static void run(struct rt_pm *pm, uint8_t mode) +{ + static uint8_t last_mode; + static char *run_str[] = PM_RUN_MODE_NAMES; + extern uint32_t __system_clock; + + if (mode == last_mode) + return; + last_mode = mode; + + ald_cmu_clock_config_default(); + __system_clock = 24000000; + switch (mode) + { + case PM_RUN_MODE_HIGH_SPEED: + case PM_RUN_MODE_NORMAL_SPEED: + /* hosc 12MHz, from hosc/3 pll to 48MHz */ + ald_cmu_pll1_config(CMU_PLL1_INPUT_HRC_6, CMU_PLL1_OUTPUT_48M); + /* MCLK 48MHz */ + ald_cmu_clock_config(CMU_CLOCK_PLL1, 48000000); + break; + case PM_RUN_MODE_MEDIUM_SPEED: + break; + case PM_RUN_MODE_LOW_SPEED: + ald_cmu_clock_config(CMU_CLOCK_HRC, 2000000); + break; + default: + break; + } + + /* 4. 更新外设时钟 */ + uart_console_reconfig(); + /* Re-Configure the Systick time */ + SysTick_Config(ald_cmu_get_sys_clock() / RT_TICK_PER_SECOND); + + rt_kprintf("switch to %s mode, frequency = %d MHz\n", run_str[mode], run_speed[mode][0]); +} + +/** + * This function caculate the PM tick from OS tick + * + * @param tick OS tick + * + * @return the PM tick + */ +static rt_tick_t es32f0_pm_tick_from_os_tick(rt_tick_t tick) +{ + rt_uint32_t freq = 1; + + return (freq * tick / RT_TICK_PER_SECOND); +} + +/** + * This function caculate the OS tick from PM tick + * + * @param tick PM tick + * + * @return the OS tick + */ +static rt_tick_t es32f0_os_tick_from_pm_tick(rt_uint32_t tick) +{ + static rt_uint32_t os_tick_remain = 0; + rt_uint32_t ret, freq; + + freq = 1; + ret = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq; + + os_tick_remain += (tick * RT_TICK_PER_SECOND); + os_tick_remain %= freq; + + return ret; +} + +/** + * This function start the timer of pm + * + * @param pm Pointer to power manage structure + * @param timeout How many OS Ticks that MCU can sleep + */ +static void pm_timer_start(struct rt_pm *pm, rt_uint32_t timeout) +{ + RT_ASSERT(pm != RT_NULL); + RT_ASSERT(timeout > 0); + + if (timeout != RT_TICK_MAX) + { + /* Convert OS Tick to pmtimer timeout value */ + timeout = es32f0_pm_tick_from_os_tick(timeout); + /* MAX 0xFFFF */ + if (timeout > 0xFFFF) + { + timeout = 0xFFFF; + } + } +} + +/** + * This function stop the timer of pm + * + * @param pm Pointer to power manage structure + */ +static void pm_timer_stop(struct rt_pm *pm) +{ + RT_ASSERT(pm != RT_NULL); +} + +/** + * This function calculate how many OS Ticks that MCU have suspended + * + * @param pm Pointer to power manage structure + * + * @return OS Ticks + */ +static rt_tick_t pm_timer_get_tick(struct rt_pm *pm) +{ + rt_uint32_t timer_tick; + + RT_ASSERT(pm != RT_NULL); + + timer_tick = 1; + + return es32f0_os_tick_from_pm_tick(timer_tick); +} + +/** + * This function initialize the power manager + */ +int drv_pm_hw_init(void) +{ + static const struct rt_pm_ops _ops = + { + sleep, + run, + pm_timer_start, + pm_timer_stop, + pm_timer_get_tick + }; + + rt_uint8_t timer_mask = 0; + + /* initialize timer mask */ + timer_mask = 1UL << PM_SLEEP_MODE_DEEP; + + /* initialize system pm module */ + rt_system_pm_init(&_ops, timer_mask, RT_NULL); + + return 0; +} +INIT_BOARD_EXPORT(drv_pm_hw_init); + +#endif diff --git a/bsp/es32f0654/drivers/drv_pm.h b/bsp/essemi/es32f0654/drivers/drv_pm.h similarity index 100% rename from bsp/es32f0654/drivers/drv_pm.h rename to bsp/essemi/es32f0654/drivers/drv_pm.h diff --git a/bsp/es32f0654/drivers/drv_pwm.c b/bsp/essemi/es32f0654/drivers/drv_pwm.c similarity index 79% rename from bsp/es32f0654/drivers/drv_pwm.c rename to bsp/essemi/es32f0654/drivers/drv_pwm.c index 4bb747654d..d324e2bbbb 100644 --- a/bsp/es32f0654/drivers/drv_pwm.c +++ b/bsp/essemi/es32f0654/drivers/drv_pwm.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-03-11 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -18,7 +19,7 @@ static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns) { - uint64_t _arr = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 / + uint64_t _arr = (uint64_t)ald_cmu_get_pclk1_clock() * ns / 1000000000 / (timer_initstruct->init.prescaler + 1); WRITE_REG(timer_initstruct->perh->AR, (uint32_t)_arr); @@ -27,7 +28,7 @@ static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns) static void pwm_set_duty(timer_handle_t *timer_initstruct, timer_channel_t ch, uint32_t ns) { - uint64_t tmp = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 / + uint64_t tmp = (uint64_t)ald_cmu_get_pclk1_clock() * ns / 1000000000 / (timer_initstruct->init.prescaler + 1); if (ch == TIMER_CHANNEL_1) @@ -87,11 +88,11 @@ static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void * switch (cmd) { case PWM_CMD_ENABLE: - timer_pwm_start(timer_initstruct, pwm_channel); + ald_timer_pwm_start(timer_initstruct, pwm_channel); break; case PWM_CMD_DISABLE: - timer_pwm_stop(timer_initstruct, pwm_channel); + ald_timer_pwm_stop(timer_initstruct, pwm_channel); break; case PWM_CMD_SET: @@ -105,13 +106,13 @@ static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void * while (timer_initstruct->init.period > 0xFFFF); /* update prescaler */ WRITE_REG(timer_initstruct->perh->PRES, --timer_initstruct->init.prescaler); - timer_oc_config_channel(timer_initstruct, &tim_ocinit, pwm_channel); + ald_timer_oc_config_channel(timer_initstruct, &tim_ocinit, pwm_channel); pwm_set_duty(timer_initstruct, pwm_channel, cfg->pulse); timer_initstruct->perh->CCEP = _ccep; break; case PWM_CMD_GET: - cfg->pulse = timer_read_capture_value(timer_initstruct, pwm_channel) * 100 / + cfg->pulse = ald_timer_read_capture_value(timer_initstruct, pwm_channel) * 100 / READ_REG(timer_initstruct->perh->AR); break; @@ -143,14 +144,14 @@ int rt_hw_pwm_init(void) static timer_handle_t timer_initstruct0; timer_initstruct0.perh = AD16C4T0; - timer_pwm_init(&timer_initstruct0); + ald_timer_pwm_init(&timer_initstruct0); /* gpio initialization */ gpio_initstructure.func = GPIO_FUNC_2; - gpio_init(GPIOA, GPIO_PIN_8, &gpio_initstructure); - gpio_init(GPIOA, GPIO_PIN_9, &gpio_initstructure); - gpio_init(GPIOA, GPIO_PIN_10, &gpio_initstructure); - gpio_init(GPIOA, GPIO_PIN_11, &gpio_initstructure); + ald_gpio_init(GPIOA, GPIO_PIN_8, &gpio_initstructure); + ald_gpio_init(GPIOA, GPIO_PIN_9, &gpio_initstructure); + ald_gpio_init(GPIOA, GPIO_PIN_10, &gpio_initstructure); + ald_gpio_init(GPIOA, GPIO_PIN_11, &gpio_initstructure); ret = rt_device_pwm_register(&pwm_dev0, "pwm0", &es32f0_pwm_ops, &timer_initstruct0); @@ -161,14 +162,14 @@ int rt_hw_pwm_init(void) static timer_handle_t timer_initstruct1; timer_initstruct1.perh = GP16C4T0; - timer_pwm_init(&timer_initstruct1); + ald_timer_pwm_init(&timer_initstruct1); /* gpio initialization */ gpio_initstructure.func = GPIO_FUNC_2; - gpio_init(GPIOB, GPIO_PIN_6, &gpio_initstructure); - gpio_init(GPIOB, GPIO_PIN_7, &gpio_initstructure); - gpio_init(GPIOB, GPIO_PIN_8, &gpio_initstructure); - gpio_init(GPIOB, GPIO_PIN_9, &gpio_initstructure); + ald_gpio_init(GPIOB, GPIO_PIN_6, &gpio_initstructure); + ald_gpio_init(GPIOB, GPIO_PIN_7, &gpio_initstructure); + ald_gpio_init(GPIOB, GPIO_PIN_8, &gpio_initstructure); + ald_gpio_init(GPIOB, GPIO_PIN_9, &gpio_initstructure); ret = rt_device_pwm_register(&pwm_dev1, "pwm1", &es32f0_pwm_ops, &timer_initstruct1); @@ -179,12 +180,12 @@ int rt_hw_pwm_init(void) static timer_handle_t timer_initstruct2; timer_initstruct2.perh = GP16C2T0; - timer_pwm_init(&timer_initstruct2); + ald_timer_pwm_init(&timer_initstruct2); /* gpio initialization */ gpio_initstructure.func = GPIO_FUNC_2; - gpio_init(GPIOA, GPIO_PIN_0, &gpio_initstructure); - gpio_init(GPIOA, GPIO_PIN_1, &gpio_initstructure); + ald_gpio_init(GPIOA, GPIO_PIN_0, &gpio_initstructure); + ald_gpio_init(GPIOA, GPIO_PIN_1, &gpio_initstructure); ret = rt_device_pwm_register(&pwm_dev2, "pwm2", &es32f0_pwm_ops, &timer_initstruct2); @@ -195,12 +196,12 @@ int rt_hw_pwm_init(void) static timer_handle_t timer_initstruct3; timer_initstruct3.perh = GP16C2T1; - timer_pwm_init(&timer_initstruct3); + ald_timer_pwm_init(&timer_initstruct3); /* gpio initialization */ gpio_initstructure.func = GPIO_FUNC_3; - gpio_init(GPIOC, GPIO_PIN_6, &gpio_initstructure); - gpio_init(GPIOC, GPIO_PIN_7, &gpio_initstructure); + ald_gpio_init(GPIOC, GPIO_PIN_6, &gpio_initstructure); + ald_gpio_init(GPIOC, GPIO_PIN_7, &gpio_initstructure); ret = rt_device_pwm_register(&pwm_dev3, "pwm3", &es32f0_pwm_ops, &timer_initstruct3); diff --git a/bsp/es32f0654/drivers/drv_pwm.h b/bsp/essemi/es32f0654/drivers/drv_pwm.h similarity index 100% rename from bsp/es32f0654/drivers/drv_pwm.h rename to bsp/essemi/es32f0654/drivers/drv_pwm.h diff --git a/bsp/es32f0654/drivers/drv_rtc.c b/bsp/essemi/es32f0654/drivers/drv_rtc.c similarity index 93% rename from bsp/es32f0654/drivers/drv_rtc.c rename to bsp/essemi/es32f0654/drivers/drv_rtc.c index a16d4f179c..32a68c3011 100644 --- a/bsp/es32f0654/drivers/drv_rtc.c +++ b/bsp/essemi/es32f0654/drivers/drv_rtc.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-03-22 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -25,7 +26,7 @@ static void __rtc_init(rtc_init_t *init) assert_param(IS_RTC_OUTPUT_SEL(init->output)); assert_param(IS_RTC_OUTPUT_POLARITY(init->output_polarity)); - rtc_reset(); + ald_rtc_reset(); RTC_UNLOCK(); MODIFY_REG(RTC->CON, RTC_CON_HFM_MSK, init->hour_format << RTC_CON_HFM_POS); @@ -51,7 +52,7 @@ static rt_err_t es32f0_rtc_control(rt_device_t dev, int cmd, void *args) { case RT_DEVICE_CTRL_RTC_GET_TIME: - rtc_get_date_time(&date, &time, RTC_FORMAT_DEC); + ald_rtc_get_date_time(&date, &time, RTC_FORMAT_DEC); time_temp.tm_sec = time.second; time_temp.tm_min = time.minute; time_temp.tm_hour = time.hour; @@ -77,8 +78,8 @@ static rt_err_t es32f0_rtc_control(rt_device_t dev, int cmd, void *args) date.year = time_temp.tm_year + 1900 - 2000; date.month = time_temp.tm_mon + 1; date.day = time_temp.tm_mday; - rtc_set_time(&time, RTC_FORMAT_DEC); - rtc_set_date(&date, RTC_FORMAT_DEC); + ald_rtc_set_time(&time, RTC_FORMAT_DEC); + ald_rtc_set_date(&date, RTC_FORMAT_DEC); /* start RTC */ RTC_UNLOCK(); SET_BIT(RTC->CON, RTC_CON_GO_MSK); @@ -118,7 +119,7 @@ int rt_hw_rtc_init(void) /* enable external 32.768kHz */ CMU_LOSC_ENABLE(); - cmu_losc_safe_config(ENABLE); + ald_cmu_losc_safe_config(ENABLE); /* set default time */ RTC_UNLOCK(); WRITE_REG(RTC->TIME, 0x134251); diff --git a/bsp/es32f0654/drivers/drv_rtc.h b/bsp/essemi/es32f0654/drivers/drv_rtc.h similarity index 100% rename from bsp/es32f0654/drivers/drv_rtc.h rename to bsp/essemi/es32f0654/drivers/drv_rtc.h diff --git a/bsp/es32f0654/drivers/drv_spi.c b/bsp/essemi/es32f0654/drivers/drv_spi.c similarity index 82% rename from bsp/es32f0654/drivers/drv_spi.c rename to bsp/essemi/es32f0654/drivers/drv_spi.c index f79258df3a..a029c6c772 100644 --- a/bsp/es32f0654/drivers/drv_spi.c +++ b/bsp/essemi/es32f0654/drivers/drv_spi.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-01-24 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -80,14 +81,14 @@ rt_err_t spi_configure(struct rt_spi_device *device, } /* config spi clock */ - if (cfg->max_hz >= cmu_get_pclk1_clock() / 2) + if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 2) { /* pclk1 max speed 48MHz, spi master max speed 10MHz */ - if (cmu_get_pclk1_clock() / 2 <= 10000000) + if (ald_cmu_get_pclk1_clock() / 2 <= 10000000) { hspi->init.baud = SPI_BAUD_2; } - else if (cmu_get_pclk1_clock() / 4 <= 10000000) + else if (ald_cmu_get_pclk1_clock() / 4 <= 10000000) { hspi->init.baud = SPI_BAUD_4; } @@ -96,10 +97,10 @@ rt_err_t spi_configure(struct rt_spi_device *device, hspi->init.baud = SPI_BAUD_8; } } - else if (cfg->max_hz >= cmu_get_pclk1_clock() / 4) + else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 4) { /* pclk1 max speed 48MHz, spi master max speed 10MHz */ - if (cmu_get_pclk1_clock() / 4 <= 10000000) + if (ald_cmu_get_pclk1_clock() / 4 <= 10000000) { hspi->init.baud = SPI_BAUD_4; } @@ -108,23 +109,23 @@ rt_err_t spi_configure(struct rt_spi_device *device, hspi->init.baud = SPI_BAUD_8; } } - else if (cfg->max_hz >= cmu_get_pclk1_clock() / 8) + else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 8) { hspi->init.baud = SPI_BAUD_8; } - else if (cfg->max_hz >= cmu_get_pclk1_clock() / 16) + else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 16) { hspi->init.baud = SPI_BAUD_16; } - else if (cfg->max_hz >= cmu_get_pclk1_clock() / 32) + else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 32) { hspi->init.baud = SPI_BAUD_32; } - else if (cfg->max_hz >= cmu_get_pclk1_clock() / 64) + else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 64) { hspi->init.baud = SPI_BAUD_64; } - else if (cfg->max_hz >= cmu_get_pclk1_clock() / 128) + else if (cfg->max_hz >= ald_cmu_get_pclk1_clock() / 128) { hspi->init.baud = SPI_BAUD_128; } @@ -132,7 +133,7 @@ rt_err_t spi_configure(struct rt_spi_device *device, { hspi->init.baud = SPI_BAUD_256; } - spi_init(hspi); + ald_spi_init(hspi); return RT_EOK; } @@ -157,7 +158,7 @@ static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message * { rt_pin_write(cs->pin, 0); } - res = spi_send(hspi, (rt_uint8_t *)message->send_buf, (rt_int32_t)message->length, SPITIMEOUT); + res = ald_spi_send(hspi, (rt_uint8_t *)message->send_buf, (rt_int32_t)message->length, SPITIMEOUT); if (message->cs_release) { rt_pin_write(cs->pin, 1); @@ -173,7 +174,7 @@ static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message * { rt_pin_write(cs->pin, 0); } - res = spi_recv(hspi, (rt_uint8_t *)message->recv_buf, (rt_int32_t)message->length, SPITIMEOUT); + res = ald_spi_recv(hspi, (rt_uint8_t *)message->recv_buf, (rt_int32_t)message->length, SPITIMEOUT); if (message->cs_release) { rt_pin_write(cs->pin, 1); @@ -189,8 +190,8 @@ static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message * { rt_pin_write(cs->pin, 0); } - res = spi_send_recv(hspi, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, - (rt_int32_t)message->length, SPITIMEOUT); + res = ald_spi_send_recv(hspi, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, + (rt_int32_t)message->length, SPITIMEOUT); if (message->cs_release) { rt_pin_write(cs->pin, 1); @@ -230,11 +231,11 @@ int es32f0_spi_register_bus(SPI_TypeDef *SPIx, const char *name) gpio_instruct.flt = GPIO_FILTER_DISABLE; /* PB3->SPI0_SCK, PB5->SPI0_MOSI */ - gpio_init(GPIOB, GPIO_PIN_3 | GPIO_PIN_5, &gpio_instruct); + ald_gpio_init(GPIOB, GPIO_PIN_3 | GPIO_PIN_5, &gpio_instruct); /* PB4->SPI0_MISO */ gpio_instruct.mode = GPIO_MODE_INPUT; - gpio_init(GPIOB, GPIO_PIN_4, &gpio_instruct); + ald_gpio_init(GPIOB, GPIO_PIN_4, &gpio_instruct); } else if (SPIx == SPI1) { @@ -250,11 +251,11 @@ int es32f0_spi_register_bus(SPI_TypeDef *SPIx, const char *name) gpio_instruct.flt = GPIO_FILTER_DISABLE; /* PB13->SPI1_SCK, PB15->SPI1_MOSI */ - gpio_init(GPIOB, GPIO_PIN_13 | GPIO_PIN_15, &gpio_instruct); + ald_gpio_init(GPIOB, GPIO_PIN_13 | GPIO_PIN_15, &gpio_instruct); /* PB14->SPI1_MISO */ gpio_instruct.mode = GPIO_MODE_INPUT; - gpio_init(GPIOB, GPIO_PIN_14, &gpio_instruct); + ald_gpio_init(GPIOB, GPIO_PIN_14, &gpio_instruct); } else { diff --git a/bsp/es32f0654/drivers/drv_spi.h b/bsp/essemi/es32f0654/drivers/drv_spi.h similarity index 100% rename from bsp/es32f0654/drivers/drv_spi.h rename to bsp/essemi/es32f0654/drivers/drv_spi.h diff --git a/bsp/es32f0654/drivers/drv_spiflash.c b/bsp/essemi/es32f0654/drivers/drv_spiflash.c similarity index 92% rename from bsp/es32f0654/drivers/drv_spiflash.c rename to bsp/essemi/es32f0654/drivers/drv_spiflash.c index 0ed0dcc445..c84fe1be78 100644 --- a/bsp/es32f0654/drivers/drv_spiflash.c +++ b/bsp/essemi/es32f0654/drivers/drv_spiflash.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-02-15 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include diff --git a/bsp/es32f0654/drivers/drv_spiflash.h b/bsp/essemi/es32f0654/drivers/drv_spiflash.h similarity index 100% rename from bsp/es32f0654/drivers/drv_spiflash.h rename to bsp/essemi/es32f0654/drivers/drv_spiflash.h diff --git a/bsp/es32f0654/drivers/drv_uart.c b/bsp/essemi/es32f0654/drivers/drv_uart.c similarity index 90% rename from bsp/es32f0654/drivers/drv_uart.c rename to bsp/essemi/es32f0654/drivers/drv_uart.c index 776f1de9ad..4ebd18f826 100644 --- a/bsp/es32f0654/drivers/drv_uart.c +++ b/bsp/essemi/es32f0654/drivers/drv_uart.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2019-01-23 wangyq the first version + * 2019-11-01 wangyq update libraries */ #include @@ -43,38 +44,38 @@ static rt_err_t es32f0x_configure(struct rt_serial_device *serial, struct serial #ifdef BSP_USING_UART0 gpio_initstructure.func = GPIO_FUNC_3; - gpio_init(GPIOB, GPIO_PIN_10, &gpio_initstructure); + ald_gpio_init(GPIOB, GPIO_PIN_10, &gpio_initstructure); /* Initialize rx pin ,the same as txpin except mode */ gpio_initstructure.mode = GPIO_MODE_INPUT; - gpio_init(GPIOB, GPIO_PIN_11, &gpio_initstructure); + ald_gpio_init(GPIOB, GPIO_PIN_11, &gpio_initstructure); #endif /* uart0 gpio init */ #ifdef BSP_USING_UART1 gpio_initstructure.func = GPIO_FUNC_3; - gpio_init(GPIOC, GPIO_PIN_10, &gpio_initstructure); + ald_gpio_init(GPIOC, GPIO_PIN_10, &gpio_initstructure); /* Initialize rx pin ,the same as txpin except mode */ gpio_initstructure.mode = GPIO_MODE_INPUT; - gpio_init(GPIOC, GPIO_PIN_11, &gpio_initstructure); + ald_gpio_init(GPIOC, GPIO_PIN_11, &gpio_initstructure); #endif /* uart1 gpio init */ #ifdef BSP_USING_UART2 gpio_initstructure.func = GPIO_FUNC_5; - gpio_init(GPIOC, GPIO_PIN_12, &gpio_initstructure); + ald_gpio_init(GPIOC, GPIO_PIN_12, &gpio_initstructure); /* Initialize rx pin ,the same as txpin except mode */ gpio_initstructure.mode = GPIO_MODE_INPUT; - gpio_init(GPIOD, GPIO_PIN_2, &gpio_initstructure); + ald_gpio_init(GPIOD, GPIO_PIN_2, &gpio_initstructure); #endif /* uart2 gpio init */ #ifdef BSP_USING_UART3 gpio_initstructure.func = GPIO_FUNC_4; - gpio_init(GPIOC, GPIO_PIN_4, &gpio_initstructure); + ald_gpio_init(GPIOC, GPIO_PIN_4, &gpio_initstructure); /* Initialize rx pin ,the same as txpin except mode */ gpio_initstructure.mode = GPIO_MODE_INPUT; - gpio_init(GPIOC, GPIO_PIN_5, &gpio_initstructure); + ald_gpio_init(GPIOC, GPIO_PIN_5, &gpio_initstructure); #endif /* uart3 gpio init */ uart->huart.init.mode = UART_MODE_UART; @@ -82,7 +83,7 @@ static rt_err_t es32f0x_configure(struct rt_serial_device *serial, struct serial uart->huart.init.word_length = (uart_word_length_t)(cfg->data_bits - 5); uart->huart.init.parity = (uart_parity_t)(cfg->parity == PARITY_EVEN ? UART_PARITY_EVEN : cfg->parity); uart->huart.init.fctl = UART_HW_FLOW_CTL_DISABLE; - uart_init(&uart->huart); + ald_uart_init(&uart->huart); if (cfg->bit_order == BIT_ORDER_MSB) { @@ -103,7 +104,7 @@ static rt_err_t es32f0x_configure(struct rt_serial_device *serial, struct serial } /* enable rx int */ - uart_interrupt_config(&uart->huart, UART_IT_RXRD, ENABLE); + ald_uart_interrupt_config(&uart->huart, UART_IT_RXRD, ENABLE); return RT_EOK; } @@ -120,14 +121,14 @@ static rt_err_t es32f0x_control(struct rt_serial_device *serial, int cmd, void * /* disable rx irq */ NVIC_DisableIRQ(uart->irq); /* disable interrupt */ - uart_interrupt_config(&uart->huart, UART_IT_RXRD, DISABLE); + ald_uart_interrupt_config(&uart->huart, UART_IT_RXRD, DISABLE); break; case RT_DEVICE_CTRL_SET_INT: /* enable rx irq */ NVIC_EnableIRQ(uart->irq); /* enable interrupt */ - uart_interrupt_config(&uart->huart, UART_IT_RXRD, ENABLE); + ald_uart_interrupt_config(&uart->huart, UART_IT_RXRD, ENABLE); break; } diff --git a/bsp/es32f0654/drivers/drv_uart.h b/bsp/essemi/es32f0654/drivers/drv_uart.h similarity index 100% rename from bsp/es32f0654/drivers/drv_uart.h rename to bsp/essemi/es32f0654/drivers/drv_uart.h diff --git a/bsp/es32f0654/drivers/linker_scripts/link.sct b/bsp/essemi/es32f0654/drivers/linker_scripts/link.sct similarity index 100% rename from bsp/es32f0654/drivers/linker_scripts/link.sct rename to bsp/essemi/es32f0654/drivers/linker_scripts/link.sct diff --git a/bsp/es32f0654/figures/ES-PDS-ES32F0654-V1.1.jpg b/bsp/essemi/es32f0654/figures/ES-PDS-ES32F0654-V1.1.jpg similarity index 100% rename from bsp/es32f0654/figures/ES-PDS-ES32F0654-V1.1.jpg rename to bsp/essemi/es32f0654/figures/ES-PDS-ES32F0654-V1.1.jpg diff --git a/bsp/es32f0654/figures/ESLinkII-mini.jpg b/bsp/essemi/es32f0654/figures/ESLinkII-mini.jpg similarity index 100% rename from bsp/es32f0654/figures/ESLinkII-mini.jpg rename to bsp/essemi/es32f0654/figures/ESLinkII-mini.jpg diff --git a/bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Include/es32f065x.h b/bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Include/es32f065x.h new file mode 100644 index 0000000000..645d1ff801 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Include/es32f065x.h @@ -0,0 +1,6631 @@ +/** + ********************************************************************************* + * + * @file es32f065x.h + * @brief ES32F065x Device Head File + * + * @version V1.0 + * @date 07 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ********************************************************************************* + */ + +#ifndef __ES32F0XX_H__ +#define __ES32F0XX_H__ + + +#define __I volatile const /* defines 'read only' permissions */ +#define __O volatile /* defines 'write only' permissions */ +#define __IO volatile /* defines 'read / write' permissions */ + +#define __CHECK_DEVICE_DEFINES +#define __NVIC_PRIO_BITS 2U +#define __CM0_REV 0x0000U +#define __Vendor_SysTickConfig 0U + +typedef enum IRQn { + /* Cortex-M0 processor cxceptions index */ + Reset_IRQn = -15, + NMI_IRQn = -14, + HardFault_IRQn = -13, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + + /* es32f0xx specific interrupt index */ + WWDG_IWDG_IRQn = 0, + LVD_IRQn = 1, + RTC_TSENSE_IRQn = 2, + CRYPT_TRNG_IRQn = 3, + CMU_IRQn = 4, + EXTI0_3_IRQn = 5, + EXTI4_7_IRQn = 6, + EXTI8_11_IRQn = 7, + EXTI12_15_IRQn = 8, + DMA_IRQn = 9, + CAN0_IRQn = 10, + LPTIM0_SPI2_IRQn = 11, + ADC_ACMP_IRQn = 12, + AD16C4T0_BRK_UP_TRIG_COM_IRQn = 13, + AD16C4T0_CC_IRQn = 14, + BS16T0_IRQn = 15, + GP16C2T0_IRQn = 17, + GP16C2T1_IRQn = 18, + BS16T1_UART2_IRQn = 19, + BS16T2_UART3_IRQn = 20, + GP16C4T0_LCD_IRQn = 21, + BS16T3_DAC0_IRQn = 22, + I2C0_IRQn = 23, + I2C1_IRQn = 24, + SPI0_IRQn = 25, + SPI1_IRQn = 26, + UART0_IRQn = 27, + UART1_IRQn = 28, + USART0_IRQn = 29, + USART1_IRQn = 30, + LPUART0_IRQn = 31, +} IRQn_Type; + + +#include +#include "core_cm0.h" + +#if defined (__CC_ARM) +#pragma anon_unions +#endif + +/* Peripheral register define */ + +/****************** Bit definition for SYSCFG_PROT register ************************/ + +#define SYSCFG_PROT_KEY_POSS 1U +#define SYSCFG_PROT_KEY_POSE 31U +#define SYSCFG_PROT_KEY_MSK BITS(SYSCFG_PROT_KEY_POSS,SYSCFG_PROT_KEY_POSE) + +#define SYSCFG_PROT_PROT_POS 0U +#define SYSCFG_PROT_PROT_MSK BIT(SYSCFG_PROT_PROT_POS) + +/****************** Bit definition for SYSCFG_MEMRMP register ************************/ + +#define SYSCFG_MEMRMP_VTOEN_POS 16U +#define SYSCFG_MEMRMP_VTOEN_MSK BIT(SYSCFG_MEMRMP_VTOEN_POS) + +#define SYSCFG_MEMRMP_BFRMPEN_POS 8U +#define SYSCFG_MEMRMP_BFRMPEN_MSK BIT(SYSCFG_MEMRMP_BFRMPEN_POS) + +#define SYSCFG_MEMRMP_BRRMPEN_POS 0U +#define SYSCFG_MEMRMP_BRRMPEN_MSK BIT(SYSCFG_MEMRMP_BRRMPEN_POS) + +/****************** Bit definition for SYSCFG_VTOR register ************************/ + +#define SYSCFG_VTOR_VTO_POSS 0U +#define SYSCFG_VTOR_VTO_POSE 29U +#define SYSCFG_VTOR_VTO_MSK BITS(SYSCFG_VTOR_VTO_POSS,SYSCFG_VTOR_VTO_POSE) + +typedef struct +{ + __IO uint32_t PROT; + __IO uint32_t MEMRMP; + __IO uint32_t VTOR; +} SYSCFG_TypeDef; + +/****************** Bit definition for MSC_FLASHKEY register ************************/ + +#define MSC_FLASHKEY_STATUS_POSS 0U +#define MSC_FLASHKEY_STATUS_POSE 1U +#define MSC_FLASHKEY_STATUS_MSK BITS(MSC_FLASHKEY_STATUS_POSS,MSC_FLASHKEY_STATUS_POSE) + +/****************** Bit definition for MSC_INFOKEY register ************************/ + +#define MSC_INFOKEY_STATUS_POSS 0U +#define MSC_INFOKEY_STATUS_POSE 1U +#define MSC_INFOKEY_STATUS_MSK BITS(MSC_INFOKEY_STATUS_POSS,MSC_INFOKEY_STATUS_POSE) + +/****************** Bit definition for MSC_FLASHADDR register ************************/ + +#define MSC_FLASHADDR_IFREN_POS 18U +#define MSC_FLASHADDR_IFREN_MSK BIT(MSC_FLASHADDR_IFREN_POS) + +#define MSC_FLASHADDR_ADDR_POSS 0U +#define MSC_FLASHADDR_ADDR_POSE 17U +#define MSC_FLASHADDR_ADDR_MSK BITS(MSC_FLASHADDR_ADDR_POSS,MSC_FLASHADDR_ADDR_POSE) + +/****************** Bit definition for MSC_FLASHFIFO register ************************/ + +#define MSC_FLASHFIFO_FIFO_POSS 0U +#define MSC_FLASHFIFO_FIFO_POSE 31U +#define MSC_FLASHFIFO_FIFO_MSK BITS(MSC_FLASHFIFO_FIFO_POSS,MSC_FLASHFIFO_FIFO_POSE) + +/****************** Bit definition for MSC_FLASHDL register ************************/ + +#define MSC_FLASHDL_DATAL_POSS 0U +#define MSC_FLASHDL_DATAL_POSE 31U +#define MSC_FLASHDL_DATAL_MSK BITS(MSC_FLASHDL_DATAL_POSS,MSC_FLASHDL_DATAL_POSE) + +/****************** Bit definition for MSC_FLASHDH register ************************/ + +#define MSC_FLASHDH_DATAH_POSS 0U +#define MSC_FLASHDH_DATAH_POSE 31U +#define MSC_FLASHDH_DATAH_MSK BITS(MSC_FLASHDH_DATAH_POSS,MSC_FLASHDH_DATAH_POSE) + +/****************** Bit definition for MSC_FLASHCMD register ************************/ + +#define MSC_FLASHCMD_CMD_POSS 0U +#define MSC_FLASHCMD_CMD_POSE 31U +#define MSC_FLASHCMD_CMD_MSK BITS(MSC_FLASHCMD_CMD_POSS,MSC_FLASHCMD_CMD_POSE) + +/****************** Bit definition for MSC_FLASHCR register ************************/ + +#define MSC_FLASHCR_FIFOEN_POS 5U +#define MSC_FLASHCR_FIFOEN_MSK BIT(MSC_FLASHCR_FIFOEN_POS) + +#define MSC_FLASHCR_FLASHREQ_POS 4U +#define MSC_FLASHCR_FLASHREQ_MSK BIT(MSC_FLASHCR_FLASHREQ_POS) + +#define MSC_FLASHCR_IAPRST_POS 1U +#define MSC_FLASHCR_IAPRST_MSK BIT(MSC_FLASHCR_IAPRST_POS) + +#define MSC_FLASHCR_IAPEN_POS 0U +#define MSC_FLASHCR_IAPEN_MSK BIT(MSC_FLASHCR_IAPEN_POS) + +/****************** Bit definition for MSC_FLASHSR register ************************/ + +#define MSC_FLASHSR_TIMEOUT_POS 7U +#define MSC_FLASHSR_TIMEOUT_MSK BIT(MSC_FLASHSR_TIMEOUT_POS) + +#define MSC_FLASHSR_PROG_POS 6U +#define MSC_FLASHSR_PROG_MSK BIT(MSC_FLASHSR_PROG_POS) + +#define MSC_FLASHSR_SERA_POS 5U +#define MSC_FLASHSR_SERA_MSK BIT(MSC_FLASHSR_SERA_POS) + +#define MSC_FLASHSR_MASE_POS 4U +#define MSC_FLASHSR_MASE_MSK BIT(MSC_FLASHSR_MASE_POS) + +#define MSC_FLASHSR_ADDR_OV_POS 3U +#define MSC_FLASHSR_ADDR_OV_MSK BIT(MSC_FLASHSR_ADDR_OV_POS) + +#define MSC_FLASHSR_WRP_FLAG_POS 2U +#define MSC_FLASHSR_WRP_FLAG_MSK BIT(MSC_FLASHSR_WRP_FLAG_POS) + +#define MSC_FLASHSR_BUSY_POS 1U +#define MSC_FLASHSR_BUSY_MSK BIT(MSC_FLASHSR_BUSY_POS) + +#define MSC_FLASHSR_FLASHACK_POS 0U +#define MSC_FLASHSR_FLASHACK_MSK BIT(MSC_FLASHSR_FLASHACK_POS) + +/****************** Bit definition for MSC_FLASHPL register ************************/ + +#define MSC_FLASHPL_PROG_LEN_POSS 0U +#define MSC_FLASHPL_PROG_LEN_POSE 15U +#define MSC_FLASHPL_PROG_LEN_MSK BITS(MSC_FLASHPL_PROG_LEN_POSS,MSC_FLASHPL_PROG_LEN_POSE) + +/****************** Bit definition for MSC_MEMWAIT register ************************/ + +#define MSC_MEMWAIT_SRAM_W_POSS 8U +#define MSC_MEMWAIT_SRAM_W_POSE 9U +#define MSC_MEMWAIT_SRAM_W_MSK BITS(MSC_MEMWAIT_SRAM_W_POSS,MSC_MEMWAIT_SRAM_W_POSE) + +#define MSC_MEMWAIT_FLASH_W_POSS 0U +#define MSC_MEMWAIT_FLASH_W_POSE 3U +#define MSC_MEMWAIT_FLASH_W_MSK BITS(MSC_MEMWAIT_FLASH_W_POSS,MSC_MEMWAIT_FLASH_W_POSE) + +typedef struct +{ + __IO uint32_t FLASHKEY; + __IO uint32_t INFOKEY; + __IO uint32_t FLASHADDR; + __O uint32_t FLASHFIFO; + __IO uint32_t FLASHDL; + __IO uint32_t FLASHDH; + __O uint32_t FLASHCMD; + __IO uint32_t FLASHCR; + __I uint32_t FLASHSR; + __IO uint32_t FLASHPL; + __IO uint32_t MEMWAIT; +} MSC_TypeDef; + +/****************** Bit definition for BKPC_PROT register ************************/ + +#define BKPC_PROT_KEY_POSS 1U +#define BKPC_PROT_KEY_POSE 31U +#define BKPC_PROT_KEY_MSK BITS(BKPC_PROT_KEY_POSS,BKPC_PROT_KEY_POSE) + +#define BKPC_PROT_PROT_POS 0U +#define BKPC_PROT_PROT_MSK BIT(BKPC_PROT_PROT_POS) + +/****************** Bit definition for BKPC_CR register ************************/ + +#define BKPC_CR_LDO_VSEL_POSS 24U +#define BKPC_CR_LDO_VSEL_POSE 26U +#define BKPC_CR_LDO_VSEL_MSK BITS(BKPC_CR_LDO_VSEL_POSS,BKPC_CR_LDO_VSEL_POSE) + +#define BKPC_CR_MT_STDB_POS 19U +#define BKPC_CR_MT_STDB_MSK BIT(BKPC_CR_MT_STDB_POS) + +#define BKPC_CR_VR1P5_VSEL_POSS 16U +#define BKPC_CR_VR1P5_VSEL_POSE 18U +#define BKPC_CR_VR1P5_VSEL_MSK BITS(BKPC_CR_VR1P5_VSEL_POSS,BKPC_CR_VR1P5_VSEL_POSE) + +#define BKPC_CR_TC_PWRDWN_POS 13U +#define BKPC_CR_TC_PWRDWN_MSK BIT(BKPC_CR_TC_PWRDWN_POS) + +#define BKPC_CR_WKPOL_POS 12U +#define BKPC_CR_WKPOL_MSK BIT(BKPC_CR_WKPOL_POS) + +#define BKPC_CR_WKPS_POSS 9U +#define BKPC_CR_WKPS_POSE 11U +#define BKPC_CR_WKPS_MSK BITS(BKPC_CR_WKPS_POSS,BKPC_CR_WKPS_POSE) + +#define BKPC_CR_WKPEN_POS 8U +#define BKPC_CR_WKPEN_MSK BIT(BKPC_CR_WKPEN_POS) + +#define BKPC_CR_LRCEN_POS 2U +#define BKPC_CR_LRCEN_MSK BIT(BKPC_CR_LRCEN_POS) + +#define BKPC_CR_LOSMEN_POS 1U +#define BKPC_CR_LOSMEN_MSK BIT(BKPC_CR_LOSMEN_POS) + +#define BKPC_CR_LOSCEN_POS 0U +#define BKPC_CR_LOSCEN_MSK BIT(BKPC_CR_LOSCEN_POS) + +/****************** Bit definition for BKPC_PCCR register ************************/ + +#define BKPC_PCCR_TSENSECS_POSS 4U +#define BKPC_PCCR_TSENSECS_POSE 5U +#define BKPC_PCCR_TSENSECS_MSK BITS(BKPC_PCCR_TSENSECS_POSS,BKPC_PCCR_TSENSECS_POSE) + +#define BKPC_PCCR_RTCCS_POSS 0U +#define BKPC_PCCR_RTCCS_POSE 1U +#define BKPC_PCCR_RTCCS_MSK BITS(BKPC_PCCR_RTCCS_POSS,BKPC_PCCR_RTCCS_POSE) + +/****************** Bit definition for BKPC_PCR register ************************/ + +#define BKPC_PCR_BORS_POSS 1U +#define BKPC_PCR_BORS_POSE 4U +#define BKPC_PCR_BORS_MSK BITS(BKPC_PCR_BORS_POSS,BKPC_PCR_BORS_POSE) + +#define BKPC_PCR_BOREN_POS 0U +#define BKPC_PCR_BOREN_MSK BIT(BKPC_PCR_BOREN_POS) + +typedef struct +{ + __IO uint32_t PROT; + __IO uint32_t CR; + __IO uint32_t PCCR; + __IO uint32_t PCR; +} BKPC_TypeDef; + +/****************** Bit definition for PMU_CR register ************************/ + +#define PMU_CR_MTSTOP_POS 21U +#define PMU_CR_MTSTOP_MSK BIT(PMU_CR_MTSTOP_POS) + +#define PMU_CR_LPSTOP_POS 20U +#define PMU_CR_LPSTOP_MSK BIT(PMU_CR_LPSTOP_POS) + +#define PMU_CR_LPRUN_POS 19U +#define PMU_CR_LPRUN_MSK BIT(PMU_CR_LPRUN_POS) + +#define PMU_CR_LPVS_POSS 16U +#define PMU_CR_LPVS_POSE 18U +#define PMU_CR_LPVS_MSK BITS(PMU_CR_LPVS_POSS,PMU_CR_LPVS_POSE) + +#define PMU_CR_WKPS_POSS 9U +#define PMU_CR_WKPS_POSE 11U +#define PMU_CR_WKPS_MSK BITS(PMU_CR_WKPS_POSS,PMU_CR_WKPS_POSE) + +#define PMU_CR_WKPEN_POS 8U +#define PMU_CR_WKPEN_MSK BIT(PMU_CR_WKPEN_POS) + +#define PMU_CR_CSTANDBYF_POS 3U +#define PMU_CR_CSTANDBYF_MSK BIT(PMU_CR_CSTANDBYF_POS) + +#define PMU_CR_CWUF_POS 2U +#define PMU_CR_CWUF_MSK BIT(PMU_CR_CWUF_POS) + +#define PMU_CR_LPM_POSS 0U +#define PMU_CR_LPM_POSE 1U +#define PMU_CR_LPM_MSK BITS(PMU_CR_LPM_POSS,PMU_CR_LPM_POSE) + +/****************** Bit definition for PMU_SR register ************************/ + +#define PMU_SR_STANDBYF_POS 1U +#define PMU_SR_STANDBYF_MSK BIT(PMU_SR_STANDBYF_POS) + +#define PMU_SR_WUF_POS 0U +#define PMU_SR_WUF_MSK BIT(PMU_SR_WUF_POS) + +/****************** Bit definition for PMU_LVDCR register ************************/ + +#define PMU_LVDCR_LVDO_POS 15U +#define PMU_LVDCR_LVDO_MSK BIT(PMU_LVDCR_LVDO_POS) + +#define PMU_LVDCR_LVDFLT_POS 11U +#define PMU_LVDCR_LVDFLT_MSK BIT(PMU_LVDCR_LVDFLT_POS) + +#define PMU_LVDCR_LVIFS_POSS 8U +#define PMU_LVDCR_LVIFS_POSE 10U +#define PMU_LVDCR_LVIFS_MSK BITS(PMU_LVDCR_LVIFS_POSS,PMU_LVDCR_LVIFS_POSE) + +#define PMU_LVDCR_LVDS_POSS 4U +#define PMU_LVDCR_LVDS_POSE 7U +#define PMU_LVDCR_LVDS_MSK BITS(PMU_LVDCR_LVDS_POSS,PMU_LVDCR_LVDS_POSE) + +#define PMU_LVDCR_LVDCIF_POS 3U +#define PMU_LVDCR_LVDCIF_MSK BIT(PMU_LVDCR_LVDCIF_POS) + +#define PMU_LVDCR_LVDIF_POS 2U +#define PMU_LVDCR_LVDIF_MSK BIT(PMU_LVDCR_LVDIF_POS) + +#define PMU_LVDCR_LVDIE_POS 1U +#define PMU_LVDCR_LVDIE_MSK BIT(PMU_LVDCR_LVDIE_POS) + +#define PMU_LVDCR_LVDEN_POS 0U +#define PMU_LVDCR_LVDEN_MSK BIT(PMU_LVDCR_LVDEN_POS) + +/****************** Bit definition for PMU_PWRCR register ************************/ + +#define PMU_PWRCR_BXCAN_POS 4U +#define PMU_PWRCR_BXCAN_MSK BIT(PMU_PWRCR_BXCAN_POS) + +#define PMU_PWRCR_SRAM_POSS 0U +#define PMU_PWRCR_SRAM_POSE 1U +#define PMU_PWRCR_SRAM_MSK BITS(PMU_PWRCR_SRAM_POSS,PMU_PWRCR_SRAM_POSE) + +/****************** Bit definition for PMU_TWUR register ************************/ + +#define PMU_TWUR_TWU_POSS 0U +#define PMU_TWUR_TWU_POSE 11U +#define PMU_TWUR_TWU_MSK BITS(PMU_TWUR_TWU_POSS,PMU_TWUR_TWU_POSE) + +/****************** Bit definition for PMU_VREFCR register ************************/ + +#define PMU_VREFCR_FLTS_POSS 13U +#define PMU_VREFCR_FLTS_POSE 14U +#define PMU_VREFCR_FLTS_MSK BITS(PMU_VREFCR_FLTS_POSS,PMU_VREFCR_FLTS_POSE) + +#define PMU_VREFCR_CHOPCS_POSS 10U +#define PMU_VREFCR_CHOPCS_POSE 12U +#define PMU_VREFCR_CHOPCS_MSK BITS(PMU_VREFCR_CHOPCS_POSS,PMU_VREFCR_CHOPCS_POSE) + +#define PMU_VREFCR_CHOP1EN_POS 9U +#define PMU_VREFCR_CHOP1EN_MSK BIT(PMU_VREFCR_CHOP1EN_POS) + +#define PMU_VREFCR_CHOPEN_POS 8U +#define PMU_VREFCR_CHOPEN_MSK BIT(PMU_VREFCR_CHOPEN_POS) + +#define PMU_VREFCR_VREFEN_POS 0U +#define PMU_VREFCR_VREFEN_MSK BIT(PMU_VREFCR_VREFEN_POS) + +typedef struct +{ + __IO uint32_t CR; + __I uint32_t SR; + __IO uint32_t LVDCR; + __IO uint32_t PWRCR; + __IO uint32_t TWUR; + __IO uint32_t VREFCR; +} PMU_TypeDef; + +/****************** Bit definition for RMU_CR register ************************/ + +#define RMU_CR_BORVS_POSS 4U +#define RMU_CR_BORVS_POSE 7U +#define RMU_CR_BORVS_MSK BITS(RMU_CR_BORVS_POSS,RMU_CR_BORVS_POSE) + +#define RMU_CR_BORFLT_POSS 1U +#define RMU_CR_BORFLT_POSE 3U +#define RMU_CR_BORFLT_MSK BITS(RMU_CR_BORFLT_POSS,RMU_CR_BORFLT_POSE) + +#define RMU_CR_BOREN_POS 0U +#define RMU_CR_BOREN_MSK BIT(RMU_CR_BOREN_POS) + +/****************** Bit definition for RMU_RSTSR register ************************/ + +#define RMU_RSTSR_CFGERR_POS 16U +#define RMU_RSTSR_CFGERR_MSK BIT(RMU_RSTSR_CFGERR_POS) + +#define RMU_RSTSR_CFG_POS 10U +#define RMU_RSTSR_CFG_MSK BIT(RMU_RSTSR_CFG_POS) + +#define RMU_RSTSR_CPU_POS 9U +#define RMU_RSTSR_CPU_MSK BIT(RMU_RSTSR_CPU_POS) + +#define RMU_RSTSR_MCU_POS 8U +#define RMU_RSTSR_MCU_MSK BIT(RMU_RSTSR_MCU_POS) + +#define RMU_RSTSR_CHIP_POS 7U +#define RMU_RSTSR_CHIP_MSK BIT(RMU_RSTSR_CHIP_POS) + +#define RMU_RSTSR_LOCKUP_POS 6U +#define RMU_RSTSR_LOCKUP_MSK BIT(RMU_RSTSR_LOCKUP_POS) + +#define RMU_RSTSR_WWDT_POS 5U +#define RMU_RSTSR_WWDT_MSK BIT(RMU_RSTSR_WWDT_POS) + +#define RMU_RSTSR_IWDT_POS 4U +#define RMU_RSTSR_IWDT_MSK BIT(RMU_RSTSR_IWDT_POS) + +#define RMU_RSTSR_NMRST_POS 3U +#define RMU_RSTSR_NMRST_MSK BIT(RMU_RSTSR_NMRST_POS) + +#define RMU_RSTSR_BOR_POS 2U +#define RMU_RSTSR_BOR_MSK BIT(RMU_RSTSR_BOR_POS) + +#define RMU_RSTSR_WAKEUP_POS 1U +#define RMU_RSTSR_WAKEUP_MSK BIT(RMU_RSTSR_WAKEUP_POS) + +#define RMU_RSTSR_POR_POS 0U +#define RMU_RSTSR_POR_MSK BIT(RMU_RSTSR_POR_POS) + +/****************** Bit definition for RMU_CRSTSR register ************************/ + +#define RMU_CRSTSR_CFG_POS 10U +#define RMU_CRSTSR_CFG_MSK BIT(RMU_CRSTSR_CFG_POS) + +#define RMU_CRSTSR_CPU_POS 9U +#define RMU_CRSTSR_CPU_MSK BIT(RMU_CRSTSR_CPU_POS) + +#define RMU_CRSTSR_MCU_POS 8U +#define RMU_CRSTSR_MCU_MSK BIT(RMU_CRSTSR_MCU_POS) + +#define RMU_CRSTSR_CHIP_POS 7U +#define RMU_CRSTSR_CHIP_MSK BIT(RMU_CRSTSR_CHIP_POS) + +#define RMU_CRSTSR_LOCKUP_POS 6U +#define RMU_CRSTSR_LOCKUP_MSK BIT(RMU_CRSTSR_LOCKUP_POS) + +#define RMU_CRSTSR_WWDT_POS 5U +#define RMU_CRSTSR_WWDT_MSK BIT(RMU_CRSTSR_WWDT_POS) + +#define RMU_CRSTSR_IWDT_POS 4U +#define RMU_CRSTSR_IWDT_MSK BIT(RMU_CRSTSR_IWDT_POS) + +#define RMU_CRSTSR_NMRST_POS 3U +#define RMU_CRSTSR_NMRST_MSK BIT(RMU_CRSTSR_NMRST_POS) + +#define RMU_CRSTSR_BOR_POS 2U +#define RMU_CRSTSR_BOR_MSK BIT(RMU_CRSTSR_BOR_POS) + +#define RMU_CRSTSR_WAKEUP_POS 1U +#define RMU_CRSTSR_WAKEUP_MSK BIT(RMU_CRSTSR_WAKEUP_POS) + +#define RMU_CRSTSR_POR_POS 0U +#define RMU_CRSTSR_POR_MSK BIT(RMU_CRSTSR_POR_POS) + +/****************** Bit definition for RMU_AHB1RSTR register ************************/ + +#define RMU_AHB1RSTR_PISRST_POS 5U +#define RMU_AHB1RSTR_PISRST_MSK BIT(RMU_AHB1RSTR_PISRST_POS) + +#define RMU_AHB1RSTR_TRNGRST_POS 4U +#define RMU_AHB1RSTR_TRNGRST_MSK BIT(RMU_AHB1RSTR_TRNGRST_POS) + +#define RMU_AHB1RSTR_CRYPTRST_POS 3U +#define RMU_AHB1RSTR_CRYPTRST_MSK BIT(RMU_AHB1RSTR_CRYPTRST_POS) + +#define RMU_AHB1RSTR_CALCRST_POS 2U +#define RMU_AHB1RSTR_CALCRST_MSK BIT(RMU_AHB1RSTR_CALCRST_POS) + +#define RMU_AHB1RSTR_CRCRST_POS 1U +#define RMU_AHB1RSTR_CRCRST_MSK BIT(RMU_AHB1RSTR_CRCRST_POS) + +#define RMU_AHB1RSTR_GPIORST_POS 0U +#define RMU_AHB1RSTR_GPIORST_MSK BIT(RMU_AHB1RSTR_GPIORST_POS) + +/****************** Bit definition for RMU_AHB2RSTR register ************************/ + +#define RMU_AHB2RSTR_CPURST_POS 1U +#define RMU_AHB2RSTR_CPURST_MSK BIT(RMU_AHB2RSTR_CPURST_POS) + +#define RMU_AHB2RSTR_CHIPRST_POS 0U +#define RMU_AHB2RSTR_CHIPRST_MSK BIT(RMU_AHB2RSTR_CHIPRST_POS) + +/****************** Bit definition for RMU_APB1RSTR register ************************/ + +#define RMU_APB1RSTR_CAN0RST_POS 24U +#define RMU_APB1RSTR_CAN0RST_MSK BIT(RMU_APB1RSTR_CAN0RST_POS) + +#define RMU_APB1RSTR_I2C1RST_POS 21U +#define RMU_APB1RSTR_I2C1RST_MSK BIT(RMU_APB1RSTR_I2C1RST_POS) + +#define RMU_APB1RSTR_I2C0RST_POS 20U +#define RMU_APB1RSTR_I2C0RST_MSK BIT(RMU_APB1RSTR_I2C0RST_POS) + +#define RMU_APB1RSTR_SPI2RST_POS 18U +#define RMU_APB1RSTR_SPI2RST_MSK BIT(RMU_APB1RSTR_SPI2RST_POS) + +#define RMU_APB1RSTR_SPI1RST_POS 17U +#define RMU_APB1RSTR_SPI1RST_MSK BIT(RMU_APB1RSTR_SPI1RST_POS) + +#define RMU_APB1RSTR_SPI0RST_POS 16U +#define RMU_APB1RSTR_SPI0RST_MSK BIT(RMU_APB1RSTR_SPI0RST_POS) + +#define RMU_APB1RSTR_USART1RST_POS 13U +#define RMU_APB1RSTR_USART1RST_MSK BIT(RMU_APB1RSTR_USART1RST_POS) + +#define RMU_APB1RSTR_USART0RST_POS 12U +#define RMU_APB1RSTR_USART0RST_MSK BIT(RMU_APB1RSTR_USART0RST_POS) + +#define RMU_APB1RSTR_UART3RST_POS 11U +#define RMU_APB1RSTR_UART3RST_MSK BIT(RMU_APB1RSTR_UART3RST_POS) + +#define RMU_APB1RSTR_UART2RST_POS 10U +#define RMU_APB1RSTR_UART2RST_MSK BIT(RMU_APB1RSTR_UART2RST_POS) + +#define RMU_APB1RSTR_UART1RST_POS 9U +#define RMU_APB1RSTR_UART1RST_MSK BIT(RMU_APB1RSTR_UART1RST_POS) + +#define RMU_APB1RSTR_UART0RST_POS 8U +#define RMU_APB1RSTR_UART0RST_MSK BIT(RMU_APB1RSTR_UART0RST_POS) + +#define RMU_APB1RSTR_TIM7RST_POS 7U +#define RMU_APB1RSTR_TIM7RST_MSK BIT(RMU_APB1RSTR_TIM7RST_POS) + +#define RMU_APB1RSTR_TIM6RST_POS 6U +#define RMU_APB1RSTR_TIM6RST_MSK BIT(RMU_APB1RSTR_TIM6RST_POS) + +#define RMU_APB1RSTR_TIM5RST_POS 5U +#define RMU_APB1RSTR_TIM5RST_MSK BIT(RMU_APB1RSTR_TIM5RST_POS) + +#define RMU_APB1RSTR_TIM4RST_POS 4U +#define RMU_APB1RSTR_TIM4RST_MSK BIT(RMU_APB1RSTR_TIM4RST_POS) + +#define RMU_APB1RSTR_TIM3RST_POS 3U +#define RMU_APB1RSTR_TIM3RST_MSK BIT(RMU_APB1RSTR_TIM3RST_POS) + +#define RMU_APB1RSTR_TIM2RST_POS 2U +#define RMU_APB1RSTR_TIM2RST_MSK BIT(RMU_APB1RSTR_TIM2RST_POS) + +#define RMU_APB1RSTR_TIM1RST_POS 1U +#define RMU_APB1RSTR_TIM1RST_MSK BIT(RMU_APB1RSTR_TIM1RST_POS) + +#define RMU_APB1RSTR_TIM0RST_POS 0U +#define RMU_APB1RSTR_TIM0RST_MSK BIT(RMU_APB1RSTR_TIM0RST_POS) + +/****************** Bit definition for RMU_APB2RSTR register ************************/ + +#define RMU_APB2RSTR_BKPRAMRST_POS 18U +#define RMU_APB2RSTR_BKPRAMRST_MSK BIT(RMU_APB2RSTR_BKPRAMRST_POS) + +#define RMU_APB2RSTR_BKPCRST_POS 17U +#define RMU_APB2RSTR_BKPCRST_MSK BIT(RMU_APB2RSTR_BKPCRST_POS) + +#define RMU_APB2RSTR_TSENSERST_POS 16U +#define RMU_APB2RSTR_TSENSERST_MSK BIT(RMU_APB2RSTR_TSENSERST_POS) + +#define RMU_APB2RSTR_RTCRST_POS 15U +#define RMU_APB2RSTR_RTCRST_MSK BIT(RMU_APB2RSTR_RTCRST_POS) + +#define RMU_APB2RSTR_IWDTRST_POS 14U +#define RMU_APB2RSTR_IWDTRST_MSK BIT(RMU_APB2RSTR_IWDTRST_POS) + +#define RMU_APB2RSTR_LCDRST_POS 13U +#define RMU_APB2RSTR_LCDRST_MSK BIT(RMU_APB2RSTR_LCDRST_POS) + +#define RMU_APB2RSTR_WWDTRST_POS 12U +#define RMU_APB2RSTR_WWDTRST_MSK BIT(RMU_APB2RSTR_WWDTRST_POS) + +#define RMU_APB2RSTR_OPAMPRST_POS 8U +#define RMU_APB2RSTR_OPAMPRST_MSK BIT(RMU_APB2RSTR_OPAMPRST_POS) + +#define RMU_APB2RSTR_ACMP1RST_POS 7U +#define RMU_APB2RSTR_ACMP1RST_MSK BIT(RMU_APB2RSTR_ACMP1RST_POS) + +#define RMU_APB2RSTR_ACMP0RST_POS 6U +#define RMU_APB2RSTR_ACMP0RST_MSK BIT(RMU_APB2RSTR_ACMP0RST_POS) + +#define RMU_APB2RSTR_ADC0RST_POS 4U +#define RMU_APB2RSTR_ADC0RST_MSK BIT(RMU_APB2RSTR_ADC0RST_POS) + +#define RMU_APB2RSTR_LPUART0RST_POS 2U +#define RMU_APB2RSTR_LPUART0RST_MSK BIT(RMU_APB2RSTR_LPUART0RST_POS) + +#define RMU_APB2RSTR_LPTIM0RST_POS 0U +#define RMU_APB2RSTR_LPTIM0RST_MSK BIT(RMU_APB2RSTR_LPTIM0RST_POS) + +typedef struct +{ + __IO uint32_t CR; + uint32_t RESERVED0[3] ; + __I uint32_t RSTSR; + __O uint32_t CRSTSR; + uint32_t RESERVED1[2] ; + __O uint32_t AHB1RSTR; + __O uint32_t AHB2RSTR; + uint32_t RESERVED2[2] ; + __O uint32_t APB1RSTR; + __O uint32_t APB2RSTR; +} RMU_TypeDef; + +/****************** Bit definition for CMU_CSR register ************************/ + +#define CMU_CSR_CFT_RDYN_POS 25U +#define CMU_CSR_CFT_RDYN_MSK BIT(CMU_CSR_CFT_RDYN_POS) + +#define CMU_CSR_CFT_STU_POS 24U +#define CMU_CSR_CFT_STU_MSK BIT(CMU_CSR_CFT_STU_POS) + +#define CMU_CSR_CFT_CMD_POSS 16U +#define CMU_CSR_CFT_CMD_POSE 23U +#define CMU_CSR_CFT_CMD_MSK BITS(CMU_CSR_CFT_CMD_POSS,CMU_CSR_CFT_CMD_POSE) + +#define CMU_CSR_SYS_RDYN_POS 12U +#define CMU_CSR_SYS_RDYN_MSK BIT(CMU_CSR_SYS_RDYN_POS) + +#define CMU_CSR_SYS_STU_POSS 8U +#define CMU_CSR_SYS_STU_POSE 10U +#define CMU_CSR_SYS_STU_MSK BITS(CMU_CSR_SYS_STU_POSS,CMU_CSR_SYS_STU_POSE) + +#define CMU_CSR_SYS_CMD_POSS 0U +#define CMU_CSR_SYS_CMD_POSE 2U +#define CMU_CSR_SYS_CMD_MSK BITS(CMU_CSR_SYS_CMD_POSS,CMU_CSR_SYS_CMD_POSE) + +/****************** Bit definition for CMU_CFGR register ************************/ + +#define CMU_CFGR_HRCFST_POS 25U +#define CMU_CFGR_HRCFST_MSK BIT(CMU_CFGR_HRCFST_POS) + +#define CMU_CFGR_HRCFSW_POS 24U +#define CMU_CFGR_HRCFSW_MSK BIT(CMU_CFGR_HRCFSW_POS) + +#define CMU_CFGR_PCLK2DIV_POSS 20U +#define CMU_CFGR_PCLK2DIV_POSE 23U +#define CMU_CFGR_PCLK2DIV_MSK BITS(CMU_CFGR_PCLK2DIV_POSS,CMU_CFGR_PCLK2DIV_POSE) + +#define CMU_CFGR_PCLK1DIV_POSS 16U +#define CMU_CFGR_PCLK1DIV_POSE 19U +#define CMU_CFGR_PCLK1DIV_MSK BITS(CMU_CFGR_PCLK1DIV_POSS,CMU_CFGR_PCLK1DIV_POSE) + +#define CMU_CFGR_SYSDIV_POSS 12U +#define CMU_CFGR_SYSDIV_POSE 15U +#define CMU_CFGR_SYSDIV_MSK BITS(CMU_CFGR_SYSDIV_POSS,CMU_CFGR_SYSDIV_POSE) + +#define CMU_CFGR_HCLK1DIV_POSS 0U +#define CMU_CFGR_HCLK1DIV_POSE 3U +#define CMU_CFGR_HCLK1DIV_MSK BITS(CMU_CFGR_HCLK1DIV_POSS,CMU_CFGR_HCLK1DIV_POSE) + +/****************** Bit definition for CMU_CLKENR register ************************/ + +#define CMU_CLKENR_PLL2EN_POS 9U +#define CMU_CLKENR_PLL2EN_MSK BIT(CMU_CLKENR_PLL2EN_POS) + +#define CMU_CLKENR_PLL1EN_POS 8U +#define CMU_CLKENR_PLL1EN_MSK BIT(CMU_CLKENR_PLL1EN_POS) + +#define CMU_CLKENR_ULRCEN_POS 4U +#define CMU_CLKENR_ULRCEN_MSK BIT(CMU_CLKENR_ULRCEN_POS) + +#define CMU_CLKENR_LRCEN_POS 3U +#define CMU_CLKENR_LRCEN_MSK BIT(CMU_CLKENR_LRCEN_POS) + +#define CMU_CLKENR_HRCEN_POS 2U +#define CMU_CLKENR_HRCEN_MSK BIT(CMU_CLKENR_HRCEN_POS) + +#define CMU_CLKENR_LOSCEN_POS 1U +#define CMU_CLKENR_LOSCEN_MSK BIT(CMU_CLKENR_LOSCEN_POS) + +#define CMU_CLKENR_HOSCEN_POS 0U +#define CMU_CLKENR_HOSCEN_MSK BIT(CMU_CLKENR_HOSCEN_POS) + +/****************** Bit definition for CMU_CLKSR register ************************/ + +#define CMU_CLKSR_PLL2RDY_POS 25U +#define CMU_CLKSR_PLL2RDY_MSK BIT(CMU_CLKSR_PLL2RDY_POS) + +#define CMU_CLKSR_PLL1RDY_POS 24U +#define CMU_CLKSR_PLL1RDY_MSK BIT(CMU_CLKSR_PLL1RDY_POS) + +#define CMU_CLKSR_LRCRDY_POS 19U +#define CMU_CLKSR_LRCRDY_MSK BIT(CMU_CLKSR_LRCRDY_POS) + +#define CMU_CLKSR_HRCRDY_POS 18U +#define CMU_CLKSR_HRCRDY_MSK BIT(CMU_CLKSR_HRCRDY_POS) + +#define CMU_CLKSR_LOSCRDY_POS 17U +#define CMU_CLKSR_LOSCRDY_MSK BIT(CMU_CLKSR_LOSCRDY_POS) + +#define CMU_CLKSR_HOSCRDY_POS 16U +#define CMU_CLKSR_HOSCRDY_MSK BIT(CMU_CLKSR_HOSCRDY_POS) + +#define CMU_CLKSR_PLL2ACT_POS 9U +#define CMU_CLKSR_PLL2ACT_MSK BIT(CMU_CLKSR_PLL2ACT_POS) + +#define CMU_CLKSR_PLL1ACT_POS 8U +#define CMU_CLKSR_PLL1ACT_MSK BIT(CMU_CLKSR_PLL1ACT_POS) + +#define CMU_CLKSR_ULRCACT_POS 4U +#define CMU_CLKSR_ULRCACT_MSK BIT(CMU_CLKSR_ULRCACT_POS) + +#define CMU_CLKSR_LRCACT_POS 3U +#define CMU_CLKSR_LRCACT_MSK BIT(CMU_CLKSR_LRCACT_POS) + +#define CMU_CLKSR_HRCACT_POS 2U +#define CMU_CLKSR_HRCACT_MSK BIT(CMU_CLKSR_HRCACT_POS) + +#define CMU_CLKSR_LOSCACT_POS 1U +#define CMU_CLKSR_LOSCACT_MSK BIT(CMU_CLKSR_LOSCACT_POS) + +#define CMU_CLKSR_HOSCACT_POS 0U +#define CMU_CLKSR_HOSCACT_MSK BIT(CMU_CLKSR_HOSCACT_POS) + +/****************** Bit definition for CMU_PLLCFG register ************************/ + +#define CMU_PLLCFG_PLL2LCKN_POS 17U +#define CMU_PLLCFG_PLL2LCKN_MSK BIT(CMU_PLLCFG_PLL2LCKN_POS) + +#define CMU_PLLCFG_PLL1LCKN_POS 16U +#define CMU_PLLCFG_PLL1LCKN_MSK BIT(CMU_PLLCFG_PLL1LCKN_POS) + +#define CMU_PLLCFG_PLL2RFS_POSS 8U +#define CMU_PLLCFG_PLL2RFS_POSE 9U +#define CMU_PLLCFG_PLL2RFS_MSK BITS(CMU_PLLCFG_PLL2RFS_POSS,CMU_PLLCFG_PLL2RFS_POSE) + +#define CMU_PLLCFG_PLL1OS_POS 4U +#define CMU_PLLCFG_PLL1OS_MSK BIT(CMU_PLLCFG_PLL1OS_POS) + +#define CMU_PLLCFG_PLL1RFS_POSS 0U +#define CMU_PLLCFG_PLL1RFS_POSE 2U +#define CMU_PLLCFG_PLL1RFS_MSK BITS(CMU_PLLCFG_PLL1RFS_POSS,CMU_PLLCFG_PLL1RFS_POSE) + +/****************** Bit definition for CMU_HOSCCFG register ************************/ + +#define CMU_HOSCCFG_FREQ_POSS 0U +#define CMU_HOSCCFG_FREQ_POSE 4U +#define CMU_HOSCCFG_FREQ_MSK BITS(CMU_HOSCCFG_FREQ_POSS,CMU_HOSCCFG_FREQ_POSE) + +/****************** Bit definition for CMU_HOSMCR register ************************/ + +#define CMU_HOSMCR_NMIE_POS 20U +#define CMU_HOSMCR_NMIE_MSK BIT(CMU_HOSMCR_NMIE_POS) + +#define CMU_HOSMCR_STPIF_POS 19U +#define CMU_HOSMCR_STPIF_MSK BIT(CMU_HOSMCR_STPIF_POS) + +#define CMU_HOSMCR_STRIF_POS 18U +#define CMU_HOSMCR_STRIF_MSK BIT(CMU_HOSMCR_STRIF_POS) + +#define CMU_HOSMCR_STPIE_POS 17U +#define CMU_HOSMCR_STPIE_MSK BIT(CMU_HOSMCR_STPIE_POS) + +#define CMU_HOSMCR_STRIE_POS 16U +#define CMU_HOSMCR_STRIE_MSK BIT(CMU_HOSMCR_STRIE_POS) + +#define CMU_HOSMCR_FRQS_POSS 8U +#define CMU_HOSMCR_FRQS_POSE 10U +#define CMU_HOSMCR_FRQS_MSK BITS(CMU_HOSMCR_FRQS_POSS,CMU_HOSMCR_FRQS_POSE) + +#define CMU_HOSMCR_CLKS_POS 1U +#define CMU_HOSMCR_CLKS_MSK BIT(CMU_HOSMCR_CLKS_POS) + +#define CMU_HOSMCR_EN_POS 0U +#define CMU_HOSMCR_EN_MSK BIT(CMU_HOSMCR_EN_POS) + +/****************** Bit definition for CMU_LOSMCR register ************************/ + +#define CMU_LOSMCR_NMIE_POS 20U +#define CMU_LOSMCR_NMIE_MSK BIT(CMU_LOSMCR_NMIE_POS) + +#define CMU_LOSMCR_STPIF_POS 19U +#define CMU_LOSMCR_STPIF_MSK BIT(CMU_LOSMCR_STPIF_POS) + +#define CMU_LOSMCR_STRIF_POS 18U +#define CMU_LOSMCR_STRIF_MSK BIT(CMU_LOSMCR_STRIF_POS) + +#define CMU_LOSMCR_STPIE_POS 17U +#define CMU_LOSMCR_STPIE_MSK BIT(CMU_LOSMCR_STPIE_POS) + +#define CMU_LOSMCR_STRIE_POS 16U +#define CMU_LOSMCR_STRIE_MSK BIT(CMU_LOSMCR_STRIE_POS) + +#define CMU_LOSMCR_CLKS_POS 1U +#define CMU_LOSMCR_CLKS_MSK BIT(CMU_LOSMCR_CLKS_POS) + +#define CMU_LOSMCR_EN_POS 0U +#define CMU_LOSMCR_EN_MSK BIT(CMU_LOSMCR_EN_POS) + +/****************** Bit definition for CMU_PULMCR register ************************/ + +#define CMU_PULMCR_NMIE_POS 20U +#define CMU_PULMCR_NMIE_MSK BIT(CMU_PULMCR_NMIE_POS) + +#define CMU_PULMCR_ULKIF_POS 19U +#define CMU_PULMCR_ULKIF_MSK BIT(CMU_PULMCR_ULKIF_POS) + +#define CMU_PULMCR_LCKIF_POS 18U +#define CMU_PULMCR_LCKIF_MSK BIT(CMU_PULMCR_LCKIF_POS) + +#define CMU_PULMCR_ULKIE_POS 17U +#define CMU_PULMCR_ULKIE_MSK BIT(CMU_PULMCR_ULKIE_POS) + +#define CMU_PULMCR_LCKIE_POS 16U +#define CMU_PULMCR_LCKIE_MSK BIT(CMU_PULMCR_LCKIE_POS) + +#define CMU_PULMCR_MODE_POSS 8U +#define CMU_PULMCR_MODE_POSE 9U +#define CMU_PULMCR_MODE_MSK BITS(CMU_PULMCR_MODE_POSS,CMU_PULMCR_MODE_POSE) + +#define CMU_PULMCR_CLKS_POS 1U +#define CMU_PULMCR_CLKS_MSK BIT(CMU_PULMCR_CLKS_POS) + +#define CMU_PULMCR_EN_POS 0U +#define CMU_PULMCR_EN_MSK BIT(CMU_PULMCR_EN_POS) + +/****************** Bit definition for CMU_CLKOCR register ************************/ + +#define CMU_CLKOCR_LSCOS_POSS 24U +#define CMU_CLKOCR_LSCOS_POSE 26U +#define CMU_CLKOCR_LSCOS_MSK BITS(CMU_CLKOCR_LSCOS_POSS,CMU_CLKOCR_LSCOS_POSE) + +#define CMU_CLKOCR_LSCOEN_POS 16U +#define CMU_CLKOCR_LSCOEN_MSK BIT(CMU_CLKOCR_LSCOEN_POS) + +#define CMU_CLKOCR_HSCODIV_POSS 12U +#define CMU_CLKOCR_HSCODIV_POSE 14U +#define CMU_CLKOCR_HSCODIV_MSK BITS(CMU_CLKOCR_HSCODIV_POSS,CMU_CLKOCR_HSCODIV_POSE) + +#define CMU_CLKOCR_HSCOS_POSS 8U +#define CMU_CLKOCR_HSCOS_POSE 10U +#define CMU_CLKOCR_HSCOS_MSK BITS(CMU_CLKOCR_HSCOS_POSS,CMU_CLKOCR_HSCOS_POSE) + +#define CMU_CLKOCR_HSCOEN_POS 0U +#define CMU_CLKOCR_HSCOEN_MSK BIT(CMU_CLKOCR_HSCOEN_POS) + +/****************** Bit definition for CMU_BUZZCR register ************************/ + +#define CMU_BUZZCR_DAT_POSS 16U +#define CMU_BUZZCR_DAT_POSE 31U +#define CMU_BUZZCR_DAT_MSK BITS(CMU_BUZZCR_DAT_POSS,CMU_BUZZCR_DAT_POSE) + +#define CMU_BUZZCR_DIV_POSS 8U +#define CMU_BUZZCR_DIV_POSE 10U +#define CMU_BUZZCR_DIV_MSK BITS(CMU_BUZZCR_DIV_POSS,CMU_BUZZCR_DIV_POSE) + +#define CMU_BUZZCR_EN_POS 0U +#define CMU_BUZZCR_EN_MSK BIT(CMU_BUZZCR_EN_POS) + +/****************** Bit definition for CMU_AHB1ENR register ************************/ + +#define CMU_AHB1ENR_PISEN_POS 5U +#define CMU_AHB1ENR_PISEN_MSK BIT(CMU_AHB1ENR_PISEN_POS) + +#define CMU_AHB1ENR_TRNGEN_POS 4U +#define CMU_AHB1ENR_TRNGEN_MSK BIT(CMU_AHB1ENR_TRNGEN_POS) + +#define CMU_AHB1ENR_CRYPTEN_POS 3U +#define CMU_AHB1ENR_CRYPTEN_MSK BIT(CMU_AHB1ENR_CRYPTEN_POS) + +#define CMU_AHB1ENR_CALCEN_POS 2U +#define CMU_AHB1ENR_CALCEN_MSK BIT(CMU_AHB1ENR_CALCEN_POS) + +#define CMU_AHB1ENR_CRCEN_POS 1U +#define CMU_AHB1ENR_CRCEN_MSK BIT(CMU_AHB1ENR_CRCEN_POS) + +#define CMU_AHB1ENR_GPIOEN_POS 0U +#define CMU_AHB1ENR_GPIOEN_MSK BIT(CMU_AHB1ENR_GPIOEN_POS) + +/****************** Bit definition for CMU_APB1ENR register ************************/ + +#define CMU_APB1ENR_CAN0EN_POS 24U +#define CMU_APB1ENR_CAN0EN_MSK BIT(CMU_APB1ENR_CAN0EN_POS) + +#define CMU_APB1ENR_I2C1EN_POS 21U +#define CMU_APB1ENR_I2C1EN_MSK BIT(CMU_APB1ENR_I2C1EN_POS) + +#define CMU_APB1ENR_I2C0EN_POS 20U +#define CMU_APB1ENR_I2C0EN_MSK BIT(CMU_APB1ENR_I2C0EN_POS) + +#define CMU_APB1ENR_SPI2EN_POS 18U +#define CMU_APB1ENR_SPI2EN_MSK BIT(CMU_APB1ENR_SPI2EN_POS) + +#define CMU_APB1ENR_SPI1EN_POS 17U +#define CMU_APB1ENR_SPI1EN_MSK BIT(CMU_APB1ENR_SPI1EN_POS) + +#define CMU_APB1ENR_SPI0EN_POS 16U +#define CMU_APB1ENR_SPI0EN_MSK BIT(CMU_APB1ENR_SPI0EN_POS) + +#define CMU_APB1ENR_USART1EN_POS 13U +#define CMU_APB1ENR_USART1EN_MSK BIT(CMU_APB1ENR_USART1EN_POS) + +#define CMU_APB1ENR_USART0EN_POS 12U +#define CMU_APB1ENR_USART0EN_MSK BIT(CMU_APB1ENR_USART0EN_POS) + +#define CMU_APB1ENR_UART3EN_POS 11U +#define CMU_APB1ENR_UART3EN_MSK BIT(CMU_APB1ENR_UART3EN_POS) + +#define CMU_APB1ENR_UART2EN_POS 10U +#define CMU_APB1ENR_UART2EN_MSK BIT(CMU_APB1ENR_UART2EN_POS) + +#define CMU_APB1ENR_UART1EN_POS 9U +#define CMU_APB1ENR_UART1EN_MSK BIT(CMU_APB1ENR_UART1EN_POS) + +#define CMU_APB1ENR_UART0EN_POS 8U +#define CMU_APB1ENR_UART0EN_MSK BIT(CMU_APB1ENR_UART0EN_POS) + +#define CMU_APB1ENR_TIM7EN_POS 7U +#define CMU_APB1ENR_TIM7EN_MSK BIT(CMU_APB1ENR_TIM7EN_POS) + +#define CMU_APB1ENR_TIM6EN_POS 6U +#define CMU_APB1ENR_TIM6EN_MSK BIT(CMU_APB1ENR_TIM6EN_POS) + +#define CMU_APB1ENR_TIM5EN_POS 5U +#define CMU_APB1ENR_TIM5EN_MSK BIT(CMU_APB1ENR_TIM5EN_POS) + +#define CMU_APB1ENR_TIM4EN_POS 4U +#define CMU_APB1ENR_TIM4EN_MSK BIT(CMU_APB1ENR_TIM4EN_POS) + +#define CMU_APB1ENR_TIM3EN_POS 3U +#define CMU_APB1ENR_TIM3EN_MSK BIT(CMU_APB1ENR_TIM3EN_POS) + +#define CMU_APB1ENR_TIM2EN_POS 2U +#define CMU_APB1ENR_TIM2EN_MSK BIT(CMU_APB1ENR_TIM2EN_POS) + +#define CMU_APB1ENR_TIM1EN_POS 1U +#define CMU_APB1ENR_TIM1EN_MSK BIT(CMU_APB1ENR_TIM1EN_POS) + +#define CMU_APB1ENR_TIM0EN_POS 0U +#define CMU_APB1ENR_TIM0EN_MSK BIT(CMU_APB1ENR_TIM0EN_POS) + +/****************** Bit definition for CMU_APB2ENR register ************************/ + +#define CMU_APB2ENR_DBGCEN_POS 19U +#define CMU_APB2ENR_DBGCEN_MSK BIT(CMU_APB2ENR_DBGCEN_POS) + +#define CMU_APB2ENR_BKPCEN_POS 17U +#define CMU_APB2ENR_BKPCEN_MSK BIT(CMU_APB2ENR_BKPCEN_POS) + +#define CMU_APB2ENR_TSENSEEN_POS 16U +#define CMU_APB2ENR_TSENSEEN_MSK BIT(CMU_APB2ENR_TSENSEEN_POS) + +#define CMU_APB2ENR_RTCEN_POS 15U +#define CMU_APB2ENR_RTCEN_MSK BIT(CMU_APB2ENR_RTCEN_POS) + +#define CMU_APB2ENR_IWDTEN_POS 14U +#define CMU_APB2ENR_IWDTEN_MSK BIT(CMU_APB2ENR_IWDTEN_POS) + +#define CMU_APB2ENR_LCDEN_POS 13U +#define CMU_APB2ENR_LCDEN_MSK BIT(CMU_APB2ENR_LCDEN_POS) + +#define CMU_APB2ENR_WWDTEN_POS 12U +#define CMU_APB2ENR_WWDTEN_MSK BIT(CMU_APB2ENR_WWDTEN_POS) + +#define CMU_APB2ENR_OPAMPEN_POS 8U +#define CMU_APB2ENR_OPAMPEN_MSK BIT(CMU_APB2ENR_OPAMPEN_POS) + +#define CMU_APB2ENR_ACMP1EN_POS 7U +#define CMU_APB2ENR_ACMP1EN_MSK BIT(CMU_APB2ENR_ACMP1EN_POS) + +#define CMU_APB2ENR_ACMP0EN_POS 6U +#define CMU_APB2ENR_ACMP0EN_MSK BIT(CMU_APB2ENR_ACMP0EN_POS) + +#define CMU_APB2ENR_ADC0EN_POS 4U +#define CMU_APB2ENR_ADC0EN_MSK BIT(CMU_APB2ENR_ADC0EN_POS) + +#define CMU_APB2ENR_LPUART0EN_POS 2U +#define CMU_APB2ENR_LPUART0EN_MSK BIT(CMU_APB2ENR_LPUART0EN_POS) + +#define CMU_APB2ENR_LPTIM0EN_POS 0U +#define CMU_APB2ENR_LPTIM0EN_MSK BIT(CMU_APB2ENR_LPTIM0EN_POS) + +/****************** Bit definition for CMU_LPENR register ************************/ + +#define CMU_LPENR_HOSCEN_POS 3U +#define CMU_LPENR_HOSCEN_MSK BIT(CMU_LPENR_HOSCEN_POS) + +#define CMU_LPENR_HRCEN_POS 2U +#define CMU_LPENR_HRCEN_MSK BIT(CMU_LPENR_HRCEN_POS) + +#define CMU_LPENR_LOSCEN_POS 1U +#define CMU_LPENR_LOSCEN_MSK BIT(CMU_LPENR_LOSCEN_POS) + +#define CMU_LPENR_LRCEN_POS 0U +#define CMU_LPENR_LRCEN_MSK BIT(CMU_LPENR_LRCEN_POS) + +/****************** Bit definition for CMU_PERICR register ************************/ + +#define CMU_PERICR_LCD_POSS 16U +#define CMU_PERICR_LCD_POSE 18U +#define CMU_PERICR_LCD_MSK BITS(CMU_PERICR_LCD_POSS,CMU_PERICR_LCD_POSE) + +#define CMU_PERICR_LPUART0_POSS 8U +#define CMU_PERICR_LPUART0_POSE 11U +#define CMU_PERICR_LPUART0_MSK BITS(CMU_PERICR_LPUART0_POSS,CMU_PERICR_LPUART0_POSE) + +#define CMU_PERICR_LPTIM0_POSS 0U +#define CMU_PERICR_LPTIM0_POSE 3U +#define CMU_PERICR_LPTIM0_MSK BITS(CMU_PERICR_LPTIM0_POSS,CMU_PERICR_LPTIM0_POSE) + +/****************** Bit definition for CMU_HRCACR register ************************/ + +#define CMU_HRCACR_IB_POSS 28U +#define CMU_HRCACR_IB_POSE 29U +#define CMU_HRCACR_IB_MSK BITS(CMU_HRCACR_IB_POSS,CMU_HRCACR_IB_POSE) + +#define CMU_HRCACR_CAP_POSS 26U +#define CMU_HRCACR_CAP_POSE 27U +#define CMU_HRCACR_CAP_MSK BITS(CMU_HRCACR_CAP_POSS,CMU_HRCACR_CAP_POSE) + +#define CMU_HRCACR_CAL_POSS 16U +#define CMU_HRCACR_CAL_POSE 25U +#define CMU_HRCACR_CAL_MSK BITS(CMU_HRCACR_CAL_POSS,CMU_HRCACR_CAL_POSE) + +#define CMU_HRCACR_IBSET_POSS 14U +#define CMU_HRCACR_IBSET_POSE 15U +#define CMU_HRCACR_IBSET_MSK BITS(CMU_HRCACR_IBSET_POSS,CMU_HRCACR_IBSET_POSE) + +#define CMU_HRCACR_CAPSET_POSS 12U +#define CMU_HRCACR_CAPSET_POSE 13U +#define CMU_HRCACR_CAPSET_MSK BITS(CMU_HRCACR_CAPSET_POSS,CMU_HRCACR_CAPSET_POSE) + +#define CMU_HRCACR_STA_POSS 9U +#define CMU_HRCACR_STA_POSE 10U +#define CMU_HRCACR_STA_MSK BITS(CMU_HRCACR_STA_POSS,CMU_HRCACR_STA_POSE) + +#define CMU_HRCACR_BUSY_POS 8U +#define CMU_HRCACR_BUSY_MSK BIT(CMU_HRCACR_BUSY_POS) + +#define CMU_HRCACR_WRTRG_POS 7U +#define CMU_HRCACR_WRTRG_MSK BIT(CMU_HRCACR_WRTRG_POS) + +#define CMU_HRCACR_AC_POSS 4U +#define CMU_HRCACR_AC_POSE 6U +#define CMU_HRCACR_AC_MSK BITS(CMU_HRCACR_AC_POSS,CMU_HRCACR_AC_POSE) + +#define CMU_HRCACR_IBS_POS 3U +#define CMU_HRCACR_IBS_MSK BIT(CMU_HRCACR_IBS_POS) + +#define CMU_HRCACR_RFSEL_POS 2U +#define CMU_HRCACR_RFSEL_MSK BIT(CMU_HRCACR_RFSEL_POS) + +#define CMU_HRCACR_FREQ_POS 1U +#define CMU_HRCACR_FREQ_MSK BIT(CMU_HRCACR_FREQ_POS) + +#define CMU_HRCACR_EN_POS 0U +#define CMU_HRCACR_EN_MSK BIT(CMU_HRCACR_EN_POS) + +typedef struct +{ + __O uint32_t CSR; + __IO uint32_t CFGR; + uint32_t RESERVED0[2] ; + __IO uint32_t CLKENR; + __I uint32_t CLKSR; + __IO uint32_t PLLCFG; + __IO uint32_t HOSCCFG; + __IO uint32_t HOSMCR; + __IO uint32_t LOSMCR; + __IO uint32_t PULMCR; + uint32_t RESERVED1 ; + __IO uint32_t CLKOCR; + __IO uint32_t BUZZCR; + uint32_t RESERVED2[2] ; + __IO uint32_t AHB1ENR; + uint32_t RESERVED3[3] ; + __IO uint32_t APB1ENR; + __IO uint32_t APB2ENR; + uint32_t RESERVED4[2] ; + __IO uint32_t LPENR; + uint32_t RESERVED5[7] ; + __IO uint32_t PERICR; + uint32_t RESERVED6[3] ; + __IO uint32_t HRCACR; +} CMU_TypeDef; + +/****************** Bit definition for DMA_STATUS register ************************/ + +#define DMA_STATUS_STATUS_POSS 4U +#define DMA_STATUS_STATUS_POSE 7U +#define DMA_STATUS_STATUS_MSK BITS(DMA_STATUS_STATUS_POSS,DMA_STATUS_STATUS_POSE) + +#define DMA_STATUS_MASTER_ENABLE_POS 0U +#define DMA_STATUS_MASTER_ENABLE_MSK BIT(DMA_STATUS_MASTER_ENABLE_POS) + +/****************** Bit definition for DMA_CFG register ************************/ + +#define DMA_CFG_CHNL_PROT_CTRL_POSS 5U +#define DMA_CFG_CHNL_PROT_CTRL_POSE 7U +#define DMA_CFG_CHNL_PROT_CTRL_MSK BITS(DMA_CFG_CHNL_PROT_CTRL_POSS,DMA_CFG_CHNL_PROT_CTRL_POSE) + +#define DMA_CFG_MASTER_ENABLE_POS 0U +#define DMA_CFG_MASTER_ENABLE_MSK BIT(DMA_CFG_MASTER_ENABLE_POS) + +/****************** Bit definition for DMA_CTRLBASE register ************************/ + +#define DMA_CTRLBASE_CTRL_BASE_PTR_POSS 9U +#define DMA_CTRLBASE_CTRL_BASE_PTR_POSE 31U +#define DMA_CTRLBASE_CTRL_BASE_PTR_MSK BITS(DMA_CTRLBASE_CTRL_BASE_PTR_POSS,DMA_CTRLBASE_CTRL_BASE_PTR_POSE) + +/****************** Bit definition for DMA_ALTCTRLBASE register ************************/ + +#define DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_POSS 0U +#define DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_POSE 31U +#define DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_MSK BITS(DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_POSS,DMA_ALTCTRLBASE_ALT_CTRL_BASE_PTR_POSE) + +/****************** Bit definition for DMA_CHWAITSTATUS register ************************/ + +#define DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_POSS 0U +#define DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_POSE 31U +#define DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_MSK BITS(DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_POSS,DMA_CHWAITSTATUS_DMA_WAITONREQ_STATUS_POSE) + +/****************** Bit definition for DMA_CHSWREQ register ************************/ + +#define DMA_CHSWREQ_CHSWREQ_POSS 0U +#define DMA_CHSWREQ_CHSWREQ_POSE 31U +#define DMA_CHSWREQ_CHSWREQ_MSK BITS(DMA_CHSWREQ_CHSWREQ_POSS,DMA_CHSWREQ_CHSWREQ_POSE) + +/****************** Bit definition for DMA_CHUSEBURSTSET register ************************/ + +#define DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_POSS 0U +#define DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_POSE 31U +#define DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_MSK BITS(DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_POSS,DMA_CHUSEBURSTSET_CHNL_USEBURST_SET_POSE) + +/****************** Bit definition for DMA_CHUSEBURSTCLR register ************************/ + +#define DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_POSS 0U +#define DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_POSE 31U +#define DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_MSK BITS(DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_POSS,DMA_CHUSEBURSTCLR_CHNL_USEBURST_CLR_POSE) + +/****************** Bit definition for DMA_CHREQMASKSET register ************************/ + +#define DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_POSS 0U +#define DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_POSE 31U +#define DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_MSK BITS(DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_POSS,DMA_CHREQMASKSET_CHNL_REQ_MASK_SET_POSE) + +/****************** Bit definition for DMA_CHREQMASKCLR register ************************/ + +#define DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_POSS 0U +#define DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_POSE 31U +#define DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_MSK BITS(DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_POSS,DMA_CHREQMASKCLR_CHNL_REQ_MASK_CLR_POSE) + +/****************** Bit definition for DMA_CHENSET register ************************/ + +#define DMA_CHENSET_CHNL_ENABLE_SET_POSS 0U +#define DMA_CHENSET_CHNL_ENABLE_SET_POSE 31U +#define DMA_CHENSET_CHNL_ENABLE_SET_MSK BITS(DMA_CHENSET_CHNL_ENABLE_SET_POSS,DMA_CHENSET_CHNL_ENABLE_SET_POSE) + +/****************** Bit definition for DMA_CHENCLR register ************************/ + +#define DMA_CHENCLR_CHNL_ENABLE_CLR_POSS 0U +#define DMA_CHENCLR_CHNL_ENABLE_CLR_POSE 31U +#define DMA_CHENCLR_CHNL_ENABLE_CLR_MSK BITS(DMA_CHENCLR_CHNL_ENABLE_CLR_POSS,DMA_CHENCLR_CHNL_ENABLE_CLR_POSE) + +/****************** Bit definition for DMA_CHPRIALTSET register ************************/ + +#define DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_POSS 0U +#define DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_POSE 31U +#define DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_MSK BITS(DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_POSS,DMA_CHPRIALTSET_CHNL_PRI_ALT_SET_POSE) + +/****************** Bit definition for DMA_CHPRIALTCLR register ************************/ + +#define DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_POSS 0U +#define DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_POSE 31U +#define DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_MSK BITS(DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_POSS,DMA_CHPRIALTCLR_CHNL_PRI_ALT_CLR_POSE) + +/****************** Bit definition for DMA_CHPRSET register ************************/ + +#define DMA_CHPRSET_CHNL_PRIORITY_SET_POSS 0U +#define DMA_CHPRSET_CHNL_PRIORITY_SET_POSE 31U +#define DMA_CHPRSET_CHNL_PRIORITY_SET_MSK BITS(DMA_CHPRSET_CHNL_PRIORITY_SET_POSS,DMA_CHPRSET_CHNL_PRIORITY_SET_POSE) + +/****************** Bit definition for DMA_CHPRCLR register ************************/ + +#define DMA_CHPRCLR_CHNL_PRIORITY_CLR_POSS 0U +#define DMA_CHPRCLR_CHNL_PRIORITY_CLR_POSE 31U +#define DMA_CHPRCLR_CHNL_PRIORITY_CLR_MSK BITS(DMA_CHPRCLR_CHNL_PRIORITY_CLR_POSS,DMA_CHPRCLR_CHNL_PRIORITY_CLR_POSE) + +/****************** Bit definition for DMA_ERRCLR register ************************/ + +#define DMA_ERRCLR_ERR_CLR_POS 0U +#define DMA_ERRCLR_ERR_CLR_MSK BIT(DMA_ERRCLR_ERR_CLR_POS) + +/****************** Bit definition for DMA_IFLAG register ************************/ + +#define DMA_IFLAG_DMAERRIF_POS 31U +#define DMA_IFLAG_DMAERRIF_MSK BIT(DMA_IFLAG_DMAERRIF_POS) + +#define DMA_IFLAG_CH5DONEIF_POS 5U +#define DMA_IFLAG_CH5DONEIF_MSK BIT(DMA_IFLAG_CH5DONEIF_POS) + +#define DMA_IFLAG_CH4DONEIF_POS 4U +#define DMA_IFLAG_CH4DONEIF_MSK BIT(DMA_IFLAG_CH4DONEIF_POS) + +#define DMA_IFLAG_CH3DONEIF_POS 3U +#define DMA_IFLAG_CH3DONEIF_MSK BIT(DMA_IFLAG_CH3DONEIF_POS) + +#define DMA_IFLAG_CH2DONEIF_POS 2U +#define DMA_IFLAG_CH2DONEIF_MSK BIT(DMA_IFLAG_CH2DONEIF_POS) + +#define DMA_IFLAG_CH1DONEIF_POS 1U +#define DMA_IFLAG_CH1DONEIF_MSK BIT(DMA_IFLAG_CH1DONEIF_POS) + +#define DMA_IFLAG_CH0DONEIF_POS 0U +#define DMA_IFLAG_CH0DONEIF_MSK BIT(DMA_IFLAG_CH0DONEIF_POS) + +/****************** Bit definition for DMA_ICFR register ************************/ + +#define DMA_ICFR_DMAERRC_POS 31U +#define DMA_ICFR_DMAERRC_MSK BIT(DMA_ICFR_DMAERRC_POS) + +#define DMA_ICFR_CH5DONEC_POS 5U +#define DMA_ICFR_CH5DONEC_MSK BIT(DMA_ICFR_CH5DONEC_POS) + +#define DMA_ICFR_CH4DONEC_POS 4U +#define DMA_ICFR_CH4DONEC_MSK BIT(DMA_ICFR_CH4DONEC_POS) + +#define DMA_ICFR_CH3DONEC_POS 3U +#define DMA_ICFR_CH3DONEC_MSK BIT(DMA_ICFR_CH3DONEC_POS) + +#define DMA_ICFR_CH2DONEC_POS 2U +#define DMA_ICFR_CH2DONEC_MSK BIT(DMA_ICFR_CH2DONEC_POS) + +#define DMA_ICFR_CH1DONEC_POS 1U +#define DMA_ICFR_CH1DONEC_MSK BIT(DMA_ICFR_CH1DONEC_POS) + +#define DMA_ICFR_CH0DONEC_POS 0U +#define DMA_ICFR_CH0DONEC_MSK BIT(DMA_ICFR_CH0DONEC_POS) + +/****************** Bit definition for DMA_IER register ************************/ + +#define DMA_IER_DMAERRIE_POS 31U +#define DMA_IER_DMAERRIE_MSK BIT(DMA_IER_DMAERRIE_POS) + +#define DMA_IER_CH5DONEIE_POS 5U +#define DMA_IER_CH5DONEIE_MSK BIT(DMA_IER_CH5DONEIE_POS) + +#define DMA_IER_CH4DONEIE_POS 4U +#define DMA_IER_CH4DONEIE_MSK BIT(DMA_IER_CH4DONEIE_POS) + +#define DMA_IER_CH3DONEIE_POS 3U +#define DMA_IER_CH3DONEIE_MSK BIT(DMA_IER_CH3DONEIE_POS) + +#define DMA_IER_CH2DONEIE_POS 2U +#define DMA_IER_CH2DONEIE_MSK BIT(DMA_IER_CH2DONEIE_POS) + +#define DMA_IER_CH1DONEIE_POS 1U +#define DMA_IER_CH1DONEIE_MSK BIT(DMA_IER_CH1DONEIE_POS) + +#define DMA_IER_CH0DONEIE_POS 0U +#define DMA_IER_CH0DONEIE_MSK BIT(DMA_IER_CH0DONEIE_POS) + +/****************** Bit definition for DMA_CH0_SELCON register ************************/ + +#define DMA_CH0_SELCON_MSEL_POSS 8U +#define DMA_CH0_SELCON_MSEL_POSE 13U +#define DMA_CH0_SELCON_MSEL_MSK BITS(DMA_CH0_SELCON_MSEL_POSS,DMA_CH0_SELCON_MSEL_POSE) + +#define DMA_CH0_SELCON_MSIGSEL_POSS 0U +#define DMA_CH0_SELCON_MSIGSEL_POSE 3U +#define DMA_CH0_SELCON_MSIGSEL_MSK BITS(DMA_CH0_SELCON_MSIGSEL_POSS,DMA_CH0_SELCON_MSIGSEL_POSE) + +typedef struct +{ + __I uint32_t STATUS; + __IO uint32_t CFG; + __IO uint32_t CTRLBASE; + __I uint32_t ALTCTRLBASE; + __I uint32_t CHWAITSTATUS; + __IO uint32_t CHSWREQ; + __IO uint32_t CHUSEBURSTSET; + __O uint32_t CHUSEBURSTCLR; + __IO uint32_t CHREQMASKSET; + __O uint32_t CHREQMASKCLR; + __IO uint32_t CHENSET; + __O uint32_t CHENCLR; + __IO uint32_t CHPRIALTSET; + __O uint32_t CHPRIALTCLR; + __IO uint32_t CHPRSET; + __O uint32_t CHPRCLR; + uint32_t RESERVED0[3] ; + __IO uint32_t ERRCLR; + uint32_t RESERVED1[1004] ; + __I uint32_t IFLAG; + uint32_t RESERVED2 ; + __O uint32_t ICFR; + __IO uint32_t IER; + uint32_t RESERVED3[60] ; + __IO uint32_t CH_SELCON[6]; +} DMA_TypeDef; + +/****************** Bit definition for PIS_CH0_CON register ************************/ + +#define PIS_CH0_CON_SYNCSEL_POSS 24U +#define PIS_CH0_CON_SYNCSEL_POSE 26U +#define PIS_CH0_CON_SYNCSEL_MSK BITS(PIS_CH0_CON_SYNCSEL_POSS,PIS_CH0_CON_SYNCSEL_POSE) + +#define PIS_CH0_CON_PULCK_POSS 18U +#define PIS_CH0_CON_PULCK_POSE 19U +#define PIS_CH0_CON_PULCK_MSK BITS(PIS_CH0_CON_PULCK_POSS,PIS_CH0_CON_PULCK_POSE) + +#define PIS_CH0_CON_EDGS_POSS 16U +#define PIS_CH0_CON_EDGS_POSE 17U +#define PIS_CH0_CON_EDGS_MSK BITS(PIS_CH0_CON_EDGS_POSS,PIS_CH0_CON_EDGS_POSE) + +#define PIS_CH0_CON_SRCS_POSS 8U +#define PIS_CH0_CON_SRCS_POSE 13U +#define PIS_CH0_CON_SRCS_MSK BITS(PIS_CH0_CON_SRCS_POSS,PIS_CH0_CON_SRCS_POSE) + +#define PIS_CH0_CON_MSIGS_POSS 0U +#define PIS_CH0_CON_MSIGS_POSE 3U +#define PIS_CH0_CON_MSIGS_MSK BITS(PIS_CH0_CON_MSIGS_POSS,PIS_CH0_CON_MSIGS_POSE) + +/****************** Bit definition for PIS_CH_OER register ************************/ + +#define PIS_CH_OER_CH3OE_POS 3U +#define PIS_CH_OER_CH3OE_MSK BIT(PIS_CH_OER_CH3OE_POS) + +#define PIS_CH_OER_CH2OE_POS 2U +#define PIS_CH_OER_CH2OE_MSK BIT(PIS_CH_OER_CH2OE_POS) + +#define PIS_CH_OER_CH1OE_POS 1U +#define PIS_CH_OER_CH1OE_MSK BIT(PIS_CH_OER_CH1OE_POS) + +#define PIS_CH_OER_CH0OE_POS 0U +#define PIS_CH_OER_CH0OE_MSK BIT(PIS_CH_OER_CH0OE_POS) + +/****************** Bit definition for PIS_TAR_CON0 register ************************/ + +#define PIS_TAR_CON0_TIM3_CH2IN_SEL_POS 25U +#define PIS_TAR_CON0_TIM3_CH2IN_SEL_MSK BIT(PIS_TAR_CON0_TIM3_CH2IN_SEL_POS) + +#define PIS_TAR_CON0_TIM3_CH1IN_SEL_POS 24U +#define PIS_TAR_CON0_TIM3_CH1IN_SEL_MSK BIT(PIS_TAR_CON0_TIM3_CH1IN_SEL_POS) + +#define PIS_TAR_CON0_TIM2_CH2IN_SEL_POS 17U +#define PIS_TAR_CON0_TIM2_CH2IN_SEL_MSK BIT(PIS_TAR_CON0_TIM2_CH2IN_SEL_POS) + +#define PIS_TAR_CON0_TIM2_CH1IN_SEL_POS 16U +#define PIS_TAR_CON0_TIM2_CH1IN_SEL_MSK BIT(PIS_TAR_CON0_TIM2_CH1IN_SEL_POS) + +#define PIS_TAR_CON0_TIM0_BRKIN_SEL_POS 4U +#define PIS_TAR_CON0_TIM0_BRKIN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_BRKIN_SEL_POS) + +#define PIS_TAR_CON0_TIM0_CH4IN_SEL_POS 3U +#define PIS_TAR_CON0_TIM0_CH4IN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_CH4IN_SEL_POS) + +#define PIS_TAR_CON0_TIM0_CH3IN_SEL_POS 2U +#define PIS_TAR_CON0_TIM0_CH3IN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_CH3IN_SEL_POS) + +#define PIS_TAR_CON0_TIM0_CH2IN_SEL_POS 1U +#define PIS_TAR_CON0_TIM0_CH2IN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_CH2IN_SEL_POS) + +#define PIS_TAR_CON0_TIM0_CH1IN_SEL_POS 0U +#define PIS_TAR_CON0_TIM0_CH1IN_SEL_MSK BIT(PIS_TAR_CON0_TIM0_CH1IN_SEL_POS) + +/****************** Bit definition for PIS_TAR_CON1 register ************************/ + +#define PIS_TAR_CON1_SPI1_CLK_SEL_POS 15U +#define PIS_TAR_CON1_SPI1_CLK_SEL_MSK BIT(PIS_TAR_CON1_SPI1_CLK_SEL_POS) + +#define PIS_TAR_CON1_SPI1_RX_SEL_POS 14U +#define PIS_TAR_CON1_SPI1_RX_SEL_MSK BIT(PIS_TAR_CON1_SPI1_RX_SEL_POS) + +#define PIS_TAR_CON1_SPI0_CLK_SEL_POS 13U +#define PIS_TAR_CON1_SPI0_CLK_SEL_MSK BIT(PIS_TAR_CON1_SPI0_CLK_SEL_POS) + +#define PIS_TAR_CON1_SPI0_RX_SEL_POS 12U +#define PIS_TAR_CON1_SPI0_RX_SEL_MSK BIT(PIS_TAR_CON1_SPI0_RX_SEL_POS) + +#define PIS_TAR_CON1_LPUART0_RXD_SEL_POS 8U +#define PIS_TAR_CON1_LPUART0_RXD_SEL_MSK BIT(PIS_TAR_CON1_LPUART0_RXD_SEL_POS) + +#define PIS_TAR_CON1_USART1_RXD_SEL_POS 7U +#define PIS_TAR_CON1_USART1_RXD_SEL_MSK BIT(PIS_TAR_CON1_USART1_RXD_SEL_POS) + +#define PIS_TAR_CON1_USART0_RXD_SEL_POS 6U +#define PIS_TAR_CON1_USART0_RXD_SEL_MSK BIT(PIS_TAR_CON1_USART0_RXD_SEL_POS) + +#define PIS_TAR_CON1_UART3_RXD_SEL_POS 3U +#define PIS_TAR_CON1_UART3_RXD_SEL_MSK BIT(PIS_TAR_CON1_UART3_RXD_SEL_POS) + +#define PIS_TAR_CON1_UART2_RXD_SEL_POS 2U +#define PIS_TAR_CON1_UART2_RXD_SEL_MSK BIT(PIS_TAR_CON1_UART2_RXD_SEL_POS) + +#define PIS_TAR_CON1_UART1_RXD_SEL_POS 1U +#define PIS_TAR_CON1_UART1_RXD_SEL_MSK BIT(PIS_TAR_CON1_UART1_RXD_SEL_POS) + +#define PIS_TAR_CON1_UART0_RXD_SEL_POS 0U +#define PIS_TAR_CON1_UART0_RXD_SEL_MSK BIT(PIS_TAR_CON1_UART0_RXD_SEL_POS) + +/****************** Bit definition for PIS_TXMCR register ************************/ + +#define PIS_TXMCR_TXMLVLS_POS 8U +#define PIS_TXMCR_TXMLVLS_MSK BIT(PIS_TXMCR_TXMLVLS_POS) + +#define PIS_TXMCR_TXMSS_POSS 4U +#define PIS_TXMCR_TXMSS_POSE 7U +#define PIS_TXMCR_TXMSS_MSK BITS(PIS_TXMCR_TXMSS_POSS,PIS_TXMCR_TXMSS_POSE) + +#define PIS_TXMCR_TXSIGS_POSS 0U +#define PIS_TXMCR_TXSIGS_POSE 3U +#define PIS_TXMCR_TXSIGS_MSK BITS(PIS_TXMCR_TXSIGS_POSS,PIS_TXMCR_TXSIGS_POSE) + +typedef struct +{ + __IO uint32_t CH_CON[8]; + uint32_t RESERVED0[8] ; + __IO uint32_t CH_OER; + __IO uint32_t TAR_CON0; + __IO uint32_t TAR_CON1; + uint32_t RESERVED1[5] ; + __IO uint32_t UART0_TXMCR; + __IO uint32_t UART1_TXMCR; + __IO uint32_t UART2_TXMCR; + __IO uint32_t UART3_TXMCR; + __IO uint32_t LPUART0_TXMCR; +} PIS_TypeDef; + +/****************** Bit definition for GPIO_DIN register ************************/ + +#define GPIO_DIN_DIN_POSS 0U +#define GPIO_DIN_DIN_POSE 15U +#define GPIO_DIN_DIN_MSK BITS(GPIO_DIN_DIN_POSS,GPIO_DIN_DIN_POSE) + +/****************** Bit definition for GPIO_DOUT register ************************/ + +#define GPIO_DOUT_DOUT_POSS 0U +#define GPIO_DOUT_DOUT_POSE 15U +#define GPIO_DOUT_DOUT_MSK BITS(GPIO_DOUT_DOUT_POSS,GPIO_DOUT_DOUT_POSE) + +/****************** Bit definition for GPIO_BSRR register ************************/ + +#define GPIO_BSRR_BRR_POSS 16U +#define GPIO_BSRR_BRR_POSE 31U +#define GPIO_BSRR_BRR_MSK BITS(GPIO_BSRR_BRR_POSS,GPIO_BSRR_BRR_POSE) + +#define GPIO_BSRR_BSR_POSS 0U +#define GPIO_BSRR_BSR_POSE 15U +#define GPIO_BSRR_BSR_MSK BITS(GPIO_BSRR_BSR_POSS,GPIO_BSRR_BSR_POSE) + +/****************** Bit definition for GPIO_BIR register ************************/ + +#define GPIO_BIR_BIR_POSS 0U +#define GPIO_BIR_BIR_POSE 15U +#define GPIO_BIR_BIR_MSK BITS(GPIO_BIR_BIR_POSS,GPIO_BIR_BIR_POSE) + +/****************** Bit definition for GPIO_MODE register ************************/ + +#define GPIO_MODE_MODE_POSS 0U +#define GPIO_MODE_MODE_POSE 31U +#define GPIO_MODE_MODE_MSK BITS(GPIO_MODE_MODE_POSS,GPIO_MODE_MODE_POSE) + +/****************** Bit definition for GPIO_ODOS register ************************/ + +#define GPIO_ODOS_ODOS_POSS 0U +#define GPIO_ODOS_ODOS_POSE 31U +#define GPIO_ODOS_ODOS_MSK BITS(GPIO_ODOS_ODOS_POSS,GPIO_ODOS_ODOS_POSE) + +/****************** Bit definition for GPIO_PUPD register ************************/ + +#define GPIO_PUPD_PUPD_POSS 0U +#define GPIO_PUPD_PUPD_POSE 31U +#define GPIO_PUPD_PUPD_MSK BITS(GPIO_PUPD_PUPD_POSS,GPIO_PUPD_PUPD_POSE) + +/****************** Bit definition for GPIO_ODRV register ************************/ + +#define GPIO_ODRV_ODRV_POSS 0U +#define GPIO_ODRV_ODRV_POSE 31U +#define GPIO_ODRV_ODRV_MSK BITS(GPIO_ODRV_ODRV_POSS,GPIO_ODRV_ODRV_POSE) + +/****************** Bit definition for GPIO_FLT register ************************/ + +#define GPIO_FLT_FLT_POSS 0U +#define GPIO_FLT_FLT_POSE 15U +#define GPIO_FLT_FLT_MSK BITS(GPIO_FLT_FLT_POSS,GPIO_FLT_FLT_POSE) + +/****************** Bit definition for GPIO_TYPE register ************************/ + +#define GPIO_TYPE_TYPE_POSS 0U +#define GPIO_TYPE_TYPE_POSE 15U +#define GPIO_TYPE_TYPE_MSK BITS(GPIO_TYPE_TYPE_POSS,GPIO_TYPE_TYPE_POSE) + +/****************** Bit definition for GPIO_FUNC0 register ************************/ + +#define GPIO_FUNC0_FSEL_IO7_POSS 28U +#define GPIO_FUNC0_FSEL_IO7_POSE 31U +#define GPIO_FUNC0_FSEL_IO7_MSK BITS(GPIO_FUNC0_FSEL_IO7_POSS,GPIO_FUNC0_FSEL_IO7_POSE) + +#define GPIO_FUNC0_FSEL_IO6_POSS 24U +#define GPIO_FUNC0_FSEL_IO6_POSE 27U +#define GPIO_FUNC0_FSEL_IO6_MSK BITS(GPIO_FUNC0_FSEL_IO6_POSS,GPIO_FUNC0_FSEL_IO6_POSE) + +#define GPIO_FUNC0_FSEL_IO5_POSS 20U +#define GPIO_FUNC0_FSEL_IO5_POSE 23U +#define GPIO_FUNC0_FSEL_IO5_MSK BITS(GPIO_FUNC0_FSEL_IO5_POSS,GPIO_FUNC0_FSEL_IO5_POSE) + +#define GPIO_FUNC0_FSEL_IO4_POSS 16U +#define GPIO_FUNC0_FSEL_IO4_POSE 19U +#define GPIO_FUNC0_FSEL_IO4_MSK BITS(GPIO_FUNC0_FSEL_IO4_POSS,GPIO_FUNC0_FSEL_IO4_POSE) + +#define GPIO_FUNC0_FSEL_IO3_POSS 12U +#define GPIO_FUNC0_FSEL_IO3_POSE 15U +#define GPIO_FUNC0_FSEL_IO3_MSK BITS(GPIO_FUNC0_FSEL_IO3_POSS,GPIO_FUNC0_FSEL_IO3_POSE) + +#define GPIO_FUNC0_FSEL_IO2_POSS 8U +#define GPIO_FUNC0_FSEL_IO2_POSE 11U +#define GPIO_FUNC0_FSEL_IO2_MSK BITS(GPIO_FUNC0_FSEL_IO2_POSS,GPIO_FUNC0_FSEL_IO2_POSE) + +#define GPIO_FUNC0_FSEL_IO1_POSS 4U +#define GPIO_FUNC0_FSEL_IO1_POSE 7U +#define GPIO_FUNC0_FSEL_IO1_MSK BITS(GPIO_FUNC0_FSEL_IO1_POSS,GPIO_FUNC0_FSEL_IO1_POSE) + +#define GPIO_FUNC0_FSEL_IO0_POSS 0U +#define GPIO_FUNC0_FSEL_IO0_POSE 3U +#define GPIO_FUNC0_FSEL_IO0_MSK BITS(GPIO_FUNC0_FSEL_IO0_POSS,GPIO_FUNC0_FSEL_IO0_POSE) + +/****************** Bit definition for GPIO_FUNC1 register ************************/ + +#define GPIO_FUNC1_FSEL_IO15_POSS 28U +#define GPIO_FUNC1_FSEL_IO15_POSE 31U +#define GPIO_FUNC1_FSEL_IO15_MSK BITS(GPIO_FUNC1_FSEL_IO15_POSS,GPIO_FUNC1_FSEL_IO15_POSE) + +#define GPIO_FUNC1_FSEL_IO14_POSS 24U +#define GPIO_FUNC1_FSEL_IO14_POSE 27U +#define GPIO_FUNC1_FSEL_IO14_MSK BITS(GPIO_FUNC1_FSEL_IO14_POSS,GPIO_FUNC1_FSEL_IO14_POSE) + +#define GPIO_FUNC1_FSEL_IO13_POSS 20U +#define GPIO_FUNC1_FSEL_IO13_POSE 23U +#define GPIO_FUNC1_FSEL_IO13_MSK BITS(GPIO_FUNC1_FSEL_IO13_POSS,GPIO_FUNC1_FSEL_IO13_POSE) + +#define GPIO_FUNC1_FSEL_IO12_POSS 16U +#define GPIO_FUNC1_FSEL_IO12_POSE 19U +#define GPIO_FUNC1_FSEL_IO12_MSK BITS(GPIO_FUNC1_FSEL_IO12_POSS,GPIO_FUNC1_FSEL_IO12_POSE) + +#define GPIO_FUNC1_FSEL_IO11_POSS 12U +#define GPIO_FUNC1_FSEL_IO11_POSE 15U +#define GPIO_FUNC1_FSEL_IO11_MSK BITS(GPIO_FUNC1_FSEL_IO11_POSS,GPIO_FUNC1_FSEL_IO11_POSE) + +#define GPIO_FUNC1_FSEL_IO10_POSS 8U +#define GPIO_FUNC1_FSEL_IO10_POSE 11U +#define GPIO_FUNC1_FSEL_IO10_MSK BITS(GPIO_FUNC1_FSEL_IO10_POSS,GPIO_FUNC1_FSEL_IO10_POSE) + +#define GPIO_FUNC1_FSEL_IO9_POSS 4U +#define GPIO_FUNC1_FSEL_IO9_POSE 7U +#define GPIO_FUNC1_FSEL_IO9_MSK BITS(GPIO_FUNC1_FSEL_IO9_POSS,GPIO_FUNC1_FSEL_IO9_POSE) + +#define GPIO_FUNC1_FSEL_IO8_POSS 0U +#define GPIO_FUNC1_FSEL_IO8_POSE 3U +#define GPIO_FUNC1_FSEL_IO8_MSK BITS(GPIO_FUNC1_FSEL_IO8_POSS,GPIO_FUNC1_FSEL_IO8_POSE) + +/****************** Bit definition for GPIO_LOCK register ************************/ + +#define GPIO_LOCK_KEY_POSS 16U +#define GPIO_LOCK_KEY_POSE 31U +#define GPIO_LOCK_KEY_MSK BITS(GPIO_LOCK_KEY_POSS,GPIO_LOCK_KEY_POSE) + +#define GPIO_LOCK_LOCK_POSS 0U +#define GPIO_LOCK_LOCK_POSE 15U +#define GPIO_LOCK_LOCK_MSK BITS(GPIO_LOCK_LOCK_POSS,GPIO_LOCK_LOCK_POSE) + +typedef struct +{ + __I uint32_t DIN; + __IO uint32_t DOUT; + __O uint32_t BSRR; + __O uint32_t BIR; + __IO uint32_t MODE; + __IO uint32_t ODOS; + __IO uint32_t PUPD; + __IO uint32_t ODRV; + __IO uint32_t FLT; + __IO uint32_t TYPE; + __IO uint32_t FUNC0; + __IO uint32_t FUNC1; + __IO uint32_t LOCK; +} GPIO_TypeDef; + +/****************** Bit definition for GPIO_EXTIRER register ************************/ + +#define GPIO_EXTIRER_EXTIRER_POSS 0U +#define GPIO_EXTIRER_EXTIRER_POSE 15U +#define GPIO_EXTIRER_EXTIRER_MSK BITS(GPIO_EXTIRER_EXTIRER_POSS,GPIO_EXTIRER_EXTIRER_POSE) + +/****************** Bit definition for GPIO_EXTIFER register ************************/ + +#define GPIO_EXTIFER_EXTIFER_POSS 0U +#define GPIO_EXTIFER_EXTIFER_POSE 15U +#define GPIO_EXTIFER_EXTIFER_MSK BITS(GPIO_EXTIFER_EXTIFER_POSS,GPIO_EXTIFER_EXTIFER_POSE) + +/****************** Bit definition for GPIO_EXTIEN register ************************/ + +#define GPIO_EXTIEN_EXTIEN_POSS 0U +#define GPIO_EXTIEN_EXTIEN_POSE 15U +#define GPIO_EXTIEN_EXTIEN_MSK BITS(GPIO_EXTIEN_EXTIEN_POSS,GPIO_EXTIEN_EXTIEN_POSE) + +/****************** Bit definition for GPIO_EXTIFLAG register ************************/ + +#define GPIO_EXTIFLAG_EXTIFLAG_POSS 0U +#define GPIO_EXTIFLAG_EXTIFLAG_POSE 15U +#define GPIO_EXTIFLAG_EXTIFLAG_MSK BITS(GPIO_EXTIFLAG_EXTIFLAG_POSS,GPIO_EXTIFLAG_EXTIFLAG_POSE) + +/****************** Bit definition for GPIO_EXTISFR register ************************/ + +#define GPIO_EXTISFR_EXTISFR_POSS 0U +#define GPIO_EXTISFR_EXTISFR_POSE 15U +#define GPIO_EXTISFR_EXTISFR_MSK BITS(GPIO_EXTISFR_EXTISFR_POSS,GPIO_EXTISFR_EXTISFR_POSE) + +/****************** Bit definition for GPIO_EXTICFR register ************************/ + +#define GPIO_EXTICFR_EXTICFR_POSS 0U +#define GPIO_EXTICFR_EXTICFR_POSE 15U +#define GPIO_EXTICFR_EXTICFR_MSK BITS(GPIO_EXTICFR_EXTICFR_POSS,GPIO_EXTICFR_EXTICFR_POSE) + +/****************** Bit definition for GPIO_EXTIPSR0 register ************************/ + +#define GPIO_EXTIPSR0_EXTIS7_POSS 28U +#define GPIO_EXTIPSR0_EXTIS7_POSE 30U +#define GPIO_EXTIPSR0_EXTIS7_MSK BITS(GPIO_EXTIPSR0_EXTIS7_POSS,GPIO_EXTIPSR0_EXTIS7_POSE) + +#define GPIO_EXTIPSR0_EXTIS6_POSS 24U +#define GPIO_EXTIPSR0_EXTIS6_POSE 26U +#define GPIO_EXTIPSR0_EXTIS6_MSK BITS(GPIO_EXTIPSR0_EXTIS6_POSS,GPIO_EXTIPSR0_EXTIS6_POSE) + +#define GPIO_EXTIPSR0_EXTIS5_POSS 20U +#define GPIO_EXTIPSR0_EXTIS5_POSE 22U +#define GPIO_EXTIPSR0_EXTIS5_MSK BITS(GPIO_EXTIPSR0_EXTIS5_POSS,GPIO_EXTIPSR0_EXTIS5_POSE) + +#define GPIO_EXTIPSR0_EXTIS4_POSS 16U +#define GPIO_EXTIPSR0_EXTIS4_POSE 18U +#define GPIO_EXTIPSR0_EXTIS4_MSK BITS(GPIO_EXTIPSR0_EXTIS4_POSS,GPIO_EXTIPSR0_EXTIS4_POSE) + +#define GPIO_EXTIPSR0_EXTIS3_POSS 12U +#define GPIO_EXTIPSR0_EXTIS3_POSE 14U +#define GPIO_EXTIPSR0_EXTIS3_MSK BITS(GPIO_EXTIPSR0_EXTIS3_POSS,GPIO_EXTIPSR0_EXTIS3_POSE) + +#define GPIO_EXTIPSR0_EXTIS2_POSS 8U +#define GPIO_EXTIPSR0_EXTIS2_POSE 10U +#define GPIO_EXTIPSR0_EXTIS2_MSK BITS(GPIO_EXTIPSR0_EXTIS2_POSS,GPIO_EXTIPSR0_EXTIS2_POSE) + +#define GPIO_EXTIPSR0_EXTIS1_POSS 4U +#define GPIO_EXTIPSR0_EXTIS1_POSE 6U +#define GPIO_EXTIPSR0_EXTIS1_MSK BITS(GPIO_EXTIPSR0_EXTIS1_POSS,GPIO_EXTIPSR0_EXTIS1_POSE) + +#define GPIO_EXTIPSR0_EXTIS0_POSS 0U +#define GPIO_EXTIPSR0_EXTIS0_POSE 2U +#define GPIO_EXTIPSR0_EXTIS0_MSK BITS(GPIO_EXTIPSR0_EXTIS0_POSS,GPIO_EXTIPSR0_EXTIS0_POSE) + +/****************** Bit definition for GPIO_EXTIPSR1 register ************************/ + +#define GPIO_EXTIPSR1_EXTIS15_POSS 28U +#define GPIO_EXTIPSR1_EXTIS15_POSE 30U +#define GPIO_EXTIPSR1_EXTIS15_MSK BITS(GPIO_EXTIPSR1_EXTIS15_POSS,GPIO_EXTIPSR1_EXTIS15_POSE) + +#define GPIO_EXTIPSR1_EXTIS14_POSS 24U +#define GPIO_EXTIPSR1_EXTIS14_POSE 26U +#define GPIO_EXTIPSR1_EXTIS14_MSK BITS(GPIO_EXTIPSR1_EXTIS14_POSS,GPIO_EXTIPSR1_EXTIS14_POSE) + +#define GPIO_EXTIPSR1_EXTIS13_POSS 20U +#define GPIO_EXTIPSR1_EXTIS13_POSE 22U +#define GPIO_EXTIPSR1_EXTIS13_MSK BITS(GPIO_EXTIPSR1_EXTIS13_POSS,GPIO_EXTIPSR1_EXTIS13_POSE) + +#define GPIO_EXTIPSR1_EXTIS12_POSS 16U +#define GPIO_EXTIPSR1_EXTIS12_POSE 18U +#define GPIO_EXTIPSR1_EXTIS12_MSK BITS(GPIO_EXTIPSR1_EXTIS12_POSS,GPIO_EXTIPSR1_EXTIS12_POSE) + +#define GPIO_EXTIPSR1_EXTIS11_POSS 12U +#define GPIO_EXTIPSR1_EXTIS11_POSE 14U +#define GPIO_EXTIPSR1_EXTIS11_MSK BITS(GPIO_EXTIPSR1_EXTIS11_POSS,GPIO_EXTIPSR1_EXTIS11_POSE) + +#define GPIO_EXTIPSR1_EXTIS10_POSS 8U +#define GPIO_EXTIPSR1_EXTIS10_POSE 10U +#define GPIO_EXTIPSR1_EXTIS10_MSK BITS(GPIO_EXTIPSR1_EXTIS10_POSS,GPIO_EXTIPSR1_EXTIS10_POSE) + +#define GPIO_EXTIPSR1_EXTIS9_POSS 4U +#define GPIO_EXTIPSR1_EXTIS9_POSE 6U +#define GPIO_EXTIPSR1_EXTIS9_MSK BITS(GPIO_EXTIPSR1_EXTIS9_POSS,GPIO_EXTIPSR1_EXTIS9_POSE) + +#define GPIO_EXTIPSR1_EXTIS8_POSS 0U +#define GPIO_EXTIPSR1_EXTIS8_POSE 2U +#define GPIO_EXTIPSR1_EXTIS8_MSK BITS(GPIO_EXTIPSR1_EXTIS8_POSS,GPIO_EXTIPSR1_EXTIS8_POSE) + +/****************** Bit definition for GPIO_EXTIFLTCR register ************************/ + +#define GPIO_EXTIFLTCR_FLTCKS_POSS 24U +#define GPIO_EXTIFLTCR_FLTCKS_POSE 25U +#define GPIO_EXTIFLTCR_FLTCKS_MSK BITS(GPIO_EXTIFLTCR_FLTCKS_POSS,GPIO_EXTIFLTCR_FLTCKS_POSE) + +#define GPIO_EXTIFLTCR_FLTSEL_POSS 16U +#define GPIO_EXTIFLTCR_FLTSEL_POSE 23U +#define GPIO_EXTIFLTCR_FLTSEL_MSK BITS(GPIO_EXTIFLTCR_FLTSEL_POSS,GPIO_EXTIFLTCR_FLTSEL_POSE) + +#define GPIO_EXTIFLTCR_FLTEN_POSS 0U +#define GPIO_EXTIFLTCR_FLTEN_POSE 15U +#define GPIO_EXTIFLTCR_FLTEN_MSK BITS(GPIO_EXTIFLTCR_FLTEN_POSS,GPIO_EXTIFLTCR_FLTEN_POSE) + +typedef struct +{ + __IO uint32_t EXTIRER; + uint32_t RESERVED0 ; + __IO uint32_t EXTIFER; + uint32_t RESERVED1 ; + __IO uint32_t EXTIEN; + uint32_t RESERVED2 ; + __I uint32_t EXTIFLAG; + uint32_t RESERVED3 ; + __O uint32_t EXTISFR; + uint32_t RESERVED4 ; + __O uint32_t EXTICFR; + uint32_t RESERVED5 ; + __IO uint32_t EXTIPSR0; + __IO uint32_t EXTIPSR1; + uint32_t RESERVED6[2] ; + __IO uint32_t EXTIFLTCR; +} EXTI_TypeDef; + +/****************** Bit definition for RTC_WPR register ************************/ + +#define RTC_WPR_WP_POS 0U +#define RTC_WPR_WP_MSK BIT(RTC_WPR_WP_POS) + +/****************** Bit definition for RTC_CON register ************************/ + +#define RTC_CON_SSEC_POS 25U +#define RTC_CON_SSEC_MSK BIT(RTC_CON_SSEC_POS) + +#define RTC_CON_BUSY_POS 24U +#define RTC_CON_BUSY_MSK BIT(RTC_CON_BUSY_POS) + +#define RTC_CON_POL_POS 22U +#define RTC_CON_POL_MSK BIT(RTC_CON_POL_POS) + +#define RTC_CON_EOS_POSS 20U +#define RTC_CON_EOS_POSE 21U +#define RTC_CON_EOS_MSK BITS(RTC_CON_EOS_POSS,RTC_CON_EOS_POSE) + +#define RTC_CON_CKOS_POSS 17U +#define RTC_CON_CKOS_POSE 19U +#define RTC_CON_CKOS_MSK BITS(RTC_CON_CKOS_POSS,RTC_CON_CKOS_POSE) + +#define RTC_CON_CKOE_POS 16U +#define RTC_CON_CKOE_MSK BIT(RTC_CON_CKOE_POS) + +#define RTC_CON_WUCKS_POSS 13U +#define RTC_CON_WUCKS_POSE 15U +#define RTC_CON_WUCKS_MSK BITS(RTC_CON_WUCKS_POSS,RTC_CON_WUCKS_POSE) + +#define RTC_CON_WUTE_POS 12U +#define RTC_CON_WUTE_MSK BIT(RTC_CON_WUTE_POS) + +#define RTC_CON_DSTS_POS 10U +#define RTC_CON_DSTS_MSK BIT(RTC_CON_DSTS_POS) + +#define RTC_CON_SUB1H_POS 9U +#define RTC_CON_SUB1H_MSK BIT(RTC_CON_SUB1H_POS) + +#define RTC_CON_ADD1H_POS 8U +#define RTC_CON_ADD1H_MSK BIT(RTC_CON_ADD1H_POS) + +#define RTC_CON_TSPIN_POS 7U +#define RTC_CON_TSPIN_MSK BIT(RTC_CON_TSPIN_POS) + +#define RTC_CON_TSSEL_POS 6U +#define RTC_CON_TSSEL_MSK BIT(RTC_CON_TSSEL_POS) + +#define RTC_CON_TSEN_POS 5U +#define RTC_CON_TSEN_MSK BIT(RTC_CON_TSEN_POS) + +#define RTC_CON_SHDBP_POS 4U +#define RTC_CON_SHDBP_MSK BIT(RTC_CON_SHDBP_POS) + +#define RTC_CON_HFM_POS 3U +#define RTC_CON_HFM_MSK BIT(RTC_CON_HFM_POS) + +#define RTC_CON_ALMBEN_POS 2U +#define RTC_CON_ALMBEN_MSK BIT(RTC_CON_ALMBEN_POS) + +#define RTC_CON_ALMAEN_POS 1U +#define RTC_CON_ALMAEN_MSK BIT(RTC_CON_ALMAEN_POS) + +#define RTC_CON_GO_POS 0U +#define RTC_CON_GO_MSK BIT(RTC_CON_GO_POS) + +/****************** Bit definition for RTC_PSR register ************************/ + +#define RTC_PSR_APRS_POSS 16U +#define RTC_PSR_APRS_POSE 22U +#define RTC_PSR_APRS_MSK BITS(RTC_PSR_APRS_POSS,RTC_PSR_APRS_POSE) + +#define RTC_PSR_SPRS_POSS 0U +#define RTC_PSR_SPRS_POSE 14U +#define RTC_PSR_SPRS_MSK BITS(RTC_PSR_SPRS_POSS,RTC_PSR_SPRS_POSE) + +/****************** Bit definition for RTC_TAMPCON register ************************/ + +#define RTC_TAMPCON_TAMPFLT_POSS 20U +#define RTC_TAMPCON_TAMPFLT_POSE 21U +#define RTC_TAMPCON_TAMPFLT_MSK BITS(RTC_TAMPCON_TAMPFLT_POSS,RTC_TAMPCON_TAMPFLT_POSE) + +#define RTC_TAMPCON_TAMPCKS_POSS 17U +#define RTC_TAMPCON_TAMPCKS_POSE 19U +#define RTC_TAMPCON_TAMPCKS_MSK BITS(RTC_TAMPCON_TAMPCKS_POSS,RTC_TAMPCON_TAMPCKS_POSE) + +#define RTC_TAMPCON_TAMPTS_POS 16U +#define RTC_TAMPCON_TAMPTS_MSK BIT(RTC_TAMPCON_TAMPTS_POS) + +#define RTC_TAMPCON_TAMP2LV_POS 9U +#define RTC_TAMPCON_TAMP2LV_MSK BIT(RTC_TAMPCON_TAMP2LV_POS) + +#define RTC_TAMPCON_TAMP2EN_POS 8U +#define RTC_TAMPCON_TAMP2EN_MSK BIT(RTC_TAMPCON_TAMP2EN_POS) + +#define RTC_TAMPCON_TAMP1LV_POS 1U +#define RTC_TAMPCON_TAMP1LV_MSK BIT(RTC_TAMPCON_TAMP1LV_POS) + +#define RTC_TAMPCON_TAMP1EN_POS 0U +#define RTC_TAMPCON_TAMP1EN_MSK BIT(RTC_TAMPCON_TAMP1EN_POS) + +/****************** Bit definition for RTC_TIME register ************************/ + +#define RTC_TIME_PM_POS 22U +#define RTC_TIME_PM_MSK BIT(RTC_TIME_PM_POS) + +#define RTC_TIME_HRT_POSS 20U +#define RTC_TIME_HRT_POSE 21U +#define RTC_TIME_HRT_MSK BITS(RTC_TIME_HRT_POSS,RTC_TIME_HRT_POSE) + +#define RTC_TIME_HRU_POSS 16U +#define RTC_TIME_HRU_POSE 19U +#define RTC_TIME_HRU_MSK BITS(RTC_TIME_HRU_POSS,RTC_TIME_HRU_POSE) + +#define RTC_TIME_MINT_POSS 12U +#define RTC_TIME_MINT_POSE 14U +#define RTC_TIME_MINT_MSK BITS(RTC_TIME_MINT_POSS,RTC_TIME_MINT_POSE) + +#define RTC_TIME_MINU_POSS 8U +#define RTC_TIME_MINU_POSE 11U +#define RTC_TIME_MINU_MSK BITS(RTC_TIME_MINU_POSS,RTC_TIME_MINU_POSE) + +#define RTC_TIME_SECT_POSS 4U +#define RTC_TIME_SECT_POSE 6U +#define RTC_TIME_SECT_MSK BITS(RTC_TIME_SECT_POSS,RTC_TIME_SECT_POSE) + +#define RTC_TIME_SECU_POSS 0U +#define RTC_TIME_SECU_POSE 3U +#define RTC_TIME_SECU_MSK BITS(RTC_TIME_SECU_POSS,RTC_TIME_SECU_POSE) + +/****************** Bit definition for RTC_DATE register ************************/ + +#define RTC_DATE_WD_POSS 24U +#define RTC_DATE_WD_POSE 26U +#define RTC_DATE_WD_MSK BITS(RTC_DATE_WD_POSS,RTC_DATE_WD_POSE) + +#define RTC_DATE_YRT_POSS 20U +#define RTC_DATE_YRT_POSE 23U +#define RTC_DATE_YRT_MSK BITS(RTC_DATE_YRT_POSS,RTC_DATE_YRT_POSE) + +#define RTC_DATE_YRU_POSS 16U +#define RTC_DATE_YRU_POSE 19U +#define RTC_DATE_YRU_MSK BITS(RTC_DATE_YRU_POSS,RTC_DATE_YRU_POSE) + +#define RTC_DATE_MONT_POS 12U +#define RTC_DATE_MONT_MSK BIT(RTC_DATE_MONT_POS) + +#define RTC_DATE_MONU_POSS 8U +#define RTC_DATE_MONU_POSE 11U +#define RTC_DATE_MONU_MSK BITS(RTC_DATE_MONU_POSS,RTC_DATE_MONU_POSE) + +#define RTC_DATE_DAYT_POSS 4U +#define RTC_DATE_DAYT_POSE 5U +#define RTC_DATE_DAYT_MSK BITS(RTC_DATE_DAYT_POSS,RTC_DATE_DAYT_POSE) + +#define RTC_DATE_DAYU_POSS 0U +#define RTC_DATE_DAYU_POSE 3U +#define RTC_DATE_DAYU_MSK BITS(RTC_DATE_DAYU_POSS,RTC_DATE_DAYU_POSE) + +/****************** Bit definition for RTC_SSEC register ************************/ + +#define RTC_SSEC_VAL_POSS 0U +#define RTC_SSEC_VAL_POSE 15U +#define RTC_SSEC_VAL_MSK BITS(RTC_SSEC_VAL_POSS,RTC_SSEC_VAL_POSE) + +/****************** Bit definition for RTC_WUMAT register ************************/ + +#define RTC_WUMAT_VAL_POSS 0U +#define RTC_WUMAT_VAL_POSE 15U +#define RTC_WUMAT_VAL_MSK BITS(RTC_WUMAT_VAL_POSS,RTC_WUMAT_VAL_POSE) + +/****************** Bit definition for RTC_ALMA register ************************/ + +#define RTC_ALMA_WDS_POS 31U +#define RTC_ALMA_WDS_MSK BIT(RTC_ALMA_WDS_POS) + +#define RTC_ALMA_DAWD_POSS 24U +#define RTC_ALMA_DAWD_POSE 30U +#define RTC_ALMA_DAWD_MSK BITS(RTC_ALMA_DAWD_POSS,RTC_ALMA_DAWD_POSE) + +#define RTC_ALMA_DAYMSK_POS 30U +#define RTC_ALMA_DAYMSK_MSK BIT(RTC_ALMA_DAYMSK_POS) + +#define RTC_ALMA_DAWD_DAYT_POSS 28U +#define RTC_ALMA_DAWD_DAYT_POSE 29U +#define RTC_ALMA_DAWD_DAYT_MSK BITS(RTC_ALMA_DAWD_DAYT_POSS, RTC_ALMA_DAWD_DAYT_POSE) + +#define RTC_ALMA_DAWD_DAYU_POSS 24U +#define RTC_ALMA_DAWD_DAYU_POSE 27U +#define RTC_ALMA_DAWD_DAYU_MSK BITS(RTC_ALMA_DAWD_DAYU_POSS, RTC_ALMA_DAWD_DAYU_POSE) + +#define RTC_ALMA_HRMSK_POS 23U +#define RTC_ALMA_HRMSK_MSK BIT(RTC_ALMA_HRMSK_POS) + +#define RTC_ALMA_PM_POS 22U +#define RTC_ALMA_PM_MSK BIT(RTC_ALMA_PM_POS) + +#define RTC_ALMA_HRT_POSS 20U +#define RTC_ALMA_HRT_POSE 21U +#define RTC_ALMA_HRT_MSK BITS(RTC_ALMA_HRT_POSS,RTC_ALMA_HRT_POSE) + +#define RTC_ALMA_HRU_POSS 16U +#define RTC_ALMA_HRU_POSE 19U +#define RTC_ALMA_HRU_MSK BITS(RTC_ALMA_HRU_POSS,RTC_ALMA_HRU_POSE) + +#define RTC_ALMA_MINMSK_POS 15U +#define RTC_ALMA_MINMSK_MSK BIT(RTC_ALMA_MINMSK_POS) + +#define RTC_ALMA_MINT_POSS 12U +#define RTC_ALMA_MINT_POSE 14U +#define RTC_ALMA_MINT_MSK BITS(RTC_ALMA_MINT_POSS,RTC_ALMA_MINT_POSE) + +#define RTC_ALMA_MINU_POSS 8U +#define RTC_ALMA_MINU_POSE 11U +#define RTC_ALMA_MINU_MSK BITS(RTC_ALMA_MINU_POSS,RTC_ALMA_MINU_POSE) + +#define RTC_ALMA_SECMSK_POS 7U +#define RTC_ALMA_SECMSK_MSK BIT(RTC_ALMA_SECMSK_POS) + +#define RTC_ALMA_SECT_POSS 4U +#define RTC_ALMA_SECT_POSE 6U +#define RTC_ALMA_SECT_MSK BITS(RTC_ALMA_SECT_POSS,RTC_ALMA_SECT_POSE) + +#define RTC_ALMA_SECU_POSS 0U +#define RTC_ALMA_SECU_POSE 3U +#define RTC_ALMA_SECU_MSK BITS(RTC_ALMA_SECU_POSS,RTC_ALMA_SECU_POSE) + +/****************** Bit definition for RTC_ALMB register ************************/ + +#define RTC_ALMB_WDS_POS 31U +#define RTC_ALMB_WDS_MSK BIT(RTC_ALMB_WDS_POS) + +#define RTC_ALMB_DAWD_POSS 24U +#define RTC_ALMB_DAWD_POSE 30U +#define RTC_ALMB_DAWD_MSK BITS(RTC_ALMB_DAWD_POSS,RTC_ALMB_DAWD_POSE) + +#define RTC_ALMB_DAYMSK_POS 30U +#define RTC_ALMB_DAYMSK_MSK BIT(RTC_ALMB_DAYMSK_POS) + +#define RTC_ALMB_DAWD_DAYT_POSS 28U +#define RTC_ALMB_DAWD_DAYT_POSE 29U +#define RTC_ALMB_DAWD_DAYT_MSK BITS(RTC_ALMB_DAWD_DAYT_POSS, RTC_ALMB_DAWD_DAYT_POSE) + +#define RTC_ALMB_DAWD_DAYU_POSS 24U +#define RTC_ALMB_DAWD_DAYU_POSE 27U +#define RTC_ALMB_DAWD_DAYU_MSK BITS(RTC_ALMB_DAWD_DAYU_POSS, RTC_ALMB_DAWD_DAYU_POSE) + +#define RTC_ALMB_HRMSK_POS 23U +#define RTC_ALMB_HRMSK_MSK BIT(RTC_ALMB_HRMSK_POS) + +#define RTC_ALMB_PM_POS 22U +#define RTC_ALMB_PM_MSK BIT(RTC_ALMB_PM_POS) + +#define RTC_ALMB_HRT_POSS 20U +#define RTC_ALMB_HRT_POSE 21U +#define RTC_ALMB_HRT_MSK BITS(RTC_ALMB_HRT_POSS,RTC_ALMB_HRT_POSE) + +#define RTC_ALMB_HRU_POSS 16U +#define RTC_ALMB_HRU_POSE 19U +#define RTC_ALMB_HRU_MSK BITS(RTC_ALMB_HRU_POSS,RTC_ALMB_HRU_POSE) + +#define RTC_ALMB_MINMSK_POS 15U +#define RTC_ALMB_MINMSK_MSK BIT(RTC_ALMB_MINMSK_POS) + +#define RTC_ALMB_MINT_POSS 12U +#define RTC_ALMB_MINT_POSE 14U +#define RTC_ALMB_MINT_MSK BITS(RTC_ALMB_MINT_POSS,RTC_ALMB_MINT_POSE) + +#define RTC_ALMB_MINU_POSS 8U +#define RTC_ALMB_MINU_POSE 11U +#define RTC_ALMB_MINU_MSK BITS(RTC_ALMB_MINU_POSS,RTC_ALMB_MINU_POSE) + +#define RTC_ALMB_SECMSK_POS 7U +#define RTC_ALMB_SECMSK_MSK BIT(RTC_ALMB_SECMSK_POS) + +#define RTC_ALMB_SECT_POSS 4U +#define RTC_ALMB_SECT_POSE 6U +#define RTC_ALMB_SECT_MSK BITS(RTC_ALMB_SECT_POSS,RTC_ALMB_SECT_POSE) + +#define RTC_ALMB_SECU_POSS 0U +#define RTC_ALMB_SECU_POSE 3U +#define RTC_ALMB_SECU_MSK BITS(RTC_ALMB_SECU_POSS,RTC_ALMB_SECU_POSE) + +/****************** Bit definition for RTC_ALMASSEC register ************************/ + +#define RTC_ALMASSEC_SSECM_POSS 24U +#define RTC_ALMASSEC_SSECM_POSE 27U +#define RTC_ALMASSEC_SSECM_MSK BITS(RTC_ALMASSEC_SSECM_POSS,RTC_ALMASSEC_SSECM_POSE) + +#define RTC_ALMASSEC_SSEC_POSS 0U +#define RTC_ALMASSEC_SSEC_POSE 14U +#define RTC_ALMASSEC_SSEC_MSK BITS(RTC_ALMASSEC_SSEC_POSS,RTC_ALMASSEC_SSEC_POSE) + +/****************** Bit definition for RTC_ALMBSSEC register ************************/ + +#define RTC_ALMBSSEC_SSECM_POSS 24U +#define RTC_ALMBSSEC_SSECM_POSE 27U +#define RTC_ALMBSSEC_SSECM_MSK BITS(RTC_ALMBSSEC_SSECM_POSS,RTC_ALMBSSEC_SSECM_POSE) + +#define RTC_ALMBSSEC_SSEC_POSS 0U +#define RTC_ALMBSSEC_SSEC_POSE 14U +#define RTC_ALMBSSEC_SSEC_MSK BITS(RTC_ALMBSSEC_SSEC_POSS,RTC_ALMBSSEC_SSEC_POSE) + +/****************** Bit definition for RTC_TSTIME register ************************/ + +#define RTC_TSTIME_PM_POS 22U +#define RTC_TSTIME_PM_MSK BIT(RTC_TSTIME_PM_POS) + +#define RTC_TSTIME_HRT_POSS 20U +#define RTC_TSTIME_HRT_POSE 21U +#define RTC_TSTIME_HRT_MSK BITS(RTC_TSTIME_HRT_POSS,RTC_TSTIME_HRT_POSE) + +#define RTC_TSTIME_HRU_POSS 16U +#define RTC_TSTIME_HRU_POSE 19U +#define RTC_TSTIME_HRU_MSK BITS(RTC_TSTIME_HRU_POSS,RTC_TSTIME_HRU_POSE) + +#define RTC_TSTIME_MINT_POSS 12U +#define RTC_TSTIME_MINT_POSE 14U +#define RTC_TSTIME_MINT_MSK BITS(RTC_TSTIME_MINT_POSS,RTC_TSTIME_MINT_POSE) + +#define RTC_TSTIME_MINU_POSS 8U +#define RTC_TSTIME_MINU_POSE 11U +#define RTC_TSTIME_MINU_MSK BITS(RTC_TSTIME_MINU_POSS,RTC_TSTIME_MINU_POSE) + +#define RTC_TSTIME_SECT_POSS 4U +#define RTC_TSTIME_SECT_POSE 6U +#define RTC_TSTIME_SECT_MSK BITS(RTC_TSTIME_SECT_POSS,RTC_TSTIME_SECT_POSE) + +#define RTC_TSTIME_SECU_POSS 0U +#define RTC_TSTIME_SECU_POSE 3U +#define RTC_TSTIME_SECU_MSK BITS(RTC_TSTIME_SECU_POSS,RTC_TSTIME_SECU_POSE) + +/****************** Bit definition for RTC_TSDATE register ************************/ + +#define RTC_TSDATE_WD_POSS 24U +#define RTC_TSDATE_WD_POSE 26U +#define RTC_TSDATE_WD_MSK BITS(RTC_TSDATE_WD_POSS,RTC_TSDATE_WD_POSE) + +#define RTC_TSDATE_YRT_POSS 20U +#define RTC_TSDATE_YRT_POSE 23U +#define RTC_TSDATE_YRT_MSK BITS(RTC_TSDATE_YRT_POSS,RTC_TSDATE_YRT_POSE) + +#define RTC_TSDATE_YRU_POSS 16U +#define RTC_TSDATE_YRU_POSE 19U +#define RTC_TSDATE_YRU_MSK BITS(RTC_TSDATE_YRU_POSS,RTC_TSDATE_YRU_POSE) + +#define RTC_TSDATE_MONT_POS 12U +#define RTC_TSDATE_MONT_MSK BIT(RTC_TSDATE_MONT_POS) + +#define RTC_TSDATE_MONU_POSS 8U +#define RTC_TSDATE_MONU_POSE 11U +#define RTC_TSDATE_MONU_MSK BITS(RTC_TSDATE_MONU_POSS,RTC_TSDATE_MONU_POSE) + +#define RTC_TSDATE_DAYT_POSS 4U +#define RTC_TSDATE_DAYT_POSE 5U +#define RTC_TSDATE_DAYT_MSK BITS(RTC_TSDATE_DAYT_POSS,RTC_TSDATE_DAYT_POSE) + +#define RTC_TSDATE_DAYU_POSS 0U +#define RTC_TSDATE_DAYU_POSE 3U +#define RTC_TSDATE_DAYU_MSK BITS(RTC_TSDATE_DAYU_POSS,RTC_TSDATE_DAYU_POSE) + +/****************** Bit definition for RTC_TSSSEC register ************************/ + +#define RTC_TSSSEC_SSEC_POSS 0U +#define RTC_TSSSEC_SSEC_POSE 15U +#define RTC_TSSSEC_SSEC_MSK BITS(RTC_TSSSEC_SSEC_POSS,RTC_TSSSEC_SSEC_POSE) + +/****************** Bit definition for RTC_SSECTR register ************************/ + +#define RTC_SSECTR_INC_POS 31U +#define RTC_SSECTR_INC_MSK BIT(RTC_SSECTR_INC_POS) + +#define RTC_SSECTR_TRIM_POSS 0U +#define RTC_SSECTR_TRIM_POSE 14U +#define RTC_SSECTR_TRIM_MSK BITS(RTC_SSECTR_TRIM_POSS,RTC_SSECTR_TRIM_POSE) + +/****************** Bit definition for RTC_IER register ************************/ + +#define RTC_IER_TCE_POS 25U +#define RTC_IER_TCE_MSK BIT(RTC_IER_TCE_POS) + +#define RTC_IER_TCC_POS 24U +#define RTC_IER_TCC_MSK BIT(RTC_IER_TCC_POS) + +#define RTC_IER_WU_POS 18U +#define RTC_IER_WU_MSK BIT(RTC_IER_WU_POS) + +#define RTC_IER_SSTC_POS 17U +#define RTC_IER_SSTC_MSK BIT(RTC_IER_SSTC_POS) + +#define RTC_IER_RSC_POS 16U +#define RTC_IER_RSC_MSK BIT(RTC_IER_RSC_POS) + +#define RTC_IER_TAMP2_POS 13U +#define RTC_IER_TAMP2_MSK BIT(RTC_IER_TAMP2_POS) + +#define RTC_IER_TAMP1_POS 12U +#define RTC_IER_TAMP1_MSK BIT(RTC_IER_TAMP1_POS) + +#define RTC_IER_TSOV_POS 11U +#define RTC_IER_TSOV_MSK BIT(RTC_IER_TSOV_POS) + +#define RTC_IER_TS_POS 10U +#define RTC_IER_TS_MSK BIT(RTC_IER_TS_POS) + +#define RTC_IER_ALMB_POS 9U +#define RTC_IER_ALMB_MSK BIT(RTC_IER_ALMB_POS) + +#define RTC_IER_ALMA_POS 8U +#define RTC_IER_ALMA_MSK BIT(RTC_IER_ALMA_POS) + +#define RTC_IER_YR_POS 5U +#define RTC_IER_YR_MSK BIT(RTC_IER_YR_POS) + +#define RTC_IER_MON_POS 4U +#define RTC_IER_MON_MSK BIT(RTC_IER_MON_POS) + +#define RTC_IER_DAY_POS 3U +#define RTC_IER_DAY_MSK BIT(RTC_IER_DAY_POS) + +#define RTC_IER_HR_POS 2U +#define RTC_IER_HR_MSK BIT(RTC_IER_HR_POS) + +#define RTC_IER_MIN_POS 1U +#define RTC_IER_MIN_MSK BIT(RTC_IER_MIN_POS) + +#define RTC_IER_SEC_POS 0U +#define RTC_IER_SEC_MSK BIT(RTC_IER_SEC_POS) + +/****************** Bit definition for RTC_IFR register ************************/ + +#define RTC_IFR_TCEF_POS 25U +#define RTC_IFR_TCEF_MSK BIT(RTC_IFR_TCEF_POS) + +#define RTC_IFR_TCCF_POS 24U +#define RTC_IFR_TCCF_MSK BIT(RTC_IFR_TCCF_POS) + +#define RTC_IFR_WUF_POS 18U +#define RTC_IFR_WUF_MSK BIT(RTC_IFR_WUF_POS) + +#define RTC_IFR_SSTCF_POS 17U +#define RTC_IFR_SSTCF_MSK BIT(RTC_IFR_SSTCF_POS) + +#define RTC_IFR_RSCF_POS 16U +#define RTC_IFR_RSCF_MSK BIT(RTC_IFR_RSCF_POS) + +#define RTC_IFR_TAMP2F_POS 13U +#define RTC_IFR_TAMP2F_MSK BIT(RTC_IFR_TAMP2F_POS) + +#define RTC_IFR_TAMP1F_POS 12U +#define RTC_IFR_TAMP1F_MSK BIT(RTC_IFR_TAMP1F_POS) + +#define RTC_IFR_TSOVF_POS 11U +#define RTC_IFR_TSOVF_MSK BIT(RTC_IFR_TSOVF_POS) + +#define RTC_IFR_TSF_POS 10U +#define RTC_IFR_TSF_MSK BIT(RTC_IFR_TSF_POS) + +#define RTC_IFR_ALMBF_POS 9U +#define RTC_IFR_ALMBF_MSK BIT(RTC_IFR_ALMBF_POS) + +#define RTC_IFR_ALMAF_POS 8U +#define RTC_IFR_ALMAF_MSK BIT(RTC_IFR_ALMAF_POS) + +#define RTC_IFR_YRF_POS 5U +#define RTC_IFR_YRF_MSK BIT(RTC_IFR_YRF_POS) + +#define RTC_IFR_MONF_POS 4U +#define RTC_IFR_MONF_MSK BIT(RTC_IFR_MONF_POS) + +#define RTC_IFR_DAYF_POS 3U +#define RTC_IFR_DAYF_MSK BIT(RTC_IFR_DAYF_POS) + +#define RTC_IFR_HRF_POS 2U +#define RTC_IFR_HRF_MSK BIT(RTC_IFR_HRF_POS) + +#define RTC_IFR_MINF_POS 1U +#define RTC_IFR_MINF_MSK BIT(RTC_IFR_MINF_POS) + +#define RTC_IFR_SECF_POS 0U +#define RTC_IFR_SECF_MSK BIT(RTC_IFR_SECF_POS) + +/****************** Bit definition for RTC_IFCR register ************************/ + +#define RTC_IFCR_TCEFC_POS 25U +#define RTC_IFCR_TCEFC_MSK BIT(RTC_IFCR_TCEFC_POS) + +#define RTC_IFCR_TCCFC_POS 24U +#define RTC_IFCR_TCCFC_MSK BIT(RTC_IFCR_TCCFC_POS) + +#define RTC_IFCR_WUFC_POS 18U +#define RTC_IFCR_WUFC_MSK BIT(RTC_IFCR_WUFC_POS) + +#define RTC_IFCR_SSTCFC_POS 17U +#define RTC_IFCR_SSTCFC_MSK BIT(RTC_IFCR_SSTCFC_POS) + +#define RTC_IFCR_RSCFC_POS 16U +#define RTC_IFCR_RSCFC_MSK BIT(RTC_IFCR_RSCFC_POS) + +#define RTC_IFCR_TAMP2FC_POS 13U +#define RTC_IFCR_TAMP2FC_MSK BIT(RTC_IFCR_TAMP2FC_POS) + +#define RTC_IFCR_TAMP1FC_POS 12U +#define RTC_IFCR_TAMP1FC_MSK BIT(RTC_IFCR_TAMP1FC_POS) + +#define RTC_IFCR_TSOVFC_POS 11U +#define RTC_IFCR_TSOVFC_MSK BIT(RTC_IFCR_TSOVFC_POS) + +#define RTC_IFCR_TSSTC_POS 10U +#define RTC_IFCR_TSSTC_MSK BIT(RTC_IFCR_TSSTC_POS) + +#define RTC_IFCR_ALMBFC_POS 9U +#define RTC_IFCR_ALMBFC_MSK BIT(RTC_IFCR_ALMBFC_POS) + +#define RTC_IFCR_ALMAFC_POS 8U +#define RTC_IFCR_ALMAFC_MSK BIT(RTC_IFCR_ALMAFC_POS) + +#define RTC_IFCR_YRFC_POS 5U +#define RTC_IFCR_YRFC_MSK BIT(RTC_IFCR_YRFC_POS) + +#define RTC_IFCR_MONFC_POS 4U +#define RTC_IFCR_MONFC_MSK BIT(RTC_IFCR_MONFC_POS) + +#define RTC_IFCR_DAYFC_POS 3U +#define RTC_IFCR_DAYFC_MSK BIT(RTC_IFCR_DAYFC_POS) + +#define RTC_IFCR_HRFC_POS 2U +#define RTC_IFCR_HRFC_MSK BIT(RTC_IFCR_HRFC_POS) + +#define RTC_IFCR_MINFC_POS 1U +#define RTC_IFCR_MINFC_MSK BIT(RTC_IFCR_MINFC_POS) + +#define RTC_IFCR_SECFC_POS 0U +#define RTC_IFCR_SECFC_MSK BIT(RTC_IFCR_SECFC_POS) + +/****************** Bit definition for RTC_ISR register ************************/ + +#define RTC_ISR_TCEF_POS 25U +#define RTC_ISR_TCEF_MSK BIT(RTC_ISR_TCEF_POS) + +#define RTC_ISR_TCCF_POS 24U +#define RTC_ISR_TCCF_MSK BIT(RTC_ISR_TCCF_POS) + +#define RTC_ISR_WUF_POS 18U +#define RTC_ISR_WUF_MSK BIT(RTC_ISR_WUF_POS) + +#define RTC_ISR_SSTCF_POS 17U +#define RTC_ISR_SSTCF_MSK BIT(RTC_ISR_SSTCF_POS) + +#define RTC_ISR_RSCF_POS 16U +#define RTC_ISR_RSCF_MSK BIT(RTC_ISR_RSCF_POS) + +#define RTC_ISR_TAMP2F_POS 13U +#define RTC_ISR_TAMP2F_MSK BIT(RTC_ISR_TAMP2F_POS) + +#define RTC_ISR_TAMP1F_POS 12U +#define RTC_ISR_TAMP1F_MSK BIT(RTC_ISR_TAMP1F_POS) + +#define RTC_ISR_TSOVF_POS 11U +#define RTC_ISR_TSOVF_MSK BIT(RTC_ISR_TSOVF_POS) + +#define RTC_ISR_TSF_POS 10U +#define RTC_ISR_TSF_MSK BIT(RTC_ISR_TSF_POS) + +#define RTC_ISR_ALMBF_POS 9U +#define RTC_ISR_ALMBF_MSK BIT(RTC_ISR_ALMBF_POS) + +#define RTC_ISR_ALMAF_POS 8U +#define RTC_ISR_ALMAF_MSK BIT(RTC_ISR_ALMAF_POS) + +#define RTC_ISR_YRF_POS 5U +#define RTC_ISR_YRF_MSK BIT(RTC_ISR_YRF_POS) + +#define RTC_ISR_MONF_POS 4U +#define RTC_ISR_MONF_MSK BIT(RTC_ISR_MONF_POS) + +#define RTC_ISR_DAYF_POS 3U +#define RTC_ISR_DAYF_MSK BIT(RTC_ISR_DAYF_POS) + +#define RTC_ISR_HRF_POS 2U +#define RTC_ISR_HRF_MSK BIT(RTC_ISR_HRF_POS) + +#define RTC_ISR_MINF_POS 1U +#define RTC_ISR_MINF_MSK BIT(RTC_ISR_MINF_POS) + +#define RTC_ISR_SECF_POS 0U +#define RTC_ISR_SECF_MSK BIT(RTC_ISR_SECF_POS) + +/****************** Bit definition for RTC_CALWPR register ************************/ + +#define RTC_CALWPR_WP_POS 0U +#define RTC_CALWPR_WP_MSK BIT(RTC_CALWPR_WP_POS) + +/****************** Bit definition for RTC_CALCON register ************************/ + +#define RTC_CALCON_DCMACC_POS 24U +#define RTC_CALCON_DCMACC_MSK BIT(RTC_CALCON_DCMACC_POS) + +#define RTC_CALCON_ALG_POS 23U +#define RTC_CALCON_ALG_MSK BIT(RTC_CALCON_ALG_POS) + +#define RTC_CALCON_TCP_POSS 20U +#define RTC_CALCON_TCP_POSE 22U +#define RTC_CALCON_TCP_MSK BITS(RTC_CALCON_TCP_POSS,RTC_CALCON_TCP_POSE) + +#define RTC_CALCON_ERR_POS 19U +#define RTC_CALCON_ERR_MSK BIT(RTC_CALCON_ERR_POS) + +#define RTC_CALCON_BUSY_POS 18U +#define RTC_CALCON_BUSY_MSK BIT(RTC_CALCON_BUSY_POS) + +#define RTC_CALCON_TCM_POSS 16U +#define RTC_CALCON_TCM_POSE 17U +#define RTC_CALCON_TCM_MSK BITS(RTC_CALCON_TCM_POSS,RTC_CALCON_TCM_POSE) + +#define RTC_CALCON_CALP_POSS 1U +#define RTC_CALCON_CALP_POSE 3U +#define RTC_CALCON_CALP_MSK BITS(RTC_CALCON_CALP_POSS,RTC_CALCON_CALP_POSE) + +#define RTC_CALCON_CALEN_POS 0U +#define RTC_CALCON_CALEN_MSK BIT(RTC_CALCON_CALEN_POS) + +/****************** Bit definition for RTC_CALDR register ************************/ + +#define RTC_CALDR_DATA_POSS 16U +#define RTC_CALDR_DATA_POSE 31U +#define RTC_CALDR_DATA_MSK BITS(RTC_CALDR_DATA_POSS,RTC_CALDR_DATA_POSE) + +#define RTC_CALDR_VAL_POSS 0U +#define RTC_CALDR_VAL_POSE 15U +#define RTC_CALDR_VAL_MSK BITS(RTC_CALDR_VAL_POSS,RTC_CALDR_VAL_POSE) + +/****************** Bit definition for RTC_TEMPR register ************************/ + +#define RTC_TEMPR_DATA_POSS 16U +#define RTC_TEMPR_DATA_POSE 31U +#define RTC_TEMPR_DATA_MSK BITS(RTC_TEMPR_DATA_POSS,RTC_TEMPR_DATA_POSE) + +#define RTC_TEMPR_VAL_POSS 0U +#define RTC_TEMPR_VAL_POSE 15U +#define RTC_TEMPR_VAL_MSK BITS(RTC_TEMPR_VAL_POSS,RTC_TEMPR_VAL_POSE) + +/****************** Bit definition for RTC_TEMPBDR register ************************/ + +#define RTC_TEMPBDR_VAL_POSS 0U +#define RTC_TEMPBDR_VAL_POSE 15U +#define RTC_TEMPBDR_VAL_MSK BITS(RTC_TEMPBDR_VAL_POSS,RTC_TEMPBDR_VAL_POSE) + +/****************** Bit definition for RTC_BKP register ************************/ + +#define RTC_BKP_BKP_POSS 0U +#define RTC_BKP_BKP_POSE 31U +#define RTC_BKP_BKP_MSK BITS(RTC_BKP_BKP_POSS,RTC_BKP_BKP_POSE) + +typedef struct +{ + __IO uint32_t WPR; + __IO uint32_t CON; + __IO uint32_t PSR; + __IO uint32_t TAMPCON; + __IO uint32_t TIME; + __IO uint32_t DATE; + __IO uint32_t SSEC; + __IO uint32_t WUMAT; + __IO uint32_t ALMA; + __IO uint32_t ALMB; + __IO uint32_t ALMASSEC; + __IO uint32_t ALMBSSEC; + __I uint32_t TSTIME; + __I uint32_t TSDATE; + __I uint32_t TSSSEC; + __O uint32_t SSECTR; + __IO uint32_t IER; + __I uint32_t IFR; + __O uint32_t IFCR; + __I uint32_t ISR; + __IO uint32_t CALWPR; + __IO uint32_t CALCON; + __IO uint32_t CALDR; + __IO uint32_t TEMPR; + __IO uint32_t LTCAR; + __IO uint32_t LTCBR; + __IO uint32_t LTCCR; + __IO uint32_t LTCDR; + __IO uint32_t LTCER; + __IO uint32_t HTCAR; + __IO uint32_t HTCBR; + __IO uint32_t HTCCR; + __IO uint32_t HTCDR; + __IO uint32_t HTCER; + __IO uint32_t TEMPBDR; + uint32_t RESERVED0[29] ; + __IO uint32_t BKPR[32]; +} RTC_TypeDef; + +/****************** Bit definition for TIMER_CON1 register ************************/ + +#define TIMER_CON1_DFCKSEL_POSS 8U +#define TIMER_CON1_DFCKSEL_POSE 9U +#define TIMER_CON1_DFCKSEL_MSK BITS(TIMER_CON1_DFCKSEL_POSS,TIMER_CON1_DFCKSEL_POSE) + +#define TIMER_CON1_ARPEN_POS 7U +#define TIMER_CON1_ARPEN_MSK BIT(TIMER_CON1_ARPEN_POS) + +#define TIMER_CON1_CMSEL_POSS 5U +#define TIMER_CON1_CMSEL_POSE 6U +#define TIMER_CON1_CMSEL_MSK BITS(TIMER_CON1_CMSEL_POSS,TIMER_CON1_CMSEL_POSE) + +#define TIMER_CON1_DIRSEL_POS 4U +#define TIMER_CON1_DIRSEL_MSK BIT(TIMER_CON1_DIRSEL_POS) + +#define TIMER_CON1_SPMEN_POS 3U +#define TIMER_CON1_SPMEN_MSK BIT(TIMER_CON1_SPMEN_POS) + +#define TIMER_CON1_UERSEL_POS 2U +#define TIMER_CON1_UERSEL_MSK BIT(TIMER_CON1_UERSEL_POS) + +#define TIMER_CON1_DISUE_POS 1U +#define TIMER_CON1_DISUE_MSK BIT(TIMER_CON1_DISUE_POS) + +#define TIMER_CON1_CNTEN_POS 0U +#define TIMER_CON1_CNTEN_MSK BIT(TIMER_CON1_CNTEN_POS) + +/****************** Bit definition for TIMER_CON2 register ************************/ + +#define TIMER_CON2_OISS4_POS 14U +#define TIMER_CON2_OISS4_MSK BIT(TIMER_CON2_OISS4_POS) + +#define TIMER_CON2_OISS3N_POS 13U +#define TIMER_CON2_OISS3N_MSK BIT(TIMER_CON2_OISS3N_POS) + +#define TIMER_CON2_OISS3_POS 12U +#define TIMER_CON2_OISS3_MSK BIT(TIMER_CON2_OISS3_POS) + +#define TIMER_CON2_OISS2N_POS 11U +#define TIMER_CON2_OISS2N_MSK BIT(TIMER_CON2_OISS2N_POS) + +#define TIMER_CON2_OISS2_POS 10U +#define TIMER_CON2_OISS2_MSK BIT(TIMER_CON2_OISS2_POS) + +#define TIMER_CON2_OISS1N_POS 9U +#define TIMER_CON2_OISS1N_MSK BIT(TIMER_CON2_OISS1N_POS) + +#define TIMER_CON2_OISS1_POS 8U +#define TIMER_CON2_OISS1_MSK BIT(TIMER_CON2_OISS1_POS) + +#define TIMER_CON2_I1FSEL_POS 7U +#define TIMER_CON2_I1FSEL_MSK BIT(TIMER_CON2_I1FSEL_POS) + +#define TIMER_CON2_TRGOSEL_POSS 4U +#define TIMER_CON2_TRGOSEL_POSE 6U +#define TIMER_CON2_TRGOSEL_MSK BITS(TIMER_CON2_TRGOSEL_POSS,TIMER_CON2_TRGOSEL_POSE) + +#define TIMER_CON2_CCDMASEL_POS 3U +#define TIMER_CON2_CCDMASEL_MSK BIT(TIMER_CON2_CCDMASEL_POS) + +#define TIMER_CON2_CCUSEL_POS 2U +#define TIMER_CON2_CCUSEL_MSK BIT(TIMER_CON2_CCUSEL_POS) + +#define TIMER_CON2_CCPCEN_POS 0U +#define TIMER_CON2_CCPCEN_MSK BIT(TIMER_CON2_CCPCEN_POS) + +/****************** Bit definition for TIMER_SMCON register ************************/ + +#define TIMER_SMCON_ETPOL_POS 15U +#define TIMER_SMCON_ETPOL_MSK BIT(TIMER_SMCON_ETPOL_POS) + +#define TIMER_SMCON_ECM2EN_POS 14U +#define TIMER_SMCON_ECM2EN_MSK BIT(TIMER_SMCON_ECM2EN_POS) + +#define TIMER_SMCON_ETPSEL_POSS 12U +#define TIMER_SMCON_ETPSEL_POSE 13U +#define TIMER_SMCON_ETPSEL_MSK BITS(TIMER_SMCON_ETPSEL_POSS,TIMER_SMCON_ETPSEL_POSE) + +#define TIMER_SMCON_ETFLT_POSS 8U +#define TIMER_SMCON_ETFLT_POSE 11U +#define TIMER_SMCON_ETFLT_MSK BITS(TIMER_SMCON_ETFLT_POSS,TIMER_SMCON_ETFLT_POSE) + +#define TIMER_SMCON_MSCFG_POS 7U +#define TIMER_SMCON_MSCFG_MSK BIT(TIMER_SMCON_MSCFG_POS) + +#define TIMER_SMCON_TSSEL_POSS 4U +#define TIMER_SMCON_TSSEL_POSE 6U +#define TIMER_SMCON_TSSEL_MSK BITS(TIMER_SMCON_TSSEL_POSS,TIMER_SMCON_TSSEL_POSE) + +#define TIMER_SMCON_SMODS_POSS 0U +#define TIMER_SMCON_SMODS_POSE 2U +#define TIMER_SMCON_SMODS_MSK BITS(TIMER_SMCON_SMODS_POSS,TIMER_SMCON_SMODS_POSE) + +/****************** Bit definition for TIMER_DIER register ************************/ + +#define TIMER_DIER_TRGDMA_POS 14U +#define TIMER_DIER_TRGDMA_MSK BIT(TIMER_DIER_TRGDMA_POS) + +#define TIMER_DIER_COMDMA_POS 13U +#define TIMER_DIER_COMDMA_MSK BIT(TIMER_DIER_COMDMA_POS) + +#define TIMER_DIER_CC4DMA_POS 12U +#define TIMER_DIER_CC4DMA_MSK BIT(TIMER_DIER_CC4DMA_POS) + +#define TIMER_DIER_CC3DMA_POS 11U +#define TIMER_DIER_CC3DMA_MSK BIT(TIMER_DIER_CC3DMA_POS) + +#define TIMER_DIER_CC2DMA_POS 10U +#define TIMER_DIER_CC2DMA_MSK BIT(TIMER_DIER_CC2DMA_POS) + +#define TIMER_DIER_CC1DMA_POS 9U +#define TIMER_DIER_CC1DMA_MSK BIT(TIMER_DIER_CC1DMA_POS) + +#define TIMER_DIER_UDMA_POS 8U +#define TIMER_DIER_UDMA_MSK BIT(TIMER_DIER_UDMA_POS) + +#define TIMER_DIER_BRKIT_POS 7U +#define TIMER_DIER_BRKIT_MSK BIT(TIMER_DIER_BRKIT_POS) + +#define TIMER_DIER_TRGIT_POS 6U +#define TIMER_DIER_TRGIT_MSK BIT(TIMER_DIER_TRGIT_POS) + +#define TIMER_DIER_COMIT_POS 5U +#define TIMER_DIER_COMIT_MSK BIT(TIMER_DIER_COMIT_POS) + +#define TIMER_DIER_CC4IT_POS 4U +#define TIMER_DIER_CC4IT_MSK BIT(TIMER_DIER_CC4IT_POS) + +#define TIMER_DIER_CC3IT_POS 3U +#define TIMER_DIER_CC3IT_MSK BIT(TIMER_DIER_CC3IT_POS) + +#define TIMER_DIER_CC2IT_POS 2U +#define TIMER_DIER_CC2IT_MSK BIT(TIMER_DIER_CC2IT_POS) + +#define TIMER_DIER_CC1IT_POS 1U +#define TIMER_DIER_CC1IT_MSK BIT(TIMER_DIER_CC1IT_POS) + +#define TIMER_DIER_UIT_POS 0U +#define TIMER_DIER_UIT_MSK BIT(TIMER_DIER_UIT_POS) + +/****************** Bit definition for TIMER_DIDR register ************************/ + +#define TIMER_DIDR_TRGDMA_POS 14U +#define TIMER_DIDR_TRGDMA_MSK BIT(TIMER_DIDR_TRGDMA_POS) + +#define TIMER_DIDR_COMD_POS 13U +#define TIMER_DIDR_COMD_MSK BIT(TIMER_DIDR_COMD_POS) + +#define TIMER_DIDR_CC4D_POS 12U +#define TIMER_DIDR_CC4D_MSK BIT(TIMER_DIDR_CC4D_POS) + +#define TIMER_DIDR_CC3D_POS 11U +#define TIMER_DIDR_CC3D_MSK BIT(TIMER_DIDR_CC3D_POS) + +#define TIMER_DIDR_CC2D_POS 10U +#define TIMER_DIDR_CC2D_MSK BIT(TIMER_DIDR_CC2D_POS) + +#define TIMER_DIDR_CC1D_POS 9U +#define TIMER_DIDR_CC1D_MSK BIT(TIMER_DIDR_CC1D_POS) + +#define TIMER_DIDR_UD_POS 8U +#define TIMER_DIDR_UD_MSK BIT(TIMER_DIDR_UD_POS) + +#define TIMER_DIDR_BRKI_POS 7U +#define TIMER_DIDR_BRKI_MSK BIT(TIMER_DIDR_BRKI_POS) + +#define TIMER_DIDR_TRGI_POS 6U +#define TIMER_DIDR_TRGI_MSK BIT(TIMER_DIDR_TRGI_POS) + +#define TIMER_DIDR_COMI_POS 5U +#define TIMER_DIDR_COMI_MSK BIT(TIMER_DIDR_COMI_POS) + +#define TIMER_DIDR_CC4I_POS 4U +#define TIMER_DIDR_CC4I_MSK BIT(TIMER_DIDR_CC4I_POS) + +#define TIMER_DIDR_CC3I_POS 3U +#define TIMER_DIDR_CC3I_MSK BIT(TIMER_DIDR_CC3I_POS) + +#define TIMER_DIDR_CC2I_POS 2U +#define TIMER_DIDR_CC2I_MSK BIT(TIMER_DIDR_CC2I_POS) + +#define TIMER_DIDR_CC1I_POS 1U +#define TIMER_DIDR_CC1I_MSK BIT(TIMER_DIDR_CC1I_POS) + +#define TIMER_DIDR_UI_POS 0U +#define TIMER_DIDR_UI_MSK BIT(TIMER_DIDR_UI_POS) + +/****************** Bit definition for TIMER_DIVS register ************************/ + +#define TIMER_DIVS_TRGDMA_POS 14U +#define TIMER_DIVS_TRGDMA_MSK BIT(TIMER_DIVS_TRGDMA_POS) + +#define TIMER_DIVS_COMDMA_POS 13U +#define TIMER_DIVS_COMDMA_MSK BIT(TIMER_DIVS_COMDMA_POS) + +#define TIMER_DIVS_CC4DMA_POS 12U +#define TIMER_DIVS_CC4DMA_MSK BIT(TIMER_DIVS_CC4DMA_POS) + +#define TIMER_DIVS_CC3DMA_POS 11U +#define TIMER_DIVS_CC3DMA_MSK BIT(TIMER_DIVS_CC3DMA_POS) + +#define TIMER_DIVS_CC2DMA_POS 10U +#define TIMER_DIVS_CC2DMA_MSK BIT(TIMER_DIVS_CC2DMA_POS) + +#define TIMER_DIVS_CC1DMA_POS 9U +#define TIMER_DIVS_CC1DMA_MSK BIT(TIMER_DIVS_CC1DMA_POS) + +#define TIMER_DIVS_UEDTR_POS 8U +#define TIMER_DIVS_UEDTR_MSK BIT(TIMER_DIVS_UEDTR_POS) + +#define TIMER_DIVS_BKI_POS 7U +#define TIMER_DIVS_BKI_MSK BIT(TIMER_DIVS_BKI_POS) + +#define TIMER_DIVS_TRGI_POS 6U +#define TIMER_DIVS_TRGI_MSK BIT(TIMER_DIVS_TRGI_POS) + +#define TIMER_DIVS_COMI_POS 5U +#define TIMER_DIVS_COMI_MSK BIT(TIMER_DIVS_COMI_POS) + +#define TIMER_DIVS_CC4I_POS 4U +#define TIMER_DIVS_CC4I_MSK BIT(TIMER_DIVS_CC4I_POS) + +#define TIMER_DIVS_CC3I_POS 3U +#define TIMER_DIVS_CC3I_MSK BIT(TIMER_DIVS_CC3I_POS) + +#define TIMER_DIVS_CC2I_POS 2U +#define TIMER_DIVS_CC2I_MSK BIT(TIMER_DIVS_CC2I_POS) + +#define TIMER_DIVS_CC1I_POS 1U +#define TIMER_DIVS_CC1I_MSK BIT(TIMER_DIVS_CC1I_POS) + +#define TIMER_DIVS_UEI_POS 0U +#define TIMER_DIVS_UEI_MSK BIT(TIMER_DIVS_UEI_POS) + +/****************** Bit definition for TIMER_RIF register ************************/ + +#define TIMER_RIF_CH4OVIF_POS 12U +#define TIMER_RIF_CH4OVIF_MSK BIT(TIMER_RIF_CH4OVIF_POS) + +#define TIMER_RIF_CH3OVIF_POS 11U +#define TIMER_RIF_CH3OVIF_MSK BIT(TIMER_RIF_CH3OVIF_POS) + +#define TIMER_RIF_CH2OVIF_POS 10U +#define TIMER_RIF_CH2OVIF_MSK BIT(TIMER_RIF_CH2OVIF_POS) + +#define TIMER_RIF_CH1OVIF_POS 9U +#define TIMER_RIF_CH1OVIF_MSK BIT(TIMER_RIF_CH1OVIF_POS) + +#define TIMER_RIF_BRKIF_POS 7U +#define TIMER_RIF_BRKIF_MSK BIT(TIMER_RIF_BRKIF_POS) + +#define TIMER_RIF_TRGIF_POS 6U +#define TIMER_RIF_TRGIF_MSK BIT(TIMER_RIF_TRGIF_POS) + +#define TIMER_RIF_COMIF_POS 5U +#define TIMER_RIF_COMIF_MSK BIT(TIMER_RIF_COMIF_POS) + +#define TIMER_RIF_CH4IF_POS 4U +#define TIMER_RIF_CH4IF_MSK BIT(TIMER_RIF_CH4IF_POS) + +#define TIMER_RIF_CH3IF_POS 3U +#define TIMER_RIF_CH3IF_MSK BIT(TIMER_RIF_CH3IF_POS) + +#define TIMER_RIF_CH2IF_POS 2U +#define TIMER_RIF_CH2IF_MSK BIT(TIMER_RIF_CH2IF_POS) + +#define TIMER_RIF_CH1IF_POS 1U +#define TIMER_RIF_CH1IF_MSK BIT(TIMER_RIF_CH1IF_POS) + +#define TIMER_RIF_UEVTIF_POS 0U +#define TIMER_RIF_UEVTIF_MSK BIT(TIMER_RIF_UEVTIF_POS) + +/****************** Bit definition for TIMER_IFM register ************************/ + +#define TIMER_IFM_BRKIM_POS 7U +#define TIMER_IFM_BRKIM_MSK BIT(TIMER_IFM_BRKIM_POS) + +#define TIMER_IFM_TRGI_POS 6U +#define TIMER_IFM_TRGI_MSK BIT(TIMER_IFM_TRGI_POS) + +#define TIMER_IFM_COMI_POS 5U +#define TIMER_IFM_COMI_MSK BIT(TIMER_IFM_COMI_POS) + +#define TIMER_IFM_CH4CCI_POS 4U +#define TIMER_IFM_CH4CCI_MSK BIT(TIMER_IFM_CH4CCI_POS) + +#define TIMER_IFM_CH3CCI_POS 3U +#define TIMER_IFM_CH3CCI_MSK BIT(TIMER_IFM_CH3CCI_POS) + +#define TIMER_IFM_CH2CCI_POS 2U +#define TIMER_IFM_CH2CCI_MSK BIT(TIMER_IFM_CH2CCI_POS) + +#define TIMER_IFM_CH1CCI_POS 1U +#define TIMER_IFM_CH1CCI_MSK BIT(TIMER_IFM_CH1CCI_POS) + +#define TIMER_IFM_UEI_POS 0U +#define TIMER_IFM_UEI_MSK BIT(TIMER_IFM_UEI_POS) + +/****************** Bit definition for TIMER_ICR register ************************/ + +#define TIMER_ICR_BRKIC_POS 7U +#define TIMER_ICR_BRKIC_MSK BIT(TIMER_ICR_BRKIC_POS) + +#define TIMER_ICR_TRGIC_POS 6U +#define TIMER_ICR_TRGIC_MSK BIT(TIMER_ICR_TRGIC_POS) + +#define TIMER_ICR_COMIC_POS 5U +#define TIMER_ICR_COMIC_MSK BIT(TIMER_ICR_COMIC_POS) + +#define TIMER_ICR_CH4CCIC_POS 4U +#define TIMER_ICR_CH4CCIC_MSK BIT(TIMER_ICR_CH4CCIC_POS) + +#define TIMER_ICR_CH3CCIC_POS 3U +#define TIMER_ICR_CH3CCIC_MSK BIT(TIMER_ICR_CH3CCIC_POS) + +#define TIMER_ICR_CH2CCIC_POS 2U +#define TIMER_ICR_CH2CCIC_MSK BIT(TIMER_ICR_CH2CCIC_POS) + +#define TIMER_ICR_CH1CCIC_POS 1U +#define TIMER_ICR_CH1CCIC_MSK BIT(TIMER_ICR_CH1CCIC_POS) + +#define TIMER_ICR_UEIC_POS 0U +#define TIMER_ICR_UEIC_MSK BIT(TIMER_ICR_UEIC_POS) + +/****************** Bit definition for TIMER_SGE register ************************/ + +#define TIMER_SGE_SGBRK_POS 7U +#define TIMER_SGE_SGBRK_MSK BIT(TIMER_SGE_SGBRK_POS) + +#define TIMER_SGE_SGTRG_POS 6U +#define TIMER_SGE_SGTRG_MSK BIT(TIMER_SGE_SGTRG_POS) + +#define TIMER_SGE_SGCOM_POS 5U +#define TIMER_SGE_SGCOM_MSK BIT(TIMER_SGE_SGCOM_POS) + +#define TIMER_SGE_SGCC4E_POS 4U +#define TIMER_SGE_SGCC4E_MSK BIT(TIMER_SGE_SGCC4E_POS) + +#define TIMER_SGE_SGCC3E_POS 3U +#define TIMER_SGE_SGCC3E_MSK BIT(TIMER_SGE_SGCC3E_POS) + +#define TIMER_SGE_SGCC2E_POS 2U +#define TIMER_SGE_SGCC2E_MSK BIT(TIMER_SGE_SGCC2E_POS) + +#define TIMER_SGE_SGCC1E_POS 1U +#define TIMER_SGE_SGCC1E_MSK BIT(TIMER_SGE_SGCC1E_POS) + +#define TIMER_SGE_SGU_POS 0U +#define TIMER_SGE_SGU_MSK BIT(TIMER_SGE_SGU_POS) + +/****************** Bit definition for TIMER_CHMR1 register ************************/ +/* Output */ +#define TIMER_CHMR1_CH2OCLREN_POS 15U +#define TIMER_CHMR1_CH2OCLREN_MSK BIT(TIMER_CHMR1_CH2OCLREN_POS) + +#define TIMER_CHMR1_CH2OMOD_POSS 12U +#define TIMER_CHMR1_CH2OMOD_POSE 14U +#define TIMER_CHMR1_CH2OMOD_MSK BITS(TIMER_CHMR1_CH2OMOD_POSS,TIMER_CHMR1_CH2OMOD_POSE) + +#define TIMER_CHMR1_CH2OPEN_POS 11U +#define TIMER_CHMR1_CH2OPEN_MSK BIT(TIMER_CHMR1_CH2OPEN_POS) + +#define TIMER_CHMR1_CH2OFEN_POS 10U +#define TIMER_CHMR1_CH2OFEN_MSK BIT(TIMER_CHMR1_CH2OFEN_POS) + +#define TIMER_CHMR1_CC2SSEL_POSS 8U +#define TIMER_CHMR1_CC2SSEL_POSE 9U +#define TIMER_CHMR1_CC2SSEL_MSK BITS(TIMER_CHMR1_CC2SSEL_POSS,TIMER_CHMR1_CC2SSEL_POSE) + +#define TIMER_CHMR1_CH1OCLREN_POS 7U +#define TIMER_CHMR1_CH1OCLREN_MSK BIT(TIMER_CHMR1_CH1OCLREN_POS) + +#define TIMER_CHMR1_CH1OMOD_POSS 4U +#define TIMER_CHMR1_CH1OMOD_POSE 6U +#define TIMER_CHMR1_CH1OMOD_MSK BITS(TIMER_CHMR1_CH1OMOD_POSS,TIMER_CHMR1_CH1OMOD_POSE) + +#define TIMER_CHMR1_CH1OPREN_POS 3U +#define TIMER_CHMR1_CH1OPREN_MSK BIT(TIMER_CHMR1_CH1OPREN_POS) + +#define TIMER_CHMR1_CH1OHSEN_POS 2U +#define TIMER_CHMR1_CH1OHSEN_MSK BIT(TIMER_CHMR1_CH1OHSEN_POS) + +#define TIMER_CHMR1_CC1SSEL_POSS 0U +#define TIMER_CHMR1_CC1SSEL_POSE 1U +#define TIMER_CHMR1_CC1SSEL_MSK BITS(TIMER_CHMR1_CC1SSEL_POSS,TIMER_CHMR1_CC1SSEL_POSE) + +/* Input */ +#define TIMER_CHMR1_I2FLT_POSS 12U +#define TIMER_CHMR1_I2FLT_POSE 15U +#define TIMER_CHMR1_I2FLT_MSK BITS(TIMER_CHMR1_I2FLT_POSS,TIMER_CHMR1_I2FLT_POSE) + +#define TIMER_CHMR1_IC2PRES_POSS 10U +#define TIMER_CHMR1_IC2PRES_POSE 11U +#define TIMER_CHMR1_IC2PRES_MSK BITS(TIMER_CHMR1_IC2PRES_POSS,TIMER_CHMR1_IC2PRES_POSE) + +#define TIMER_CHMR1_CC2SSEL_POSS 8U +#define TIMER_CHMR1_CC2SSEL_POSE 9U +#define TIMER_CHMR1_CC2SSEL_MSK BITS(TIMER_CHMR1_CC2SSEL_POSS,TIMER_CHMR1_CC2SSEL_POSE) + +#define TIMER_CHMR1_I1FLT_POSS 4U +#define TIMER_CHMR1_I1FLT_POSE 7U +#define TIMER_CHMR1_I1FLT_MSK BITS(TIMER_CHMR1_I1FLT_POSS,TIMER_CHMR1_I1FLT_POSE) + +#define TIMER_CHMR1_IC1PRES_POSS 2U +#define TIMER_CHMR1_IC1PRES_POSE 3U +#define TIMER_CHMR1_IC1PRES_MSK BITS(TIMER_CHMR1_IC1PRES_POSS,TIMER_CHMR1_IC1PRES_POSE) + +#define TIMER_CHMR1_CC1SSEL_POSS 0U +#define TIMER_CHMR1_CC1SSEL_POSE 1U +#define TIMER_CHMR1_CC1SSEL_MSK BITS(TIMER_CHMR1_CC1SSEL_POSS,TIMER_CHMR1_CC1SSEL_POSE) + +/****************** Bit definition for TIMER_CHMR2 register ************************/ +/* Output */ +#define TIMER_CHMR2_CH4OCLREN_POS 15U +#define TIMER_CHMR2_CH4OCLREN_MSK BIT(TIMER_CHMR2_CH4OCLREN_POS) + +#define TIMER_CHMR2_CH4OMOD_POSS 12U +#define TIMER_CHMR2_CH4OMOD_POSE 14U +#define TIMER_CHMR2_CH4OMOD_MSK BITS(TIMER_CHMR2_CH4OMOD_POSS,TIMER_CHMR2_CH4OMOD_POSE) + +#define TIMER_CHMR2_CH4OPEN_POS 11U +#define TIMER_CHMR2_CH4OPEN_MSK BIT(TIMER_CHMR2_CH4OPEN_POS) + +#define TIMER_CHMR2_CH4OHSEN_POS 10U +#define TIMER_CHMR2_CH4OHSEN_MSK BIT(TIMER_CHMR2_CH4OHSEN_POS) + +#define TIMER_CHMR2_CC4SSEL_POSS 8U +#define TIMER_CHMR2_CC4SSEL_POSE 9U +#define TIMER_CHMR2_CC4SSEL_MSK BITS(TIMER_CHMR2_CC4SSEL_POSS,TIMER_CHMR2_CC4SSEL_POSE) + +#define TIMER_CHMR2_CH3OCLREN_POS 7U +#define TIMER_CHMR2_CH3OCLREN_MSK BIT(TIMER_CHMR2_CH3OCLREN_POS) + +#define TIMER_CHMR2_CH3OMOD_POSS 4U +#define TIMER_CHMR2_CH3OMOD_POSE 6U +#define TIMER_CHMR2_CH3OMOD_MSK BITS(TIMER_CHMR2_CH3OMOD_POSS,TIMER_CHMR2_CH3OMOD_POSE) + +#define TIMER_CHMR2_CH3OPEN_POS 3U +#define TIMER_CHMR2_CH3OPEN_MSK BIT(TIMER_CHMR2_CH3OPEN_POS) + +#define TIMER_CHMR2_CH3OFEN_POS 2U +#define TIMER_CHMR2_CH3OFEN_MSK BIT(TIMER_CHMR2_CH3OFEN_POS) + +#define TIMER_CHMR2_CC3SSEL_POSS 0U +#define TIMER_CHMR2_CC3SSEL_POSE 1U +#define TIMER_CHMR2_CC3SSEL_MSK BITS(TIMER_CHMR2_CC3SSEL_POSS,TIMER_CHMR2_CC3SSEL_POSE) + +/* Input */ +#define TIMER_CHMR2_I4FLT_POSS 12U +#define TIMER_CHMR2_I4FLT_POSE 15U +#define TIMER_CHMR2_I4FLT_MSK BITS(TIMER_CHMR2_I4FLT_POSS,TIMER_CHMR2_I4FLT_POSE) + +#define TIMER_CHMR2_IC4PRES_POSS 10U +#define TIMER_CHMR2_IC4PRES_POSE 11U +#define TIMER_CHMR2_IC4PRES_MSK BITS(TIMER_CHMR2_IC4PRES_POSS,TIMER_CHMR2_IC4PRES_POSE) + +#define TIMER_CHMR2_CC4SSEL_POSS 8U +#define TIMER_CHMR2_CC4SSEL_POSE 9U +#define TIMER_CHMR2_CC4SSEL_MSK BITS(TIMER_CHMR2_CC4SSEL_POSS,TIMER_CHMR2_CC4SSEL_POSE) + +#define TIMER_CHMR2_I3FLT_POSS 4U +#define TIMER_CHMR2_I3FLT_POSE 7U +#define TIMER_CHMR2_I3FLT_MSK BITS(TIMER_CHMR2_I3FLT_POSS,TIMER_CHMR2_I3FLT_POSE) + +#define TIMER_CHMR2_IC3PRES_POSS 2U +#define TIMER_CHMR2_IC3PRES_POSE 3U +#define TIMER_CHMR2_IC3PRES_MSK BITS(TIMER_CHMR2_IC3PRES_POSS,TIMER_CHMR2_IC3PRES_POSE) + +#define TIMER_CHMR2_CC3SSEL_POSS 0U +#define TIMER_CHMR2_CC3SSEL_POSE 1U +#define TIMER_CHMR2_CC3SSEL_MSK BITS(TIMER_CHMR2_CC3SSEL_POSS,TIMER_CHMR2_CC3SSEL_POSE) + +/****************** Bit definition for TIMER_CCEP register ************************/ + +#define TIMER_CCEP_CC4POL_POS 13U +#define TIMER_CCEP_CC4POL_MSK BIT(TIMER_CCEP_CC4POL_POS) + +#define TIMER_CCEP_CC4EN_POS 12U +#define TIMER_CCEP_CC4EN_MSK BIT(TIMER_CCEP_CC4EN_POS) + +#define TIMER_CCEP_CC3NPOL_POS 11U +#define TIMER_CCEP_CC3NPOL_MSK BIT(TIMER_CCEP_CC3NPOL_POS) + +#define TIMER_CCEP_CC3NEN_POS 10U +#define TIMER_CCEP_CC3NEN_MSK BIT(TIMER_CCEP_CC3NEN_POS) + +#define TIMER_CCEP_CC3POL_POS 9U +#define TIMER_CCEP_CC3POL_MSK BIT(TIMER_CCEP_CC3POL_POS) + +#define TIMER_CCEP_CC3EN_POS 8U +#define TIMER_CCEP_CC3EN_MSK BIT(TIMER_CCEP_CC3EN_POS) + +#define TIMER_CCEP_CC2NPOL_POS 7U +#define TIMER_CCEP_CC2NPOL_MSK BIT(TIMER_CCEP_CC2NPOL_POS) + +#define TIMER_CCEP_CC2NEN_POS 6U +#define TIMER_CCEP_CC2NEN_MSK BIT(TIMER_CCEP_CC2NEN_POS) + +#define TIMER_CCEP_CC2POL_POS 5U +#define TIMER_CCEP_CC2POL_MSK BIT(TIMER_CCEP_CC2POL_POS) + +#define TIMER_CCEP_CC2EN_POS 4U +#define TIMER_CCEP_CC2EN_MSK BIT(TIMER_CCEP_CC2EN_POS) + +#define TIMER_CCEP_CC1NPOL_POS 3U +#define TIMER_CCEP_CC1NPOL_MSK BIT(TIMER_CCEP_CC1NPOL_POS) + +#define TIMER_CCEP_CC1NEN_POS 2U +#define TIMER_CCEP_CC1NEN_MSK BIT(TIMER_CCEP_CC1NEN_POS) + +#define TIMER_CCEP_CC1POL_POS 1U +#define TIMER_CCEP_CC1POL_MSK BIT(TIMER_CCEP_CC1POL_POS) + +#define TIMER_CCEP_CC1EN_POS 0U +#define TIMER_CCEP_CC1EN_MSK BIT(TIMER_CCEP_CC1EN_POS) + +/****************** Bit definition for TIMER_COUNT register ************************/ + +#define TIMER_COUNT_CNTV_POSS 0U +#define TIMER_COUNT_CNTV_POSE 15U +#define TIMER_COUNT_CNTV_MSK BITS(TIMER_COUNT_CNTV_POSS,TIMER_COUNT_CNTV_POSE) + +/****************** Bit definition for TIMER_PRES register ************************/ + +#define TIMER_PRES_PSCV_POSS 0U +#define TIMER_PRES_PSCV_POSE 15U +#define TIMER_PRES_PSCV_MSK BITS(TIMER_PRES_PSCV_POSS,TIMER_PRES_PSCV_POSE) + +/****************** Bit definition for TIMER_AR register ************************/ + +#define TIMER_AR_ARRV_POSS 0U +#define TIMER_AR_ARRV_POSE 15U +#define TIMER_AR_ARRV_MSK BITS(TIMER_AR_ARRV_POSS,TIMER_AR_ARRV_POSE) + +/****************** Bit definition for TIMER_REPAR register ************************/ + +#define TIMER_REPAR_REPV_POSS 0U +#define TIMER_REPAR_REPV_POSE 7U +#define TIMER_REPAR_REPV_MSK BITS(TIMER_REPAR_REPV_POSS,TIMER_REPAR_REPV_POSE) + +/****************** Bit definition for TIMER_CCVAL1 register ************************/ + +#define TIMER_CCVAL1_CCRV1_POSS 0U +#define TIMER_CCVAL1_CCRV1_POSE 15U +#define TIMER_CCVAL1_CCRV1_MSK BITS(TIMER_CCVAL1_CCRV1_POSS,TIMER_CCVAL1_CCRV1_POSE) + +/****************** Bit definition for TIMER_CCVAL2 register ************************/ + +#define TIMER_CCVAL2_CCRV2_POSS 0U +#define TIMER_CCVAL2_CCRV2_POSE 15U +#define TIMER_CCVAL2_CCRV2_MSK BITS(TIMER_CCVAL2_CCRV2_POSS,TIMER_CCVAL2_CCRV2_POSE) + +/****************** Bit definition for TIMER_CCVAL3 register ************************/ + +#define TIMER_CCVAL3_CCRV3_POSS 0U +#define TIMER_CCVAL3_CCRV3_POSE 15U +#define TIMER_CCVAL3_CCRV3_MSK BITS(TIMER_CCVAL3_CCRV3_POSS,TIMER_CCVAL3_CCRV3_POSE) + +/****************** Bit definition for TIMER_CCVAL4 register ************************/ + +#define TIMER_CCVAL4_CCRV4_POSS 0U +#define TIMER_CCVAL4_CCRV4_POSE 15U +#define TIMER_CCVAL4_CCRV4_MSK BITS(TIMER_CCVAL4_CCRV4_POSS,TIMER_CCVAL4_CCRV4_POSE) + +/****************** Bit definition for TIMER_BDCFG register ************************/ + +#define TIMER_BDCFG_GOEN_POS 15U +#define TIMER_BDCFG_GOEN_MSK BIT(TIMER_BDCFG_GOEN_POS) + +#define TIMER_BDCFG_AOEN_POS 14U +#define TIMER_BDCFG_AOEN_MSK BIT(TIMER_BDCFG_AOEN_POS) + +#define TIMER_BDCFG_BRKP_POS 13U +#define TIMER_BDCFG_BRKP_MSK BIT(TIMER_BDCFG_BRKP_POS) + +#define TIMER_BDCFG_BRKEN_POS 12U +#define TIMER_BDCFG_BRKEN_MSK BIT(TIMER_BDCFG_BRKEN_POS) + +#define TIMER_BDCFG_OFFSSR_POS 11U +#define TIMER_BDCFG_OFFSSR_MSK BIT(TIMER_BDCFG_OFFSSR_POS) + +#define TIMER_BDCFG_OFFSSI_POS 10U +#define TIMER_BDCFG_OFFSSI_MSK BIT(TIMER_BDCFG_OFFSSI_POS) + +#define TIMER_BDCFG_LOCKLVL_POSS 8U +#define TIMER_BDCFG_LOCKLVL_POSE 9U +#define TIMER_BDCFG_LOCKLVL_MSK BITS(TIMER_BDCFG_LOCKLVL_POSS,TIMER_BDCFG_LOCKLVL_POSE) + +#define TIMER_BDCFG_DT_POSS 0U +#define TIMER_BDCFG_DT_POSE 7U +#define TIMER_BDCFG_DT_MSK BITS(TIMER_BDCFG_DT_POSS,TIMER_BDCFG_DT_POSE) + +typedef struct +{ + __IO uint32_t CON1; + __IO uint32_t CON2; + __IO uint32_t SMCON; + __O uint32_t DIER; + __O uint32_t DIDR; + __I uint32_t DIVS; + __I uint32_t RIF; + __I uint32_t IFM; + __O uint32_t ICR; + __O uint32_t SGE; + __IO uint32_t CHMR1; + __IO uint32_t CHMR2; + __IO uint32_t CCEP; + __IO uint32_t COUNT; + __IO uint32_t PRES; + __IO uint32_t AR; + __IO uint32_t REPAR; + __IO uint32_t CCVAL1; + __IO uint32_t CCVAL2; + __IO uint32_t CCVAL3; + __IO uint32_t CCVAL4; + __IO uint32_t BDCFG; +} TIMER_TypeDef; + +/****************** Bit definition for USART_STAT register ************************/ + +#define USART_STAT_CTSIF_POS 9U +#define USART_STAT_CTSIF_MSK BIT(USART_STAT_CTSIF_POS) + +#define USART_STAT_TXEMPIF_POS 7U +#define USART_STAT_TXEMPIF_MSK BIT(USART_STAT_TXEMPIF_POS) + +#define USART_STAT_TXCIF_POS 6U +#define USART_STAT_TXCIF_MSK BIT(USART_STAT_TXCIF_POS) + +#define USART_STAT_RXNEIF_POS 5U +#define USART_STAT_RXNEIF_MSK BIT(USART_STAT_RXNEIF_POS) + +#define USART_STAT_IDLEIF_POS 4U +#define USART_STAT_IDLEIF_MSK BIT(USART_STAT_IDLEIF_POS) + +#define USART_STAT_OVRIF_POS 3U +#define USART_STAT_OVRIF_MSK BIT(USART_STAT_OVRIF_POS) + +#define USART_STAT_NDETIF_POS 2U +#define USART_STAT_NDETIF_MSK BIT(USART_STAT_NDETIF_POS) + +#define USART_STAT_FERRIF_POS 1U +#define USART_STAT_FERRIF_MSK BIT(USART_STAT_FERRIF_POS) + +#define USART_STAT_PERRIF_POS 0U +#define USART_STAT_PERRIF_MSK BIT(USART_STAT_PERRIF_POS) + +/****************** Bit definition for USART_DATA register ************************/ + +#define USART_DATA_VAL_POSS 0U +#define USART_DATA_VAL_POSE 8U +#define USART_DATA_VAL_MSK BITS(USART_DATA_VAL_POSS,USART_DATA_VAL_POSE) + +/****************** Bit definition for USART_BAUDCON register ************************/ + +#define USART_BAUDCON_DIV_M_POSS 4U +#define USART_BAUDCON_DIV_M_POSE 15U +#define USART_BAUDCON_DIV_M_MSK BITS(USART_BAUDCON_DIV_M_POSS,USART_BAUDCON_DIV_M_POSE) + +#define USART_BAUDCON_DIV_F_POSS 0U +#define USART_BAUDCON_DIV_F_POSE 3U +#define USART_BAUDCON_DIV_F_MSK BITS(USART_BAUDCON_DIV_F_POSS,USART_BAUDCON_DIV_F_POSE) + +/****************** Bit definition for USART_CON0 register ************************/ + +#define USART_CON0_EN_POS 13U +#define USART_CON0_EN_MSK BIT(USART_CON0_EN_POS) + +#define USART_CON0_DLEN_POS 12U +#define USART_CON0_DLEN_MSK BIT(USART_CON0_DLEN_POS) + +#define USART_CON0_WKMOD_POS 11U +#define USART_CON0_WKMOD_MSK BIT(USART_CON0_WKMOD_POS) + +#define USART_CON0_PEN_POS 10U +#define USART_CON0_PEN_MSK BIT(USART_CON0_PEN_POS) + +#define USART_CON0_PSEL_POS 9U +#define USART_CON0_PSEL_MSK BIT(USART_CON0_PSEL_POS) + +#define USART_CON0_PERRIE_POS 8U +#define USART_CON0_PERRIE_MSK BIT(USART_CON0_PERRIE_POS) + +#define USART_CON0_TXEMPIE_POS 7U +#define USART_CON0_TXEMPIE_MSK BIT(USART_CON0_TXEMPIE_POS) + +#define USART_CON0_TXCIE_POS 6U +#define USART_CON0_TXCIE_MSK BIT(USART_CON0_TXCIE_POS) + +#define USART_CON0_RXNEIE_POS 5U +#define USART_CON0_RXNEIE_MSK BIT(USART_CON0_RXNEIE_POS) + +#define USART_CON0_IDLEIE_POS 4U +#define USART_CON0_IDLEIE_MSK BIT(USART_CON0_IDLEIE_POS) + +#define USART_CON0_TXEN_POS 3U +#define USART_CON0_TXEN_MSK BIT(USART_CON0_TXEN_POS) + +#define USART_CON0_RXEN_POS 2U +#define USART_CON0_RXEN_MSK BIT(USART_CON0_RXEN_POS) + +#define USART_CON0_RXWK_POS 1U +#define USART_CON0_RXWK_MSK BIT(USART_CON0_RXWK_POS) + +/****************** Bit definition for USART_CON1 register ************************/ + +#define USART_CON1_STPLEN_POSS 12U +#define USART_CON1_STPLEN_POSE 13U +#define USART_CON1_STPLEN_MSK BITS(USART_CON1_STPLEN_POSS,USART_CON1_STPLEN_POSE) + +#define USART_CON1_SCKEN_POS 11U +#define USART_CON1_SCKEN_MSK BIT(USART_CON1_SCKEN_POS) + +#define USART_CON1_SCKPOL_POS 10U +#define USART_CON1_SCKPOL_MSK BIT(USART_CON1_SCKPOL_POS) + +#define USART_CON1_SCKPHA_POS 9U +#define USART_CON1_SCKPHA_MSK BIT(USART_CON1_SCKPHA_POS) + +#define USART_CON1_LBCP_POS 8U +#define USART_CON1_LBCP_MSK BIT(USART_CON1_LBCP_POS) + +#define USART_CON1_ADDR_POSS 0U +#define USART_CON1_ADDR_POSE 3U +#define USART_CON1_ADDR_MSK BITS(USART_CON1_ADDR_POSS,USART_CON1_ADDR_POSE) + +/****************** Bit definition for USART_CON2 register ************************/ + +#define USART_CON2_CTSIE_POS 10U +#define USART_CON2_CTSIE_MSK BIT(USART_CON2_CTSIE_POS) + +#define USART_CON2_CTSEN_POS 9U +#define USART_CON2_CTSEN_MSK BIT(USART_CON2_CTSEN_POS) + +#define USART_CON2_RTSEN_POS 8U +#define USART_CON2_RTSEN_MSK BIT(USART_CON2_RTSEN_POS) + +#define USART_CON2_TXDMAEN_POS 7U +#define USART_CON2_TXDMAEN_MSK BIT(USART_CON2_TXDMAEN_POS) + +#define USART_CON2_RXDMAEN_POS 6U +#define USART_CON2_RXDMAEN_MSK BIT(USART_CON2_RXDMAEN_POS) + +#define USART_CON2_SMARTEN_POS 5U +#define USART_CON2_SMARTEN_MSK BIT(USART_CON2_SMARTEN_POS) + +#define USART_CON2_NACK_POS 4U +#define USART_CON2_NACK_MSK BIT(USART_CON2_NACK_POS) + +#define USART_CON2_HDPSEL_POS 3U +#define USART_CON2_HDPSEL_MSK BIT(USART_CON2_HDPSEL_POS) + +#define USART_CON2_IREN_POS 1U +#define USART_CON2_IREN_MSK BIT(USART_CON2_IREN_POS) + +#define USART_CON2_ERRIE_POS 0U +#define USART_CON2_ERRIE_MSK BIT(USART_CON2_ERRIE_POS) + +/****************** Bit definition for USART_GP register ************************/ + +#define USART_GP_GTVAL_POSS 8U +#define USART_GP_GTVAL_POSE 15U +#define USART_GP_GTVAL_MSK BITS(USART_GP_GTVAL_POSS,USART_GP_GTVAL_POSE) + +#define USART_GP_PSC_POSS 0U +#define USART_GP_PSC_POSE 7U +#define USART_GP_PSC_MSK BITS(USART_GP_PSC_POSS,USART_GP_PSC_POSE) + +typedef struct +{ + __IO uint32_t STAT; + __IO uint32_t DATA; + __IO uint32_t BAUDCON; + __IO uint32_t CON0; + __IO uint32_t CON1; + __IO uint32_t CON2; + __IO uint32_t GP; +} USART_TypeDef; + +/****************** Bit definition for UART_RBR register ************************/ + +#define UART_RBR_RBR_POSS 0U +#define UART_RBR_RBR_POSE 8U +#define UART_RBR_RBR_MSK BITS(UART_RBR_RBR_POSS,UART_RBR_RBR_POSE) + +/****************** Bit definition for UART_TBR register ************************/ + +#define UART_TBR_TBR_POSS 0U +#define UART_TBR_TBR_POSE 8U +#define UART_TBR_TBR_MSK BITS(UART_TBR_TBR_POSS,UART_TBR_TBR_POSE) + +/****************** Bit definition for UART_BRR register ************************/ + +#define UART_BRR_BRR_POSS 0U +#define UART_BRR_BRR_POSE 15U +#define UART_BRR_BRR_MSK BITS(UART_BRR_BRR_POSS,UART_BRR_BRR_POSE) + +/****************** Bit definition for UART_LCR register ************************/ + +#define UART_LCR_SWAP_POS 13U +#define UART_LCR_SWAP_MSK BIT(UART_LCR_SWAP_POS) + +#define UART_LCR_TXINV_POS 12U +#define UART_LCR_TXINV_MSK BIT(UART_LCR_TXINV_POS) + +#define UART_LCR_RXINV_POS 11U +#define UART_LCR_RXINV_MSK BIT(UART_LCR_RXINV_POS) + +#define UART_LCR_DATAINV_POS 10U +#define UART_LCR_DATAINV_MSK BIT(UART_LCR_DATAINV_POS) + +#define UART_LCR_MSBFIRST_POS 9U +#define UART_LCR_MSBFIRST_MSK BIT(UART_LCR_MSBFIRST_POS) + +#define UART_LCR_RTOEN_POS 8U +#define UART_LCR_RTOEN_MSK BIT(UART_LCR_RTOEN_POS) + +#define UART_LCR_BRWEN_POS 7U +#define UART_LCR_BRWEN_MSK BIT(UART_LCR_BRWEN_POS) + +#define UART_LCR_BC_POS 6U +#define UART_LCR_BC_MSK BIT(UART_LCR_BC_POS) + +#define UART_LCR_RXEN_POS 5U +#define UART_LCR_RXEN_MSK BIT(UART_LCR_RXEN_POS) + +#define UART_LCR_PS_POS 4U +#define UART_LCR_PS_MSK BIT(UART_LCR_PS_POS) + +#define UART_LCR_PEN_POS 3U +#define UART_LCR_PEN_MSK BIT(UART_LCR_PEN_POS) + +#define UART_LCR_STOP_POS 2U +#define UART_LCR_STOP_MSK BIT(UART_LCR_STOP_POS) + +#define UART_LCR_DLS_POSS 0U +#define UART_LCR_DLS_POSE 1U +#define UART_LCR_DLS_MSK BITS(UART_LCR_DLS_POSS,UART_LCR_DLS_POSE) + +/****************** Bit definition for UART_MCR register ************************/ + +#define UART_MCR_HDSEL_POS 22U +#define UART_MCR_HDSEL_MSK BIT(UART_MCR_HDSEL_POS) + +#define UART_MCR_ABRRS_POS 15U +#define UART_MCR_ABRRS_MSK BIT(UART_MCR_ABRRS_POS) + +#define UART_MCR_ABRMOD_POSS 13U +#define UART_MCR_ABRMOD_POSE 14U +#define UART_MCR_ABRMOD_MSK BITS(UART_MCR_ABRMOD_POSS,UART_MCR_ABRMOD_POSE) + +#define UART_MCR_ABREN_POS 12U +#define UART_MCR_ABREN_MSK BIT(UART_MCR_ABREN_POS) + +#define UART_MCR_DMAEN_POS 11U +#define UART_MCR_DMAEN_MSK BIT(UART_MCR_DMAEN_POS) + +#define UART_MCR_LINBDL_POS 10U +#define UART_MCR_LINBDL_MSK BIT(UART_MCR_LINBDL_POS) + +#define UART_MCR_BKREQ_POS 9U +#define UART_MCR_BKREQ_MSK BIT(UART_MCR_BKREQ_POS) + +#define UART_MCR_LINEN_POS 8U +#define UART_MCR_LINEN_MSK BIT(UART_MCR_LINEN_POS) + +#define UART_MCR_AADINV_POS 7U +#define UART_MCR_AADINV_MSK BIT(UART_MCR_AADINV_POS) + +#define UART_MCR_AADDIR_POS 6U +#define UART_MCR_AADDIR_MSK BIT(UART_MCR_AADDIR_POS) + +#define UART_MCR_AADNOR_POS 5U +#define UART_MCR_AADNOR_MSK BIT(UART_MCR_AADNOR_POS) + +#define UART_MCR_AADEN_POS 4U +#define UART_MCR_AADEN_MSK BIT(UART_MCR_AADEN_POS) + +#define UART_MCR_RTSCTRL_POS 3U +#define UART_MCR_RTSCTRL_MSK BIT(UART_MCR_RTSCTRL_POS) + +#define UART_MCR_AFCEN_POS 2U +#define UART_MCR_AFCEN_MSK BIT(UART_MCR_AFCEN_POS) + +#define UART_MCR_LBEN_POS 1U +#define UART_MCR_LBEN_MSK BIT(UART_MCR_LBEN_POS) + +#define UART_MCR_IREN_POS 0U +#define UART_MCR_IREN_MSK BIT(UART_MCR_IREN_POS) + +/****************** Bit definition for UART_CR register ************************/ + +#define UART_CR_PSC_POSS 16U +#define UART_CR_PSC_POSE 23U +#define UART_CR_PSC_MSK BITS(UART_CR_PSC_POSS,UART_CR_PSC_POSE) + +#define UART_CR_DLY_POSS 8U +#define UART_CR_DLY_POSE 15U +#define UART_CR_DLY_MSK BITS(UART_CR_DLY_POSS,UART_CR_DLY_POSE) + +#define UART_CR_ADDR_POSS 0U +#define UART_CR_ADDR_POSE 7U +#define UART_CR_ADDR_MSK BITS(UART_CR_ADDR_POSS,UART_CR_ADDR_POSE) + +/****************** Bit definition for UART_RTOR register ************************/ + +#define UART_RTOR_BLEN_POSS 24U +#define UART_RTOR_BLEN_POSE 31U +#define UART_RTOR_BLEN_MSK BITS(UART_RTOR_BLEN_POSS,UART_RTOR_BLEN_POSE) + +#define UART_RTOR_RTO_POSS 0U +#define UART_RTOR_RTO_POSE 23U +#define UART_RTOR_RTO_MSK BITS(UART_RTOR_RTO_POSS,UART_RTOR_RTO_POSE) + +/****************** Bit definition for UART_FCR register ************************/ + +#define UART_FCR_TXFL_POSS 12U +#define UART_FCR_TXFL_POSE 15U +#define UART_FCR_TXFL_MSK BITS(UART_FCR_TXFL_POSS,UART_FCR_TXFL_POSE) + +#define UART_FCR_RXFL_POSS 8U +#define UART_FCR_RXFL_POSE 11U +#define UART_FCR_RXFL_MSK BITS(UART_FCR_RXFL_POSS,UART_FCR_RXFL_POSE) + +#define UART_FCR_TXTL_POSS 6U +#define UART_FCR_TXTL_POSE 7U +#define UART_FCR_TXTL_MSK BITS(UART_FCR_TXTL_POSS,UART_FCR_TXTL_POSE) + +#define UART_FCR_RXTL_POSS 4U +#define UART_FCR_RXTL_POSE 5U +#define UART_FCR_RXTL_MSK BITS(UART_FCR_RXTL_POSS,UART_FCR_RXTL_POSE) + +#define UART_FCR_TFRST_POS 2U +#define UART_FCR_TFRST_MSK BIT(UART_FCR_TFRST_POS) + +#define UART_FCR_RFRST_POS 1U +#define UART_FCR_RFRST_MSK BIT(UART_FCR_RFRST_POS) + +#define UART_FCR_FIFOEN_POS 0U +#define UART_FCR_FIFOEN_MSK BIT(UART_FCR_FIFOEN_POS) + +/****************** Bit definition for UART_SR register ************************/ + +#define UART_SR_CTS_POS 14U +#define UART_SR_CTS_MSK BIT(UART_SR_CTS_POS) + +#define UART_SR_DCTS_POS 13U +#define UART_SR_DCTS_MSK BIT(UART_SR_DCTS_POS) + +#define UART_SR_RFF_POS 12U +#define UART_SR_RFF_MSK BIT(UART_SR_RFF_POS) + +#define UART_SR_RFNE_POS 11U +#define UART_SR_RFNE_MSK BIT(UART_SR_RFNE_POS) + +#define UART_SR_TFEM_POS 10U +#define UART_SR_TFEM_MSK BIT(UART_SR_TFEM_POS) + +#define UART_SR_TFNF_POS 9U +#define UART_SR_TFNF_MSK BIT(UART_SR_TFNF_POS) + +#define UART_SR_BUSY_POS 8U +#define UART_SR_BUSY_MSK BIT(UART_SR_BUSY_POS) + +#define UART_SR_RFE_POS 7U +#define UART_SR_RFE_MSK BIT(UART_SR_RFE_POS) + +#define UART_SR_TEM_POS 6U +#define UART_SR_TEM_MSK BIT(UART_SR_TEM_POS) + +#define UART_SR_TBEM_POS 5U +#define UART_SR_TBEM_MSK BIT(UART_SR_TBEM_POS) + +#define UART_SR_BF_POS 4U +#define UART_SR_BF_MSK BIT(UART_SR_BF_POS) + +#define UART_SR_FE_POS 3U +#define UART_SR_FE_MSK BIT(UART_SR_FE_POS) + +#define UART_SR_PE_POS 2U +#define UART_SR_PE_MSK BIT(UART_SR_PE_POS) + +#define UART_SR_OE_POS 1U +#define UART_SR_OE_MSK BIT(UART_SR_OE_POS) + +#define UART_SR_DR_POS 0U +#define UART_SR_DR_MSK BIT(UART_SR_DR_POS) + +/****************** Bit definition for UART_IER register ************************/ + +#define UART_IER_CMIE_POS 11U +#define UART_IER_CMIE_MSK BIT(UART_IER_CMIE_POS) + +#define UART_IER_EOBIE_POS 10U +#define UART_IER_EOBIE_MSK BIT(UART_IER_EOBIE_POS) + +#define UART_IER_TCIE_POS 9U +#define UART_IER_TCIE_MSK BIT(UART_IER_TCIE_POS) + +#define UART_IER_LINBKIE_POS 8U +#define UART_IER_LINBKIE_MSK BIT(UART_IER_LINBKIE_POS) + +#define UART_IER_ABTOIE_POS 7U +#define UART_IER_ABTOIE_MSK BIT(UART_IER_ABTOIE_POS) + +#define UART_IER_ABEIE_POS 6U +#define UART_IER_ABEIE_MSK BIT(UART_IER_ABEIE_POS) + +#define UART_IER_BZIE_POS 5U +#define UART_IER_BZIE_MSK BIT(UART_IER_BZIE_POS) + +#define UART_IER_RTOIE_POS 4U +#define UART_IER_RTOIE_MSK BIT(UART_IER_RTOIE_POS) + +#define UART_IER_MDSIE_POS 3U +#define UART_IER_MDSIE_MSK BIT(UART_IER_MDSIE_POS) + +#define UART_IER_RXSIE_POS 2U +#define UART_IER_RXSIE_MSK BIT(UART_IER_RXSIE_POS) + +#define UART_IER_TXSIE_POS 1U +#define UART_IER_TXSIE_MSK BIT(UART_IER_TXSIE_POS) + +#define UART_IER_RXRDIE_POS 0U +#define UART_IER_RXRDIE_MSK BIT(UART_IER_RXRDIE_POS) + +/****************** Bit definition for UART_IDR register ************************/ + +#define UART_IDR_CMID_POS 11U +#define UART_IDR_CMID_MSK BIT(UART_IDR_CMID_POS) + +#define UART_IDR_EOBID_POS 10U +#define UART_IDR_EOBID_MSK BIT(UART_IDR_EOBID_POS) + +#define UART_IDR_TCID_POS 9U +#define UART_IDR_TCID_MSK BIT(UART_IDR_TCID_POS) + +#define UART_IDR_LINBKID_POS 8U +#define UART_IDR_LINBKID_MSK BIT(UART_IDR_LINBKID_POS) + +#define UART_IDR_ABTOID_POS 7U +#define UART_IDR_ABTOID_MSK BIT(UART_IDR_ABTOID_POS) + +#define UART_IDR_ABEID_POS 6U +#define UART_IDR_ABEID_MSK BIT(UART_IDR_ABEID_POS) + +#define UART_IDR_BZID_POS 5U +#define UART_IDR_BZID_MSK BIT(UART_IDR_BZID_POS) + +#define UART_IDR_RTOID_POS 4U +#define UART_IDR_RTOID_MSK BIT(UART_IDR_RTOID_POS) + +#define UART_IDR_MDSID_POS 3U +#define UART_IDR_MDSID_MSK BIT(UART_IDR_MDSID_POS) + +#define UART_IDR_RXSID_POS 2U +#define UART_IDR_RXSID_MSK BIT(UART_IDR_RXSID_POS) + +#define UART_IDR_TXSID_POS 1U +#define UART_IDR_TXSID_MSK BIT(UART_IDR_TXSID_POS) + +#define UART_IDR_RXRDID_POS 0U +#define UART_IDR_RXRDID_MSK BIT(UART_IDR_RXRDID_POS) + +/****************** Bit definition for UART_IVS register ************************/ + +#define UART_IVS_CMIS_POS 11U +#define UART_IVS_CMIS_MSK BIT(UART_IVS_CMIS_POS) + +#define UART_IVS_EOBIS_POS 10U +#define UART_IVS_EOBIS_MSK BIT(UART_IVS_EOBIS_POS) + +#define UART_IVS_TCIS_POS 9U +#define UART_IVS_TCIS_MSK BIT(UART_IVS_TCIS_POS) + +#define UART_IVS_LINBKIS_POS 8U +#define UART_IVS_LINBKIS_MSK BIT(UART_IVS_LINBKIS_POS) + +#define UART_IVS_ABTOIS_POS 7U +#define UART_IVS_ABTOIS_MSK BIT(UART_IVS_ABTOIS_POS) + +#define UART_IVS_ABEIS_POS 6U +#define UART_IVS_ABEIS_MSK BIT(UART_IVS_ABEIS_POS) + +#define UART_IVS_BZIS_POS 5U +#define UART_IVS_BZIS_MSK BIT(UART_IVS_BZIS_POS) + +#define UART_IVS_RTOIS_POS 4U +#define UART_IVS_RTOIS_MSK BIT(UART_IVS_RTOIS_POS) + +#define UART_IVS_MDSIS_POS 3U +#define UART_IVS_MDSIS_MSK BIT(UART_IVS_MDSIS_POS) + +#define UART_IVS_RXSIS_POS 2U +#define UART_IVS_RXSIS_MSK BIT(UART_IVS_RXSIS_POS) + +#define UART_IVS_TXSIS_POS 1U +#define UART_IVS_TXSIS_MSK BIT(UART_IVS_TXSIS_POS) + +#define UART_IVS_RXRDIS_POS 0U +#define UART_IVS_RXRDIS_MSK BIT(UART_IVS_RXRDIS_POS) + +/****************** Bit definition for UART_RIF register ************************/ + +#define UART_RIF_CMIF_POS 11U +#define UART_RIF_CMIF_MSK BIT(UART_RIF_CMIF_POS) + +#define UART_RIF_EOBIF_POS 10U +#define UART_RIF_EOBIF_MSK BIT(UART_RIF_EOBIF_POS) + +#define UART_RIF_TCIF_POS 9U +#define UART_RIF_TCIF_MSK BIT(UART_RIF_TCIF_POS) + +#define UART_RIF_LINBKIF_POS 8U +#define UART_RIF_LINBKIF_MSK BIT(UART_RIF_LINBKIF_POS) + +#define UART_RIF_ABTOIF_POS 7U +#define UART_RIF_ABTOIF_MSK BIT(UART_RIF_ABTOIF_POS) + +#define UART_RIF_ABEIF_POS 6U +#define UART_RIF_ABEIF_MSK BIT(UART_RIF_ABEIF_POS) + +#define UART_RIF_BZIF_POS 5U +#define UART_RIF_BZIF_MSK BIT(UART_RIF_BZIF_POS) + +#define UART_RIF_RTOIF_POS 4U +#define UART_RIF_RTOIF_MSK BIT(UART_RIF_RTOIF_POS) + +#define UART_RIF_MDSIF_POS 3U +#define UART_RIF_MDSIF_MSK BIT(UART_RIF_MDSIF_POS) + +#define UART_RIF_RXSIF_POS 2U +#define UART_RIF_RXSIF_MSK BIT(UART_RIF_RXSIF_POS) + +#define UART_RIF_TXSIF_POS 1U +#define UART_RIF_TXSIF_MSK BIT(UART_RIF_TXSIF_POS) + +#define UART_RIF_RXRDIF_POS 0U +#define UART_RIF_RXRDIF_MSK BIT(UART_RIF_RXRDIF_POS) + +/****************** Bit definition for UART_IFM register ************************/ + +#define UART_IFM_CMIM_POS 11U +#define UART_IFM_CMIM_MSK BIT(UART_IFM_CMIM_POS) + +#define UART_IFM_EOBIM_POS 10U +#define UART_IFM_EOBIM_MSK BIT(UART_IFM_EOBIM_POS) + +#define UART_IFM_TCIM_POS 9U +#define UART_IFM_TCIM_MSK BIT(UART_IFM_TCIM_POS) + +#define UART_IFM_LINBKIM_POS 8U +#define UART_IFM_LINBKIM_MSK BIT(UART_IFM_LINBKIM_POS) + +#define UART_IFM_ABTOIM_POS 7U +#define UART_IFM_ABTOIM_MSK BIT(UART_IFM_ABTOIM_POS) + +#define UART_IFM_ABEIM_POS 6U +#define UART_IFM_ABEIM_MSK BIT(UART_IFM_ABEIM_POS) + +#define UART_IFM_BZIM_POS 5U +#define UART_IFM_BZIM_MSK BIT(UART_IFM_BZIM_POS) + +#define UART_IFM_RTOIM_POS 4U +#define UART_IFM_RTOIM_MSK BIT(UART_IFM_RTOIM_POS) + +#define UART_IFM_MDSIM_POS 3U +#define UART_IFM_MDSIM_MSK BIT(UART_IFM_MDSIM_POS) + +#define UART_IFM_RXSIM_POS 2U +#define UART_IFM_RXSIM_MSK BIT(UART_IFM_RXSIM_POS) + +#define UART_IFM_TXSIM_POS 1U +#define UART_IFM_TXSIM_MSK BIT(UART_IFM_TXSIM_POS) + +#define UART_IFM_RXRDIM_POS 0U +#define UART_IFM_RXRDIM_MSK BIT(UART_IFM_RXRDIM_POS) + +/****************** Bit definition for UART_ICR register ************************/ + +#define UART_ICR_CMIC_POS 11U +#define UART_ICR_CMIC_MSK BIT(UART_ICR_CMIC_POS) + +#define UART_ICR_EOBIC_POS 10U +#define UART_ICR_EOBIC_MSK BIT(UART_ICR_EOBIC_POS) + +#define UART_ICR_TCIC_POS 9U +#define UART_ICR_TCIC_MSK BIT(UART_ICR_TCIC_POS) + +#define UART_ICR_LINBKIC_POS 8U +#define UART_ICR_LINBKIC_MSK BIT(UART_ICR_LINBKIC_POS) + +#define UART_ICR_ABTOIC_POS 7U +#define UART_ICR_ABTOIC_MSK BIT(UART_ICR_ABTOIC_POS) + +#define UART_ICR_ABEIC_POS 6U +#define UART_ICR_ABEIC_MSK BIT(UART_ICR_ABEIC_POS) + +#define UART_ICR_BZIC_POS 5U +#define UART_ICR_BZIC_MSK BIT(UART_ICR_BZIC_POS) + +#define UART_ICR_CHTOIC_POS 4U +#define UART_ICR_CHTOIC_MSK BIT(UART_ICR_CHTOIC_POS) + +#define UART_ICR_MDSIC_POS 3U +#define UART_ICR_MDSIC_MSK BIT(UART_ICR_MDSIC_POS) + +#define UART_ICR_RXSIC_POS 2U +#define UART_ICR_RXSIC_MSK BIT(UART_ICR_RXSIC_POS) + +#define UART_ICR_TXSIC_POS 1U +#define UART_ICR_TXSIC_MSK BIT(UART_ICR_TXSIC_POS) + +#define UART_ICR_RXRDIC_POS 0U +#define UART_ICR_RXRDIC_MSK BIT(UART_ICR_RXRDIC_POS) + +typedef struct +{ + __I uint32_t RBR; + __IO uint32_t TBR; + __IO uint32_t BRR; + __IO uint32_t LCR; + __IO uint32_t MCR; + __IO uint32_t CR; + __IO uint32_t RTOR; + __IO uint32_t FCR; + __I uint32_t SR; + __O uint32_t IER; + __O uint32_t IDR; + __I uint32_t IVS; + __I uint32_t RIF; + __I uint32_t IFM; + __O uint32_t ICR; +} UART_TypeDef; + +/****************** Bit definition for LPUART_CON0 register ************************/ + +#define LPUART_CON0_MODESEL_POSS 30U +#define LPUART_CON0_MODESEL_POSE 31U +#define LPUART_CON0_MODESEL_MSK BITS(LPUART_CON0_MODESEL_POSS,LPUART_CON0_MODESEL_POSE) + +#define LPUART_CON0_TXDMAE_POS 29U +#define LPUART_CON0_TXDMAE_MSK BIT(LPUART_CON0_TXDMAE_POS) + +#define LPUART_CON0_RXDMAE_POS 28U +#define LPUART_CON0_RXDMAE_MSK BIT(LPUART_CON0_RXDMAE_POS) + +#define LPUART_CON0_INTERVAL_POSS 16U +#define LPUART_CON0_INTERVAL_POSE 23U +#define LPUART_CON0_INTERVAL_MSK BITS(LPUART_CON0_INTERVAL_POSS,LPUART_CON0_INTERVAL_POSE) + +#define LPUART_CON0_SYNCBP_POS 15U +#define LPUART_CON0_SYNCBP_MSK BIT(LPUART_CON0_SYNCBP_POS) + +#define LPUART_CON0_CTSPOL_POS 13U +#define LPUART_CON0_CTSPOL_MSK BIT(LPUART_CON0_CTSPOL_POS) + +#define LPUART_CON0_RTSPOL_POS 12U +#define LPUART_CON0_RTSPOL_MSK BIT(LPUART_CON0_RTSPOL_POS) + +#define LPUART_CON0_ATCTSE_POS 11U +#define LPUART_CON0_ATCTSE_MSK BIT(LPUART_CON0_ATCTSE_POS) + +#define LPUART_CON0_ATRTSE_POS 10U +#define LPUART_CON0_ATRTSE_MSK BIT(LPUART_CON0_ATRTSE_POS) + +#define LPUART_CON0_BRKCE_POS 8U +#define LPUART_CON0_BRKCE_MSK BIT(LPUART_CON0_BRKCE_POS) + +#define LPUART_CON0_LPBMOD_POS 7U +#define LPUART_CON0_LPBMOD_MSK BIT(LPUART_CON0_LPBMOD_POS) + +#define LPUART_CON0_STICKPARSEL_POS 6U +#define LPUART_CON0_STICKPARSEL_MSK BIT(LPUART_CON0_STICKPARSEL_POS) + +#define LPUART_CON0_EVENPARSEL_POS 5U +#define LPUART_CON0_EVENPARSEL_MSK BIT(LPUART_CON0_EVENPARSEL_POS) + +#define LPUART_CON0_PARCHKE_POS 4U +#define LPUART_CON0_PARCHKE_MSK BIT(LPUART_CON0_PARCHKE_POS) + +#define LPUART_CON0_STPLENTH_POS 3U +#define LPUART_CON0_STPLENTH_MSK BIT(LPUART_CON0_STPLENTH_POS) + +#define LPUART_CON0_DATLENTH_POSS 0U +#define LPUART_CON0_DATLENTH_POSE 2U +#define LPUART_CON0_DATLENTH_MSK BITS(LPUART_CON0_DATLENTH_POSS,LPUART_CON0_DATLENTH_POSE) + +/****************** Bit definition for LPUART_CON1 register ************************/ + +#define LPUART_CON1_ADDCMP_POSS 24U +#define LPUART_CON1_ADDCMP_POSE 31U +#define LPUART_CON1_ADDCMP_MSK BITS(LPUART_CON1_ADDCMP_POSS,LPUART_CON1_ADDCMP_POSE) + +#define LPUART_CON1_ADETE_POS 23U +#define LPUART_CON1_ADETE_MSK BIT(LPUART_CON1_ADETE_POS) + +#define LPUART_CON1_ATDIRM_POS 22U +#define LPUART_CON1_ATDIRM_MSK BIT(LPUART_CON1_ATDIRM_POS) + +#define LPUART_CON1_ATADETE_POS 21U +#define LPUART_CON1_ATADETE_MSK BIT(LPUART_CON1_ATADETE_POS) + +#define LPUART_CON1_NMPMOD_POS 20U +#define LPUART_CON1_NMPMOD_MSK BIT(LPUART_CON1_NMPMOD_POS) + +#define LPUART_CON1_IRWIDTH_POS 16U +#define LPUART_CON1_IRWIDTH_MSK BIT(LPUART_CON1_IRWIDTH_POS) + +#define LPUART_CON1_TOICMP_POSS 8U +#define LPUART_CON1_TOICMP_POSE 15U +#define LPUART_CON1_TOICMP_MSK BITS(LPUART_CON1_TOICMP_POSS,LPUART_CON1_TOICMP_POSE) + +#define LPUART_CON1_TOCNTE_POS 7U +#define LPUART_CON1_TOCNTE_MSK BIT(LPUART_CON1_TOCNTE_POS) + +#define LPUART_CON1_IRTXINV_POS 3U +#define LPUART_CON1_IRTXINV_MSK BIT(LPUART_CON1_IRTXINV_POS) + +#define LPUART_CON1_IRRXINV_POS 2U +#define LPUART_CON1_IRRXINV_MSK BIT(LPUART_CON1_IRRXINV_POS) + +#define LPUART_CON1_IRTXE_POS 1U +#define LPUART_CON1_IRTXE_MSK BIT(LPUART_CON1_IRTXE_POS) + +#define LPUART_CON1_RTS_POS 0U +#define LPUART_CON1_RTS_MSK BIT(LPUART_CON1_RTS_POS) + +/****************** Bit definition for LPUART_CLKDIV register ************************/ + +#define LPUART_CLKDIV_CLKDIV_POSS 0U +#define LPUART_CLKDIV_CLKDIV_POSE 19U +#define LPUART_CLKDIV_CLKDIV_MSK BITS(LPUART_CLKDIV_CLKDIV_POSS,LPUART_CLKDIV_CLKDIV_POSE) + +/****************** Bit definition for LPUART_FIFOCON register ************************/ + +#define LPUART_FIFOCON_RTSTRGLVL_POSS 12U +#define LPUART_FIFOCON_RTSTRGLVL_POSE 15U +#define LPUART_FIFOCON_RTSTRGLVL_MSK BITS(LPUART_FIFOCON_RTSTRGLVL_POSS,LPUART_FIFOCON_RTSTRGLVL_POSE) + +#define LPUART_FIFOCON_RXTRGLVL_POSS 8U +#define LPUART_FIFOCON_RXTRGLVL_POSE 11U +#define LPUART_FIFOCON_RXTRGLVL_MSK BITS(LPUART_FIFOCON_RXTRGLVL_POSS,LPUART_FIFOCON_RXTRGLVL_POSE) + +#define LPUART_FIFOCON_NMPMRXDIS_POS 2U +#define LPUART_FIFOCON_NMPMRXDIS_MSK BIT(LPUART_FIFOCON_NMPMRXDIS_POS) + +#define LPUART_FIFOCON_TXRESET_POS 1U +#define LPUART_FIFOCON_TXRESET_MSK BIT(LPUART_FIFOCON_TXRESET_POS) + +#define LPUART_FIFOCON_RXRESET_POS 0U +#define LPUART_FIFOCON_RXRESET_MSK BIT(LPUART_FIFOCON_RXRESET_POS) + +/****************** Bit definition for LPUART_RXDR register ************************/ + +#define LPUART_RXDR_FERR_POS 15U +#define LPUART_RXDR_FERR_MSK BIT(LPUART_RXDR_FERR_POS) + +#define LPUART_RXDR_PERR_POS 14U +#define LPUART_RXDR_PERR_MSK BIT(LPUART_RXDR_PERR_POS) + +#define LPUART_RXDR_RXDR_POSS 0U +#define LPUART_RXDR_RXDR_POSE 8U +#define LPUART_RXDR_RXDR_MSK BITS(LPUART_RXDR_RXDR_POSS,LPUART_RXDR_RXDR_POSE) + +/****************** Bit definition for LPUART_TXDR register ************************/ + +#define LPUART_TXDR_TXDR_POSS 0U +#define LPUART_TXDR_TXDR_POSE 8U +#define LPUART_TXDR_TXDR_MSK BITS(LPUART_TXDR_TXDR_POSS,LPUART_TXDR_TXDR_POSE) + +/****************** Bit definition for LPUART_STAT register ************************/ + +#define LPUART_STAT_RTSSTAT_POS 18U +#define LPUART_STAT_RTSSTAT_MSK BIT(LPUART_STAT_RTSSTAT_POS) + +#define LPUART_STAT_CTSSTAT_POS 17U +#define LPUART_STAT_CTSSTAT_MSK BIT(LPUART_STAT_CTSSTAT_POS) + +#define LPUART_STAT_TXIDLE_POS 16U +#define LPUART_STAT_TXIDLE_MSK BIT(LPUART_STAT_TXIDLE_POS) + +#define LPUART_STAT_TXFULL_POS 15U +#define LPUART_STAT_TXFULL_MSK BIT(LPUART_STAT_TXFULL_POS) + +#define LPUART_STAT_TXEMP_POS 14U +#define LPUART_STAT_TXEMP_MSK BIT(LPUART_STAT_TXEMP_POS) + +#define LPUART_STAT_TXPTR_POSS 8U +#define LPUART_STAT_TXPTR_POSE 13U +#define LPUART_STAT_TXPTR_MSK BITS(LPUART_STAT_TXPTR_POSS,LPUART_STAT_TXPTR_POSE) + +#define LPUART_STAT_RXFULL_POS 7U +#define LPUART_STAT_RXFULL_MSK BIT(LPUART_STAT_RXFULL_POS) + +#define LPUART_STAT_RXEMP_POS 6U +#define LPUART_STAT_RXEMP_MSK BIT(LPUART_STAT_RXEMP_POS) + +#define LPUART_STAT_RXPTR_POSS 0U +#define LPUART_STAT_RXPTR_POSE 5U +#define LPUART_STAT_RXPTR_MSK BITS(LPUART_STAT_RXPTR_POSS,LPUART_STAT_RXPTR_POSE) + +/****************** Bit definition for LPUART_IER register ************************/ + +#define LPUART_IER_TCIE_POS 15U +#define LPUART_IER_TCIE_MSK BIT(LPUART_IER_TCIE_POS) + +#define LPUART_IER_ADETIE_POS 12U +#define LPUART_IER_ADETIE_MSK BIT(LPUART_IER_ADETIE_POS) + +#define LPUART_IER_BRKERRIE_POS 11U +#define LPUART_IER_BRKERRIE_MSK BIT(LPUART_IER_BRKERRIE_POS) + +#define LPUART_IER_FERRIE_POS 10U +#define LPUART_IER_FERRIE_MSK BIT(LPUART_IER_FERRIE_POS) + +#define LPUART_IER_PERRIE_POS 9U +#define LPUART_IER_PERRIE_MSK BIT(LPUART_IER_PERRIE_POS) + +#define LPUART_IER_DATWKIE_POS 8U +#define LPUART_IER_DATWKIE_MSK BIT(LPUART_IER_DATWKIE_POS) + +#define LPUART_IER_CTSWKIE_POS 7U +#define LPUART_IER_CTSWKIE_MSK BIT(LPUART_IER_CTSWKIE_POS) + +#define LPUART_IER_TXOVIE_POS 5U +#define LPUART_IER_TXOVIE_MSK BIT(LPUART_IER_TXOVIE_POS) + +#define LPUART_IER_RXOVIE_POS 4U +#define LPUART_IER_RXOVIE_MSK BIT(LPUART_IER_RXOVIE_POS) + +#define LPUART_IER_RXTOIE_POS 3U +#define LPUART_IER_RXTOIE_MSK BIT(LPUART_IER_RXTOIE_POS) + +#define LPUART_IER_CTSDETIE_POS 2U +#define LPUART_IER_CTSDETIE_MSK BIT(LPUART_IER_CTSDETIE_POS) + +#define LPUART_IER_TBEMPIE_POS 1U +#define LPUART_IER_TBEMPIE_MSK BIT(LPUART_IER_TBEMPIE_POS) + +#define LPUART_IER_RBRIE_POS 0U +#define LPUART_IER_RBRIE_MSK BIT(LPUART_IER_RBRIE_POS) + +/****************** Bit definition for LPUART_IFLAG register ************************/ + +#define LPUART_IFLAG_TCIF_POS 15U +#define LPUART_IFLAG_TCIF_MSK BIT(LPUART_IFLAG_TCIF_POS) + +#define LPUART_IFLAG_ADETIF_POS 12U +#define LPUART_IFLAG_ADETIF_MSK BIT(LPUART_IFLAG_ADETIF_POS) + +#define LPUART_IFLAG_BRKERRIF_POS 11U +#define LPUART_IFLAG_BRKERRIF_MSK BIT(LPUART_IFLAG_BRKERRIF_POS) + +#define LPUART_IFLAG_FERRIF_POS 10U +#define LPUART_IFLAG_FERRIF_MSK BIT(LPUART_IFLAG_FERRIF_POS) + +#define LPUART_IFLAG_PERRIF_POS 9U +#define LPUART_IFLAG_PERRIF_MSK BIT(LPUART_IFLAG_PERRIF_POS) + +#define LPUART_IFLAG_DATWKIF_POS 8U +#define LPUART_IFLAG_DATWKIF_MSK BIT(LPUART_IFLAG_DATWKIF_POS) + +#define LPUART_IFLAG_CTSWKIF_POS 7U +#define LPUART_IFLAG_CTSWKIF_MSK BIT(LPUART_IFLAG_CTSWKIF_POS) + +#define LPUART_IFLAG_TXOVIF_POS 5U +#define LPUART_IFLAG_TXOVIF_MSK BIT(LPUART_IFLAG_TXOVIF_POS) + +#define LPUART_IFLAG_RXOVIF_POS 4U +#define LPUART_IFLAG_RXOVIF_MSK BIT(LPUART_IFLAG_RXOVIF_POS) + +#define LPUART_IFLAG_RXTOIF_POS 3U +#define LPUART_IFLAG_RXTOIF_MSK BIT(LPUART_IFLAG_RXTOIF_POS) + +#define LPUART_IFLAG_CTSDETIF_POS 2U +#define LPUART_IFLAG_CTSDETIF_MSK BIT(LPUART_IFLAG_CTSDETIF_POS) + +#define LPUART_IFLAG_TBEMPIF_POS 1U +#define LPUART_IFLAG_TBEMPIF_MSK BIT(LPUART_IFLAG_TBEMPIF_POS) + +#define LPUART_IFLAG_RBRIF_POS 0U +#define LPUART_IFLAG_RBRIF_MSK BIT(LPUART_IFLAG_RBRIF_POS) + +/****************** Bit definition for LPUART_IFC register ************************/ + +#define LPUART_IFC_TCIFC_POS 15U +#define LPUART_IFC_TCIFC_MSK BIT(LPUART_IFC_TCIFC_POS) + +#define LPUART_IFC_ADETIFC_POS 12U +#define LPUART_IFC_ADETIFC_MSK BIT(LPUART_IFC_ADETIFC_POS) + +#define LPUART_IFC_BRKERRIFC_POS 11U +#define LPUART_IFC_BRKERRIFC_MSK BIT(LPUART_IFC_BRKERRIFC_POS) + +#define LPUART_IFC_FERRIFC_POS 10U +#define LPUART_IFC_FERRIFC_MSK BIT(LPUART_IFC_FERRIFC_POS) + +#define LPUART_IFC_PERRIFC_POS 9U +#define LPUART_IFC_PERRIFC_MSK BIT(LPUART_IFC_PERRIFC_POS) + +#define LPUART_IFC_DATWKIFC_POS 8U +#define LPUART_IFC_DATWKIFC_MSK BIT(LPUART_IFC_DATWKIFC_POS) + +#define LPUART_IFC_CTSWKIFC_POS 7U +#define LPUART_IFC_CTSWKIFC_MSK BIT(LPUART_IFC_CTSWKIFC_POS) + +#define LPUART_IFC_TXOVIFC_POS 5U +#define LPUART_IFC_TXOVIFC_MSK BIT(LPUART_IFC_TXOVIFC_POS) + +#define LPUART_IFC_RXOVIFC_POS 4U +#define LPUART_IFC_RXOVIFC_MSK BIT(LPUART_IFC_RXOVIFC_POS) + +#define LPUART_IFC_CTSDETIFC_POS 2U +#define LPUART_IFC_CTSDETIFC_MSK BIT(LPUART_IFC_CTSDETIFC_POS) + +#define LPUART_IFC_TBEMPIFC_POS 1U +#define LPUART_IFC_TBEMPIFC_MSK BIT(LPUART_IFC_TBEMPIFC_POS) + +#define LPUART_IFC_RBRIFC_POS 0U +#define LPUART_IFC_RBRIFC_MSK BIT(LPUART_IFC_RBRIFC_POS) + +/****************** Bit definition for LPUART_ISTAT register ************************/ + +#define LPUART_ISTAT_TCINT_POS 15U +#define LPUART_ISTAT_TCINT_MSK BIT(LPUART_ISTAT_TCINT_POS) + +#define LPUART_ISTAT_RXSTATINT_POS 9U +#define LPUART_ISTAT_RXSTATINT_MSK BIT(LPUART_ISTAT_RXSTATINT_POS) + +#define LPUART_ISTAT_DATWKINT_POS 8U +#define LPUART_ISTAT_DATWKINT_MSK BIT(LPUART_ISTAT_DATWKINT_POS) + +#define LPUART_ISTAT_CTSWKINT_POS 7U +#define LPUART_ISTAT_CTSWKINT_MSK BIT(LPUART_ISTAT_CTSWKINT_POS) + +#define LPUART_ISTAT_BUFERRINT_POS 4U +#define LPUART_ISTAT_BUFERRINT_MSK BIT(LPUART_ISTAT_BUFERRINT_POS) + +#define LPUART_ISTAT_RXTOINT_POS 3U +#define LPUART_ISTAT_RXTOINT_MSK BIT(LPUART_ISTAT_RXTOINT_POS) + +#define LPUART_ISTAT_CTSDETINT_POS 2U +#define LPUART_ISTAT_CTSDETINT_MSK BIT(LPUART_ISTAT_CTSDETINT_POS) + +#define LPUART_ISTAT_TBEMPINT_POS 1U +#define LPUART_ISTAT_TBEMPINT_MSK BIT(LPUART_ISTAT_TBEMPINT_POS) + +#define LPUART_ISTAT_RBRINT_POS 0U +#define LPUART_ISTAT_RBRINT_MSK BIT(LPUART_ISTAT_RBRINT_POS) + +/****************** Bit definition for LPUART_UPDATE register ************************/ + +#define LPUART_UPDATE_UDIS_POS 0U +#define LPUART_UPDATE_UDIS_MSK BIT(LPUART_UPDATE_UDIS_POS) + +/****************** Bit definition for LPUART_SYNCSTAT register ************************/ + +#define LPUART_SYNCSTAT_FIFOCONWBSY_POS 3U +#define LPUART_SYNCSTAT_FIFOCONWBSY_MSK BIT(LPUART_SYNCSTAT_FIFOCONWBSY_POS) + +#define LPUART_SYNCSTAT_CLKDIVWBSY_POS 2U +#define LPUART_SYNCSTAT_CLKDIVWBSY_MSK BIT(LPUART_SYNCSTAT_CLKDIVWBSY_POS) + +#define LPUART_SYNCSTAT_CON1WBSY_POS 1U +#define LPUART_SYNCSTAT_CON1WBSY_MSK BIT(LPUART_SYNCSTAT_CON1WBSY_POS) + +#define LPUART_SYNCSTAT_CON0WBSY_POS 0U +#define LPUART_SYNCSTAT_CON0WBSY_MSK BIT(LPUART_SYNCSTAT_CON0WBSY_POS) + +typedef struct +{ + __IO uint32_t CON0; + __IO uint32_t CON1; + __IO uint32_t CLKDIV; + __IO uint32_t FIFOCON; + uint32_t RESERVED0 ; + __I uint32_t RXDR; + __O uint32_t TXDR; + __I uint32_t STAT; + __IO uint32_t IER; + __I uint32_t IFLAG; + __O uint32_t IFC; + __I uint32_t ISTAT; + uint32_t RESERVED1[2] ; + __IO uint32_t UPDATE; + __I uint32_t SYNCSTAT; +} LPUART_TypeDef; + +/****************** Bit definition for SPI_CON1 register ************************/ + +#define SPI_CON1_BIDEN_POS 15U +#define SPI_CON1_BIDEN_MSK BIT(SPI_CON1_BIDEN_POS) + +#define SPI_CON1_BIDOEN_POS 14U +#define SPI_CON1_BIDOEN_MSK BIT(SPI_CON1_BIDOEN_POS) + +#define SPI_CON1_CRCEN_POS 13U +#define SPI_CON1_CRCEN_MSK BIT(SPI_CON1_CRCEN_POS) + +#define SPI_CON1_NXTCRC_POS 12U +#define SPI_CON1_NXTCRC_MSK BIT(SPI_CON1_NXTCRC_POS) + +#define SPI_CON1_FLEN_POS 11U +#define SPI_CON1_FLEN_MSK BIT(SPI_CON1_FLEN_POS) + +#define SPI_CON1_RXO_POS 10U +#define SPI_CON1_RXO_MSK BIT(SPI_CON1_RXO_POS) + +#define SPI_CON1_SSEN_POS 9U +#define SPI_CON1_SSEN_MSK BIT(SPI_CON1_SSEN_POS) + +#define SPI_CON1_SSOUT_POS 8U +#define SPI_CON1_SSOUT_MSK BIT(SPI_CON1_SSOUT_POS) + +#define SPI_CON1_LSBFST_POS 7U +#define SPI_CON1_LSBFST_MSK BIT(SPI_CON1_LSBFST_POS) + +#define SPI_CON1_SPIEN_POS 6U +#define SPI_CON1_SPIEN_MSK BIT(SPI_CON1_SPIEN_POS) + +#define SPI_CON1_BAUD_POSS 3U +#define SPI_CON1_BAUD_POSE 5U +#define SPI_CON1_BAUD_MSK BITS(SPI_CON1_BAUD_POSS,SPI_CON1_BAUD_POSE) + +#define SPI_CON1_MSTREN_POS 2U +#define SPI_CON1_MSTREN_MSK BIT(SPI_CON1_MSTREN_POS) + +#define SPI_CON1_CPOL_POS 1U +#define SPI_CON1_CPOL_MSK BIT(SPI_CON1_CPOL_POS) + +#define SPI_CON1_CPHA_POS 0U +#define SPI_CON1_CPHA_MSK BIT(SPI_CON1_CPHA_POS) + +/****************** Bit definition for SPI_CON2 register ************************/ + +#define SPI_CON2_TXBEIE_POS 7U +#define SPI_CON2_TXBEIE_MSK BIT(SPI_CON2_TXBEIE_POS) + +#define SPI_CON2_RXBNEIE_POS 6U +#define SPI_CON2_RXBNEIE_MSK BIT(SPI_CON2_RXBNEIE_POS) + +#define SPI_CON2_ERRIE_POS 5U +#define SPI_CON2_ERRIE_MSK BIT(SPI_CON2_ERRIE_POS) + +#define SPI_CON2_NSSOE_POS 2U +#define SPI_CON2_NSSOE_MSK BIT(SPI_CON2_NSSOE_POS) + +#define SPI_CON2_TXDMA_POS 1U +#define SPI_CON2_TXDMA_MSK BIT(SPI_CON2_TXDMA_POS) + +#define SPI_CON2_RXDMA_POS 0U +#define SPI_CON2_RXDMA_MSK BIT(SPI_CON2_RXDMA_POS) + +/****************** Bit definition for SPI_STAT register ************************/ + +#define SPI_STAT_BUSY_POS 7U +#define SPI_STAT_BUSY_MSK BIT(SPI_STAT_BUSY_POS) + +#define SPI_STAT_OVERR_POS 6U +#define SPI_STAT_OVERR_MSK BIT(SPI_STAT_OVERR_POS) + +#define SPI_STAT_MODERR_POS 5U +#define SPI_STAT_MODERR_MSK BIT(SPI_STAT_MODERR_POS) + +#define SPI_STAT_CRCERR_POS 4U +#define SPI_STAT_CRCERR_MSK BIT(SPI_STAT_CRCERR_POS) + +#define SPI_STAT_TXBE_POS 1U +#define SPI_STAT_TXBE_MSK BIT(SPI_STAT_TXBE_POS) + +#define SPI_STAT_RXBNE_POS 0U +#define SPI_STAT_RXBNE_MSK BIT(SPI_STAT_RXBNE_POS) + +/****************** Bit definition for SPI_DATA register ************************/ + +#define SPI_DATA_VALUE_POSS 0U +#define SPI_DATA_VALUE_POSE 15U +#define SPI_DATA_VALUE_MSK BITS(SPI_DATA_VALUE_POSS,SPI_DATA_VALUE_POSE) + +/****************** Bit definition for SPI_CRCPOLY register ************************/ + +#define SPI_CRCPOLY_VALUE_POSS 0U +#define SPI_CRCPOLY_VALUE_POSE 15U +#define SPI_CRCPOLY_VALUE_MSK BITS(SPI_CRCPOLY_VALUE_POSS,SPI_CRCPOLY_VALUE_POSE) + +/****************** Bit definition for SPI_RXCRC register ************************/ + +#define SPI_RXCRC_CRCVAL_POSS 0U +#define SPI_RXCRC_CRCVAL_POSE 15U +#define SPI_RXCRC_CRCVAL_MSK BITS(SPI_RXCRC_CRCVAL_POSS,SPI_RXCRC_CRCVAL_POSE) + +/****************** Bit definition for SPI_TXCRC register ************************/ + +#define SPI_TXCRC_CRCVAL_POSS 0U +#define SPI_TXCRC_CRCVAL_POSE 15U +#define SPI_TXCRC_CRCVAL_MSK BITS(SPI_TXCRC_CRCVAL_POSS,SPI_TXCRC_CRCVAL_POSE) + +typedef struct +{ + __IO uint32_t CON1; + __IO uint32_t CON2; + __IO uint32_t STAT; + __IO uint32_t DATA; + __IO uint32_t CRCPOLY; + __I uint32_t RXCRC; + __I uint32_t TXCRC; +} SPI_TypeDef; + +/****************** Bit definition for I2C_CON1 register ************************/ + +#define I2C_CON1_SRST_POS 15U +#define I2C_CON1_SRST_MSK BIT(I2C_CON1_SRST_POS) + +#define I2C_CON1_ALARM_POS 13U +#define I2C_CON1_ALARM_MSK BIT(I2C_CON1_ALARM_POS) + +#define I2C_CON1_TRPEC_POS 12U +#define I2C_CON1_TRPEC_MSK BIT(I2C_CON1_TRPEC_POS) + +#define I2C_CON1_POSAP_POS 11U +#define I2C_CON1_POSAP_MSK BIT(I2C_CON1_POSAP_POS) + +#define I2C_CON1_ACKEN_POS 10U +#define I2C_CON1_ACKEN_MSK BIT(I2C_CON1_ACKEN_POS) + +#define I2C_CON1_STOP_POS 9U +#define I2C_CON1_STOP_MSK BIT(I2C_CON1_STOP_POS) + +#define I2C_CON1_START_POS 8U +#define I2C_CON1_START_MSK BIT(I2C_CON1_START_POS) + +#define I2C_CON1_DISCS_POS 7U +#define I2C_CON1_DISCS_MSK BIT(I2C_CON1_DISCS_POS) + +#define I2C_CON1_GCEN_POS 6U +#define I2C_CON1_GCEN_MSK BIT(I2C_CON1_GCEN_POS) + +#define I2C_CON1_PECEN_POS 5U +#define I2C_CON1_PECEN_MSK BIT(I2C_CON1_PECEN_POS) + +#define I2C_CON1_ARPEN_POS 4U +#define I2C_CON1_ARPEN_MSK BIT(I2C_CON1_ARPEN_POS) + +#define I2C_CON1_SMBMOD_POS 3U +#define I2C_CON1_SMBMOD_MSK BIT(I2C_CON1_SMBMOD_POS) + +#define I2C_CON1_PMOD_POS 1U +#define I2C_CON1_PMOD_MSK BIT(I2C_CON1_PMOD_POS) + +#define I2C_CON1_PEN_POS 0U +#define I2C_CON1_PEN_MSK BIT(I2C_CON1_PEN_POS) + +/****************** Bit definition for I2C_CON2 register ************************/ + +#define I2C_CON2_LDMA_POS 12U +#define I2C_CON2_LDMA_MSK BIT(I2C_CON2_LDMA_POS) + +#define I2C_CON2_DMAEN_POS 11U +#define I2C_CON2_DMAEN_MSK BIT(I2C_CON2_DMAEN_POS) + +#define I2C_CON2_BUFIE_POS 10U +#define I2C_CON2_BUFIE_MSK BIT(I2C_CON2_BUFIE_POS) + +#define I2C_CON2_EVTIE_POS 9U +#define I2C_CON2_EVTIE_MSK BIT(I2C_CON2_EVTIE_POS) + +#define I2C_CON2_ERRIE_POS 8U +#define I2C_CON2_ERRIE_MSK BIT(I2C_CON2_ERRIE_POS) + +#define I2C_CON2_CLKF_POSS 0U +#define I2C_CON2_CLKF_POSE 5U +#define I2C_CON2_CLKF_MSK BITS(I2C_CON2_CLKF_POSS,I2C_CON2_CLKF_POSE) + +/****************** Bit definition for I2C_ADDR1 register ************************/ + +#define I2C_ADDR1_ADDTYPE_POS 15U +#define I2C_ADDR1_ADDTYPE_MSK BIT(I2C_ADDR1_ADDTYPE_POS) + +#define I2C_ADDR1_ADDH_POSS 8U +#define I2C_ADDR1_ADDH_POSE 9U +#define I2C_ADDR1_ADDH_MSK BITS(I2C_ADDR1_ADDH_POSS,I2C_ADDR1_ADDH_POSE) + +#define I2C_ADDR1_ADD_POSS 1U +#define I2C_ADDR1_ADD_POSE 7U +#define I2C_ADDR1_ADD_MSK BITS(I2C_ADDR1_ADD_POSS,I2C_ADDR1_ADD_POSE) + +#define I2C_ADDR1_ADDLSB_POS 0U +#define I2C_ADDR1_ADDLSB_MSK BIT(I2C_ADDR1_ADDLSB_POS) + +/****************** Bit definition for I2C_ADDR2 register ************************/ + +#define I2C_ADDR2_ADD_POSS 1U +#define I2C_ADDR2_ADD_POSE 7U +#define I2C_ADDR2_ADD_MSK BITS(I2C_ADDR2_ADD_POSS,I2C_ADDR2_ADD_POSE) + +#define I2C_ADDR2_DUALEN_POS 0U +#define I2C_ADDR2_DUALEN_MSK BIT(I2C_ADDR2_DUALEN_POS) + +/****************** Bit definition for I2C_DATA register ************************/ + +#define I2C_DATA_TRBUF_POSS 0U +#define I2C_DATA_TRBUF_POSE 7U +#define I2C_DATA_TRBUF_MSK BITS(I2C_DATA_TRBUF_POSS,I2C_DATA_TRBUF_POSE) + +/****************** Bit definition for I2C_STAT1 register ************************/ + +#define I2C_STAT1_SMBALARM_POS 15U +#define I2C_STAT1_SMBALARM_MSK BIT(I2C_STAT1_SMBALARM_POS) + +#define I2C_STAT1_SMBTO_POS 14U +#define I2C_STAT1_SMBTO_MSK BIT(I2C_STAT1_SMBTO_POS) + +#define I2C_STAT1_PECERR_POS 12U +#define I2C_STAT1_PECERR_MSK BIT(I2C_STAT1_PECERR_POS) + +#define I2C_STAT1_ROUERR_POS 11U +#define I2C_STAT1_ROUERR_MSK BIT(I2C_STAT1_ROUERR_POS) + +#define I2C_STAT1_ACKERR_POS 10U +#define I2C_STAT1_ACKERR_MSK BIT(I2C_STAT1_ACKERR_POS) + +#define I2C_STAT1_LARB_POS 9U +#define I2C_STAT1_LARB_MSK BIT(I2C_STAT1_LARB_POS) + +#define I2C_STAT1_BUSERR_POS 8U +#define I2C_STAT1_BUSERR_MSK BIT(I2C_STAT1_BUSERR_POS) + +#define I2C_STAT1_TXBE_POS 7U +#define I2C_STAT1_TXBE_MSK BIT(I2C_STAT1_TXBE_POS) + +#define I2C_STAT1_RXBNE_POS 6U +#define I2C_STAT1_RXBNE_MSK BIT(I2C_STAT1_RXBNE_POS) + +#define I2C_STAT1_DETSTP_POS 4U +#define I2C_STAT1_DETSTP_MSK BIT(I2C_STAT1_DETSTP_POS) + +#define I2C_STAT1_SENDADD10_POS 3U +#define I2C_STAT1_SENDADD10_MSK BIT(I2C_STAT1_SENDADD10_POS) + +#define I2C_STAT1_BTC_POS 2U +#define I2C_STAT1_BTC_MSK BIT(I2C_STAT1_BTC_POS) + +#define I2C_STAT1_ADDR_POS 1U +#define I2C_STAT1_ADDR_MSK BIT(I2C_STAT1_ADDR_POS) + +#define I2C_STAT1_SENDSTR_POS 0U +#define I2C_STAT1_SENDSTR_MSK BIT(I2C_STAT1_SENDSTR_POS) + +/****************** Bit definition for I2C_STAT2 register ************************/ + +#define I2C_STAT2_PECV_POSS 8U +#define I2C_STAT2_PECV_POSE 15U +#define I2C_STAT2_PECV_MSK BITS(I2C_STAT2_PECV_POSS,I2C_STAT2_PECV_POSE) + +#define I2C_STAT2_DMF_POS 7U +#define I2C_STAT2_DMF_MSK BIT(I2C_STAT2_DMF_POS) + +#define I2C_STAT2_SMBHH_POS 6U +#define I2C_STAT2_SMBHH_MSK BIT(I2C_STAT2_SMBHH_POS) + +#define I2C_STAT2_SMBDEF_POS 5U +#define I2C_STAT2_SMBDEF_MSK BIT(I2C_STAT2_SMBDEF_POS) + +#define I2C_STAT2_RXGCF_POS 4U +#define I2C_STAT2_RXGCF_MSK BIT(I2C_STAT2_RXGCF_POS) + +#define I2C_STAT2_TRF_POS 2U +#define I2C_STAT2_TRF_MSK BIT(I2C_STAT2_TRF_POS) + +#define I2C_STAT2_BSYF_POS 1U +#define I2C_STAT2_BSYF_MSK BIT(I2C_STAT2_BSYF_POS) + +#define I2C_STAT2_MASTER_POS 0U +#define I2C_STAT2_MASTER_MSK BIT(I2C_STAT2_MASTER_POS) + +/****************** Bit definition for I2C_CKCFG register ************************/ + +#define I2C_CKCFG_CLKMOD_POS 15U +#define I2C_CKCFG_CLKMOD_MSK BIT(I2C_CKCFG_CLKMOD_POS) + +#define I2C_CKCFG_DUTY_POS 14U +#define I2C_CKCFG_DUTY_MSK BIT(I2C_CKCFG_DUTY_POS) + +#define I2C_CKCFG_CLKSET_POSS 0U +#define I2C_CKCFG_CLKSET_POSE 11U +#define I2C_CKCFG_CLKSET_MSK BITS(I2C_CKCFG_CLKSET_POSS,I2C_CKCFG_CLKSET_POSE) + +/****************** Bit definition for I2C_RT register ************************/ + +#define I2C_RT_RISET_POSS 0U +#define I2C_RT_RISET_POSE 5U +#define I2C_RT_RISET_MSK BITS(I2C_RT_RISET_POSS,I2C_RT_RISET_POSE) + +typedef struct +{ + __IO uint32_t CON1; + __IO uint32_t CON2; + __IO uint32_t ADDR1; + __IO uint32_t ADDR2; + __IO uint32_t DATA; + __IO uint32_t STAT1; + __I uint32_t STAT2; + __IO uint32_t CKCFG; + __IO uint32_t RT; +} I2C_TypeDef; + +/****************** Bit definition for CAN_CON register ************************/ + +#define CAN_CON_DBGSTP_POS 16U +#define CAN_CON_DBGSTP_MSK BIT(CAN_CON_DBGSTP_POS) + +#define CAN_CON_RST_POS 15U +#define CAN_CON_RST_MSK BIT(CAN_CON_RST_POS) + +#define CAN_CON_TTCEN_POS 7U +#define CAN_CON_TTCEN_MSK BIT(CAN_CON_TTCEN_POS) + +#define CAN_CON_ABOFFEN_POS 6U +#define CAN_CON_ABOFFEN_MSK BIT(CAN_CON_ABOFFEN_POS) + +#define CAN_CON_AWKEN_POS 5U +#define CAN_CON_AWKEN_MSK BIT(CAN_CON_AWKEN_POS) + +#define CAN_CON_ARTXDIS_POS 4U +#define CAN_CON_ARTXDIS_MSK BIT(CAN_CON_ARTXDIS_POS) + +#define CAN_CON_RXFOPM_POS 3U +#define CAN_CON_RXFOPM_MSK BIT(CAN_CON_RXFOPM_POS) + +#define CAN_CON_TXMP_POS 2U +#define CAN_CON_TXMP_MSK BIT(CAN_CON_TXMP_POS) + +#define CAN_CON_SLPREQ_POS 1U +#define CAN_CON_SLPREQ_MSK BIT(CAN_CON_SLPREQ_POS) + +#define CAN_CON_INIREQ_POS 0U +#define CAN_CON_INIREQ_MSK BIT(CAN_CON_INIREQ_POS) + +/****************** Bit definition for CAN_STAT register ************************/ + +#define CAN_STAT_RX_POS 11U +#define CAN_STAT_RX_MSK BIT(CAN_STAT_RX_POS) + +#define CAN_STAT_PRESMP_POS 10U +#define CAN_STAT_PRESMP_MSK BIT(CAN_STAT_PRESMP_POS) + +#define CAN_STAT_RXSTAT_POS 9U +#define CAN_STAT_RXSTAT_MSK BIT(CAN_STAT_RXSTAT_POS) + +#define CAN_STAT_TXSTAT_POS 8U +#define CAN_STAT_TXSTAT_MSK BIT(CAN_STAT_TXSTAT_POS) + +#define CAN_STAT_SLPIF_POS 4U +#define CAN_STAT_SLPIF_MSK BIT(CAN_STAT_SLPIF_POS) + +#define CAN_STAT_WKIF_POS 3U +#define CAN_STAT_WKIF_MSK BIT(CAN_STAT_WKIF_POS) + +#define CAN_STAT_ERRIF_POS 2U +#define CAN_STAT_ERRIF_MSK BIT(CAN_STAT_ERRIF_POS) + +#define CAN_STAT_SLPSTAT_POS 1U +#define CAN_STAT_SLPSTAT_MSK BIT(CAN_STAT_SLPSTAT_POS) + +#define CAN_STAT_INISTAT_POS 0U +#define CAN_STAT_INISTAT_MSK BIT(CAN_STAT_INISTAT_POS) + +/****************** Bit definition for CAN_IFC register ************************/ + +#define CAN_IFC_SLPIFC_POS 4U +#define CAN_IFC_SLPIFC_MSK BIT(CAN_IFC_SLPIFC_POS) + +#define CAN_IFC_WKIFC_POS 3U +#define CAN_IFC_WKIFC_MSK BIT(CAN_IFC_WKIFC_POS) + +#define CAN_IFC_ERRIFC_POS 2U +#define CAN_IFC_ERRIFC_MSK BIT(CAN_IFC_ERRIFC_POS) + +/****************** Bit definition for CAN_TXSTAT register ************************/ + +#define CAN_TXSTAT_TXM2LPF_POS 31U +#define CAN_TXSTAT_TXM2LPF_MSK BIT(CAN_TXSTAT_TXM2LPF_POS) + +#define CAN_TXSTAT_TXM1LPF_POS 30U +#define CAN_TXSTAT_TXM1LPF_MSK BIT(CAN_TXSTAT_TXM1LPF_POS) + +#define CAN_TXSTAT_TXM0LPF_POS 29U +#define CAN_TXSTAT_TXM0LPF_MSK BIT(CAN_TXSTAT_TXM0LPF_POS) + +#define CAN_TXSTAT_TXM2EF_POS 28U +#define CAN_TXSTAT_TXM2EF_MSK BIT(CAN_TXSTAT_TXM2EF_POS) + +#define CAN_TXSTAT_TXM1EF_POS 27U +#define CAN_TXSTAT_TXM1EF_MSK BIT(CAN_TXSTAT_TXM1EF_POS) + +#define CAN_TXSTAT_TXM0EF_POS 26U +#define CAN_TXSTAT_TXM0EF_MSK BIT(CAN_TXSTAT_TXM0EF_POS) + +#define CAN_TXSTAT_CODE_POSS 24U +#define CAN_TXSTAT_CODE_POSE 25U +#define CAN_TXSTAT_CODE_MSK BITS(CAN_TXSTAT_CODE_POSS,CAN_TXSTAT_CODE_POSE) + +#define CAN_TXSTAT_M2STPREQ_POS 23U +#define CAN_TXSTAT_M2STPREQ_MSK BIT(CAN_TXSTAT_M2STPREQ_POS) + +#define CAN_TXSTAT_M2TXERR_POS 19U +#define CAN_TXSTAT_M2TXERR_MSK BIT(CAN_TXSTAT_M2TXERR_POS) + +#define CAN_TXSTAT_M2ARBLST_POS 18U +#define CAN_TXSTAT_M2ARBLST_MSK BIT(CAN_TXSTAT_M2ARBLST_POS) + +#define CAN_TXSTAT_M2TXC_POS 17U +#define CAN_TXSTAT_M2TXC_MSK BIT(CAN_TXSTAT_M2TXC_POS) + +#define CAN_TXSTAT_M2REQC_POS 16U +#define CAN_TXSTAT_M2REQC_MSK BIT(CAN_TXSTAT_M2REQC_POS) + +#define CAN_TXSTAT_M1STPREQ_POS 15U +#define CAN_TXSTAT_M1STPREQ_MSK BIT(CAN_TXSTAT_M1STPREQ_POS) + +#define CAN_TXSTAT_M1TXERR_POS 11U +#define CAN_TXSTAT_M1TXERR_MSK BIT(CAN_TXSTAT_M1TXERR_POS) + +#define CAN_TXSTAT_M1ARBLST_POS 10U +#define CAN_TXSTAT_M1ARBLST_MSK BIT(CAN_TXSTAT_M1ARBLST_POS) + +#define CAN_TXSTAT_M1TXC_POS 9U +#define CAN_TXSTAT_M1TXC_MSK BIT(CAN_TXSTAT_M1TXC_POS) + +#define CAN_TXSTAT_M1REQC_POS 8U +#define CAN_TXSTAT_M1REQC_MSK BIT(CAN_TXSTAT_M1REQC_POS) + +#define CAN_TXSTAT_M0STPREQ_POS 7U +#define CAN_TXSTAT_M0STPREQ_MSK BIT(CAN_TXSTAT_M0STPREQ_POS) + +#define CAN_TXSTAT_M0TXERR_POS 3U +#define CAN_TXSTAT_M0TXERR_MSK BIT(CAN_TXSTAT_M0TXERR_POS) + +#define CAN_TXSTAT_M0ARBLST_POS 2U +#define CAN_TXSTAT_M0ARBLST_MSK BIT(CAN_TXSTAT_M0ARBLST_POS) + +#define CAN_TXSTAT_M0TXC_POS 1U +#define CAN_TXSTAT_M0TXC_MSK BIT(CAN_TXSTAT_M0TXC_POS) + +#define CAN_TXSTAT_M0REQC_POS 0U +#define CAN_TXSTAT_M0REQC_MSK BIT(CAN_TXSTAT_M0REQC_POS) + +/****************** Bit definition for CAN_TXSTATC register ************************/ + +#define CAN_TXSTATC_M2TXERR_POS 19U +#define CAN_TXSTATC_M2TXERR_MSK BIT(CAN_TXSTATC_M2TXERR_POS) + +#define CAN_TXSTATC_M2ARBLST_POS 18U +#define CAN_TXSTATC_M2ARBLST_MSK BIT(CAN_TXSTATC_M2ARBLST_POS) + +#define CAN_TXSTATC_M2TXC_POS 17U +#define CAN_TXSTATC_M2TXC_MSK BIT(CAN_TXSTATC_M2TXC_POS) + +#define CAN_TXSTATC_M2REQC_POS 16U +#define CAN_TXSTATC_M2REQC_MSK BIT(CAN_TXSTATC_M2REQC_POS) + +#define CAN_TXSTATC_M1TXERR_POS 11U +#define CAN_TXSTATC_M1TXERR_MSK BIT(CAN_TXSTATC_M1TXERR_POS) + +#define CAN_TXSTATC_M1ARBLST_POS 10U +#define CAN_TXSTATC_M1ARBLST_MSK BIT(CAN_TXSTATC_M1ARBLST_POS) + +#define CAN_TXSTATC_M1TXC_POS 9U +#define CAN_TXSTATC_M1TXC_MSK BIT(CAN_TXSTATC_M1TXC_POS) + +#define CAN_TXSTATC_M1REQC_POS 8U +#define CAN_TXSTATC_M1REQC_MSK BIT(CAN_TXSTATC_M1REQC_POS) + +#define CAN_TXSTATC_M0TXERR_POS 3U +#define CAN_TXSTATC_M0TXERR_MSK BIT(CAN_TXSTATC_M0TXERR_POS) + +#define CAN_TXSTATC_M0ARBLST_POS 2U +#define CAN_TXSTATC_M0ARBLST_MSK BIT(CAN_TXSTATC_M0ARBLST_POS) + +#define CAN_TXSTATC_M0TXC_POS 1U +#define CAN_TXSTATC_M0TXC_MSK BIT(CAN_TXSTATC_M0TXC_POS) + +#define CAN_TXSTATC_M0REQC_POS 0U +#define CAN_TXSTATC_M0REQC_MSK BIT(CAN_TXSTATC_M0REQC_POS) + +/****************** Bit definition for CAN_RXF0 register ************************/ + +#define CAN_RXF0_FREE_POS 5U +#define CAN_RXF0_FREE_MSK BIT(CAN_RXF0_FREE_POS) + +#define CAN_RXF0_OVR_POS 4U +#define CAN_RXF0_OVR_MSK BIT(CAN_RXF0_OVR_POS) + +#define CAN_RXF0_FULL_POS 3U +#define CAN_RXF0_FULL_MSK BIT(CAN_RXF0_FULL_POS) + +#define CAN_RXF0_PEND_POSS 0U +#define CAN_RXF0_PEND_POSE 1U +#define CAN_RXF0_PEND_MSK BITS(CAN_RXF0_PEND_POSS,CAN_RXF0_PEND_POSE) + +/****************** Bit definition for CAN_RXF0C register ************************/ + +#define CAN_RXF0C_OVRC_POS 4U +#define CAN_RXF0C_OVRC_MSK BIT(CAN_RXF0C_OVRC_POS) + +#define CAN_RXF0C_FULLC_POS 3U +#define CAN_RXF0C_FULLC_MSK BIT(CAN_RXF0C_FULLC_POS) + +/****************** Bit definition for CAN_RXF1 register ************************/ + +#define CAN_RXF1_FREE_POS 5U +#define CAN_RXF1_FREE_MSK BIT(CAN_RXF1_FREE_POS) + +#define CAN_RXF1_OVR_POS 4U +#define CAN_RXF1_OVR_MSK BIT(CAN_RXF1_OVR_POS) + +#define CAN_RXF1_FULL_POS 3U +#define CAN_RXF1_FULL_MSK BIT(CAN_RXF1_FULL_POS) + +#define CAN_RXF1_PEND_POSS 0U +#define CAN_RXF1_PEND_POSE 1U +#define CAN_RXF1_PEND_MSK BITS(CAN_RXF1_PEND_POSS,CAN_RXF1_PEND_POSE) + +/****************** Bit definition for CAN_RXF1C register ************************/ + +#define CAN_RXF1C_OVRC_POS 4U +#define CAN_RXF1C_OVRC_MSK BIT(CAN_RXF1C_OVRC_POS) + +#define CAN_RXF1C_FULLC_POS 3U +#define CAN_RXF1C_FULLC_MSK BIT(CAN_RXF1C_FULLC_POS) + +/****************** Bit definition for CAN_IE register ************************/ + +#define CAN_IE_SLPIE_POS 17U +#define CAN_IE_SLPIE_MSK BIT(CAN_IE_SLPIE_POS) + +#define CAN_IE_WKIE_POS 16U +#define CAN_IE_WKIE_MSK BIT(CAN_IE_WKIE_POS) + +#define CAN_IE_ERRIE_POS 15U +#define CAN_IE_ERRIE_MSK BIT(CAN_IE_ERRIE_POS) + +#define CAN_IE_PRERRIE_POS 11U +#define CAN_IE_PRERRIE_MSK BIT(CAN_IE_PRERRIE_POS) + +#define CAN_IE_BOFFIE_POS 10U +#define CAN_IE_BOFFIE_MSK BIT(CAN_IE_BOFFIE_POS) + +#define CAN_IE_PERRIE_POS 9U +#define CAN_IE_PERRIE_MSK BIT(CAN_IE_PERRIE_POS) + +#define CAN_IE_WARNIE_POS 8U +#define CAN_IE_WARNIE_MSK BIT(CAN_IE_WARNIE_POS) + +#define CAN_IE_F1OVRIE_POS 6U +#define CAN_IE_F1OVRIE_MSK BIT(CAN_IE_F1OVRIE_POS) + +#define CAN_IE_F1FULIE_POS 5U +#define CAN_IE_F1FULIE_MSK BIT(CAN_IE_F1FULIE_POS) + +#define CAN_IE_F1PIE_POS 4U +#define CAN_IE_F1PIE_MSK BIT(CAN_IE_F1PIE_POS) + +#define CAN_IE_F0OVRIE_POS 3U +#define CAN_IE_F0OVRIE_MSK BIT(CAN_IE_F0OVRIE_POS) + +#define CAN_IE_F0FULIE_POS 2U +#define CAN_IE_F0FULIE_MSK BIT(CAN_IE_F0FULIE_POS) + +#define CAN_IE_F0PIE_POS 1U +#define CAN_IE_F0PIE_MSK BIT(CAN_IE_F0PIE_POS) + +#define CAN_IE_TXMEIE_POS 0U +#define CAN_IE_TXMEIE_MSK BIT(CAN_IE_TXMEIE_POS) + +/****************** Bit definition for CAN_ERRSTAT register ************************/ + +#define CAN_ERRSTAT_RXERRC_POSS 24U +#define CAN_ERRSTAT_RXERRC_POSE 31U +#define CAN_ERRSTAT_RXERRC_MSK BITS(CAN_ERRSTAT_RXERRC_POSS,CAN_ERRSTAT_RXERRC_POSE) + +#define CAN_ERRSTAT_TXERRC_POSS 16U +#define CAN_ERRSTAT_TXERRC_POSE 23U +#define CAN_ERRSTAT_TXERRC_MSK BITS(CAN_ERRSTAT_TXERRC_POSS,CAN_ERRSTAT_TXERRC_POSE) + +#define CAN_ERRSTAT_PRERRF_POSS 4U +#define CAN_ERRSTAT_PRERRF_POSE 6U +#define CAN_ERRSTAT_PRERRF_MSK BITS(CAN_ERRSTAT_PRERRF_POSS,CAN_ERRSTAT_PRERRF_POSE) + +#define CAN_ERRSTAT_BOFF_POS 2U +#define CAN_ERRSTAT_BOFF_MSK BIT(CAN_ERRSTAT_BOFF_POS) + +#define CAN_ERRSTAT_PERRF_POS 1U +#define CAN_ERRSTAT_PERRF_MSK BIT(CAN_ERRSTAT_PERRF_POS) + +#define CAN_ERRSTAT_WARNF_POS 0U +#define CAN_ERRSTAT_WARNF_MSK BIT(CAN_ERRSTAT_WARNF_POS) + +/****************** Bit definition for CAN_BTIME register ************************/ + +#define CAN_BTIME_SILENT_POS 31U +#define CAN_BTIME_SILENT_MSK BIT(CAN_BTIME_SILENT_POS) + +#define CAN_BTIME_LOOP_POS 30U +#define CAN_BTIME_LOOP_MSK BIT(CAN_BTIME_LOOP_POS) + +#define CAN_BTIME_RESJW_POSS 24U +#define CAN_BTIME_RESJW_POSE 25U +#define CAN_BTIME_RESJW_MSK BITS(CAN_BTIME_RESJW_POSS,CAN_BTIME_RESJW_POSE) + +#define CAN_BTIME_SEG2_POSS 20U +#define CAN_BTIME_SEG2_POSE 22U +#define CAN_BTIME_SEG2_MSK BITS(CAN_BTIME_SEG2_POSS,CAN_BTIME_SEG2_POSE) + +#define CAN_BTIME_SEG1_POSS 16U +#define CAN_BTIME_SEG1_POSE 19U +#define CAN_BTIME_SEG1_MSK BITS(CAN_BTIME_SEG1_POSS,CAN_BTIME_SEG1_POSE) + +#define CAN_BTIME_BPSC_POSS 0U +#define CAN_BTIME_BPSC_POSE 9U +#define CAN_BTIME_BPSC_MSK BITS(CAN_BTIME_BPSC_POSS,CAN_BTIME_BPSC_POSE) + +/****************** Bit definition for CAN_TXID0 register ************************/ + +#define CAN_TXID0_STDID_POSS 21U +#define CAN_TXID0_STDID_POSE 31U +#define CAN_TXID0_STDID_MSK BITS(CAN_TXID0_STDID_POSS,CAN_TXID0_STDID_POSE) + +#define CAN_TXID0_EXID_POSS 3U +#define CAN_TXID0_EXID_POSE 20U +#define CAN_TXID0_EXID_MSK BITS(CAN_TXID0_EXID_POSS,CAN_TXID0_EXID_POSE) + +#define CAN_TXID0_IDE_POS 2U +#define CAN_TXID0_IDE_MSK BIT(CAN_TXID0_IDE_POS) + +#define CAN_TXID0_RTR_POS 1U +#define CAN_TXID0_RTR_MSK BIT(CAN_TXID0_RTR_POS) + +#define CAN_TXID0_TXMREQ_POS 0U +#define CAN_TXID0_TXMREQ_MSK BIT(CAN_TXID0_TXMREQ_POS) + +/****************** Bit definition for CAN_TXFCON0 register ************************/ + +#define CAN_TXFCON0_STAMP_POSS 16U +#define CAN_TXFCON0_STAMP_POSE 31U +#define CAN_TXFCON0_STAMP_MSK BITS(CAN_TXFCON0_STAMP_POSS,CAN_TXFCON0_STAMP_POSE) + +#define CAN_TXFCON0_TXGT_POS 8U +#define CAN_TXFCON0_TXGT_MSK BIT(CAN_TXFCON0_TXGT_POS) + +#define CAN_TXFCON0_DLEN_POSS 0U +#define CAN_TXFCON0_DLEN_POSE 3U +#define CAN_TXFCON0_DLEN_MSK BITS(CAN_TXFCON0_DLEN_POSS,CAN_TXFCON0_DLEN_POSE) + +/****************** Bit definition for CAN_TXDL0 register ************************/ + +#define CAN_TXDL0_BYTE3_POSS 24U +#define CAN_TXDL0_BYTE3_POSE 31U +#define CAN_TXDL0_BYTE3_MSK BITS(CAN_TXDL0_BYTE3_POSS,CAN_TXDL0_BYTE3_POSE) + +#define CAN_TXDL0_BYTE2_POSS 16U +#define CAN_TXDL0_BYTE2_POSE 23U +#define CAN_TXDL0_BYTE2_MSK BITS(CAN_TXDL0_BYTE2_POSS,CAN_TXDL0_BYTE2_POSE) + +#define CAN_TXDL0_BYTE1_POSS 8U +#define CAN_TXDL0_BYTE1_POSE 15U +#define CAN_TXDL0_BYTE1_MSK BITS(CAN_TXDL0_BYTE1_POSS,CAN_TXDL0_BYTE1_POSE) + +#define CAN_TXDL0_BYTE0_POSS 0U +#define CAN_TXDL0_BYTE0_POSE 7U +#define CAN_TXDL0_BYTE0_MSK BITS(CAN_TXDL0_BYTE0_POSS,CAN_TXDL0_BYTE0_POSE) + +/****************** Bit definition for CAN_TXDH0 register ************************/ + +#define CAN_TXDH0_BYTE7_POSS 24U +#define CAN_TXDH0_BYTE7_POSE 31U +#define CAN_TXDH0_BYTE7_MSK BITS(CAN_TXDH0_BYTE7_POSS,CAN_TXDH0_BYTE7_POSE) + +#define CAN_TXDH0_BYTE6_POSS 16U +#define CAN_TXDH0_BYTE6_POSE 23U +#define CAN_TXDH0_BYTE6_MSK BITS(CAN_TXDH0_BYTE6_POSS,CAN_TXDH0_BYTE6_POSE) + +#define CAN_TXDH0_BYTE5_POSS 8U +#define CAN_TXDH0_BYTE5_POSE 15U +#define CAN_TXDH0_BYTE5_MSK BITS(CAN_TXDH0_BYTE5_POSS,CAN_TXDH0_BYTE5_POSE) + +#define CAN_TXDH0_BYTE4_POSS 0U +#define CAN_TXDH0_BYTE4_POSE 7U +#define CAN_TXDH0_BYTE4_MSK BITS(CAN_TXDH0_BYTE4_POSS,CAN_TXDH0_BYTE4_POSE) + +/****************** Bit definition for CAN_TXID1 register ************************/ + +#define CAN_TXID1_STDID_POSS 21U +#define CAN_TXID1_STDID_POSE 31U +#define CAN_TXID1_STDID_MSK BITS(CAN_TXID1_STDID_POSS,CAN_TXID1_STDID_POSE) + +#define CAN_TXID1_EXID_POSS 3U +#define CAN_TXID1_EXID_POSE 20U +#define CAN_TXID1_EXID_MSK BITS(CAN_TXID1_EXID_POSS,CAN_TXID1_EXID_POSE) + +#define CAN_TXID1_IDE_POS 2U +#define CAN_TXID1_IDE_MSK BIT(CAN_TXID1_IDE_POS) + +#define CAN_TXID1_RTR_POS 1U +#define CAN_TXID1_RTR_MSK BIT(CAN_TXID1_RTR_POS) + +#define CAN_TXID1_TXMREQ_POS 0U +#define CAN_TXID1_TXMREQ_MSK BIT(CAN_TXID1_TXMREQ_POS) + +/****************** Bit definition for CAN_TXFCON1 register ************************/ + +#define CAN_TXFCON1_STAMP_POSS 16U +#define CAN_TXFCON1_STAMP_POSE 31U +#define CAN_TXFCON1_STAMP_MSK BITS(CAN_TXFCON1_STAMP_POSS,CAN_TXFCON1_STAMP_POSE) + +#define CAN_TXFCON1_TXGT_POS 8U +#define CAN_TXFCON1_TXGT_MSK BIT(CAN_TXFCON1_TXGT_POS) + +#define CAN_TXFCON1_DLEN_POSS 0U +#define CAN_TXFCON1_DLEN_POSE 3U +#define CAN_TXFCON1_DLEN_MSK BITS(CAN_TXFCON1_DLEN_POSS,CAN_TXFCON1_DLEN_POSE) + +/****************** Bit definition for CAN_TXDL1 register ************************/ + +#define CAN_TXDL1_BYTE3_POSS 24U +#define CAN_TXDL1_BYTE3_POSE 31U +#define CAN_TXDL1_BYTE3_MSK BITS(CAN_TXDL1_BYTE3_POSS,CAN_TXDL1_BYTE3_POSE) + +#define CAN_TXDL1_BYTE2_POSS 16U +#define CAN_TXDL1_BYTE2_POSE 23U +#define CAN_TXDL1_BYTE2_MSK BITS(CAN_TXDL1_BYTE2_POSS,CAN_TXDL1_BYTE2_POSE) + +#define CAN_TXDL1_BYTE1_POSS 8U +#define CAN_TXDL1_BYTE1_POSE 15U +#define CAN_TXDL1_BYTE1_MSK BITS(CAN_TXDL1_BYTE1_POSS,CAN_TXDL1_BYTE1_POSE) + +#define CAN_TXDL1_BYTE0_POSS 0U +#define CAN_TXDL1_BYTE0_POSE 7U +#define CAN_TXDL1_BYTE0_MSK BITS(CAN_TXDL1_BYTE0_POSS,CAN_TXDL1_BYTE0_POSE) + +/****************** Bit definition for CAN_TXDH1 register ************************/ + +#define CAN_TXDH1_BYTE7_POSS 24U +#define CAN_TXDH1_BYTE7_POSE 31U +#define CAN_TXDH1_BYTE7_MSK BITS(CAN_TXDH1_BYTE7_POSS,CAN_TXDH1_BYTE7_POSE) + +#define CAN_TXDH1_BYTE6_POSS 16U +#define CAN_TXDH1_BYTE6_POSE 23U +#define CAN_TXDH1_BYTE6_MSK BITS(CAN_TXDH1_BYTE6_POSS,CAN_TXDH1_BYTE6_POSE) + +#define CAN_TXDH1_BYTE5_POSS 8U +#define CAN_TXDH1_BYTE5_POSE 15U +#define CAN_TXDH1_BYTE5_MSK BITS(CAN_TXDH1_BYTE5_POSS,CAN_TXDH1_BYTE5_POSE) + +#define CAN_TXDH1_BYTE4_POSS 0U +#define CAN_TXDH1_BYTE4_POSE 7U +#define CAN_TXDH1_BYTE4_MSK BITS(CAN_TXDH1_BYTE4_POSS,CAN_TXDH1_BYTE4_POSE) + +/****************** Bit definition for CAN_TXID2 register ************************/ + +#define CAN_TXID2_STDID_POSS 21U +#define CAN_TXID2_STDID_POSE 31U +#define CAN_TXID2_STDID_MSK BITS(CAN_TXID2_STDID_POSS,CAN_TXID2_STDID_POSE) + +#define CAN_TXID2_EXID_POSS 3U +#define CAN_TXID2_EXID_POSE 20U +#define CAN_TXID2_EXID_MSK BITS(CAN_TXID2_EXID_POSS,CAN_TXID2_EXID_POSE) + +#define CAN_TXID2_IDE_POS 2U +#define CAN_TXID2_IDE_MSK BIT(CAN_TXID2_IDE_POS) + +#define CAN_TXID2_RTR_POS 1U +#define CAN_TXID2_RTR_MSK BIT(CAN_TXID2_RTR_POS) + +#define CAN_TXID2_TXMREQ_POS 0U +#define CAN_TXID2_TXMREQ_MSK BIT(CAN_TXID2_TXMREQ_POS) + +/****************** Bit definition for CAN_TXFCON2 register ************************/ + +#define CAN_TXFCON2_STAMP_POSS 16U +#define CAN_TXFCON2_STAMP_POSE 31U +#define CAN_TXFCON2_STAMP_MSK BITS(CAN_TXFCON2_STAMP_POSS,CAN_TXFCON2_STAMP_POSE) + +#define CAN_TXFCON2_TXGT_POS 8U +#define CAN_TXFCON2_TXGT_MSK BIT(CAN_TXFCON2_TXGT_POS) + +#define CAN_TXFCON2_DLEN_POSS 0U +#define CAN_TXFCON2_DLEN_POSE 3U +#define CAN_TXFCON2_DLEN_MSK BITS(CAN_TXFCON2_DLEN_POSS,CAN_TXFCON2_DLEN_POSE) + +/****************** Bit definition for CAN_TXDL2 register ************************/ + +#define CAN_TXDL2_BYTE3_POSS 24U +#define CAN_TXDL2_BYTE3_POSE 31U +#define CAN_TXDL2_BYTE3_MSK BITS(CAN_TXDL2_BYTE3_POSS,CAN_TXDL2_BYTE3_POSE) + +#define CAN_TXDL2_BYTE2_POSS 16U +#define CAN_TXDL2_BYTE2_POSE 23U +#define CAN_TXDL2_BYTE2_MSK BITS(CAN_TXDL2_BYTE2_POSS,CAN_TXDL2_BYTE2_POSE) + +#define CAN_TXDL2_BYTE1_POSS 8U +#define CAN_TXDL2_BYTE1_POSE 15U +#define CAN_TXDL2_BYTE1_MSK BITS(CAN_TXDL2_BYTE1_POSS,CAN_TXDL2_BYTE1_POSE) + +#define CAN_TXDL2_BYTE0_POSS 0U +#define CAN_TXDL2_BYTE0_POSE 7U +#define CAN_TXDL2_BYTE0_MSK BITS(CAN_TXDL2_BYTE0_POSS,CAN_TXDL2_BYTE0_POSE) + +/****************** Bit definition for CAN_TXDH2 register ************************/ + +#define CAN_TXDH2_BYTE7_POSS 24U +#define CAN_TXDH2_BYTE7_POSE 31U +#define CAN_TXDH2_BYTE7_MSK BITS(CAN_TXDH2_BYTE7_POSS,CAN_TXDH2_BYTE7_POSE) + +#define CAN_TXDH2_BYTE6_POSS 16U +#define CAN_TXDH2_BYTE6_POSE 23U +#define CAN_TXDH2_BYTE6_MSK BITS(CAN_TXDH2_BYTE6_POSS,CAN_TXDH2_BYTE6_POSE) + +#define CAN_TXDH2_BYTE5_POSS 8U +#define CAN_TXDH2_BYTE5_POSE 15U +#define CAN_TXDH2_BYTE5_MSK BITS(CAN_TXDH2_BYTE5_POSS,CAN_TXDH2_BYTE5_POSE) + +#define CAN_TXDH2_BYTE4_POSS 0U +#define CAN_TXDH2_BYTE4_POSE 7U +#define CAN_TXDH2_BYTE4_MSK BITS(CAN_TXDH2_BYTE4_POSS,CAN_TXDH2_BYTE4_POSE) + +/****************** Bit definition for CAN_RXF0ID register ************************/ + +#define CAN_RXF0ID_STDID_POSS 21U +#define CAN_RXF0ID_STDID_POSE 31U +#define CAN_RXF0ID_STDID_MSK BITS(CAN_RXF0ID_STDID_POSS,CAN_RXF0ID_STDID_POSE) + +#define CAN_RXF0ID_EXID_POSS 3U +#define CAN_RXF0ID_EXID_POSE 20U +#define CAN_RXF0ID_EXID_MSK BITS(CAN_RXF0ID_EXID_POSS,CAN_RXF0ID_EXID_POSE) + +#define CAN_RXF0ID_IDE_POS 2U +#define CAN_RXF0ID_IDE_MSK BIT(CAN_RXF0ID_IDE_POS) + +#define CAN_RXF0ID_RTR_POS 1U +#define CAN_RXF0ID_RTR_MSK BIT(CAN_RXF0ID_RTR_POS) + +/****************** Bit definition for CAN_RXF0INF register ************************/ + +#define CAN_RXF0INF_STAMP_POSS 16U +#define CAN_RXF0INF_STAMP_POSE 31U +#define CAN_RXF0INF_STAMP_MSK BITS(CAN_RXF0INF_STAMP_POSS,CAN_RXF0INF_STAMP_POSE) + +#define CAN_RXF0INF_FLTIDX_POSS 8U +#define CAN_RXF0INF_FLTIDX_POSE 15U +#define CAN_RXF0INF_FLTIDX_MSK BITS(CAN_RXF0INF_FLTIDX_POSS,CAN_RXF0INF_FLTIDX_POSE) + +#define CAN_RXF0INF_DLEN_POSS 0U +#define CAN_RXF0INF_DLEN_POSE 3U +#define CAN_RXF0INF_DLEN_MSK BITS(CAN_RXF0INF_DLEN_POSS,CAN_RXF0INF_DLEN_POSE) + +/****************** Bit definition for CAN_RXF0DL register ************************/ + +#define CAN_RXF0DL_BYTE3_POSS 24U +#define CAN_RXF0DL_BYTE3_POSE 31U +#define CAN_RXF0DL_BYTE3_MSK BITS(CAN_RXF0DL_BYTE3_POSS,CAN_RXF0DL_BYTE3_POSE) + +#define CAN_RXF0DL_BYTE2_POSS 16U +#define CAN_RXF0DL_BYTE2_POSE 23U +#define CAN_RXF0DL_BYTE2_MSK BITS(CAN_RXF0DL_BYTE2_POSS,CAN_RXF0DL_BYTE2_POSE) + +#define CAN_RXF0DL_BYTE1_POSS 8U +#define CAN_RXF0DL_BYTE1_POSE 15U +#define CAN_RXF0DL_BYTE1_MSK BITS(CAN_RXF0DL_BYTE1_POSS,CAN_RXF0DL_BYTE1_POSE) + +#define CAN_RXF0DL_BYTE0_POSS 0U +#define CAN_RXF0DL_BYTE0_POSE 7U +#define CAN_RXF0DL_BYTE0_MSK BITS(CAN_RXF0DL_BYTE0_POSS,CAN_RXF0DL_BYTE0_POSE) + +/****************** Bit definition for CAN_RXF0DH register ************************/ + +#define CAN_RXF0DH_BYTE7_POSS 24U +#define CAN_RXF0DH_BYTE7_POSE 31U +#define CAN_RXF0DH_BYTE7_MSK BITS(CAN_RXF0DH_BYTE7_POSS,CAN_RXF0DH_BYTE7_POSE) + +#define CAN_RXF0DH_BYTE6_POSS 16U +#define CAN_RXF0DH_BYTE6_POSE 23U +#define CAN_RXF0DH_BYTE6_MSK BITS(CAN_RXF0DH_BYTE6_POSS,CAN_RXF0DH_BYTE6_POSE) + +#define CAN_RXF0DH_BYTE5_POSS 8U +#define CAN_RXF0DH_BYTE5_POSE 15U +#define CAN_RXF0DH_BYTE5_MSK BITS(CAN_RXF0DH_BYTE5_POSS,CAN_RXF0DH_BYTE5_POSE) + +#define CAN_RXF0DH_BYTE4_POSS 0U +#define CAN_RXF0DH_BYTE4_POSE 7U +#define CAN_RXF0DH_BYTE4_MSK BITS(CAN_RXF0DH_BYTE4_POSS,CAN_RXF0DH_BYTE4_POSE) + +/****************** Bit definition for CAN_RXF1ID register ************************/ + +#define CAN_RXF1ID_STDID_POSS 21U +#define CAN_RXF1ID_STDID_POSE 31U +#define CAN_RXF1ID_STDID_MSK BITS(CAN_RXF1ID_STDID_POSS,CAN_RXF1ID_STDID_POSE) + +#define CAN_RXF1ID_EXID_POSS 3U +#define CAN_RXF1ID_EXID_POSE 20U +#define CAN_RXF1ID_EXID_MSK BITS(CAN_RXF1ID_EXID_POSS,CAN_RXF1ID_EXID_POSE) + +#define CAN_RXF1ID_IDE_POS 2U +#define CAN_RXF1ID_IDE_MSK BIT(CAN_RXF1ID_IDE_POS) + +#define CAN_RXF1ID_RTR_POS 1U +#define CAN_RXF1ID_RTR_MSK BIT(CAN_RXF1ID_RTR_POS) + +/****************** Bit definition for CAN_RXF1INF register ************************/ + +#define CAN_RXF1INF_STAMP_POSS 16U +#define CAN_RXF1INF_STAMP_POSE 31U +#define CAN_RXF1INF_STAMP_MSK BITS(CAN_RXF1INF_STAMP_POSS,CAN_RXF1INF_STAMP_POSE) + +#define CAN_RXF1INF_FLTIDX_POSS 8U +#define CAN_RXF1INF_FLTIDX_POSE 15U +#define CAN_RXF1INF_FLTIDX_MSK BITS(CAN_RXF1INF_FLTIDX_POSS,CAN_RXF1INF_FLTIDX_POSE) + +#define CAN_RXF1INF_DLEN_POSS 0U +#define CAN_RXF1INF_DLEN_POSE 3U +#define CAN_RXF1INF_DLEN_MSK BITS(CAN_RXF1INF_DLEN_POSS,CAN_RXF1INF_DLEN_POSE) + +/****************** Bit definition for CAN_RXF1DL register ************************/ + +#define CAN_RXF1DL_BYTE3_POSS 24U +#define CAN_RXF1DL_BYTE3_POSE 31U +#define CAN_RXF1DL_BYTE3_MSK BITS(CAN_RXF1DL_BYTE3_POSS,CAN_RXF1DL_BYTE3_POSE) + +#define CAN_RXF1DL_BYTE2_POSS 16U +#define CAN_RXF1DL_BYTE2_POSE 23U +#define CAN_RXF1DL_BYTE2_MSK BITS(CAN_RXF1DL_BYTE2_POSS,CAN_RXF1DL_BYTE2_POSE) + +#define CAN_RXF1DL_BYTE1_POSS 8U +#define CAN_RXF1DL_BYTE1_POSE 15U +#define CAN_RXF1DL_BYTE1_MSK BITS(CAN_RXF1DL_BYTE1_POSS,CAN_RXF1DL_BYTE1_POSE) + +#define CAN_RXF1DL_BYTE0_POSS 0U +#define CAN_RXF1DL_BYTE0_POSE 7U +#define CAN_RXF1DL_BYTE0_MSK BITS(CAN_RXF1DL_BYTE0_POSS,CAN_RXF1DL_BYTE0_POSE) + +/****************** Bit definition for CAN_RXF1DH register ************************/ + +#define CAN_RXF1DH_BYTE7_POSS 24U +#define CAN_RXF1DH_BYTE7_POSE 31U +#define CAN_RXF1DH_BYTE7_MSK BITS(CAN_RXF1DH_BYTE7_POSS,CAN_RXF1DH_BYTE7_POSE) + +#define CAN_RXF1DH_BYTE6_POSS 16U +#define CAN_RXF1DH_BYTE6_POSE 23U +#define CAN_RXF1DH_BYTE6_MSK BITS(CAN_RXF1DH_BYTE6_POSS,CAN_RXF1DH_BYTE6_POSE) + +#define CAN_RXF1DH_BYTE5_POSS 8U +#define CAN_RXF1DH_BYTE5_POSE 15U +#define CAN_RXF1DH_BYTE5_MSK BITS(CAN_RXF1DH_BYTE5_POSS,CAN_RXF1DH_BYTE5_POSE) + +#define CAN_RXF1DH_BYTE4_POSS 0U +#define CAN_RXF1DH_BYTE4_POSE 7U +#define CAN_RXF1DH_BYTE4_MSK BITS(CAN_RXF1DH_BYTE4_POSS,CAN_RXF1DH_BYTE4_POSE) + +/****************** Bit definition for CAN_FLTCON register ************************/ + +#define CAN_FLTCON_FLTINI_POS 0U +#define CAN_FLTCON_FLTINI_MSK BIT(CAN_FLTCON_FLTINI_POS) + +/****************** Bit definition for CAN_FLTM register ************************/ + +#define CAN_FLTM_MOD_POSS 0U +#define CAN_FLTM_MOD_POSE 13U +#define CAN_FLTM_MOD_MSK BITS(CAN_FLTM_MOD_POSS,CAN_FLTM_MOD_POSE) + +/****************** Bit definition for CAN_FLTWS register ************************/ + +#define CAN_FLTWS_SEL_POSS 0U +#define CAN_FLTWS_SEL_POSE 13U +#define CAN_FLTWS_SEL_MSK BITS(CAN_FLTWS_SEL_POSS,CAN_FLTWS_SEL_POSE) + +/****************** Bit definition for CAN_FLTAS register ************************/ + +#define CAN_FLTAS_ASSIGN_POSS 0U +#define CAN_FLTAS_ASSIGN_POSE 13U +#define CAN_FLTAS_ASSIGN_MSK BITS(CAN_FLTAS_ASSIGN_POSS,CAN_FLTAS_ASSIGN_POSE) + +/****************** Bit definition for CAN_FLTGO register ************************/ + +#define CAN_FLTGO_GO_POSS 0U +#define CAN_FLTGO_GO_POSE 13U +#define CAN_FLTGO_GO_MSK BITS(CAN_FLTGO_GO_POSS,CAN_FLTGO_GO_POSE) + +typedef struct { + __IO uint32_t TXID; + __IO uint32_t TXFCON; + __IO uint32_t TXDL; + __IO uint32_t TXDH; +} CAN_TxMailBox_Typedef; + +typedef struct { + __IO uint32_t RXFID; + __IO uint32_t RXFINF; + __IO uint32_t RXFDL; + __IO uint32_t RXFDH; +} CAN_RxFIFO_Typedef; + +typedef struct { + __IO uint32_t FLT1; + __IO uint32_t FLT2; +} CAN_Filter_Typedef; + +typedef struct +{ + __IO uint32_t CON; + __I uint32_t STAT; + __O uint32_t IFC; + __IO uint32_t TXSTAT; + __O uint32_t TXSTATC; + __IO uint32_t RXF0; + __O uint32_t RXF0C; + __IO uint32_t RXF1; + __O uint32_t RXF1C; + __IO uint32_t IE; + __IO uint32_t ERRSTAT; + __IO uint32_t BTIME; + uint32_t RESERVED0[84] ; + CAN_TxMailBox_Typedef TxMailBox[3]; + CAN_RxFIFO_Typedef RxFIFO[2]; + uint32_t RESERVED1[12] ; + __IO uint32_t FLTCON; + __IO uint32_t FLTM; + uint32_t RESERVED2 ; + __IO uint32_t FLTWS; + uint32_t RESERVED3 ; + __IO uint32_t FLTAS; + uint32_t RESERVED4 ; + __IO uint32_t FLTGO; + uint32_t RESERVED5[8] ; + CAN_Filter_Typedef Filter[14]; +} CAN_TypeDef; + +/****************** Bit definition for CRC_CR register ************************/ +#define CRC_CR_BYTORD_POS 24U +#define CRC_CR_BYTORD_MSK BIT(CRC_CR_BYTORD_POS) + +#define CRC_CR_DATLEN_POSS 22U +#define CRC_CR_DATLEN_POSE 23U +#define CRC_CR_DATLEN_MSK BITS(CRC_CR_DATLEN_POSS,CRC_CR_DATLEN_POSE) + +#define CRC_CR_MODE_POSS 20U +#define CRC_CR_MODE_POSE 21U +#define CRC_CR_MODE_MSK BITS(CRC_CR_MODE_POSS,CRC_CR_MODE_POSE) + +#define CRC_CR_CHSINV_POS 19U +#define CRC_CR_CHSINV_MSK BIT(CRC_CR_CHSINV_POS) + +#define CRC_CR_DATINV_POS 18U +#define CRC_CR_DATINV_MSK BIT(CRC_CR_DATINV_POS) + +#define CRC_CR_CHSREV_POS 17U +#define CRC_CR_CHSREV_MSK BIT(CRC_CR_CHSREV_POS) + +#define CRC_CR_DATREV_POS 16U +#define CRC_CR_DATREV_MSK BIT(CRC_CR_DATREV_POS) + +#define CRC_CR_DMAEN_POS 4U +#define CRC_CR_DMAEN_MSK BIT(CRC_CR_DMAEN_POS) + +#define CRC_CR_CWERR_POS 3U +#define CRC_CR_CWERR_MSK BIT(CRC_CR_CWERR_POS) + +#define CRC_CR_WERR_POS 2U +#define CRC_CR_WERR_MSK BIT(CRC_CR_WERR_POS) + +#define CRC_CR_RST_POS 1U +#define CRC_CR_RST_MSK BIT(CRC_CR_RST_POS) + +#define CRC_CR_EN_POS 0U +#define CRC_CR_EN_MSK BIT(CRC_CR_EN_POS) + +/****************** Bit definition for CRC_DATA register ************************/ + +#define CRC_DATA_DATA_POSS 0U +#define CRC_DATA_DATA_POSE 31U +#define CRC_DATA_DATA_MSK BITS(CRC_DATA_DATA_POSS,CRC_DATA_DATA_POSE) + +/****************** Bit definition for CRC_SEED register ************************/ + +#define CRC_SEED_SEED_POSS 0U +#define CRC_SEED_SEED_POSE 31U +#define CRC_SEED_SEED_MSK BITS(CRC_SEED_SEED_POSS,CRC_SEED_SEED_POSE) + +/****************** Bit definition for CRC_CHECKSUM register ************************/ + +#define CRC_CHECKSUM_CHECKSUM_POSS 0U +#define CRC_CHECKSUM_CHECKSUM_POSE 31U +#define CRC_CHECKSUM_CHECKSUM_MSK BITS(CRC_CHECKSUM_CHECKSUM_POSS,CRC_CHECKSUM_CHECKSUM_POSE) + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t DATA; + __IO uint32_t SEED; + __I uint32_t CHECKSUM; +} CRC_TypeDef; + +/****************** Bit definition for CRYPT_CON register ************************/ + +#define CRYPT_CON_CRYSEL_POS 31U +#define CRYPT_CON_CRYSEL_MSK BIT(CRYPT_CON_CRYSEL_POS) + +#define CRYPT_CON_RESCLR_POS 15U +#define CRYPT_CON_RESCLR_MSK BIT(CRYPT_CON_RESCLR_POS) + +#define CRYPT_CON_DMAEN_POS 14U +#define CRYPT_CON_DMAEN_MSK BIT(CRYPT_CON_DMAEN_POS) + +#define CRYPT_CON_FIFOODR_POS 13U +#define CRYPT_CON_FIFOODR_MSK BIT(CRYPT_CON_FIFOODR_POS) + +#define CRYPT_CON_FIFOEN_POS 12U +#define CRYPT_CON_FIFOEN_MSK BIT(CRYPT_CON_FIFOEN_POS) + +#define CRYPT_CON_DESKS_POS 11U +#define CRYPT_CON_DESKS_MSK BIT(CRYPT_CON_DESKS_POS) + +#define CRYPT_CON_TDES_POS 10U +#define CRYPT_CON_TDES_MSK BIT(CRYPT_CON_TDES_POS) + +#define CRYPT_CON_TYPE_POSS 8U +#define CRYPT_CON_TYPE_POSE 9U +#define CRYPT_CON_TYPE_MSK BITS(CRYPT_CON_TYPE_POSS,CRYPT_CON_TYPE_POSE) + +#define CRYPT_CON_IE_POS 7U +#define CRYPT_CON_IE_MSK BIT(CRYPT_CON_IE_POS) + +#define CRYPT_CON_IVEN_POS 6U +#define CRYPT_CON_IVEN_MSK BIT(CRYPT_CON_IVEN_POS) + +#define CRYPT_CON_MODE_POSS 4U +#define CRYPT_CON_MODE_POSE 5U +#define CRYPT_CON_MODE_MSK BITS(CRYPT_CON_MODE_POSS,CRYPT_CON_MODE_POSE) + +#define CRYPT_CON_AESKS_POSS 2U +#define CRYPT_CON_AESKS_POSE 3U +#define CRYPT_CON_AESKS_MSK BITS(CRYPT_CON_AESKS_POSS,CRYPT_CON_AESKS_POSE) + +#define CRYPT_CON_ENCS_POS 1U +#define CRYPT_CON_ENCS_MSK BIT(CRYPT_CON_ENCS_POS) + +#define CRYPT_CON_GO_POS 0U +#define CRYPT_CON_GO_MSK BIT(CRYPT_CON_GO_POS) + +/****************** Bit definition for CRYPT_IF register ************************/ + +#define CRYPT_IF_DONE_POS 8U +#define CRYPT_IF_DONE_MSK BIT(CRYPT_IF_DONE_POS) + +#define CRYPT_IF_MULTHIF_POS 2U +#define CRYPT_IF_MULTHIF_MSK BIT(CRYPT_IF_MULTHIF_POS) + +#define CRYPT_IF_DESIF_POS 1U +#define CRYPT_IF_DESIF_MSK BIT(CRYPT_IF_DESIF_POS) + +#define CRYPT_IF_AESIF_POS 0U +#define CRYPT_IF_AESIF_MSK BIT(CRYPT_IF_AESIF_POS) + +/****************** Bit definition for CRYPT_IFC register ************************/ + +#define CRYPT_IFC_MULTHIFC_POS 2U +#define CRYPT_IFC_MULTHIFC_MSK BIT(CRYPT_IFC_MULTHIFC_POS) + +#define CRYPT_IFC_DESIFC_POS 1U +#define CRYPT_IFC_DESIFC_MSK BIT(CRYPT_IFC_DESIFC_POS) + +#define CRYPT_IFC_AESIFC_POS 0U +#define CRYPT_IFC_AESIFC_MSK BIT(CRYPT_IFC_AESIFC_POS) + +/****************** Bit definition for CRYPT_FIFO register ************************/ + +#define CRYPT_FIFO_FIFO_POSS 0U +#define CRYPT_FIFO_FIFO_POSE 31U +#define CRYPT_FIFO_FIFO_MSK BITS(CRYPT_FIFO_FIFO_POSS,CRYPT_FIFO_FIFO_POSE) + +typedef struct +{ + __IO uint32_t DATA[4]; + __IO uint32_t KEY[8]; + __IO uint32_t IV[4]; + __I uint32_t RES[4]; + __IO uint32_t CON; + __I uint32_t IF; + __O uint32_t IFC; + __IO uint32_t FIFO; +} CRYPT_TypeDef; + +/****************** Bit definition for LCD_CR register ************************/ + +#define LCD_CR_VCHPS_POSS 24U +#define LCD_CR_VCHPS_POSE 25U +#define LCD_CR_VCHPS_MSK BITS(LCD_CR_VCHPS_POSS,LCD_CR_VCHPS_POSE) + +#define LCD_CR_DSLD_POSS 20U +#define LCD_CR_DSLD_POSE 23U +#define LCD_CR_DSLD_MSK BITS(LCD_CR_DSLD_POSS,LCD_CR_DSLD_POSE) + +#define LCD_CR_DSHD_POSS 16U +#define LCD_CR_DSHD_POSE 19U +#define LCD_CR_DSHD_MSK BITS(LCD_CR_DSHD_POSS,LCD_CR_DSHD_POSE) + +#define LCD_CR_VBUFLD_POS 15U +#define LCD_CR_VBUFLD_MSK BIT(LCD_CR_VBUFLD_POS) + +#define LCD_CR_VBUFHD_POS 14U +#define LCD_CR_VBUFHD_MSK BIT(LCD_CR_VBUFHD_POS) + +#define LCD_CR_RESLD_POSS 12U +#define LCD_CR_RESLD_POSE 13U +#define LCD_CR_RESLD_MSK BITS(LCD_CR_RESLD_POSS,LCD_CR_RESLD_POSE) + +#define LCD_CR_RESHD_POSS 10U +#define LCD_CR_RESHD_POSE 11U +#define LCD_CR_RESHD_MSK BITS(LCD_CR_RESHD_POSS,LCD_CR_RESHD_POSE) + +#define LCD_CR_BIAS_POSS 8U +#define LCD_CR_BIAS_POSE 9U +#define LCD_CR_BIAS_MSK BITS(LCD_CR_BIAS_POSS,LCD_CR_BIAS_POSE) + +#define LCD_CR_DUTY_POSS 4U +#define LCD_CR_DUTY_POSE 6U +#define LCD_CR_DUTY_MSK BITS(LCD_CR_DUTY_POSS,LCD_CR_DUTY_POSE) + +#define LCD_CR_OE_POS 3U +#define LCD_CR_OE_MSK BIT(LCD_CR_OE_POS) + +#define LCD_CR_VSEL_POSS 1U +#define LCD_CR_VSEL_POSE 2U +#define LCD_CR_VSEL_MSK BITS(LCD_CR_VSEL_POSS,LCD_CR_VSEL_POSE) + +#define LCD_CR_EN_POS 0U +#define LCD_CR_EN_MSK BIT(LCD_CR_EN_POS) + +/****************** Bit definition for LCD_FCR register ************************/ + +#define LCD_FCR_WFS_POS 31U +#define LCD_FCR_WFS_MSK BIT(LCD_FCR_WFS_POS) + +#define LCD_FCR_PRS_POSS 24U +#define LCD_FCR_PRS_POSE 27U +#define LCD_FCR_PRS_MSK BITS(LCD_FCR_PRS_POSS,LCD_FCR_PRS_POSE) + +#define LCD_FCR_DIV_POSS 20U +#define LCD_FCR_DIV_POSE 23U +#define LCD_FCR_DIV_MSK BITS(LCD_FCR_DIV_POSS,LCD_FCR_DIV_POSE) + +#define LCD_FCR_BLMOD_POSS 16U +#define LCD_FCR_BLMOD_POSE 17U +#define LCD_FCR_BLMOD_MSK BITS(LCD_FCR_BLMOD_POSS,LCD_FCR_BLMOD_POSE) + +#define LCD_FCR_BLFRQ_POSS 12U +#define LCD_FCR_BLFRQ_POSE 14U +#define LCD_FCR_BLFRQ_MSK BITS(LCD_FCR_BLFRQ_POSS,LCD_FCR_BLFRQ_POSE) + +#define LCD_FCR_DEAD_POSS 8U +#define LCD_FCR_DEAD_POSE 10U +#define LCD_FCR_DEAD_MSK BITS(LCD_FCR_DEAD_POSS,LCD_FCR_DEAD_POSE) + +#define LCD_FCR_HD_POS 7U +#define LCD_FCR_HD_MSK BIT(LCD_FCR_HD_POS) + +#define LCD_FCR_PON_POSS 4U +#define LCD_FCR_PON_POSE 6U +#define LCD_FCR_PON_MSK BITS(LCD_FCR_PON_POSS,LCD_FCR_PON_POSE) + +#define LCD_FCR_VGS_POSS 0U +#define LCD_FCR_VGS_POSE 3U +#define LCD_FCR_VGS_MSK BITS(LCD_FCR_VGS_POSS,LCD_FCR_VGS_POSE) + +/****************** Bit definition for LCD_SEGCR0 register ************************/ + +#define LCD_SEGCR0_SEG_OE_POSS 0U +#define LCD_SEGCR0_SEG_OE_POSE 31U +#define LCD_SEGCR0_SEG_OE_MSK BITS(LCD_SEGCR0_SEG_OE_POSS,LCD_SEGCR0_SEG_OE_POSE) + +/****************** Bit definition for LCD_SEGCR1 register ************************/ + +#define LCD_SEGCR1_SEG_OE_POSS 0U +#define LCD_SEGCR1_SEG_OE_POSE 11U +#define LCD_SEGCR1_SEG_OE_MSK BITS(LCD_SEGCR1_SEG_OE_POSS,LCD_SEGCR1_SEG_OE_POSE) + +/****************** Bit definition for LCD_IE register ************************/ + +#define LCD_IE_UDDIE_POS 1U +#define LCD_IE_UDDIE_MSK BIT(LCD_IE_UDDIE_POS) + +#define LCD_IE_SOFIE_POS 0U +#define LCD_IE_SOFIE_MSK BIT(LCD_IE_SOFIE_POS) + +/****************** Bit definition for LCD_IF register ************************/ + +#define LCD_IF_UDDIF_POS 1U +#define LCD_IF_UDDIF_MSK BIT(LCD_IF_UDDIF_POS) + +#define LCD_IF_SOFIF_POS 0U +#define LCD_IF_SOFIF_MSK BIT(LCD_IF_SOFIF_POS) + +/****************** Bit definition for LCD_IFCR register ************************/ + +#define LCD_IFCR_UDDIFC_POS 1U +#define LCD_IFCR_UDDIFC_MSK BIT(LCD_IFCR_UDDIFC_POS) + +#define LCD_IFCR_SOFIFC_POS 0U +#define LCD_IFCR_SOFIFC_MSK BIT(LCD_IFCR_SOFIFC_POS) + +/****************** Bit definition for LCD_SR register ************************/ + +#define LCD_SR_FCRSF_POS 3U +#define LCD_SR_FCRSF_MSK BIT(LCD_SR_FCRSF_POS) + +#define LCD_SR_UDR_POS 2U +#define LCD_SR_UDR_MSK BIT(LCD_SR_UDR_POS) + +#define LCD_SR_ENS_POS 1U +#define LCD_SR_ENS_MSK BIT(LCD_SR_ENS_POS) + +#define LCD_SR_RDY_POS 0U +#define LCD_SR_RDY_MSK BIT(LCD_SR_RDY_POS) + +/****************** Bit definition for LCD_BUF register ************************/ + +#define LCD_BUF_SEG_DATA_POSS 0U +#define LCD_BUF_SEG_DATA_POSE 31U +#define LCD_BUF_SEG_DATA_MSK BITS(LCD_BUF_SEG_DATA_POSS,LCD_BUF_SEG_DATA_POSE) + +typedef struct +{ + __IO uint32_t CR; + __IO uint32_t FCR; + __IO uint32_t SEGCR0; + __IO uint32_t SEGCR1; + __IO uint32_t IE; + __I uint32_t IF; + __O uint32_t IFCR; + __I uint32_t SR; + uint32_t RESERVED0[8] ; + __IO uint32_t BUF[16]; +} LCD_TypeDef; + +/****************** Bit definition for ADC_STAT register ************************/ + +#define ADC_STAT_ICHS_POS 9U +#define ADC_STAT_ICHS_MSK BIT(ADC_STAT_ICHS_POS) + +#define ADC_STAT_NCHS_POS 8U +#define ADC_STAT_NCHS_MSK BIT(ADC_STAT_NCHS_POS) + +#define ADC_STAT_OVR_POS 3U +#define ADC_STAT_OVR_MSK BIT(ADC_STAT_OVR_POS) + +#define ADC_STAT_ICHE_POS 2U +#define ADC_STAT_ICHE_MSK BIT(ADC_STAT_ICHE_POS) + +#define ADC_STAT_NCHE_POS 1U +#define ADC_STAT_NCHE_MSK BIT(ADC_STAT_NCHE_POS) + +#define ADC_STAT_AWDF_POS 0U +#define ADC_STAT_AWDF_MSK BIT(ADC_STAT_AWDF_POS) + +/****************** Bit definition for ADC_CLR register ************************/ + +#define ADC_CLR_ICHS_POS 9U +#define ADC_CLR_ICHS_MSK BIT(ADC_CLR_ICHS_POS) + +#define ADC_CLR_NCHS_POS 8U +#define ADC_CLR_NCHS_MSK BIT(ADC_CLR_NCHS_POS) + +#define ADC_CLR_OVR_POS 3U +#define ADC_CLR_OVR_MSK BIT(ADC_CLR_OVR_POS) + +#define ADC_CLR_ICHE_POS 2U +#define ADC_CLR_ICHE_MSK BIT(ADC_CLR_ICHE_POS) + +#define ADC_CLR_NCHE_POS 1U +#define ADC_CLR_NCHE_MSK BIT(ADC_CLR_NCHE_POS) + +#define ADC_CLR_AWDF_POS 0U +#define ADC_CLR_AWDF_MSK BIT(ADC_CLR_AWDF_POS) + +/****************** Bit definition for ADC_CON0 register ************************/ + +#define ADC_CON0_OVRIE_POS 26U +#define ADC_CON0_OVRIE_MSK BIT(ADC_CON0_OVRIE_POS) + +#define ADC_CON0_RSEL_POSS 24U +#define ADC_CON0_RSEL_POSE 25U +#define ADC_CON0_RSEL_MSK BITS(ADC_CON0_RSEL_POSS,ADC_CON0_RSEL_POSE) + +#define ADC_CON0_NCHWDEN_POS 23U +#define ADC_CON0_NCHWDEN_MSK BIT(ADC_CON0_NCHWDEN_POS) + +#define ADC_CON0_ICHWDTEN_POS 22U +#define ADC_CON0_ICHWDTEN_MSK BIT(ADC_CON0_ICHWDTEN_POS) + +#define ADC_CON0_ETRGN_POSS 13U +#define ADC_CON0_ETRGN_POSE 15U +#define ADC_CON0_ETRGN_MSK BITS(ADC_CON0_ETRGN_POSS,ADC_CON0_ETRGN_POSE) + +#define ADC_CON0_ICHDCEN_POS 12U +#define ADC_CON0_ICHDCEN_MSK BIT(ADC_CON0_ICHDCEN_POS) + +#define ADC_CON0_NCHDCEN_POS 11U +#define ADC_CON0_NCHDCEN_MSK BIT(ADC_CON0_NCHDCEN_POS) + +#define ADC_CON0_IAUTO_POS 10U +#define ADC_CON0_IAUTO_MSK BIT(ADC_CON0_IAUTO_POS) + +#define ADC_CON0_AWDSGL_POS 9U +#define ADC_CON0_AWDSGL_MSK BIT(ADC_CON0_AWDSGL_POS) + +#define ADC_CON0_SCANEN_POS 8U +#define ADC_CON0_SCANEN_MSK BIT(ADC_CON0_SCANEN_POS) + +#define ADC_CON0_ICHEIE_POS 7U +#define ADC_CON0_ICHEIE_MSK BIT(ADC_CON0_ICHEIE_POS) + +#define ADC_CON0_AWDIE_POS 6U +#define ADC_CON0_AWDIE_MSK BIT(ADC_CON0_AWDIE_POS) + +#define ADC_CON0_NCHEIE_POS 5U +#define ADC_CON0_NCHEIE_MSK BIT(ADC_CON0_NCHEIE_POS) + +#define ADC_CON0_AWDCH_POSS 0U +#define ADC_CON0_AWDCH_POSE 4U +#define ADC_CON0_AWDCH_MSK BITS(ADC_CON0_AWDCH_POSS,ADC_CON0_AWDCH_POSE) + +/****************** Bit definition for ADC_CON1 register ************************/ + +#define ADC_CON1_NCHTRG_POS 30U +#define ADC_CON1_NCHTRG_MSK BIT(ADC_CON1_NCHTRG_POS) + +#define ADC_CON1_ICHTRG_POS 22U +#define ADC_CON1_ICHTRG_MSK BIT(ADC_CON1_ICHTRG_POS) + +#define ADC_CON1_ALIGN_POS 11U +#define ADC_CON1_ALIGN_MSK BIT(ADC_CON1_ALIGN_POS) + +#define ADC_CON1_NCHESEL_POS 10U +#define ADC_CON1_NCHESEL_MSK BIT(ADC_CON1_NCHESEL_POS) + +#define ADC_CON1_OVRDIS_POS 8U +#define ADC_CON1_OVRDIS_MSK BIT(ADC_CON1_OVRDIS_POS) + +#define ADC_CON1_CM_POS 1U +#define ADC_CON1_CM_MSK BIT(ADC_CON1_CM_POS) + +#define ADC_CON1_ADCEN_POS 0U +#define ADC_CON1_ADCEN_MSK BIT(ADC_CON1_ADCEN_POS) + +/****************** Bit definition for ADC_SMPT1 register ************************/ + +#define ADC_SMPT1_CHT_POSS 0U +#define ADC_SMPT1_CHT_POSE 31U +#define ADC_SMPT1_CHT_MSK BITS(ADC_SMPT1_CHT_POSS,ADC_SMPT1_CHT_POSE) + +/****************** Bit definition for ADC_SMPT2 register ************************/ + +#define ADC_SMPT2_CHT_POSS 0U +#define ADC_SMPT2_CHT_POSE 7U +#define ADC_SMPT2_CHT_MSK BITS(ADC_SMPT2_CHT_POSS,ADC_SMPT2_CHT_POSE) + +/****************** Bit definition for ADC_ICHOFF1 register ************************/ + +#define ADC_ICHOFF1_IOFF_POSS 0U +#define ADC_ICHOFF1_IOFF_POSE 11U +#define ADC_ICHOFF1_IOFF_MSK BITS(ADC_ICHOFF1_IOFF_POSS,ADC_ICHOFF1_IOFF_POSE) + +/****************** Bit definition for ADC_ICHOFF2 register ************************/ + +#define ADC_ICHOFF2_IOFF_POSS 0U +#define ADC_ICHOFF2_IOFF_POSE 11U +#define ADC_ICHOFF2_IOFF_MSK BITS(ADC_ICHOFF2_IOFF_POSS,ADC_ICHOFF2_IOFF_POSE) + +/****************** Bit definition for ADC_ICHOFF3 register ************************/ + +#define ADC_ICHOFF3_IOFF_POSS 0U +#define ADC_ICHOFF3_IOFF_POSE 11U +#define ADC_ICHOFF3_IOFF_MSK BITS(ADC_ICHOFF3_IOFF_POSS,ADC_ICHOFF3_IOFF_POSE) + +/****************** Bit definition for ADC_ICHOFF4 register ************************/ + +#define ADC_ICHOFF4_IOFF_POSS 0U +#define ADC_ICHOFF4_IOFF_POSE 11U +#define ADC_ICHOFF4_IOFF_MSK BITS(ADC_ICHOFF4_IOFF_POSS,ADC_ICHOFF4_IOFF_POSE) + +/****************** Bit definition for ADC_WDTH register ************************/ + +#define ADC_WDTH_HT_POSS 0U +#define ADC_WDTH_HT_POSE 11U +#define ADC_WDTH_HT_MSK BITS(ADC_WDTH_HT_POSS,ADC_WDTH_HT_POSE) + +/****************** Bit definition for ADC_WDTL register ************************/ + +#define ADC_WDTL_LT_POSS 0U +#define ADC_WDTL_LT_POSE 11U +#define ADC_WDTL_LT_MSK BITS(ADC_WDTL_LT_POSS,ADC_WDTL_LT_POSE) + +/****************** Bit definition for ADC_NCHS1 register ************************/ + +#define ADC_NCHS1_NS4_POSS 24U +#define ADC_NCHS1_NS4_POSE 28U +#define ADC_NCHS1_NS4_MSK BITS(ADC_NCHS1_NS4_POSS,ADC_NCHS1_NS4_POSE) + +#define ADC_NCHS1_NS3_POSS 16U +#define ADC_NCHS1_NS3_POSE 20U +#define ADC_NCHS1_NS3_MSK BITS(ADC_NCHS1_NS3_POSS,ADC_NCHS1_NS3_POSE) + +#define ADC_NCHS1_NS2_POSS 8U +#define ADC_NCHS1_NS2_POSE 12U +#define ADC_NCHS1_NS2_MSK BITS(ADC_NCHS1_NS2_POSS,ADC_NCHS1_NS2_POSE) + +#define ADC_NCHS1_NS1_POSS 0U +#define ADC_NCHS1_NS1_POSE 4U +#define ADC_NCHS1_NS1_MSK BITS(ADC_NCHS1_NS1_POSS,ADC_NCHS1_NS1_POSE) + +/****************** Bit definition for ADC_NCHS2 register ************************/ + +#define ADC_NCHS2_NS8_POSS 24U +#define ADC_NCHS2_NS8_POSE 28U +#define ADC_NCHS2_NS8_MSK BITS(ADC_NCHS2_NS8_POSS,ADC_NCHS2_NS8_POSE) + +#define ADC_NCHS2_NS7_POSS 16U +#define ADC_NCHS2_NS7_POSE 20U +#define ADC_NCHS2_NS7_MSK BITS(ADC_NCHS2_NS7_POSS,ADC_NCHS2_NS7_POSE) + +#define ADC_NCHS2_NS6_POSS 8U +#define ADC_NCHS2_NS6_POSE 12U +#define ADC_NCHS2_NS6_MSK BITS(ADC_NCHS2_NS6_POSS,ADC_NCHS2_NS6_POSE) + +#define ADC_NCHS2_NS5_POSS 0U +#define ADC_NCHS2_NS5_POSE 4U +#define ADC_NCHS2_NS5_MSK BITS(ADC_NCHS2_NS5_POSS,ADC_NCHS2_NS5_POSE) + +/****************** Bit definition for ADC_NCHS3 register ************************/ + +#define ADC_NCHS3_NS12_POSS 24U +#define ADC_NCHS3_NS12_POSE 28U +#define ADC_NCHS3_NS12_MSK BITS(ADC_NCHS3_NS12_POSS,ADC_NCHS3_NS12_POSE) + +#define ADC_NCHS3_NS11_POSS 16U +#define ADC_NCHS3_NS11_POSE 20U +#define ADC_NCHS3_NS11_MSK BITS(ADC_NCHS3_NS11_POSS,ADC_NCHS3_NS11_POSE) + +#define ADC_NCHS3_NS10_POSS 8U +#define ADC_NCHS3_NS10_POSE 12U +#define ADC_NCHS3_NS10_MSK BITS(ADC_NCHS3_NS10_POSS,ADC_NCHS3_NS10_POSE) + +#define ADC_NCHS3_NS9_POSS 0U +#define ADC_NCHS3_NS9_POSE 4U +#define ADC_NCHS3_NS9_MSK BITS(ADC_NCHS3_NS9_POSS,ADC_NCHS3_NS9_POSE) + +/****************** Bit definition for ADC_NCHS4 register ************************/ + +#define ADC_NCHS4_NS16_POSS 24U +#define ADC_NCHS4_NS16_POSE 28U +#define ADC_NCHS4_NS16_MSK BITS(ADC_NCHS4_NS16_POSS,ADC_NCHS4_NS16_POSE) + +#define ADC_NCHS4_NS15_POSS 16U +#define ADC_NCHS4_NS15_POSE 20U +#define ADC_NCHS4_NS15_MSK BITS(ADC_NCHS4_NS15_POSS,ADC_NCHS4_NS15_POSE) + +#define ADC_NCHS4_NS14_POSS 8U +#define ADC_NCHS4_NS14_POSE 12U +#define ADC_NCHS4_NS14_MSK BITS(ADC_NCHS4_NS14_POSS,ADC_NCHS4_NS14_POSE) + +#define ADC_NCHS4_NS13_POSS 0U +#define ADC_NCHS4_NS13_POSE 4U +#define ADC_NCHS4_NS13_MSK BITS(ADC_NCHS4_NS13_POSS,ADC_NCHS4_NS13_POSE) + +/****************** Bit definition for ADC_ICHS register ************************/ + +#define ADC_ICHS_IS4_POSS 24U +#define ADC_ICHS_IS4_POSE 28U +#define ADC_ICHS_IS4_MSK BITS(ADC_ICHS_IS4_POSS,ADC_ICHS_IS4_POSE) + +#define ADC_ICHS_IS3_POSS 16U +#define ADC_ICHS_IS3_POSE 20U +#define ADC_ICHS_IS3_MSK BITS(ADC_ICHS_IS3_POSS,ADC_ICHS_IS3_POSE) + +#define ADC_ICHS_IS2_POSS 8U +#define ADC_ICHS_IS2_POSE 12U +#define ADC_ICHS_IS2_MSK BITS(ADC_ICHS_IS2_POSS,ADC_ICHS_IS2_POSE) + +#define ADC_ICHS_IS1_POSS 0U +#define ADC_ICHS_IS1_POSE 4U +#define ADC_ICHS_IS1_MSK BITS(ADC_ICHS_IS1_POSS,ADC_ICHS_IS1_POSE) + +/****************** Bit definition for ADC_CHSL register ************************/ + +#define ADC_CHSL_ISL_POSS 8U +#define ADC_CHSL_ISL_POSE 9U +#define ADC_CHSL_ISL_MSK BITS(ADC_CHSL_ISL_POSS,ADC_CHSL_ISL_POSE) + +#define ADC_CHSL_NSL_POSS 0U +#define ADC_CHSL_NSL_POSE 3U +#define ADC_CHSL_NSL_MSK BITS(ADC_CHSL_NSL_POSS,ADC_CHSL_NSL_POSE) + +/****************** Bit definition for ADC_ICHDR1 register ************************/ + +#define ADC_ICHDR1_VAL_POSS 0U +#define ADC_ICHDR1_VAL_POSE 15U +#define ADC_ICHDR1_VAL_MSK BITS(ADC_ICHDR1_VAL_POSS,ADC_ICHDR1_VAL_POSE) + +/****************** Bit definition for ADC_ICHDR2 register ************************/ + +#define ADC_ICHDR2_VAL_POSS 0U +#define ADC_ICHDR2_VAL_POSE 15U +#define ADC_ICHDR2_VAL_MSK BITS(ADC_ICHDR2_VAL_POSS,ADC_ICHDR2_VAL_POSE) + +/****************** Bit definition for ADC_ICHDR3 register ************************/ + +#define ADC_ICHDR3_VAL_POSS 0U +#define ADC_ICHDR3_VAL_POSE 15U +#define ADC_ICHDR3_VAL_MSK BITS(ADC_ICHDR3_VAL_POSS,ADC_ICHDR3_VAL_POSE) + +/****************** Bit definition for ADC_ICHDR4 register ************************/ + +#define ADC_ICHDR4_VAL_POSS 0U +#define ADC_ICHDR4_VAL_POSE 15U +#define ADC_ICHDR4_VAL_MSK BITS(ADC_ICHDR4_VAL_POSS,ADC_ICHDR4_VAL_POSE) + +/****************** Bit definition for ADC_NCHDR register ************************/ + +#define ADC_NCHDR_VAL_POSS 0U +#define ADC_NCHDR_VAL_POSE 15U +#define ADC_NCHDR_VAL_MSK BITS(ADC_NCHDR_VAL_POSS,ADC_NCHDR_VAL_POSE) + +/****************** Bit definition for ADC_CCR register ************************/ + +#define ADC_CCR_TRMEN_POS 28U +#define ADC_CCR_TRMEN_MSK BIT(ADC_CCR_TRMEN_POS) + +#define ADC_CCR_GAINCALEN_POS 25U +#define ADC_CCR_GAINCALEN_MSK BIT(ADC_CCR_GAINCALEN_POS) + +#define ADC_CCR_OFFCALEN_POS 24U +#define ADC_CCR_OFFCALEN_MSK BIT(ADC_CCR_OFFCALEN_POS) + +#define ADC_CCR_VREFOEN_POS 19U +#define ADC_CCR_VREFOEN_MSK BIT(ADC_CCR_VREFOEN_POS) + +#define ADC_CCR_VRNSEL_POS 18U +#define ADC_CCR_VRNSEL_MSK BIT(ADC_CCR_VRNSEL_POS) + +#define ADC_CCR_VRPSEL_POSS 16U +#define ADC_CCR_VRPSEL_POSE 17U +#define ADC_CCR_VRPSEL_MSK BITS(ADC_CCR_VRPSEL_POSS,ADC_CCR_VRPSEL_POSE) + +#define ADC_CCR_PWRMODSEL_POS 15U +#define ADC_CCR_PWRMODSEL_MSK BIT(ADC_CCR_PWRMODSEL_POS) + +#define ADC_CCR_DIFFEN_POS 12U +#define ADC_CCR_DIFFEN_MSK BIT(ADC_CCR_DIFFEN_POS) + +#define ADC_CCR_IREFEN_POS 11U +#define ADC_CCR_IREFEN_MSK BIT(ADC_CCR_IREFEN_POS) + +#define ADC_CCR_VRBUFEN_POS 10U +#define ADC_CCR_VRBUFEN_MSK BIT(ADC_CCR_VRBUFEN_POS) + +#define ADC_CCR_VCMBUFEN_POS 9U +#define ADC_CCR_VCMBUFEN_MSK BIT(ADC_CCR_VCMBUFEN_POS) + +#define ADC_CCR_VREFEN_POS 8U +#define ADC_CCR_VREFEN_MSK BIT(ADC_CCR_VREFEN_POS) + +#define ADC_CCR_CKDIV_POSS 0U +#define ADC_CCR_CKDIV_POSE 2U +#define ADC_CCR_CKDIV_MSK BITS(ADC_CCR_CKDIV_POSS,ADC_CCR_CKDIV_POSE) + +typedef struct +{ + __I uint32_t STAT; + __O uint32_t CLR; + __IO uint32_t CON0; + __IO uint32_t CON1; + __IO uint32_t SMPT1; + __IO uint32_t SMPT2; + __IO uint32_t ICHOFF[4]; + __IO uint32_t WDTH; + __IO uint32_t WDTL; + __IO uint32_t NCHS1; + __IO uint32_t NCHS2; + __IO uint32_t NCHS3; + __IO uint32_t NCHS4; + __IO uint32_t ICHS; + __IO uint32_t CHSL; + __I uint32_t ICHDR[4]; + __I uint32_t NCHDR; + __IO uint32_t CCR; +} ADC_TypeDef; + +/****************** Bit definition for ACMP_CON register ************************/ + +#define ACMP_CON_FALLEN_POS 17U +#define ACMP_CON_FALLEN_MSK BIT(ACMP_CON_FALLEN_POS) + +#define ACMP_CON_RISEEN_POS 16U +#define ACMP_CON_RISEEN_MSK BIT(ACMP_CON_RISEEN_POS) + +#define ACMP_CON_MODSEL_POSS 14U +#define ACMP_CON_MODSEL_POSE 15U +#define ACMP_CON_MODSEL_MSK BITS(ACMP_CON_MODSEL_POSS,ACMP_CON_MODSEL_POSE) + +#define ACMP_CON_WARMUPT_POSS 8U +#define ACMP_CON_WARMUPT_POSE 10U +#define ACMP_CON_WARMUPT_MSK BITS(ACMP_CON_WARMUPT_POSS,ACMP_CON_WARMUPT_POSE) + +#define ACMP_CON_HYSTSEL_POSS 4U +#define ACMP_CON_HYSTSEL_POSE 6U +#define ACMP_CON_HYSTSEL_MSK BITS(ACMP_CON_HYSTSEL_POSS,ACMP_CON_HYSTSEL_POSE) + +#define ACMP_CON_OUTINV_POS 3U +#define ACMP_CON_OUTINV_MSK BIT(ACMP_CON_OUTINV_POS) + +#define ACMP_CON_INACTV_POS 2U +#define ACMP_CON_INACTV_MSK BIT(ACMP_CON_INACTV_POS) + +#define ACMP_CON_EN_POS 0U +#define ACMP_CON_EN_MSK BIT(ACMP_CON_EN_POS) + +/****************** Bit definition for ACMP_INPUTSEL register ************************/ + +#define ACMP_INPUTSEL_VDDLVL_POSS 8U +#define ACMP_INPUTSEL_VDDLVL_POSE 13U +#define ACMP_INPUTSEL_VDDLVL_MSK BITS(ACMP_INPUTSEL_VDDLVL_POSS,ACMP_INPUTSEL_VDDLVL_POSE) + +#define ACMP_INPUTSEL_NSEL_POSS 4U +#define ACMP_INPUTSEL_NSEL_POSE 7U +#define ACMP_INPUTSEL_NSEL_MSK BITS(ACMP_INPUTSEL_NSEL_POSS,ACMP_INPUTSEL_NSEL_POSE) + +#define ACMP_INPUTSEL_PSEL_POSS 0U +#define ACMP_INPUTSEL_PSEL_POSE 2U +#define ACMP_INPUTSEL_PSEL_MSK BITS(ACMP_INPUTSEL_PSEL_POSS,ACMP_INPUTSEL_PSEL_POSE) + +/****************** Bit definition for ACMP_STAT register ************************/ + +#define ACMP_STAT_OUT_POS 1U +#define ACMP_STAT_OUT_MSK BIT(ACMP_STAT_OUT_POS) + +#define ACMP_STAT_ACT_POS 0U +#define ACMP_STAT_ACT_MSK BIT(ACMP_STAT_ACT_POS) + +/****************** Bit definition for ACMP_IES register ************************/ + +#define ACMP_IES_WARMUP_POS 1U +#define ACMP_IES_WARMUP_MSK BIT(ACMP_IES_WARMUP_POS) + +#define ACMP_IES_EDGE_POS 0U +#define ACMP_IES_EDGE_MSK BIT(ACMP_IES_EDGE_POS) + +/****************** Bit definition for ACMP_IEV register ************************/ + +#define ACMP_IEV_WARMUP_POS 1U +#define ACMP_IEV_WARMUP_MSK BIT(ACMP_IEV_WARMUP_POS) + +#define ACMP_IEV_EDGE_POS 0U +#define ACMP_IEV_EDGE_MSK BIT(ACMP_IEV_EDGE_POS) + +/****************** Bit definition for ACMP_IEC register ************************/ + +#define ACMP_IEC_WARMUP_POS 1U +#define ACMP_IEC_WARMUP_MSK BIT(ACMP_IEC_WARMUP_POS) + +#define ACMP_IEC_EDGE_POS 0U +#define ACMP_IEC_EDGE_MSK BIT(ACMP_IEC_EDGE_POS) + +/****************** Bit definition for ACMP_RIF register ************************/ + +#define ACMP_RIF_WARMUP_POS 1U +#define ACMP_RIF_WARMUP_MSK BIT(ACMP_RIF_WARMUP_POS) + +#define ACMP_RIF_EDGE_POS 0U +#define ACMP_RIF_EDGE_MSK BIT(ACMP_RIF_EDGE_POS) + +/****************** Bit definition for ACMP_IFM register ************************/ + +#define ACMP_IFM_WARMUP_POS 1U +#define ACMP_IFM_WARMUP_MSK BIT(ACMP_IFM_WARMUP_POS) + +#define ACMP_IFM_EDGE_POS 0U +#define ACMP_IFM_EDGE_MSK BIT(ACMP_IFM_EDGE_POS) + +/****************** Bit definition for ACMP_IFC register ************************/ + +#define ACMP_IFC_WARMUP_POS 1U +#define ACMP_IFC_WARMUP_MSK BIT(ACMP_IFC_WARMUP_POS) + +#define ACMP_IFC_EDGE_POS 0U +#define ACMP_IFC_EDGE_MSK BIT(ACMP_IFC_EDGE_POS) + +/****************** Bit definition for ACMP_PORT register ************************/ + +#define ACMP_PORT_PEN_POS 0U +#define ACMP_PORT_PEN_MSK BIT(ACMP_PORT_PEN_POS) + +typedef struct +{ + __IO uint32_t CON; + __IO uint32_t INPUTSEL; + __I uint32_t STAT; + __O uint32_t IES; + __I uint32_t IEV; + __O uint32_t IEC; + __I uint32_t RIF; + __O uint32_t IFM; + __O uint32_t IFC; + __IO uint32_t PORT; +} ACMP_TypeDef; + +/****************** Bit definition for CALC_SQRTSR register ************************/ + +#define CALC_SQRTSR_BUSY_POS 0U +#define CALC_SQRTSR_BUSY_MSK BIT(CALC_SQRTSR_BUSY_POS) + +/****************** Bit definition for CALC_RDCND register ************************/ + +#define CALC_RDCND_RADICAND_POSS 0U +#define CALC_RDCND_RADICAND_POSE 31U +#define CALC_RDCND_RADICAND_MSK BITS(CALC_RDCND_RADICAND_POSS,CALC_RDCND_RADICAND_POSE) + +/****************** Bit definition for CALC_SQRTRES register ************************/ + +#define CALC_SQRTRES_RESULT_POSS 0U +#define CALC_SQRTRES_RESULT_POSE 15U +#define CALC_SQRTRES_RESULT_MSK BITS(CALC_SQRTRES_RESULT_POSS,CALC_SQRTRES_RESULT_POSE) + +/****************** Bit definition for CALC_DIVDR register ************************/ + +#define CALC_DIVDR_DIVD_POSS 0U +#define CALC_DIVDR_DIVD_POSE 31U +#define CALC_DIVDR_DIVD_MSK BITS(CALC_DIVDR_DIVD_POSS,CALC_DIVDR_DIVD_POSE) + +/****************** Bit definition for CALC_DIVSR register ************************/ + +#define CALC_DIVSR_DIVS_POSS 0U +#define CALC_DIVSR_DIVS_POSE 31U +#define CALC_DIVSR_DIVS_MSK BITS(CALC_DIVSR_DIVS_POSS,CALC_DIVSR_DIVS_POSE) + +/****************** Bit definition for CALC_DIVQR register ************************/ + +#define CALC_DIVQR_DIVQ_POSS 0U +#define CALC_DIVQR_DIVQ_POSE 31U +#define CALC_DIVQR_DIVQ_MSK BITS(CALC_DIVQR_DIVQ_POSS,CALC_DIVQR_DIVQ_POSE) + +/****************** Bit definition for CALC_DIVRR register ************************/ + +#define CALC_DIVRR_DIVS_POSS 0U +#define CALC_DIVRR_DIVS_POSE 31U +#define CALC_DIVRR_DIVS_MSK BITS(CALC_DIVRR_DIVS_POSS,CALC_DIVRR_DIVS_POSE) + +/****************** Bit definition for CALC_DIVCSR register ************************/ + +#define CALC_DIVCSR_TRM_POS 9U +#define CALC_DIVCSR_TRM_MSK BIT(CALC_DIVCSR_TRM_POS) + +#define CALC_DIVCSR_SIGN_POS 8U +#define CALC_DIVCSR_SIGN_MSK BIT(CALC_DIVCSR_SIGN_POS) + +#define CALC_DIVCSR_DZ_POS 1U +#define CALC_DIVCSR_DZ_MSK BIT(CALC_DIVCSR_DZ_POS) + +#define CALC_DIVCSR_BUSY_POS 0U +#define CALC_DIVCSR_BUSY_MSK BIT(CALC_DIVCSR_BUSY_POS) + +typedef struct +{ + __I uint32_t SQRTSR; + __IO uint32_t RDCND; + __I uint32_t SQRTRES; + uint32_t RESERVED0[5] ; + __IO uint32_t DIVDR; + __IO uint32_t DIVSR; + __I uint32_t DIVQR; + __I uint32_t DIVRR; + __IO uint32_t DIVCSR; +} CALC_TypeDef; + +/****************** Bit definition for TRNG_CR register ************************/ + +#define TRNG_CR_ADJC_POSS 16U +#define TRNG_CR_ADJC_POSE 17U +#define TRNG_CR_ADJC_MSK BITS(TRNG_CR_ADJC_POSS,TRNG_CR_ADJC_POSE) + +#define TRNG_CR_SDSEL_POSS 10U +#define TRNG_CR_SDSEL_POSE 11U +#define TRNG_CR_SDSEL_MSK BITS(TRNG_CR_SDSEL_POSS,TRNG_CR_SDSEL_POSE) + +#define TRNG_CR_DSEL_POSS 8U +#define TRNG_CR_DSEL_POSE 9U +#define TRNG_CR_DSEL_MSK BITS(TRNG_CR_DSEL_POSS,TRNG_CR_DSEL_POSE) + +#define TRNG_CR_POSTEN_POS 3U +#define TRNG_CR_POSTEN_MSK BIT(TRNG_CR_POSTEN_POS) + +#define TRNG_CR_TRNGSEL_POS 2U +#define TRNG_CR_TRNGSEL_MSK BIT(TRNG_CR_TRNGSEL_POS) + +#define TRNG_CR_ADJM_POS 1U +#define TRNG_CR_ADJM_MSK BIT(TRNG_CR_ADJM_POS) + +#define TRNG_CR_TRNGEN_POS 0U +#define TRNG_CR_TRNGEN_MSK BIT(TRNG_CR_TRNGEN_POS) + +/****************** Bit definition for TRNG_SR register ************************/ + +#define TRNG_SR_OVER_POS 3U +#define TRNG_SR_OVER_MSK BIT(TRNG_SR_OVER_POS) + +#define TRNG_SR_SERR_POS 2U +#define TRNG_SR_SERR_MSK BIT(TRNG_SR_SERR_POS) + +#define TRNG_SR_DAVLD_POS 1U +#define TRNG_SR_DAVLD_MSK BIT(TRNG_SR_DAVLD_POS) + +#define TRNG_SR_START_POS 0U +#define TRNG_SR_START_MSK BIT(TRNG_SR_START_POS) + +/****************** Bit definition for TRNG_DR register ************************/ + +#define TRNG_DR_DATA_POSS 0U +#define TRNG_DR_DATA_POSE 31U +#define TRNG_DR_DATA_MSK BITS(TRNG_DR_DATA_POSS,TRNG_DR_DATA_POSE) + +/****************** Bit definition for TRNG_SEED register ************************/ + +#define TRNG_SEED_SEED_POSS 0U +#define TRNG_SEED_SEED_POSE 31U +#define TRNG_SEED_SEED_MSK BITS(TRNG_SEED_SEED_POSS,TRNG_SEED_SEED_POSE) + +/****************** Bit definition for TRNG_CFGR register ************************/ + +#define TRNG_CFGR_TOPLMT_POSS 16U +#define TRNG_CFGR_TOPLMT_POSE 24U +#define TRNG_CFGR_TOPLMT_MSK BITS(TRNG_CFGR_TOPLMT_POSS,TRNG_CFGR_TOPLMT_POSE) + +#define TRNG_CFGR_CKDIV_POSS 8U +#define TRNG_CFGR_CKDIV_POSE 11U +#define TRNG_CFGR_CKDIV_MSK BITS(TRNG_CFGR_CKDIV_POSS,TRNG_CFGR_CKDIV_POSE) + +#define TRNG_CFGR_TSTART_POSS 0U +#define TRNG_CFGR_TSTART_POSE 2U +#define TRNG_CFGR_TSTART_MSK BITS(TRNG_CFGR_TSTART_POSS,TRNG_CFGR_TSTART_POSE) + +/****************** Bit definition for TRNG_IER register ************************/ + +#define TRNG_IER_SERR_POS 2U +#define TRNG_IER_SERR_MSK BIT(TRNG_IER_SERR_POS) + +#define TRNG_IER_DAVLD_POS 1U +#define TRNG_IER_DAVLD_MSK BIT(TRNG_IER_DAVLD_POS) + +#define TRNG_IER_START_POS 0U +#define TRNG_IER_START_MSK BIT(TRNG_IER_START_POS) + +/****************** Bit definition for TRNG_IFR register ************************/ + +#define TRNG_IFR_SERR_POS 2U +#define TRNG_IFR_SERR_MSK BIT(TRNG_IFR_SERR_POS) + +#define TRNG_IFR_DAVLD_POS 1U +#define TRNG_IFR_DAVLD_MSK BIT(TRNG_IFR_DAVLD_POS) + +#define TRNG_IFR_START_POS 0U +#define TRNG_IFR_START_MSK BIT(TRNG_IFR_START_POS) + +/****************** Bit definition for TRNG_IFCR register ************************/ + +#define TRNG_IFCR_SERRC_POS 2U +#define TRNG_IFCR_SERRC_MSK BIT(TRNG_IFCR_SERRC_POS) + +#define TRNG_IFCR_DAVLDC_POS 1U +#define TRNG_IFCR_DAVLDC_MSK BIT(TRNG_IFCR_DAVLDC_POS) + +#define TRNG_IFCR_STARTC_POS 0U +#define TRNG_IFCR_STARTC_MSK BIT(TRNG_IFCR_STARTC_POS) + +/****************** Bit definition for TRNG_ISR register ************************/ + +#define TRNG_ISR_SERR_POS 2U +#define TRNG_ISR_SERR_MSK BIT(TRNG_ISR_SERR_POS) + +#define TRNG_ISR_DAVLD_POS 1U +#define TRNG_ISR_DAVLD_MSK BIT(TRNG_ISR_DAVLD_POS) + +#define TRNG_ISR_START_POS 0U +#define TRNG_ISR_START_MSK BIT(TRNG_ISR_START_POS) + +typedef struct +{ + __IO uint32_t CR; + __I uint32_t SR; + __I uint32_t DR; + __IO uint32_t SEED; + __IO uint32_t CFGR; + __IO uint32_t IER; + __I uint32_t IFR; + __O uint32_t IFCR; + __I uint32_t ISR; +} TRNG_TypeDef; + +/****************** Bit definition for TSENSE_WPR register ************************/ + +#define TSENSE_WPR_WP_POS 0U +#define TSENSE_WPR_WP_MSK BIT(TSENSE_WPR_WP_POS) + +/****************** Bit definition for TSENSE_CR register ************************/ + +#define TSENSE_CR_TSU_POSS 12U +#define TSENSE_CR_TSU_POSE 14U +#define TSENSE_CR_TSU_MSK BITS(TSENSE_CR_TSU_POSS,TSENSE_CR_TSU_POSE) + +#define TSENSE_CR_TOM_POSS 8U +#define TSENSE_CR_TOM_POSE 10U +#define TSENSE_CR_TOM_MSK BITS(TSENSE_CR_TOM_POSS,TSENSE_CR_TOM_POSE) + +#define TSENSE_CR_CTN_POS 4U +#define TSENSE_CR_CTN_MSK BIT(TSENSE_CR_CTN_POS) + +#define TSENSE_CR_RST_POS 3U +#define TSENSE_CR_RST_MSK BIT(TSENSE_CR_RST_POS) + +#define TSENSE_CR_ENS_POS 2U +#define TSENSE_CR_ENS_MSK BIT(TSENSE_CR_ENS_POS) + +#define TSENSE_CR_REQEN_POS 1U +#define TSENSE_CR_REQEN_MSK BIT(TSENSE_CR_REQEN_POS) + +#define TSENSE_CR_EN_POS 0U +#define TSENSE_CR_EN_MSK BIT(TSENSE_CR_EN_POS) + +/****************** Bit definition for TSENSE_DR register ************************/ + +#define TSENSE_DR_ERR_POS 31U +#define TSENSE_DR_ERR_MSK BIT(TSENSE_DR_ERR_POS) + +#define TSENSE_DR_DATA_POSS 0U +#define TSENSE_DR_DATA_POSE 15U +#define TSENSE_DR_DATA_MSK BITS(TSENSE_DR_DATA_POSS,TSENSE_DR_DATA_POSE) + +/****************** Bit definition for TSENSE_PSR register ************************/ + +#define TSENSE_PSR_PRS_POSS 0U +#define TSENSE_PSR_PRS_POSE 7U +#define TSENSE_PSR_PRS_MSK BITS(TSENSE_PSR_PRS_POSS,TSENSE_PSR_PRS_POSE) + +/****************** Bit definition for TSENSE_IE register ************************/ + +#define TSENSE_IE_TSENSE_POS 0U +#define TSENSE_IE_TSENSE_MSK BIT(TSENSE_IE_TSENSE_POS) + +/****************** Bit definition for TSENSE_IF register ************************/ + +#define TSENSE_IF_TSENSE_POS 0U +#define TSENSE_IF_TSENSE_MSK BIT(TSENSE_IF_TSENSE_POS) + +/****************** Bit definition for TSENSE_IFCR register ************************/ + +#define TSENSE_IFCR_TSENSE_POS 0U +#define TSENSE_IFCR_TSENSE_MSK BIT(TSENSE_IFCR_TSENSE_POS) + +/****************** Bit definition for TSENSE_LTGR register ************************/ + +#define TSENSE_LTGR_LTG_POSS 0U +#define TSENSE_LTGR_LTG_POSE 20U +#define TSENSE_LTGR_LTG_MSK BITS(TSENSE_LTGR_LTG_POSS,TSENSE_LTGR_LTG_POSE) + +/****************** Bit definition for TSENSE_HTGR register ************************/ + +#define TSENSE_HTGR_HTG_POSS 0U +#define TSENSE_HTGR_HTG_POSE 20U +#define TSENSE_HTGR_HTG_MSK BITS(TSENSE_HTGR_HTG_POSS,TSENSE_HTGR_HTG_POSE) + +/****************** Bit definition for TSENSE_TBDR register ************************/ + +#define TSENSE_TBDR_TBD_POSS 0U +#define TSENSE_TBDR_TBD_POSE 15U +#define TSENSE_TBDR_TBD_MSK BITS(TSENSE_TBDR_TBD_POSS,TSENSE_TBDR_TBD_POSE) + +/****************** Bit definition for TSENSE_TCALBDR register ************************/ + +#define TSENSE_TCALBDR_TCAL_POSS 0U +#define TSENSE_TCALBDR_TCAL_POSE 16U +#define TSENSE_TCALBDR_TCAL_MSK BITS(TSENSE_TCALBDR_TCAL_POSS,TSENSE_TCALBDR_TCAL_POSE) + +/****************** Bit definition for TSENSE_SR register ************************/ + +#define TSENSE_SR_TSOUT_POS 31U +#define TSENSE_SR_TSOUT_MSK BIT(TSENSE_SR_TSOUT_POS) + +#define TSENSE_SR_NVLD_POS 25U +#define TSENSE_SR_NVLD_MSK BIT(TSENSE_SR_NVLD_POS) + +#define TSENSE_SR_TCAL_POSS 0U +#define TSENSE_SR_TCAL_POSE 24U +#define TSENSE_SR_TCAL_MSK BITS(TSENSE_SR_TCAL_POSS,TSENSE_SR_TCAL_POSE) + +typedef struct +{ + __IO uint32_t WPR; + __IO uint32_t CR; + __I uint32_t DR; + __IO uint32_t PSR; + __IO uint32_t IE; + __I uint32_t IF; + __IO uint32_t IFCR; + __IO uint32_t LTGR; + __IO uint32_t HTGR; + __IO uint32_t TBDR; + __IO uint32_t TCALBDR; + __I uint32_t SR; +} TSENSE_TypeDef; + +/****************** Bit definition for IWDT_LOAD register ************************/ + +#define IWDT_LOAD_LOAD_POSS 0U +#define IWDT_LOAD_LOAD_POSE 31U +#define IWDT_LOAD_LOAD_MSK BITS(IWDT_LOAD_LOAD_POSS,IWDT_LOAD_LOAD_POSE) + +/****************** Bit definition for IWDT_VALUE register ************************/ + +#define IWDT_VALUE_VALUE_POSS 0U +#define IWDT_VALUE_VALUE_POSE 31U +#define IWDT_VALUE_VALUE_MSK BITS(IWDT_VALUE_VALUE_POSS,IWDT_VALUE_VALUE_POSE) + +/****************** Bit definition for IWDT_CON register ************************/ + +#define IWDT_CON_CLKS_POS 3U +#define IWDT_CON_CLKS_MSK BIT(IWDT_CON_CLKS_POS) + +#define IWDT_CON_RSTEN_POS 2U +#define IWDT_CON_RSTEN_MSK BIT(IWDT_CON_RSTEN_POS) + +#define IWDT_CON_IE_POS 1U +#define IWDT_CON_IE_MSK BIT(IWDT_CON_IE_POS) + +#define IWDT_CON_EN_POS 0U +#define IWDT_CON_EN_MSK BIT(IWDT_CON_EN_POS) + +/****************** Bit definition for IWDT_INTCLR register ************************/ + +#define IWDT_INTCLR_INTCLR_POSS 0U +#define IWDT_INTCLR_INTCLR_POSE 31U +#define IWDT_INTCLR_INTCLR_MSK BITS(IWDT_INTCLR_INTCLR_POSS,IWDT_INTCLR_INTCLR_POSE) + +/****************** Bit definition for IWDT_RIS register ************************/ + +#define IWDT_RIS_WDTIF_POS 0U +#define IWDT_RIS_WDTIF_MSK BIT(IWDT_RIS_WDTIF_POS) + +/****************** Bit definition for IWDT_LOCK register ************************/ + +#define IWDT_LOCK_LOCK_POS 0U +#define IWDT_LOCK_LOCK_MSK BIT(IWDT_LOCK_LOCK_POS) + +typedef struct +{ + __O uint32_t LOAD; + __I uint32_t VALUE; + __IO uint32_t CON; + __O uint32_t INTCLR; + __I uint32_t RIS; + uint32_t RESERVED0[59] ; + __IO uint32_t LOCK; +} IWDT_TypeDef; + +/****************** Bit definition for WWDT_LOAD register ************************/ + +#define WWDT_LOAD_LOAD_POSS 0U +#define WWDT_LOAD_LOAD_POSE 31U +#define WWDT_LOAD_LOAD_MSK BITS(WWDT_LOAD_LOAD_POSS,WWDT_LOAD_LOAD_POSE) + +/****************** Bit definition for WWDT_VALUE register ************************/ + +#define WWDT_VALUE_VALUE_POSS 0U +#define WWDT_VALUE_VALUE_POSE 31U +#define WWDT_VALUE_VALUE_MSK BITS(WWDT_VALUE_VALUE_POSS,WWDT_VALUE_VALUE_POSE) + +/****************** Bit definition for WWDT_CON register ************************/ + +#define WWDT_CON_WWDTWIN_POSS 4U +#define WWDT_CON_WWDTWIN_POSE 5U +#define WWDT_CON_WWDTWIN_MSK BITS(WWDT_CON_WWDTWIN_POSS,WWDT_CON_WWDTWIN_POSE) + +#define WWDT_CON_CLKS_POS 3U +#define WWDT_CON_CLKS_MSK BIT(WWDT_CON_CLKS_POS) + +#define WWDT_CON_RSTEN_POS 2U +#define WWDT_CON_RSTEN_MSK BIT(WWDT_CON_RSTEN_POS) + +#define WWDT_CON_IE_POS 1U +#define WWDT_CON_IE_MSK BIT(WWDT_CON_IE_POS) + +#define WWDT_CON_EN_POS 0U +#define WWDT_CON_EN_MSK BIT(WWDT_CON_EN_POS) + +/****************** Bit definition for WWDT_INTCLR register ************************/ + +#define WWDT_INTCLR_INTCLR_POSS 0U +#define WWDT_INTCLR_INTCLR_POSE 31U +#define WWDT_INTCLR_INTCLR_MSK BITS(WWDT_INTCLR_INTCLR_POSS,WWDT_INTCLR_INTCLR_POSE) + +/****************** Bit definition for WWDT_RIS register ************************/ + +#define WWDT_RIS_WWDTIF_POS 0U +#define WWDT_RIS_WWDTIF_MSK BIT(WWDT_RIS_WWDTIF_POS) + +/****************** Bit definition for WWDT_LOCK register ************************/ + +#define WWDT_LOCK_LOCK_POS 0U +#define WWDT_LOCK_LOCK_MSK BIT(WWDT_LOCK_LOCK_POS) + +typedef struct +{ + __O uint32_t LOAD; + __I uint32_t VALUE; + __IO uint32_t CON; + __O uint32_t INTCLR; + __I uint32_t RIS; + uint32_t RESERVED0[59]; + __IO uint32_t LOCK; +} WWDT_TypeDef; + +/****************** Bit definition for LP16T_CON0 register ************************/ + +#define LP16T_CON0_PRELOAD_POS 22U +#define LP16T_CON0_PRELOAD_MSK BIT(LP16T_CON0_PRELOAD_POS) + +#define LP16T_CON0_WAVEPOL_POS 21U +#define LP16T_CON0_WAVEPOL_MSK BIT(LP16T_CON0_WAVEPOL_POS) + +#define LP16T_CON0_WAVE_POSS 19U +#define LP16T_CON0_WAVE_POSE 20U +#define LP16T_CON0_WAVE_MSK BITS(LP16T_CON0_WAVE_POSS,LP16T_CON0_WAVE_POSE) + +#define LP16T_CON0_TRIGEN_POSS 17U +#define LP16T_CON0_TRIGEN_POSE 18U +#define LP16T_CON0_TRIGEN_MSK BITS(LP16T_CON0_TRIGEN_POSS,LP16T_CON0_TRIGEN_POSE) + +#define LP16T_CON0_TRIGSEL_POSS 13U +#define LP16T_CON0_TRIGSEL_POSE 15U +#define LP16T_CON0_TRIGSEL_MSK BITS(LP16T_CON0_TRIGSEL_POSS,LP16T_CON0_TRIGSEL_POSE) + +#define LP16T_CON0_PRESC_POSS 9U +#define LP16T_CON0_PRESC_POSE 11U +#define LP16T_CON0_PRESC_MSK BITS(LP16T_CON0_PRESC_POSS,LP16T_CON0_PRESC_POSE) + +#define LP16T_CON0_TRGFLT_POSS 6U +#define LP16T_CON0_TRGFLT_POSE 7U +#define LP16T_CON0_TRGFLT_MSK BITS(LP16T_CON0_TRGFLT_POSS,LP16T_CON0_TRGFLT_POSE) + +#define LP16T_CON0_CKFLT_POSS 3U +#define LP16T_CON0_CKFLT_POSE 4U +#define LP16T_CON0_CKFLT_MSK BITS(LP16T_CON0_CKFLT_POSS,LP16T_CON0_CKFLT_POSE) + +#define LP16T_CON0_CKPOL_POS 1U +#define LP16T_CON0_CKPOL_MSK BIT(LP16T_CON0_CKPOL_POS) + +#define LP16T_CON0_CKSEL_POS 0U +#define LP16T_CON0_CKSEL_MSK BIT(LP16T_CON0_CKSEL_POS) + +/****************** Bit definition for LP16T_CON1 register ************************/ + +#define LP16T_CON1_CNTSTRT_POS 2U +#define LP16T_CON1_CNTSTRT_MSK BIT(LP16T_CON1_CNTSTRT_POS) + +#define LP16T_CON1_SNGSTRT_POS 1U +#define LP16T_CON1_SNGSTRT_MSK BIT(LP16T_CON1_SNGSTRT_POS) + +#define LP16T_CON1_ENABLE_POS 0U +#define LP16T_CON1_ENABLE_MSK BIT(LP16T_CON1_ENABLE_POS) + +/****************** Bit definition for LP16T_ARR register ************************/ + +#define LP16T_ARR_ARR_POSS 0U +#define LP16T_ARR_ARR_POSE 15U +#define LP16T_ARR_ARR_MSK BITS(LP16T_ARR_ARR_POSS,LP16T_ARR_ARR_POSE) + +/****************** Bit definition for LP16T_CNT register ************************/ + +#define LP16T_CNT_CNT_POSS 0U +#define LP16T_CNT_CNT_POSE 15U +#define LP16T_CNT_CNT_MSK BITS(LP16T_CNT_CNT_POSS,LP16T_CNT_CNT_POSE) + +/****************** Bit definition for LP16T_CMP register ************************/ + +#define LP16T_CMP_CMP_POSS 0U +#define LP16T_CMP_CMP_POSE 15U +#define LP16T_CMP_CMP_MSK BITS(LP16T_CMP_CMP_POSS,LP16T_CMP_CMP_POSE) + +/****************** Bit definition for LP16T_IER register ************************/ + +#define LP16T_IER_EXTTRIGIE_POS 2U +#define LP16T_IER_EXTTRIGIE_MSK BIT(LP16T_IER_EXTTRIGIE_POS) + +#define LP16T_IER_ARRMIE_POS 1U +#define LP16T_IER_ARRMIE_MSK BIT(LP16T_IER_ARRMIE_POS) + +#define LP16T_IER_CMPMIE_POS 0U +#define LP16T_IER_CMPMIE_MSK BIT(LP16T_IER_CMPMIE_POS) + +/****************** Bit definition for LP16T_ISR register ************************/ + +#define LP16T_ISR_EXTTRIG_POS 2U +#define LP16T_ISR_EXTTRIG_MSK BIT(LP16T_ISR_EXTTRIG_POS) + +#define LP16T_ISR_ARRM_POS 1U +#define LP16T_ISR_ARRM_MSK BIT(LP16T_ISR_ARRM_POS) + +#define LP16T_ISR_CMPM_POS 0U +#define LP16T_ISR_CMPM_MSK BIT(LP16T_ISR_CMPM_POS) + +/****************** Bit definition for LP16T_IFC register ************************/ + +#define LP16T_IFC_EXTTRIG_POS 2U +#define LP16T_IFC_EXTTRIG_MSK BIT(LP16T_IFC_EXTTRIG_POS) + +#define LP16T_IFC_ARRM_POS 1U +#define LP16T_IFC_ARRM_MSK BIT(LP16T_IFC_ARRM_POS) + +#define LP16T_IFC_CMPM_POS 0U +#define LP16T_IFC_CMPM_MSK BIT(LP16T_IFC_CMPM_POS) + +/****************** Bit definition for LP16T_UPDATE register ************************/ + +#define LP16T_UPDATE_UDIS_POS 0U +#define LP16T_UPDATE_UDIS_MSK BIT(LP16T_UPDATE_UDIS_POS) + +/****************** Bit definition for LP16T_SYNCSTAT register ************************/ + +#define LP16T_SYNCSTAT_CMPWBSY_POS 3U +#define LP16T_SYNCSTAT_CMPWBSY_MSK BIT(LP16T_SYNCSTAT_CMPWBSY_POS) + +#define LP16T_SYNCSTAT_ARRWBSY_POS 2U +#define LP16T_SYNCSTAT_ARRWBSY_MSK BIT(LP16T_SYNCSTAT_ARRWBSY_POS) + +#define LP16T_SYNCSTAT_CON1WBSY_POS 1U +#define LP16T_SYNCSTAT_CON1WBSY_MSK BIT(LP16T_SYNCSTAT_CON1WBSY_POS) + +typedef struct +{ + __IO uint32_t CON0; + __IO uint32_t CON1; + __IO uint32_t ARR; + __I uint32_t CNT; + __IO uint32_t CMP; + uint32_t RESERVED0 ; + __IO uint32_t IER; + __I uint32_t ISR; + __O uint32_t IFC; + uint32_t RESERVED1[3] ; + __IO uint32_t UPDATE; + __I uint32_t SYNCSTAT; +} LPTIM_TypeDef; + +/****************** Bit definition for DBGC_IDCODE register ************************/ + +#define DBGC_IDCODE_REV_ID_POSS 16U +#define DBGC_IDCODE_REV_ID_POSE 31U +#define DBGC_IDCODE_REV_ID_MSK BITS(DBGC_IDCODE_REV_ID_POSS,DBGC_IDCODE_REV_ID_POSE) + +#define DBGC_IDCODE_CORE_ID_POSS 12U +#define DBGC_IDCODE_CORE_ID_POSE 15U +#define DBGC_IDCODE_CORE_ID_MSK BITS(DBGC_IDCODE_CORE_ID_POSS,DBGC_IDCODE_CORE_ID_POSE) + +#define DBGC_IDCODE_DEV_ID_POSS 0U +#define DBGC_IDCODE_DEV_ID_POSE 11U +#define DBGC_IDCODE_DEV_ID_MSK BITS(DBGC_IDCODE_DEV_ID_POSS,DBGC_IDCODE_DEV_ID_POSE) + +/****************** Bit definition for DBGC_CR register ************************/ + +#define DBGC_CR_DBG_STANDBY_POS 3U +#define DBGC_CR_DBG_STANDBY_MSK BIT(DBGC_CR_DBG_STANDBY_POS) + +#define DBGC_CR_DBG_STOP2_POS 2U +#define DBGC_CR_DBG_STOP2_MSK BIT(DBGC_CR_DBG_STOP2_POS) + +#define DBGC_CR_DBG_STOP1_POS 1U +#define DBGC_CR_DBG_STOP1_MSK BIT(DBGC_CR_DBG_STOP1_POS) + +#define DBGC_CR_DBG_SLEEP_POS 0U +#define DBGC_CR_DBG_SLEEP_MSK BIT(DBGC_CR_DBG_SLEEP_POS) + +/****************** Bit definition for DBGC_APB1FZ register ************************/ + +#define DBGC_APB1FZ_CAN_STOP_POS 12U +#define DBGC_APB1FZ_CAN_STOP_MSK BIT(DBGC_APB1FZ_CAN_STOP_POS) + +#define DBGC_APB1FZ_I2C1_SMBUS_TO_POS 9U +#define DBGC_APB1FZ_I2C1_SMBUS_TO_MSK BIT(DBGC_APB1FZ_I2C1_SMBUS_TO_POS) + +#define DBGC_APB1FZ_I2C0_SMBUS_TO_POS 8U +#define DBGC_APB1FZ_I2C0_SMBUS_TO_MSK BIT(DBGC_APB1FZ_I2C0_SMBUS_TO_POS) + +#define DBGC_APB1FZ_TIM7_STOP_POS 7U +#define DBGC_APB1FZ_TIM7_STOP_MSK BIT(DBGC_APB1FZ_TIM7_STOP_POS) + +#define DBGC_APB1FZ_TIM6_STOP_POS 6U +#define DBGC_APB1FZ_TIM6_STOP_MSK BIT(DBGC_APB1FZ_TIM6_STOP_POS) + +#define DBGC_APB1FZ_TIM5_STOP_POS 5U +#define DBGC_APB1FZ_TIM5_STOP_MSK BIT(DBGC_APB1FZ_TIM5_STOP_POS) + +#define DBGC_APB1FZ_TIM4_STOP_POS 4U +#define DBGC_APB1FZ_TIM4_STOP_MSK BIT(DBGC_APB1FZ_TIM4_STOP_POS) + +#define DBGC_APB1FZ_TIM3_STOP_POS 3U +#define DBGC_APB1FZ_TIM3_STOP_MSK BIT(DBGC_APB1FZ_TIM3_STOP_POS) + +#define DBGC_APB1FZ_TIM2_STOP_POS 2U +#define DBGC_APB1FZ_TIM2_STOP_MSK BIT(DBGC_APB1FZ_TIM2_STOP_POS) + +#define DBGC_APB1FZ_TIM1_STOP_POS 1U +#define DBGC_APB1FZ_TIM1_STOP_MSK BIT(DBGC_APB1FZ_TIM1_STOP_POS) + +#define DBGC_APB1FZ_TIM0_STOP_POS 0U +#define DBGC_APB1FZ_TIM0_STOP_MSK BIT(DBGC_APB1FZ_TIM0_STOP_POS) + +/****************** Bit definition for DBGC_APB2FZ register ************************/ + +#define DBGC_APB2FZ_RTC_STOP_POS 10U +#define DBGC_APB2FZ_RTC_STOP_MSK BIT(DBGC_APB2FZ_RTC_STOP_POS) + +#define DBGC_APB2FZ_WWDT_STOP_POS 9U +#define DBGC_APB2FZ_WWDT_STOP_MSK BIT(DBGC_APB2FZ_WWDT_STOP_POS) + +#define DBGC_APB2FZ_IWDT_STOP_POS 8U +#define DBGC_APB2FZ_IWDT_STOP_MSK BIT(DBGC_APB2FZ_IWDT_STOP_POS) + +#define DBGC_APB2FZ_LPTIM0_STOP_POS 0U +#define DBGC_APB2FZ_LPTIM0_STOP_MSK BIT(DBGC_APB2FZ_LPTIM0_STOP_POS) + +typedef struct +{ + __I uint32_t IDCODE; + __IO uint32_t CR; + __IO uint32_t APB1FZ; + __IO uint32_t APB2FZ; +} DBGC_TypeDef; + + +/* Base addresses */ +#define SRAM_BASE (0x20000000UL) +#define APB1_BASE (0x40000000UL) +#define APB2_BASE (0x40040000UL) +#define AHB_BASE (0x40080000UL) + +/* APB1 peripherals Base Address */ +#define AD16C4T0_BASE (APB1_BASE + 0x0000) +#define BS16T0_BASE (APB1_BASE + 0x0400) +#define GP16C2T0_BASE (APB1_BASE + 0x0800) +#define GP16C2T1_BASE (APB1_BASE + 0x0C00) +#define BS16T1_BASE (APB1_BASE + 0x1000) +#define BS16T2_BASE (APB1_BASE + 0x1400) +#define GP16C4T0_BASE (APB1_BASE + 0x1800) +#define BS16T3_BASE (APB1_BASE + 0x1C00) +#define UART0_BASE (APB1_BASE + 0x4000) +#define UART1_BASE (APB1_BASE + 0x4400) +#define UART2_BASE (APB1_BASE + 0x4800) +#define UART3_BASE (APB1_BASE + 0x4C00) +#define USART0_BASE (APB1_BASE + 0x5000) +#define USART1_BASE (APB1_BASE + 0x5400) +#define SPI0_BASE (APB1_BASE + 0x6000) +#define SPI1_BASE (APB1_BASE + 0x6400) +#define SPI2_BASE (APB1_BASE + 0x6800) +#define I2C0_BASE (APB1_BASE + 0x8000) +#define I2C1_BASE (APB1_BASE + 0x8400) +#define CAN0_BASE (APB1_BASE + 0xB000) +#define DMA0_BASE (APB1_BASE + 0xC000) + +/* APB2 peripherals Base Address */ +#define LPTIM0_BASE (APB2_BASE + 0x0000) +#define LPUART0_BASE (APB2_BASE + 0x1000) +#define ADC0_BASE (APB2_BASE + 0x2000) +#define ADC1_BASE (APB2_BASE + 0x2400) +#define ACMP0_BASE (APB2_BASE + 0x3000) +#define ACMP1_BASE (APB2_BASE + 0x3400) +#define OPAMP_BASE (APB2_BASE + 0x4000) +#define DAC0_BASE (APB2_BASE + 0x5000) +#define WWDT_BASE (APB2_BASE + 0x6000) +#define IWDT_BASE (APB2_BASE + 0x6400) +#define LCD_BASE (APB2_BASE + 0x7000) +#define BKPC_BASE (APB2_BASE + 0x8000) +#define RTC_BASE (APB2_BASE + 0x8400) +#define TSENSE_BASE (APB2_BASE + 0x8800) +#define DBGC_BASE (APB2_BASE + 0xA000) + +/* AHB peripherals Base Address */ +#define SYSCFG_BASE (AHB_BASE + 0x0000) +#define CMU_BASE (AHB_BASE + 0x0400) +#define RMU_BASE (AHB_BASE + 0x0800) +#define PMU_BASE (AHB_BASE + 0x0C00) +#define MSC_BASE (AHB_BASE + 0x1000) +#define GPIOA_BASE (AHB_BASE + 0x4000) +#define GPIOB_BASE (AHB_BASE + 0x4040) +#define GPIOC_BASE (AHB_BASE + 0x4080) +#define GPIOD_BASE (AHB_BASE + 0x40C0) +#define GPIOE_BASE (AHB_BASE + 0x4100) +#define GPIOF_BASE (AHB_BASE + 0x4140) +#define GPIOG_BASE (AHB_BASE + 0x4180) +#define GPIOH_BASE (AHB_BASE + 0x41C0) +#define EXTI_BASE (AHB_BASE + 0x4300) +#define CRC_BASE (AHB_BASE + 0x5000) +#define CALC_BASE (AHB_BASE + 0x5400) +#define CRYPT_BASE (AHB_BASE + 0x5800) +#define TRNG_BASE (AHB_BASE + 0x5C00) +#define PIS_BASE (AHB_BASE + 0x6000) + +/* APB1 peripherals */ +#define AD16C4T0 ((TIMER_TypeDef *)AD16C4T0_BASE) +#define BS16T0 ((TIMER_TypeDef *)BS16T0_BASE) +#define GP16C2T0 ((TIMER_TypeDef *)GP16C2T0_BASE) +#define GP16C2T1 ((TIMER_TypeDef *)GP16C2T1_BASE) +#define BS16T1 ((TIMER_TypeDef *)BS16T1_BASE) +#define BS16T2 ((TIMER_TypeDef *)BS16T2_BASE) +#define GP16C4T0 ((TIMER_TypeDef *)GP16C4T0_BASE) +#define BS16T3 ((TIMER_TypeDef *)BS16T3_BASE) +#define UART0 ((UART_TypeDef *)UART0_BASE) +#define UART1 ((UART_TypeDef *)UART1_BASE) +#define UART2 ((UART_TypeDef *)UART2_BASE) +#define UART3 ((UART_TypeDef *)UART3_BASE) +#define USART0 ((USART_TypeDef *)USART0_BASE) +#define USART1 ((USART_TypeDef *)USART1_BASE) +#define SPI0 ((SPI_TypeDef *)SPI0_BASE) +#define SPI1 ((SPI_TypeDef *)SPI1_BASE) +#define SPI2 ((SPI_TypeDef *)SPI2_BASE) +#define I2C0 ((I2C_TypeDef *)I2C0_BASE) +#define I2C1 ((I2C_TypeDef *)I2C1_BASE) +#define CAN0 ((CAN_TypeDef *)CAN0_BASE) +#define DMA0 ((DMA_TypeDef *)DMA0_BASE) + +/* APB2 peripherals */ +#define LPTIM0 ((LPTIM_TypeDef *)LPTIM0_BASE) +#define LPUART0 ((LPUART_TypeDef *)LPUART0_BASE) +#define ADC0 ((ADC_TypeDef *)ADC0_BASE) +#define ADC1 ((ADC_TypeDef *)ADC1_BASE) +#define ACMP0 ((ACMP_TypeDef *)ACMP0_BASE) +#define ACMP1 ((ACMP_TypeDef *)ACMP1_BASE) +#define OPAMP ((OPAMP_TypeDef *)OPAMP_BASE) +#define DAC0 ((DAC_TypeDef *)DAC0_BASE) +#define WWDT ((WWDT_TypeDef *)WWDT_BASE) +#define IWDT ((IWDT_TypeDef *)IWDT_BASE) +#define LCD ((LCD_TypeDef *)LCD_BASE) +#define BKPC ((BKPC_TypeDef *)BKPC_BASE) +#define RTC ((RTC_TypeDef *)RTC_BASE) +#define TSENSE ((TSENSE_TypeDef *)TSENSE_BASE) +#define DBGC ((DBGC_TypeDef *)DBGC_BASE) + +/* AHB peripherals */ +#define SYSCFG ((SYSCFG_TypeDef *)SYSCFG_BASE) +#define CMU ((CMU_TypeDef *)CMU_BASE) +#define RMU ((RMU_TypeDef *)RMU_BASE) +#define PMU ((PMU_TypeDef *)PMU_BASE) +#define MSC ((MSC_TypeDef *)MSC_BASE) +#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *)GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *)GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *)GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *)GPIOG_BASE) +#define GPIOH ((GPIO_TypeDef *)GPIOH_BASE) +#define EXTI ((EXTI_TypeDef *)EXTI_BASE) +#define CRC ((CRC_TypeDef *)CRC_BASE) +#define CALC ((CALC_TypeDef *)CALC_BASE) +#define CRYPT ((CRYPT_TypeDef *)CRYPT_BASE) +#define TRNG ((TRNG_TypeDef *)TRNG_BASE) +#define PIS ((PIS_TypeDef *)PIS_BASE) + +#endif diff --git a/bsp/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/iar/startup_es32f065x.s b/bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/iar/startup_es32f065x.s similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/iar/startup_es32f065x.s rename to bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/iar/startup_es32f065x.s diff --git a/bsp/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/keil/startup_es32f065x.s b/bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/keil/startup_es32f065x.s similarity index 56% rename from bsp/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/keil/startup_es32f065x.s rename to bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/keil/startup_es32f065x.s index 6bf19bc877..dab56328c5 100644 --- a/bsp/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/keil/startup_es32f065x.s +++ b/bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/Startup/keil/startup_es32f065x.s @@ -45,7 +45,7 @@ __Vectors DCD __initial_sp ;0, load top of stack DCD SysTick_Handler ;15, systick handler DCD WWDG_IWDG_Handler ;16, irq0 WWDG_IWDG handler DCD LVD_Handler ;17, irq1 LVD handler - DCD RTC_TEMP_Handler ;18, irq2 RTC handler + DCD RTC_TSENSE_Handler ;18, irq2 RTC handler DCD CRYPT_TRNG_Handler ;19, irq3 CRYPT handler DCD CMU_Handler ;20, irq4 CMU handler DCD EXTI0_3_Handler ;21, irq5 EXTI0_3 handler @@ -58,8 +58,8 @@ __Vectors DCD __initial_sp ;0, load top of stack DCD ADC_ACMP_Handler ;28, irq12 ADC_ACMP handler DCD AD16C4T0_BRK_UP_TRIG_COM_Handler ;29, irq13 AD16C4T0_BRK_UP_TRIG_COM handler DCD AD16C4T0_CC_Handler ;30, irq14 AD16C4T0_CC handler - DCD BS16T0_Handler ;31, irq15 BS16T0 handler - DCD 0 ;32, irq16 Reserved + DCD BS16T0_Handler ;31, irq15 BS16T0 handler + DCD 0 ;32, irq16 Reserved DCD GP16C2T0_Handler ;33, irq17 GP16C2T0 handler DCD GP16C2T1_Handler ;34, irq18 GP16C2T1 handler DCD BS16T1_UART2_Handler ;35, irq19 BS16T1_UART2 handler @@ -81,255 +81,255 @@ __Vectors DCD __initial_sp ;0, load top of stack ;Reset Handler---------------------------------------------- Reset_Handler PROC - EXPORT Reset_Handler [WEAK] - IMPORT __main - LDR R0, =__main - BX R0 - NOP - ALIGN - ENDP + EXPORT Reset_Handler [WEAK] + IMPORT __main + LDR R0, =__main + BX R0 + NOP + ALIGN + ENDP ;system int------------------------------------------------- NMI_Handler PROC ;int 2 - EXPORT NMI_Handler [WEAK] - B . - ENDP + EXPORT NMI_Handler [WEAK] + B . + ENDP HardFault_Handler \ - PROC ;int3 - EXPORT HardFault_Handler [WEAK] - B . - ENDP + PROC ;int3 + EXPORT HardFault_Handler [WEAK] + B . + ENDP SVC_Handler \ - PROC ;int11 - EXPORT SVC_Handler [WEAK] - B . - ENDP + PROC ;int11 + EXPORT SVC_Handler [WEAK] + B . + ENDP DebugMon_Handler \ - PROC ;int12 - EXPORT DebugMon_Handler [WEAK] - B . - ENDP + PROC ;int12 + EXPORT DebugMon_Handler [WEAK] + B . + ENDP PendSV_Handler PROC ;int14 - EXPORT PendSV_Handler [WEAK] - B . - ENDP + EXPORT PendSV_Handler [WEAK] + B . + ENDP SysTick_Handler \ - PROC ;int15 - EXPORT SysTick_Handler [WEAK] - B . - ENDP + PROC ;int15 + EXPORT SysTick_Handler [WEAK] + B . + ENDP ;peripheral module int ----------------------------------------------- WWDG_IWDG_Handler \ - PROC ;int16 - EXPORT WWDG_IWDG_Handler [WEAK] - B . - ENDP + PROC ;int16 + EXPORT WWDG_IWDG_Handler [WEAK] + B . + ENDP LVD_Handler \ - PROC ;int17 - EXPORT LVD_Handler [WEAK] - B . - ENDP + PROC ;int17 + EXPORT LVD_Handler [WEAK] + B . + ENDP -RTC_TEMP_Handler \ - PROC ;int18 - EXPORT RTC_TEMP_Handler [WEAK] - B . - ENDP +RTC_TSENSE_Handler \ + PROC ;int18 + EXPORT RTC_TSENSE_Handler [WEAK] + B . + ENDP CRYPT_TRNG_Handler \ - PROC ;int19 - EXPORT CRYPT_TRNG_Handler [WEAK] - B . - ENDP + PROC ;int19 + EXPORT CRYPT_TRNG_Handler [WEAK] + B . + ENDP CMU_Handler \ - PROC ;int20 - EXPORT CMU_Handler [WEAK] - B . - ENDP + PROC ;int20 + EXPORT CMU_Handler [WEAK] + B . + ENDP EXTI0_3_Handler \ - PROC ;int21 - EXPORT EXTI0_3_Handler [WEAK] - B . - ENDP + PROC ;int21 + EXPORT EXTI0_3_Handler [WEAK] + B . + ENDP EXTI4_7_Handler \ - PROC ;int22 - EXPORT EXTI4_7_Handler [WEAK] - B . - ENDP + PROC ;int22 + EXPORT EXTI4_7_Handler [WEAK] + B . + ENDP EXTI8_11_Handler \ - PROC ;int23 - EXPORT EXTI8_11_Handler [WEAK] - B . - ENDP + PROC ;int23 + EXPORT EXTI8_11_Handler [WEAK] + B . + ENDP EXTI12_15_Handler \ - PROC ;int24 - EXPORT EXTI12_15_Handler [WEAK] - B . - ENDP + PROC ;int24 + EXPORT EXTI12_15_Handler [WEAK] + B . + ENDP DMA_Handler \ - PROC ;int25 - EXPORT DMA_Handler [WEAK] - B . - ENDP + PROC ;int25 + EXPORT DMA_Handler [WEAK] + B . + ENDP CAN0_Handler \ - PROC ;int26 - EXPORT CAN0_Handler [WEAK] - B . - ENDP + PROC ;int26 + EXPORT CAN0_Handler [WEAK] + B . + ENDP LPTIM0_SPI2_Handler \ - PROC ;int27 - EXPORT LPTIM0_SPI2_Handler [WEAK] - B . - ENDP + PROC ;int27 + EXPORT LPTIM0_SPI2_Handler [WEAK] + B . + ENDP ADC_ACMP_Handler \ - PROC ;int28 - EXPORT ADC_ACMP_Handler [WEAK] - B . - ENDP + PROC ;int28 + EXPORT ADC_ACMP_Handler [WEAK] + B . + ENDP AD16C4T0_BRK_UP_TRIG_COM_Handler \ - PROC ;int29 - EXPORT AD16C4T0_BRK_UP_TRIG_COM_Handler [WEAK] - B . - ENDP + PROC ;int29 + EXPORT AD16C4T0_BRK_UP_TRIG_COM_Handler [WEAK] + B . + ENDP AD16C4T0_CC_Handler \ - PROC ;int30 - EXPORT AD16C4T0_CC_Handler [WEAK] - B . - ENDP + PROC ;int30 + EXPORT AD16C4T0_CC_Handler [WEAK] + B . + ENDP BS16T0_Handler \ - PROC ;int31 - EXPORT BS16T0_Handler [WEAK] - B . - ENDP + PROC ;int31 + EXPORT BS16T0_Handler [WEAK] + B . + ENDP GP16C2T0_Handler PROC ;int33 - EXPORT GP16C2T0_Handler [WEAK] - B . - ENDP + EXPORT GP16C2T0_Handler [WEAK] + B . + ENDP GP16C2T1_Handler PROC ;int34 - EXPORT GP16C2T1_Handler [WEAK] - B . - ENDP + EXPORT GP16C2T1_Handler [WEAK] + B . + ENDP BS16T1_UART2_Handler \ - PROC ;int35 - EXPORT BS16T1_UART2_Handler [WEAK] - B . - ENDP + PROC ;int35 + EXPORT BS16T1_UART2_Handler [WEAK] + B . + ENDP BS16T2_UART3_Handler \ - PROC ;int36 - EXPORT BS16T2_UART3_Handler [WEAK] - B . - ENDP + PROC ;int36 + EXPORT BS16T2_UART3_Handler [WEAK] + B . + ENDP GP16C4T0_LCD_Handler \ - PROC ;int37 - EXPORT GP16C4T0_LCD_Handler [WEAK] - B . - ENDP + PROC ;int37 + EXPORT GP16C4T0_LCD_Handler [WEAK] + B . + ENDP BS16T3_DAC0_Handler \ - PROC ;int38 - EXPORT BS16T3_DAC0_Handler [WEAK] - B . - ENDP + PROC ;int38 + EXPORT BS16T3_DAC0_Handler [WEAK] + B . + ENDP I2C0_Handler \ - PROC ;int39 - EXPORT I2C0_Handler [WEAK] - B . - ENDP + PROC ;int39 + EXPORT I2C0_Handler [WEAK] + B . + ENDP I2C1_Handler \ - PROC ;int40 - EXPORT I2C1_Handler [WEAK] - B . - ENDP + PROC ;int40 + EXPORT I2C1_Handler [WEAK] + B . + ENDP SPI0_Handler \ - PROC ;int41 - EXPORT SPI0_Handler [WEAK] - B . - ENDP + PROC ;int41 + EXPORT SPI0_Handler [WEAK] + B . + ENDP SPI1_Handler \ - PROC ;int42 - EXPORT SPI1_Handler [WEAK] - B . - ENDP + PROC ;int42 + EXPORT SPI1_Handler [WEAK] + B . + ENDP UART0_Handler \ - PROC ;int43 - EXPORT UART0_Handler [WEAK] - B . - ENDP + PROC ;int43 + EXPORT UART0_Handler [WEAK] + B . + ENDP UART1_Handler \ - PROC ;int44 - EXPORT UART1_Handler [WEAK] - B . - ENDP + PROC ;int44 + EXPORT UART1_Handler [WEAK] + B . + ENDP USART0_Handler \ - PROC ;int45 - EXPORT USART0_Handler [WEAK] - B . - ENDP + PROC ;int45 + EXPORT USART0_Handler [WEAK] + B . + ENDP USART1_Handler \ - PROC ;int46 - EXPORT USART1_Handler [WEAK] - B . - ENDP + PROC ;int46 + EXPORT USART1_Handler [WEAK] + B . + ENDP LPUART0_Handler \ - PROC ;int47 - EXPORT LPUART0_Handler [WEAK] - B . - ENDP + PROC ;int47 + EXPORT LPUART0_Handler [WEAK] + B . + ENDP ; User Initial Stack & Heap----------------------------------------------------- - ALIGN - IF :DEF:__MICROLIB + ALIGN + IF :DEF:__MICROLIB - EXPORT __initial_sp - EXPORT __heap_base - EXPORT __heap_limit + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit - ELSE + ELSE - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap __user_initial_stackheap - LDR R0, = Heap_Mem - LDR R1, = (Stack_Mem + Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR - ALIGN + ALIGN - ENDIF + ENDIF - END + END diff --git a/bsp/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/System/system_es32f065x.c b/bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/System/system_es32f065x.c similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/System/system_es32f065x.c rename to bsp/essemi/es32f0654/libraries/CMSIS/Device/EastSoft/ES32F065x/System/system_es32f065x.c diff --git a/bsp/es32f0654/libraries/CMSIS/Include/arm_common_tables.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/arm_common_tables.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/arm_common_tables.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/arm_common_tables.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/arm_const_structs.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/arm_const_structs.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/arm_const_structs.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/arm_const_structs.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/arm_math.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/arm_math.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/arm_math.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/arm_math.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/cmsis_armcc.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/cmsis_armcc.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/cmsis_armcc.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/cmsis_armcc.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/cmsis_armcc_V6.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/cmsis_armcc_V6.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/cmsis_armcc_V6.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/cmsis_armcc_V6.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/cmsis_gcc.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/cmsis_gcc.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/cmsis_gcc.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/cmsis_gcc.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_cm0.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cm0.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/core_cm0.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cm0.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_cm0plus.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cm0plus.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/core_cm0plus.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cm0plus.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_cmFunc.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cmFunc.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/core_cmFunc.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cmFunc.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_cmInstr.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cmInstr.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/core_cmInstr.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cmInstr.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_cmSimd.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cmSimd.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/core_cmSimd.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/core_cmSimd.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_sc000.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/core_sc000.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/core_sc000.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/core_sc000.h diff --git a/bsp/es32f0654/libraries/CMSIS/Include/core_sc300.h b/bsp/essemi/es32f0654/libraries/CMSIS/Include/core_sc300.h similarity index 100% rename from bsp/es32f0654/libraries/CMSIS/Include/core_sc300.h rename to bsp/essemi/es32f0654/libraries/CMSIS/Include/core_sc300.h diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_acmp.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_acmp.h new file mode 100644 index 0000000000..452deaf516 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_acmp.h @@ -0,0 +1,355 @@ +/** + ********************************************************************************* + * + * @file ald_acmp.h + * @brief Header file of ACMP module driver. + * + * @version V1.0 + * @date 13 Dec 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ********************************************************************************* + */ + +#ifndef __ALD_ACMP_H__ +#define __ALD_ACMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup ACMP + * @{ + */ + +/** @defgroup ACMP_Public_Types ACMP Public Types + * @{ + */ + +/** + * @brief Acmp interrupt + */ +typedef enum +{ + ACMP_IT_EDGE = (1U << 0), /**< Edge interrupt bit */ + ACMP_IT_WARMUP = (1U << 1), /**< Warm up interrupt bit */ +} acmp_it_t; + +/** + * @brief Acmp interrupt + */ +typedef enum +{ + ACMP_FLAG_EDGE = (1U << 0), /**< Edge interrupt flag */ + ACMP_FLAG_WARMUP = (1U << 1), /**< Warm up interrupt flag */ +} acmp_flag_t; + +/** + * @brief Acmp interrupt flag + */ +typedef enum +{ + ACMP_STATUS_EDGE = (1U << 0), /**< Edge interrupt flag */ + ACMP_STATUS_WARMUP = (1U << 1), /**< Warm up interrupt flag */ +} acmp_status_t; + +/** + * @brief Acmp positive input + */ +typedef enum +{ + ACMP_POS_CH0 = 0, /**< Channel 0 as positive input */ + ACMP_POS_CH1 = 1, /**< Channel 1 as positive input */ + ACMP_POS_CH2 = 2, /**< Channel 2 as positive input */ + ACMP_POS_CH3 = 3, /**< Channel 3 as positive input */ + ACMP_POS_CH4 = 4, /**< Channel 4 as positive input */ + ACMP_POS_CH5 = 5, /**< Channel 5 as positive input */ + ACMP_POS_CH6 = 6, /**< Channel 6 as positive input */ + ACMP_POS_CH7 = 7, /**< Channel 7 as positive input */ +} acmp_pos_input_t; + +/** + * @brief Acmp negative input + */ +typedef enum +{ + ACMP_NEG_CH0 = 0, /**< Channel 0 as negative input */ + ACMP_NEG_CH1 = 1, /**< Channel 1 as negative input */ + ACMP_NEG_CH2 = 2, /**< Channel 2 as negative input */ + ACMP_NEG_CH3 = 3, /**< Channel 3 as negative input */ + ACMP_NEG_CH4 = 4, /**< Channel 4 as negative input */ + ACMP_NEG_CH5 = 5, /**< Channel 5 as negative input */ + ACMP_NEG_CH6 = 6, /**< Channel 6 as negative input */ + ACMP_NEG_CH7 = 7, /**< Channel 7 as negative input */ + ACMP_NEG_1V25 = 8, /**< 1.25v as negative input */ + ACMP_NEG_2V5 = 9, /**< 2.5v as negative input */ + ACMP_NEG_VDD = 10, /**< VDD as negative input */ +} acmp_neg_input_t; + +/** + * @brief Acmp mode + */ +typedef enum +{ + ACMP_ULTRA_LOW_POWER = 0, /**< Ultra low power mode */ + ACMP_LOW_POWER = 1, /**< Low power mode */ + ACMP_MIDDLE_POWER = 2, /**< Middle power mode */ + ACMP_HIGH_POWER = 3, /**< High power mode */ +} acmp_mode_t; + +/** + * @brief Acmp warm-up time + */ +typedef enum +{ + ACMP_4_PCLK = 0, /**< 4 hfperclk cycles */ + ACMP_8_PCLK = 1, /**< 4 hfperclk cycles */ + ACMP_16_PCLK = 2, /**< 4 hfperclk cycles */ + ACMP_32_PCLK = 3, /**< 4 hfperclk cycles */ + ACMP_64_PCLK = 4, /**< 4 hfperclk cycles */ + ACMP_128_PCLK = 5, /**< 4 hfperclk cycles */ + ACMP_256_PCLK = 6, /**< 4 hfperclk cycles */ + ACMP_512_PCLK = 7, /**< 4 hfperclk cycles */ +} acmp_warm_time_t; + +/** + * @brief Acmp hysteresis level + */ +typedef enum +{ + ACMP_HYST_0 = 0, /**< No hysteresis */ + ACMP_HYST_15 = 1, /**< 15mV hysteresis */ + ACMP_HYST_22 = 2, /**< 22mV hysteresis */ + ACMP_HYST_29 = 3, /**< 29mV hysteresis */ + ACMP_HYST_36 = 4, /**< 36mV hysteresis */ + ACMP_HYST_43 = 5, /**< 43mV hysteresis */ + ACMP_HYST_50 = 6, /**< 50mV hysteresis */ + ACMP_HYST_57 = 7, /**< 57mV hysteresis */ +} acmp_hystsel_t; + +/** + * @brief Acmp inactive state + */ +typedef enum +{ + ACMP_INACTVAL_LOW = 0, /**< The inactive value is 0 */ + ACMP_INACTVAL_HIGH = 1, /**< The inactive value is 1 */ +} acmp_inactval_t; + +/** + * @brief which edges set up interrupt + */ +typedef enum +{ + ACMP_EDGE_NONE = 0, /**< Disable EDGE interrupt */ + ACMP_EDGE_FALL = 1, /**< Falling edges set EDGE interrupt */ + ACMP_EDGE_RISE = 2, /**< rise edges set EDGE interrupt */ + ACMP_EDGE_ALL = 3, /**< Falling edges and rise edges set EDGE interrupt */ +} acmp_edge_t; + +/** + * @brief Acmp output function + */ +typedef enum +{ + ACMP_OUT_DISABLE = 0, /**< Disable acmp output */ + ACMP_OUT_ENABLE = 1, /**< Enable acmp output */ +} acmp_out_func_t; + +/** + * @brief Acmp warm-up interrupt function + */ +typedef enum +{ + ACMP_WARM_DISABLE = 0, /**< Disable acmp warm-up interrupt */ + ACMP_WARM_ENABLE = 1, /**< Enable acmp warm-up interrupt */ +} acmp_warm_it_func; + +/** + * @brief Acmp gpio output invert + */ +typedef enum +{ + ACMP_GPIO_NO_INV = 0, /**< Acmp output to gpio is not inverted */ + ACMP_GPIO_INV = 1, /**< Acmp output to gpio is inverted */ +} acmp_invert_t; + +/** + * @brief Acmp output config structure definition + */ +typedef struct +{ + acmp_out_func_t out_func; /**< Acmp output function */ + acmp_invert_t gpio_inv; /**< If invert gpio output */ +} acmp_output_config_t; + +/** + * @brief Acmp init structure definition + */ +typedef struct +{ + acmp_mode_t mode; /**< Acmp operation mode */ + acmp_warm_time_t warm_time; /**< Acmp warm up time */ + acmp_hystsel_t hystsel; /**< Acmp hysteresis level */ + acmp_warm_it_func warm_func; /**< Acmp warm-up interrupt enable/disable */ + acmp_pos_input_t pos_port; /**< Acmp positive port select */ + acmp_neg_input_t neg_port; /**< Acmp negative port select */ + acmp_inactval_t inactval; /**< Acmp inavtive output value */ + acmp_edge_t edge; /** Select edges to set interrupt flag */ + uint8_t vdd_level; /** Select scaling factor for CDD reference level, MAX is 63 */ +} acmp_init_t; + +/** + * @brief ACMP Handle Structure definition + */ +typedef struct acmp_handle_s +{ + ACMP_TypeDef *perh; /**< Register base address */ + acmp_init_t init; /**< ACMP required parameters */ + lock_state_t lock; /**< Locking object */ + + void (*acmp_warmup_cplt_cbk)(struct acmp_handle_s *arg); /**< Acmp warm-up complete callback */ + void (*acmp_edge_cplt_cbk)(struct acmp_handle_s *arg); /**< Acmp edge trigger callback */ +} acmp_handle_t; +/** + * @} + */ + +/** @defgroup ACMP_Public_Macros ACMP Public Macros + * @{ + */ +#define ACMP_ENABLE(handle) (SET_BIT((handle)->perh->CON, ACMP_CON_EN_MSK)) +#define ACMP_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, ACMP_CON_EN_MSK)) +/** + * @} + */ + +/** @defgroup ACMP_Private_Macros ACMP Private Macros + * @{ + */ +#define IS_ACMP_TYPE(x) (((x) == ACMP0) || \ + ((x) == ACMP1)) +#define IS_ACMP_MODE_TYPE(x) (((x) == ACMP_ULTRA_LOW_POWER) || \ + ((x) == ACMP_LOW_POWER) || \ + ((x) == ACMP_MIDDLE_POWER) || \ + ((x) == ACMP_HIGH_POWER)) +#define IS_ACMP_IT_TYPE(x) (((x) == ACMP_IT_EDGE) || \ + ((x) == ACMP_IT_WARMUP)) +#define IS_ACMP_FLAG_TYPE(x) (((x) == ACMP_FLAG_EDGE) || \ + ((x) == ACMP_FLAG_WARMUP)) +#define IS_ACMP_STATUS_TYPE(x) (((x) == ACMP_STATUS_EDGE) || \ + ((x) == ACMP_STATUS_WARMUP)) +#define IS_ACMP_POS_INPUT_TYPE(x) (((x) == ACMP_POS_CH0) || \ + ((x) == ACMP_POS_CH1) || \ + ((x) == ACMP_POS_CH2) || \ + ((x) == ACMP_POS_CH3) || \ + ((x) == ACMP_POS_CH4) || \ + ((x) == ACMP_POS_CH5) || \ + ((x) == ACMP_POS_CH6) || \ + ((x) == ACMP_POS_CH7)) +#define IS_ACMP_NEG_INPUT_TYPE(x) (((x) == ACMP_NEG_CH0) || \ + ((x) == ACMP_NEG_CH1) || \ + ((x) == ACMP_NEG_CH2) || \ + ((x) == ACMP_NEG_CH3) || \ + ((x) == ACMP_NEG_CH4) || \ + ((x) == ACMP_NEG_CH5) || \ + ((x) == ACMP_NEG_CH6) || \ + ((x) == ACMP_NEG_CH7) || \ + ((x) == ACMP_NEG_1V25) || \ + ((x) == ACMP_NEG_2V5) || \ + ((x) == ACMP_NEG_VDD)) +#define IS_ACMP_WARM_UP_TIME_TYPE(x) (((x) == ACMP_4_PCLK) || \ + ((x) == ACMP_8_PCLK) || \ + ((x) == ACMP_16_PCLK) || \ + ((x) == ACMP_32_PCLK) || \ + ((x) == ACMP_64_PCLK) || \ + ((x) == ACMP_128_PCLK) || \ + ((x) == ACMP_256_PCLK) || \ + ((x) == ACMP_512_PCLK)) +#define IS_ACMP_HYSTSEL_TYPE(x) (((x) == ACMP_HYST_0) || \ + ((x) == ACMP_HYST_15) || \ + ((x) == ACMP_HYST_22) || \ + ((x) == ACMP_HYST_29) || \ + ((x) == ACMP_HYST_36) || \ + ((x) == ACMP_HYST_43) || \ + ((x) == ACMP_HYST_50) || \ + ((x) == ACMP_HYST_57)) +#define IS_ACMP_INACTVAL_TYPE(x) (((x) == ACMP_INACTVAL_LOW) || \ + ((x) == ACMP_INACTVAL_HIGH)) +#define IS_ACMP_EDGE_TYPE(x) (((x) == ACMP_EDGE_NONE) || \ + ((x) == ACMP_EDGE_FALL) || \ + ((x) == ACMP_EDGE_RISE) || \ + ((x) == ACMP_EDGE_ALL)) +#define IS_ACMP_OUT_FUNC_TYPE(x) (((x) == ACMP_OUT_DISABLE) || \ + ((x) == ACMP_OUT_ENABLE)) +#define IS_ACMP_INVERT_TYPE(x) (((x) == ACMP_GPIO_NO_INV) || \ + ((x) == ACMP_GPIO_INV)) +#define IS_ACMP_WARM_FUNC_TYPE(x) (((x) == ACMP_WARM_DISABLE) || \ + ((x) == ACMP_WARM_ENABLE)) +/** + * @} + */ + +/** @addtogroup ACMP_Public_Functions + * @{ + */ + +/** @addtogroup ACMP_Public_Functions_Group1 + * @{ + */ +ald_status_t ald_acmp_init(acmp_handle_t *hperh); + +/** + * @} + */ + +/** @addtogroup ACMP_Public_Functions_Group2 + * @{ + */ +ald_status_t ald_acmp_interrupt_config(acmp_handle_t *hperh, acmp_it_t it, type_func_t state); +ald_status_t ald_acmp_set_interrupt_mask(acmp_handle_t *hperh, acmp_it_t it); +it_status_t ald_acmp_get_it_status(acmp_handle_t *hperh, acmp_it_t it); +it_status_t ald_acmp_get_flag_status(acmp_handle_t *hperh, acmp_flag_t it); +ald_status_t ald_acmp_clear_flag_status(acmp_handle_t *hperh, acmp_flag_t it); +flag_status_t ald_acmp_get_status(acmp_handle_t *hperh, acmp_status_t flag); + +/** + * @} + */ + +/** @addtogroup ACMP_Public_Functions_Group3 + * @{ + */ +void ald_acmp_irq_handler(acmp_handle_t *hperh); +ald_status_t ald_acmp_out_config(acmp_handle_t *hperh, acmp_output_config_t *config); +uint8_t ald_acmp_out_result(acmp_handle_t *hperh); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +extern "C" +} +#endif + +#endif diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_adc.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_adc.h new file mode 100644 index 0000000000..d138f16c88 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_adc.h @@ -0,0 +1,572 @@ +/** + ****************************************************************************** + * @file ald_adc.h + * @brief Header file of ADC Module library. + * + * @version V1.0 + * @date 15 Dec 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ****************************************************************************** + */ + +#ifndef __ALD_ADC_H__ +#define __ALD_ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" +#include "ald_dma.h" +#include "ald_pis.h" +#include "ald_timer.h" + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/** @defgroup ADC_Pubulic_Types ADC Pubulic Types + * @{ + */ + +/** + * @brief ADC State structures definition + */ +typedef enum +{ + ADC_STATE_RESET = 0x0, /**< ADC not yet initialized or disabled */ + ADC_STATE_READY = 0x1, /**< ADC peripheral ready for use */ + ADC_STATE_BUSY_INTERNAL = 0x2, /**< ADC is busy to internal process */ + ADC_STATE_TIMEOUT = 0x4, /**< TimeOut occurrence */ + ADC_STATE_ERROR = 0x10, /**< Internal error occurrence */ + ADC_STATE_NM_BUSY = 0x100, /**< Conversion on group normal is ongoing or can occur */ + ADC_STATE_NM_EOC = 0x200, /**< Conversion data available on group normal */ + ADC_STATE_IST_BUSY = 0x1000, /**< Conversion on group insert is ongoing or can occur */ + ADC_STATE_IST_EOC = 0x2000, /**< Conversion data available on group insert */ + ADC_STATE_AWD = 0x10000, /**< Out-of-window occurrence of analog watchdog */ +} adc_state_t; + +/** + *@brief ADC Error Code + */ +typedef enum +{ + ADC_ERROR_NONE = 0x0, /**< No error */ + ADC_ERROR_INTERNAL = 0x1, /**< ADC IP internal error*/ + ADC_ERROR_OVR = 0x2, /**< Overrun error */ + ADC_ERROR_DMA = 0x4, /**< DMA transfer error */ +} adc_error_t; + +/** + *@brief ADC data alignment + */ +typedef enum +{ + ADC_DATAALIGN_RIGHT = 0x0, /**< ADC data alignment right */ + ADC_DATAALIGN_LEFT = 0x1, /**< ADC data alignment left */ +} adc_align_t; + +/** + *@brief ADC config hannal trigger the EOC IT mode + */ +typedef enum +{ + ADC_NCHESEL_MODE_ALL = 0x0, /**< ADC set RCHE after convert sequence finish */ + ADC_NCHESEL_MODE_ONE = 0x1, /**< ADC set RCHE after one convert finish */ +} adc_nchesel_t; + +/** + *@brief ADC channels + */ +typedef enum +{ + ADC_CHANNEL_0 = 0x0, /**< ADC channel 0 */ + ADC_CHANNEL_1 = 0x1, /**< ADC channel 1 */ + ADC_CHANNEL_2 = 0x2, /**< ADC channel 2 */ + ADC_CHANNEL_3 = 0x3, /**< ADC channel 3 */ + ADC_CHANNEL_4 = 0x4, /**< ADC channel 4 */ + ADC_CHANNEL_5 = 0x5, /**< ADC channel 5 */ + ADC_CHANNEL_6 = 0x6, /**< ADC channel 6 */ + ADC_CHANNEL_7 = 0x7, /**< ADC channel 7 */ + ADC_CHANNEL_8 = 0x8, /**< ADC channel 8 */ + ADC_CHANNEL_9 = 0x9, /**< ADC channel 9 */ + ADC_CHANNEL_10 = 0xA, /**< ADC channel 10 */ + ADC_CHANNEL_11 = 0xB, /**< ADC channel 11 */ + ADC_CHANNEL_12 = 0xC, /**< ADC channel 12 */ + ADC_CHANNEL_13 = 0xD, /**< ADC channel 13 */ + ADC_CHANNEL_14 = 0xE, /**< ADC channel 14 */ + ADC_CHANNEL_15 = 0xF, /**< ADC channel 15 */ + ADC_CHANNEL_16 = 0x10, /**< ADC channel 16 */ + ADC_CHANNEL_17 = 0x11, /**< ADC channel 17 */ + ADC_CHANNEL_18 = 0x12, /**< ADC channel 18 */ + ADC_CHANNEL_19 = 0x13, /**< ADC channel 19 */ +} adc_channel_t; + +/** + *@brief ADC sampling times + */ +typedef enum +{ + ADC_SAMPLETIME_1 = 0x0, /**< ADC sampling times 1 clk */ + ADC_SAMPLETIME_2 = 0x1, /**< ADC sampling times 2 clk */ + ADC_SAMPLETIME_4 = 0x2, /**< ADC sampling times 4 clk */ + ADC_SAMPLETIME_15 = 0x3, /**< ADC sampling times 15 clk */ +} adc_samp_t; + +/** + *@brief ADC rank into normal group + */ +typedef enum +{ + ADC_NCH_RANK_1 = 0x1, /**< ADC normal channel rank 1 */ + ADC_NCH_RANK_2 = 0x2, /**< ADC normal channel rank 2 */ + ADC_NCH_RANK_3 = 0x3, /**< ADC normal channel rank 3 */ + ADC_NCH_RANK_4 = 0x4, /**< ADC normal channel rank 4 */ + ADC_NCH_RANK_5 = 0x5, /**< ADC normal channel rank 5 */ + ADC_NCH_RANK_6 = 0x6, /**< ADC normal channel rank 6 */ + ADC_NCH_RANK_7 = 0x7, /**< ADC normal channel rank 7 */ + ADC_NCH_RANK_8 = 0x8, /**< ADC normal channel rank 8 */ + ADC_NCH_RANK_9 = 0x9, /**< ADC normal channel rank 9 */ + ADC_NCH_RANK_10 = 0xA, /**< ADC normal channel rank 10 */ + ADC_NCH_RANK_11 = 0xB, /**< ADC normal channel rank 11 */ + ADC_NCH_RANK_12 = 0xC, /**< ADC normal channel rank 12 */ + ADC_NCH_RANK_13 = 0xD, /**< ADC normal channel rank 13 */ + ADC_NCH_RANK_14 = 0xE, /**< ADC normal channel rank 14 */ + ADC_NCH_RANK_15 = 0xF, /**< ADC normal channel rank 15 */ + ADC_NCH_RANK_16 = 0x10, /**< ADC normal channel rank 16 */ +} adc_nch_rank_t; + +/** + * @brief ADC rank into insert group + */ +typedef enum +{ + ADC_ICH_RANK_1 = 0x1, /**< ADC insert channel rank 1 */ + ADC_ICH_RANK_2 = 0x2, /**< ADC insert channel rank 2 */ + ADC_ICH_RANK_3 = 0x3, /**< ADC insert channel rank 3 */ + ADC_ICH_RANK_4 = 0x4, /**< ADC insert channel rank 4 */ +} adc_ich_rank_t; + +/** + * @brief ADC analog watchdog mode + */ +typedef enum +{ + ADC_ANAWTD_NONE = 0x0, /**< No watch dog */ + ADC_ANAWTD_SING_NM = 0x800200, /**< One normal channel watch dog */ + ADC_ANAWTD_SING_IST = 0x400200, /**< One inset channel Injec watch dog */ + ADC_ANAWTD_SING_NMIST = 0xC00200, /**< One normal and inset channel watch dog */ + ADC_ANAWTD_ALL_NM = 0x800000, /**< All normal channel watch dog */ + ADC_ANAWTD_ALL_IST = 0x400000, /**< All inset channel watch dog */ + ADC_ANAWTD_ALL_NMIST = 0xC00000, /**< All normal and inset channel watch dog */ +} adc_ana_wtd_t; + +/** + * @brief ADC Event type + */ +typedef enum +{ + ADC_AWD_EVENT = (1U << 0), /**< ADC analog watch dog event */ +} adc_event_type_t; + +/** + * @brief ADC interrupts definition + */ +typedef enum +{ + ADC_IT_NCH = (1U << 5), /**< ADC it normal */ + ADC_IT_AWD = (1U << 6), /**< ADC it awd */ + ADC_IT_ICH = (1U << 7), /**< ADC it insert */ + ADC_IT_OVR = (1U << 26), /**< ADC it overring */ +} adc_it_t; + +/** + * @brief ADC flags definition + */ +typedef enum +{ + ADC_FLAG_AWD = (1U << 0), /**perh->CON1, ADC_CON1_ADCEN_MSK)) +#define ADC_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON1, ADC_CON1_ADCEN_MSK)) +#define ADC_NH_TRIG_BY_SOFT(handle) (SET_BIT((handle)->perh->CON1, ADC_CON1_NCHTRG_MSK)) +#define ADC_IH_TRIG_BY_SOFT(handle) (SET_BIT((handle)->perh->CON1, ADC_CON1_ICHTRG_MSK)) +#define ADC_RESET_HANDLE_STATE(handle) ((handle)->state = ADC_STATE_RESET) +#define ADC_VREF_OUT_ENABLE(handle) (SET_BIT((handle)->perh->CCR, ADC_CCR_VREFOEN_MSK)) +#define ADC_VREF_OUT_DISABLE(handle) (CLEAR_BIT((handle)->perh->CCR, ADC_CCR_VREFOEN_MSK)) +/** + * @} + */ + +/** @defgroup ADC_Private_Macros ADC Private Macros + * @{ + */ +#define IS_ADC_ICH_RANK_TYPE(x) ((x) <= ADC_ICH_RANK_4) +#define IS_ADC_NCH_RANK_TYPE(x) ((x) <= ADC_NCH_RANK_16) +#define IS_ADC_SAMPLING_TIMES_TYPE(x) (((x) == ADC_SAMPLETIME_1) || \ + ((x) == ADC_SAMPLETIME_2) || \ + ((x) == ADC_SAMPLETIME_4) || \ + ((x) == ADC_SAMPLETIME_15)) +#define IS_ADC_CHANNELS_TYPE(x) ((x) <= ADC_CHANNEL_19) +#define IS_ADC_SCAN_MODE_TYPE(x) (((x) == DISABLE) || \ + ((x) == ENABLE)) +#define IS_ADC_DATA_ALIGN_TYPE(x) (((x) == ADC_DATAALIGN_RIGHT) || \ + ((x) == ADC_DATAALIGN_LEFT)) +#define IS_ADC_ANALOG_WTD_MODE_TYPE(x) (((x) == ADC_ANAWTD_NONE) || \ + ((x) == ADC_ANAWTD_SING_NM) || \ + ((x) == ADC_ANAWTD_SING_IST) || \ + ((x) == ADC_ANAWTD_SING_NMIST) || \ + ((x) == ADC_ANAWTD_ALL_NM) || \ + ((x) == ADC_ANAWTD_ALL_IST) || \ + ((x) == ADC_ANAWTD_ALL_NMIST)) +#define IS_ADC_IT_TYPE(x) (((x) == ADC_IT_NCH) || \ + ((x) == ADC_IT_AWD) || \ + ((x) == ADC_IT_ICH) || \ + ((x) == ADC_IT_OVR )) +#define IS_ADC_FLAGS_TYPE(x) (((x) == ADC_FLAG_AWD) || \ + ((x) == ADC_FLAG_NCH) || \ + ((x) == ADC_FLAG_ICH) || \ + ((x) == ADC_FLAG_OVR) || \ + ((x) == ADC_FLAG_NCHS) || \ + ((x) == ADC_FLAG_ICHS)) +#define IS_ADC_CLK_DIV_TYPE(x) (((x) == ADC_CKDIV_1) || \ + ((x) == ADC_CKDIV_2) || \ + ((x) == ADC_CKDIV_4) || \ + ((x) == ADC_CKDIV_8) || \ + ((x) == ADC_CKDIV_16) || \ + ((x) == ADC_CKDIV_32) || \ + ((x) == ADC_CKDIV_64) || \ + ((x) == ADC_CKDIV_128)) +#define IS_ADC_NEG_REF_VOLTAGE_TYPE(x) (((x) == ADC_NEG_REF_VSS ) || \ + ((x) == ADC_NEG_REF_VREFN )) +#define IS_POS_REF_VOLTAGE_TYPE(x) (((x) == ADC_POS_REF_VDD) || \ + ((x) == ADC_POS_REF_VREEFP) || \ + ((x) == ADC_POS_REF_VREEFP_BUF)) +#define IS_ADC_NCH_LEN_TYPE(x) ((x) <= ADC_NCH_LEN_16) +#define IS_ADC_NBR_OF_IST_TYPE(x) ((x) <= ADC_ICH_LEN_4) +#define IS_ADC_DISC_MODE_TYPE(x) (((x) == ADC_ALL_DISABLE) || \ + ((x) == ADC_NCH_DISC_EN) || \ + ((x) == ADC_ICH_DISC_EN)) +#define IS_ADC_DISC_NBR_TYPE(x) ((x) <= ADC_DISC_NBR_8) +#define IS_ADC_CONV_RES_TYPE(x) (((x) == ADC_CONV_RES_12) || \ + ((x) == ADC_CONV_RES_6) || \ + ((x) == ADC_CONV_RES_8) || \ + ((x) == ADC_CONV_RES_10)) +#define IS_ADC_TRIG_MODE_TYPE(x) (((x) == ADC_TRIG_SOFT) || \ + ((x) == ADC_TRIG_PIS) || \ + ((x) == ADC_TRIG_PIS_SOFT)) +#define IS_ADC_TYPE(x) (((x) == ADC0) || \ + ((x) == ADC1)) +#define IS_ADC_NCHESEL_MODE_TYPE(x) (((x) == ADC_NCHESEL_MODE_ALL) || \ + ((x) == ADC_NCHESEL_MODE_ONE)) +#define IS_ADC_EVENT_TYPE(x) ((x) == ADC_AWD_EVENT) +#define IS_ADC_IST_OFFSET_TYPE(x) ((x) <= 0xfff) +#define IS_HTR_TYPE(x) ((x) <= 0xfff) +#define IS_LTR_TYPE(x) ((x) <= 0xfff) +/** + * @} + */ + +/** @addtogroup ADC_Public_Functions + * @{ + */ + +/** @addtogroup ADC_Public_Functions_Group1 + * @{ + */ +ald_status_t ald_adc_init(adc_handle_t *hperh); +ald_status_t ald_adc_reset(adc_handle_t *hperh); +/** + * @} + */ + +/** @addtogroup ADC_Public_Functions_Group2 + * @{ + */ +ald_status_t ald_adc_normal_start(adc_handle_t *hperh); +ald_status_t ald_adc_normal_stop(adc_handle_t *hperh); +ald_status_t ald_adc_normal_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout); +ald_status_t ald_adc_poll_for_event(adc_handle_t *hperh, adc_event_type_t event_type, uint32_t timeout); +ald_status_t ald_adc_normal_start_by_it(adc_handle_t *hperh); +ald_status_t ald_adc_normal_stop_by_it(adc_handle_t *hperh); +#ifdef ALD_DMA +ald_status_t ald_adc_start_by_dma(adc_handle_t *hperh, uint16_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_adc_stop_by_dma(adc_handle_t *hperh); +ald_status_t ald_adc_timer_trigger_adc_by_dma(adc_timer_config_t *config); +#endif +uint32_t ald_adc_normal_get_value(adc_handle_t *hperh); +uint32_t ald_adc_get_vdd_value(adc_handle_t *hperh); +ald_status_t ald_adc_insert_start(adc_handle_t *hperh); +ald_status_t ald_adc_insert_stop(adc_handle_t *hperh); +ald_status_t ald_adc_insert_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout); +ald_status_t ald_adc_insert_start_by_it(adc_handle_t *hperh); +ald_status_t ald_adc_insert_stop_by_it(adc_handle_t *hperh); +uint32_t ald_adc_insert_get_value(adc_handle_t *hperh, adc_ich_rank_t ih_rank); +void ald_adc_irq_handler(adc_handle_t *hperh); +/** + * @} + */ + +/** @addtogroup ADC_Public_Functions_Group3 + * @{ + */ +ald_status_t ald_adc_normal_channel_config(adc_handle_t *hperh, adc_nch_conf_t *config); +ald_status_t ald_adc_insert_channel_config(adc_handle_t *hperh, adc_ich_conf_t *config); +ald_status_t ald_adc_analog_wdg_config(adc_handle_t *hperh, adc_analog_wdg_conf_t *config); +void ald_adc_interrupt_config(adc_handle_t *hperh, adc_it_t it, type_func_t state); +it_status_t ald_adc_get_it_status(adc_handle_t *hperh, adc_it_t it); +flag_status_t ald_adc_get_flag_status(adc_handle_t *hperh, adc_flag_t flag); +void ald_adc_clear_flag_status(adc_handle_t *hperh, adc_flag_t flag); +/** + * @} + */ + +/** @addtogroup ADC_Public_Functions_Group4 + * @{ + */ +uint32_t ald_adc_get_state(adc_handle_t *hperh); +uint32_t ald_adc_get_error(adc_handle_t *hperh); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +extern "C" +} +#endif + +#endif /* __ALD_ADC_H */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_bkpc.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_bkpc.h similarity index 30% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_bkpc.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_bkpc.h index 67923d9a3a..7bac14c70e 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_bkpc.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_bkpc.h @@ -35,44 +35,44 @@ extern "C" { /** @defgroup BKPC_Public_Macros BKPC Public Macros * @{ */ -#define BKPC_LOCK() (WRITE_REG(BKPC->PROT, 0)) -#define BKPC_UNLOCK() (WRITE_REG(BKPC->PROT, 0x9669AA55)) -#define BKPC_LRC_ENABLE() \ -do { \ - BKPC_UNLOCK(); \ - SET_BIT(BKPC->CR, BKPC_CR_LRCEN_MSK); \ - BKPC_LOCK(); \ -} while (0) -#define BKPC_LRC_DISABLE() \ -do { \ - BKPC_UNLOCK(); \ - CLEAR_BIT(BKPC->CR, BKPC_CR_LRCEN_MSK); \ - BKPC_LOCK(); \ -} while (0) -#define BKPC_LOSM_ENABLE() \ -do { \ - BKPC_UNLOCK(); \ - SET_BIT(BKPC->CR, BKPC_CR_LOSMEN_MSK); \ - BKPC_LOCK(); \ -} while (0) -#define BKPC_LOSM_DISABLE() \ -do { \ - BKPC_UNLOCK(); \ - CLEAR_BIT(BKPC->CR, BKPC_CR_LOSMEN_MSK);\ - BKPC_LOCK(); \ -} while (0) -#define BKPC_LOSC_ENABLE() \ -do { \ - BKPC_UNLOCK(); \ - SET_BIT(BKPC->CR, BKPC_CR_LOSCEN_MSK); \ - BKPC_LOCK(); \ -} while (0) -#define BKPC_LOSC_DISABLE() \ -do { \ - BKPC_UNLOCK(); \ - CLEAR_BIT(BKPC->CR, BKPC_CR_LOSCEN_MSK);\ - BKPC_LOCK(); \ -} while (0) +#define BKPC_LOCK() (WRITE_REG(BKPC->PROT, 0)) +#define BKPC_UNLOCK() (WRITE_REG(BKPC->PROT, 0x9669AA55)) +#define BKPC_LRC_ENABLE() \ + do { \ + BKPC_UNLOCK(); \ + SET_BIT(BKPC->CR, BKPC_CR_LRCEN_MSK); \ + BKPC_LOCK(); \ + } while (0) +#define BKPC_LRC_DISABLE() \ + do { \ + BKPC_UNLOCK(); \ + CLEAR_BIT(BKPC->CR, BKPC_CR_LRCEN_MSK); \ + BKPC_LOCK(); \ + } while (0) +#define BKPC_LOSM_ENABLE() \ + do { \ + BKPC_UNLOCK(); \ + SET_BIT(BKPC->CR, BKPC_CR_LOSMEN_MSK); \ + BKPC_LOCK(); \ + } while (0) +#define BKPC_LOSM_DISABLE() \ + do { \ + BKPC_UNLOCK(); \ + CLEAR_BIT(BKPC->CR, BKPC_CR_LOSMEN_MSK);\ + BKPC_LOCK(); \ + } while (0) +#define BKPC_LOSC_ENABLE() \ + do { \ + BKPC_UNLOCK(); \ + SET_BIT(BKPC->CR, BKPC_CR_LOSCEN_MSK); \ + BKPC_LOCK(); \ + } while (0) +#define BKPC_LOSC_DISABLE() \ + do { \ + BKPC_UNLOCK(); \ + CLEAR_BIT(BKPC->CR, BKPC_CR_LOSCEN_MSK);\ + BKPC_LOCK(); \ + } while (0) /** * @} */ @@ -85,10 +85,10 @@ do { \ */ typedef enum { - BKPC_LDO_OUTPUT_1_6 = 0x0, /**< 1.6V */ - BKPC_LDO_OUTPUT_1_3 = 0x1, /**< 1.3V */ - BKPC_LDO_OUTPUT_1_4 = 0x2, /**< 1.4V */ - BKPC_LDO_OUTPUT_1_5 = 0x4, /**< 1.5V */ + BKPC_LDO_OUTPUT_1_6 = 0x0, /**< 1.6V */ + BKPC_LDO_OUTPUT_1_3 = 0x1, /**< 1.3V */ + BKPC_LDO_OUTPUT_1_4 = 0x2, /**< 1.4V */ + BKPC_LDO_OUTPUT_1_5 = 0x4, /**< 1.5V */ } bkpc_ldo_output_t; /** @@ -96,22 +96,22 @@ typedef enum */ typedef enum { - BKPC_BOR_VOL_1_7 = 0x0, /**< 1.7V */ - BKPC_BOR_VOL_2_0 = 0x1, /**< 2.0V */ - BKPC_BOR_VOL_2_1 = 0x2, /**< 2.1V */ - BKPC_BOR_VOL_2_2 = 0x3, /**< 2.2V */ - BKPC_BOR_VOL_2_3 = 0x4, /**< 2.3V */ - BKPC_BOR_VOL_2_4 = 0x5, /**< 2.4V */ - BKPC_BOR_VOL_2_5 = 0x6, /**< 2.5V */ - BKPC_BOR_VOL_2_6 = 0x7, /**< 2.6V */ - BKPC_BOR_VOL_2_8 = 0x8, /**< 2.8V */ - BKPC_BOR_VOL_3_0 = 0x9, /**< 3.0V */ - BKPC_BOR_VOL_3_1 = 0xA, /**< 3.1V */ - BKPC_BOR_VOL_3_3 = 0xB, /**< 3.3V */ - BKPC_BOR_VOL_3_6 = 0xC, /**< 3.6V */ - BKPC_BOR_VOL_3_7 = 0xD, /**< 3.7V */ - BKPC_BOR_VOL_4_0 = 0xE, /**< 4.0V */ - BKPC_BOR_VOL_4_3 = 0xF, /**< 4.3V */ + BKPC_BOR_VOL_1_7 = 0x0, /**< 1.7V */ + BKPC_BOR_VOL_2_0 = 0x1, /**< 2.0V */ + BKPC_BOR_VOL_2_1 = 0x2, /**< 2.1V */ + BKPC_BOR_VOL_2_2 = 0x3, /**< 2.2V */ + BKPC_BOR_VOL_2_3 = 0x4, /**< 2.3V */ + BKPC_BOR_VOL_2_4 = 0x5, /**< 2.4V */ + BKPC_BOR_VOL_2_5 = 0x6, /**< 2.5V */ + BKPC_BOR_VOL_2_6 = 0x7, /**< 2.6V */ + BKPC_BOR_VOL_2_8 = 0x8, /**< 2.8V */ + BKPC_BOR_VOL_3_0 = 0x9, /**< 3.0V */ + BKPC_BOR_VOL_3_1 = 0xA, /**< 3.1V */ + BKPC_BOR_VOL_3_3 = 0xB, /**< 3.3V */ + BKPC_BOR_VOL_3_6 = 0xC, /**< 3.6V */ + BKPC_BOR_VOL_3_7 = 0xD, /**< 3.7V */ + BKPC_BOR_VOL_4_0 = 0xE, /**< 4.0V */ + BKPC_BOR_VOL_4_3 = 0xF, /**< 4.3V */ } bkpc_bor_vol_t; /** @@ -122,27 +122,27 @@ typedef enum * @defgroup BKPC_Private_Macros BKPC Private Macros * @{ */ -#define IS_BKPC_LDO_OUTPUT(x) (((x) == BKPC_LDO_OUTPUT_1_6) || \ +#define IS_BKPC_LDO_OUTPUT(x) (((x) == BKPC_LDO_OUTPUT_1_6) || \ ((x) == BKPC_LDO_OUTPUT_1_3) || \ ((x) == BKPC_LDO_OUTPUT_1_4) || \ ((x) == BKPC_LDO_OUTPUT_1_5)) -#define IS_BKPC_BOR_VOL(x) (((x) == BKPC_BOR_VOL_1_7) || \ - ((x) == BKPC_BOR_VOL_2_0) || \ - ((x) == BKPC_BOR_VOL_2_1) || \ - ((x) == BKPC_BOR_VOL_2_2) || \ - ((x) == BKPC_BOR_VOL_2_3) || \ - ((x) == BKPC_BOR_VOL_2_4) || \ - ((x) == BKPC_BOR_VOL_2_5) || \ - ((x) == BKPC_BOR_VOL_2_6) || \ - ((x) == BKPC_BOR_VOL_2_8) || \ - ((x) == BKPC_BOR_VOL_3_0) || \ - ((x) == BKPC_BOR_VOL_3_1) || \ - ((x) == BKPC_BOR_VOL_3_3) || \ - ((x) == BKPC_BOR_VOL_3_6) || \ - ((x) == BKPC_BOR_VOL_3_7) || \ - ((x) == BKPC_BOR_VOL_4_0) || \ - ((x) == BKPC_BOR_VOL_4_3)) -#define IS_BKPC_RAM_IDX(x) ((x) < 32) +#define IS_BKPC_BOR_VOL(x) (((x) == BKPC_BOR_VOL_1_7) || \ + ((x) == BKPC_BOR_VOL_2_0) || \ + ((x) == BKPC_BOR_VOL_2_1) || \ + ((x) == BKPC_BOR_VOL_2_2) || \ + ((x) == BKPC_BOR_VOL_2_3) || \ + ((x) == BKPC_BOR_VOL_2_4) || \ + ((x) == BKPC_BOR_VOL_2_5) || \ + ((x) == BKPC_BOR_VOL_2_6) || \ + ((x) == BKPC_BOR_VOL_2_8) || \ + ((x) == BKPC_BOR_VOL_3_0) || \ + ((x) == BKPC_BOR_VOL_3_1) || \ + ((x) == BKPC_BOR_VOL_3_3) || \ + ((x) == BKPC_BOR_VOL_3_6) || \ + ((x) == BKPC_BOR_VOL_3_7) || \ + ((x) == BKPC_BOR_VOL_4_0) || \ + ((x) == BKPC_BOR_VOL_4_3)) +#define IS_BKPC_RAM_IDX(x) ((x) < 32) /** * @} */ @@ -154,8 +154,8 @@ typedef enum * @{ */ /* control functions */ -extern void bkpc_ldo_config(bkpc_ldo_output_t output, type_func_t state); -extern void bkpc_bor_config(bkpc_bor_vol_t vol, type_func_t state); +extern void ald_bkpc_ldo_config(bkpc_ldo_output_t output, type_func_t state); +extern void ald_bkpc_bor_config(bkpc_bor_vol_t vol, type_func_t state); /** * @} */ @@ -163,8 +163,8 @@ extern void bkpc_bor_config(bkpc_bor_vol_t vol, type_func_t state); * @{ */ /* IO operation functions */ -extern void bkpc_write_ram(uint8_t idx, uint32_t value); -extern uint32_t bkpc_read_ram(uint8_t idx); +extern void ald_bkpc_write_ram(uint8_t idx, uint32_t value); +extern uint32_t ald_bkpc_read_ram(uint8_t idx); /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_calc.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_calc.h similarity index 73% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_calc.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_calc.h index 896522b861..283417d843 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_calc.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_calc.h @@ -35,10 +35,10 @@ extern "C" { /** @addtogroup CALC_Public_Functions * @{ */ -extern uint32_t calc_sqrt(uint32_t data); -extern uint32_t calc_div(uint32_t dividend, uint32_t divisor, uint32_t *remainder); -extern int32_t calc_div_sign(int32_t dividend, int32_t divisor, int32_t *remainder); -extern flag_status_t calc_get_dz_status(void); +extern uint32_t ald_calc_sqrt(uint32_t data); +extern uint32_t ald_calc_div(uint32_t dividend, uint32_t divisor, uint32_t *remainder); +extern int32_t ald_calc_div_sign(int32_t dividend, int32_t divisor, int32_t *remainder); +extern flag_status_t ald_calc_get_dz_status(void); /** * @} */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_can.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_can.h new file mode 100644 index 0000000000..471c20e6ac --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_can.h @@ -0,0 +1,491 @@ +/** + ****************************************************************************** + * @file ald_can.h + * @brief Header file of CAN Module driver. + * + * @version V1.0 + * @date 16 Apr 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ****************************************************************************** + */ + +#ifndef __ALD_CAN_H +#define __ALD_CAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup CAN + * @{ + */ + +/** @defgroup CAN_Public_Types CAN Public Types + * @{ + */ +/** + * @brief ALD State structures definition + */ +typedef enum +{ + CAN_STATE_RESET = 0x00, /**< CAN not yet initialized or disabled */ + CAN_STATE_READY = 0x01, /**< CAN initialized and ready for use */ + CAN_STATE_BUSY = 0x02, /**< CAN process is ongoing */ + CAN_STATE_BUSY_TX = 0x11, /**< CAN process is ongoing */ + CAN_STATE_BUSY_RX = 0x21, /**< CAN process is ongoing */ + CAN_STATE_BUSY_TX_RX = 0x31, /**< CAN process is ongoing */ + CAN_STATE_TIMEOUT = 0x03, /**< CAN in Timeout state */ + CAN_STATE_ERROR = 0x04, /**< CAN error state */ +} can_state_t; + +/** + * @brief CAN Error Code + */ +typedef enum +{ + CAN_ERROR_NONE = 0x00, /**< No error */ + CAN_ERROR_EWG = 0x01, /**< EWG error */ + CAN_ERROR_EPV = 0x02, /**< EPV error */ + CAN_ERROR_BOF = 0x04, /**< BOF error */ + CAN_ERROR_STF = 0x08, /**< Stuff error */ + CAN_ERROR_FOR = 0x10, /**< Form error */ + CAN_ERROR_ACK = 0x20, /**< Acknowledgment error */ + CAN_ERROR_BR = 0x40, /**< Bit recessive */ + CAN_ERROR_BD = 0x80, /**< LEC dominant */ + CAN_ERROR_CRC = 0x100, /**< LEC transfer error */ + CAN_ERROR_UNK = 0x200, /**< Unknown error */ +} can_error_t; + +/** + * @brief CAN Operating Mode + */ +typedef enum +{ + CAN_MODE_NORMAL = 0x00, /**< Normal mode */ + CAN_MODE_LOOPBACK = 0x01, /**< Loopback mode */ + CAN_MODE_SILENT = 0x02, /**< Silent mode */ + CAN_MODE_SILENT_LOOPBACK = 0x03, /**< Loopback combined with silent mode */ +} can_operate_mode_t; + +/** + * @brief CAN Synchronization Jump Width + */ +typedef enum +{ + CAN_SJW_1 = 0x0, /**< 1 time quantum */ + CAN_SJW_2 = 0x1, /**< 2 time quantum */ + CAN_SJW_3 = 0x2, /**< 3 time quantum */ + CAN_SJW_4 = 0x3, /**< 4 time quantum */ +} can_sjw_t; + +/** + * @brief CAN Time Quantum in Bit Segment 1 + */ +typedef enum +{ + CAN_SEG1_1 = 0x0, /**< 1 time quantum */ + CAN_SEG1_2 = 0x1, /**< 2 time quantum */ + CAN_SEG1_3 = 0x2, /**< 3 time quantum */ + CAN_SEG1_4 = 0x3, /**< 4 time quantum */ + CAN_SEG1_5 = 0x4, /**< 5 time quantum */ + CAN_SEG1_6 = 0x5, /**< 6 time quantum */ + CAN_SEG1_7 = 0x6, /**< 7 time quantum */ + CAN_SEG1_8 = 0x7, /**< 8 time quantum */ + CAN_SEG1_9 = 0x8, /**< 9 time quantum */ + CAN_SEG1_10 = 0x9, /**< 10 time quantum */ + CAN_SEG1_11 = 0xA, /**< 11 time quantum */ + CAN_SEG1_12 = 0xB, /**< 12 time quantum */ + CAN_SEG1_13 = 0xC, /**< 13 time quantum */ + CAN_SEG1_14 = 0xD, /**< 14 time quantum */ + CAN_SEG1_15 = 0xE, /**< 15 time quantum */ + CAN_SEG1_16 = 0xF, /**< 16 time quantum */ +} can_seg1_t; + +/** + * @brief CAN Time Quantum in Bit Segment 2 + */ +typedef enum +{ + CAN_SEG2_1 = 0x0, /**< 1 time quantum */ + CAN_SEG2_2 = 0x1, /**< 2 time quantum */ + CAN_SEG2_3 = 0x2, /**< 3 time quantum */ + CAN_SEG2_4 = 0x3, /**< 4 time quantum */ + CAN_SEG2_5 = 0x4, /**< 5 time quantum */ + CAN_SEG2_6 = 0x5, /**< 6 time quantum */ + CAN_SEG2_7 = 0x6, /**< 7 time quantum */ + CAN_SEG2_8 = 0x7, /**< 8 time quantum */ +} can_seg2_t; + +/** + * @brief CAN Filter Mode + */ +typedef enum +{ + CAN_FILTER_MODE_MASK = 0x0, /**< Identifier mask mode */ + CAN_FILTER_MODE_LIST = 0x1, /**< Identifier list mode */ +} can_filter_mode_t; + +/** + * @brief CAN Filter Scale + */ +typedef enum +{ + CAN_FILTER_SCALE_16 = 0x0, /**< Two 16-bit filters */ + CAN_FILTER_SCALE_32 = 0x1, /**< One 32-bit filter */ +} can_filter_scale_t; + +/** + * @brief CAN Filter fifo + */ +typedef enum +{ + CAN_FILTER_FIFO0 = 0x0, /**< FIFO 0 assignment for filter */ + CAN_FILTER_FIFO1 = 0x1, /**< FIFO 1 assignment for filter */ +} can_filter_fifo_t; + +/** + * @brief CAN Identifier Type + */ +typedef enum +{ + CAN_ID_STD = 0x0, /**< Standard Id */ + CAN_ID_EXT = 0x1, /**< Extended Id */ +} can_id_type_t; + +/** + * @brief CAN Remote Transmission Request + */ +typedef enum +{ + CAN_RTR_DATA = 0x0, /**< Data frame */ + CAN_RTR_REMOTE = 0x1, /**< Remote frame */ +} can_remote_req_t; + +/** + * @brief CAN Transmit Constants + */ +typedef enum +{ + CAN_TX_MAILBOX_0 = 0x0, /**< TX mailbox index 0 */ + CAN_TX_MAILBOX_1 = 0x1, /**< TX mailbox index 1 */ + CAN_TX_MAILBOX_2 = 0x2, /**< TX mailbox index 2 */ + CAN_TX_MAILBOX_NONE = 0x3, /**< MailBox can't be used */ +} can_tx_mailbox_t; + +/** + * @brief CAN Receive fifo Number + */ +typedef enum +{ + CAN_RX_FIFO0 = 0x0, /**< CAN fifo 0 used to receive */ + CAN_RX_FIFO1 = 0x1, /**< CAN fifo 1 used to receive */ +} can_rx_fifo_t; + +/** + * @brief CAN Flags + */ +typedef enum +{ + CAN_FLAG_SLPS = (1U << 1), /**< Sleep acknowledge flag */ + CAN_FLAG_ERR = (1U << 2), /**< Error flag*/ + CAN_FLAG_WK = (1U << 3), /**< Wake up flag */ + CAN_FLAG_SLP = (1U << 4), /**< Sleep acknowledge flag */ + CAN_FLAG_M0REQC = (1U << 20) | (1U << 0), /**< Request MailBox0 flag */ + CAN_FLAG_M0TXC = (1U << 20) | (1U << 1), /**< Transmission OK MailBox0 flag */ + CAN_FLAG_M1REQC = (1U << 20) | (1U << 8), /**< Request MailBox1 flag */ + CAN_FLAG_M1TXC = (1U << 20) | (1U << 9), /**< Transmission OK MailBox1 flag */ + CAN_FLAG_M2REQC = (1U << 20) | (1U << 16), /**< Request MailBox2 flag */ + CAN_FLAG_M2TXC = (1U << 20) | (1U << 17), /**< Transmission OK MailBox2 flag */ + CAN_FLAG_TXM0 = (1U << 20) | (1U << 26), /**< Transmit mailbox 0 empty flag */ + CAN_FLAG_TXM1 = (1U << 20) | (1U << 27), /**< Transmit mailbox 1 empty flag */ + CAN_FLAG_TXM2 = (1U << 20) | (1U << 28), /**< Transmit mailbox 2 empty flag */ + CAN_FLAG_FF0 = (2U << 20) | (1U << 3), /**< FIFO 0 Full flag */ + CAN_FLAG_FOV0 = (2U << 20) | (1U << 4), /**< FIFO 0 Overrun flag */ + CAN_FLAG_FF1 = (3U << 20) | (1U << 3), /**< FIFO 1 Full flag */ + CAN_FLAG_FOV1 = (3U << 20) | (1U << 4), /**< FIFO 1 Overrun flag */ + CAN_FLAG_WARN = (4U << 20) | (1U << 0), /**< Error warning flag */ + CAN_FLAG_PERR = (4U << 20) | (1U << 1), /**< Error passive flag */ + CAN_FLAG_BOF = (4U << 20) | (1U << 2), /**< Bus-Off flag */ +} can_flag_t; + +/** + * @brief CAN Interrupts + */ +typedef enum +{ + CAN_IT_TXM = (1U << 0), /**< Transmit mailbox empty interrupt bit */ + CAN_IT_FP0 = (1U << 1), /**< FIFO0 message pending interrupt bit */ + CAN_IT_FF0 = (1U << 2), /**< FIFO0 full interrupt bit */ + CAN_IT_FOV0 = (1U << 3), /**< FIFO0 overrun interrupt bit */ + CAN_IT_FP1 = (1U << 4), /**< FIFO1 message pending interrupt bit */ + CAN_IT_FF1 = (1U << 5), /**< FIFO1 full interrupt bit */ + CAN_IT_FOV1 = (1U << 6), /**< FIFO1 overrun interrupt bit */ + CAN_IT_WARN = (1U << 8), /**< Error warning interrupt bit */ + CAN_IT_PERR = (1U << 9), /**< Error passive interrupt bit */ + CAN_IT_BOF = (1U << 10), /**< Bus-off interrupt bit */ + CAN_IT_PRERR = (1U << 11), /**< Last error code interrupt bit */ + CAN_IT_ERR = (1U << 15), /**< Error interrupt bit */ + CAN_IT_WK = (1U << 16), /**< wake-up interrupt bit */ + CAN_IT_SLP = (1U << 17), /**< sleep interrupt bit */ +} can_it_t; + +/** + * @brief CAN filter configuration structure definition + */ +typedef struct +{ + uint32_t id_high; /**< Specifies the filter identification number */ + uint32_t id_low; /**< Specifies the filter identification number */ + uint32_t mask_id_high; /**< Specifies the filter mask number or identification number */ + uint32_t mask_id_low; /**< Specifies the filter mask number or identification number */ + can_filter_fifo_t fifo; /**< Specifies the fifo (0 or 1) which will be assigned to the filter. */ + uint32_t number; /**< Specifies the filter which will be initialized. */ + can_filter_mode_t mode; /**< Specifies the filter mode to be initialized. */ + can_filter_scale_t scale; /**< Specifies the filter scale. */ + type_func_t active; /**< Enable or disable the filter. */ + uint32_t bank_number; /**< Select the start slave bank filter. */ +} can_filter_t; + +/** + * @brief CAN init structure definition + */ +typedef struct +{ + uint32_t psc; /**< Specifies the length of a time quantum. */ + can_operate_mode_t mode; /**< Specifies the CAN operating mode. */ + can_sjw_t sjw; /**< Specifies the maximum number of time quanta the CAN hardware is + allowed to lengthen or shorten a bit to perform resynchronization. */ + can_seg1_t seg1; /**< Specifies the number of time quanta in Bit Segment 1. */ + can_seg2_t seg2; /**< Specifies the number of time quanta in Bit Segment 2. */ + type_func_t ttcm; /**< Enable or disable the time triggered communication mode. */ + type_func_t abom; /**< Enable or disable the automatic bus-off management. */ + type_func_t awk; /**< Enable or disable the automatic wake-up mode. */ + type_func_t artx; /**< Enable or disable the non-automatic retransmission mode. */ + type_func_t rfom; /**< Enable or disable the Receive fifo Locked mode. */ + type_func_t txmp; /**< Enable or disable the transmit fifo priority. */ +} can_init_t; + +/** + * @brief CAN Tx message structure definition + */ +typedef struct +{ + uint32_t std; /**< Specifies the standard identifier. */ + uint32_t ext; /**< Specifies the extended identifier. */ + can_id_type_t type; /**< Specifies the type of identifier for the message that will be transmitted. */ + can_remote_req_t rtr; /**< Specifies the type of frame for the message that will be transmitted. */ + uint32_t len; /**< Specifies the length of the frame that will be transmitted. */ + uint8_t data[8]; /**< Contains the data to be transmitted. */ +} can_tx_msg_t; + +/** + * @brief CAN Rx message structure definition + */ +typedef struct +{ + uint32_t std; /**< Specifies the standard identifier. */ + uint32_t ext; /**< Specifies the extended identifier. */ + can_id_type_t type; /**< Specifies the type of identifier for the message that will be received. */ + can_remote_req_t rtr; /**< Specifies the type of frame for the received message. */ + uint32_t len; /**< Specifies the length of the frame that will be received. */ + uint8_t data[8]; /**< Contains the data to be received. */ + uint32_t fmi; /**< Specifies the index of the filter the message stored in the mailbox passes through. */ + can_rx_fifo_t num; /**< Specifies the receive fifo number. */ +} can_rx_msg_t; + +/** + * @brief CAN handle Structure definition + */ +typedef struct can_handle_s +{ + CAN_TypeDef *perh; /**< Register base address */ + can_init_t init; /**< CAN required parameters */ + can_rx_msg_t *rx_msg; /**< Pointer to receive message */ + lock_state_t lock; /**< CAN locking object */ + can_state_t state; /**< CAN communication state */ + can_error_t err; /**< CAN Error code */ + + void (*tx_cplt_cbk)(struct can_handle_s *arg); /**< Tx completed callback */ + void (*rx_cplt_cbk)(struct can_handle_s *arg); /**< Rx completed callback */ + void (*error_cbk)(struct can_handle_s *arg); /**< error callback */ +} can_handle_t; +/** + * @} + */ + +/** @defgroup CAN_Public_Macro CAN Public Macros + * @{ + */ +#define CAN_RESET_HANDLE_STATE(x) ((x)->state = CAN_STATE_RESET) +#define CAN_RX_MSG_PENDING(x, y) (((y) == CAN_RX_FIFO0) ? \ + (READ_BIT((x)->perh->RXF0, CAN_RXF0_PEND_MSK)) : (READ_BIT((x)->perh->RXF1, CAN_RXF1_PEND_MSK))) +#define CAN_DBG_FREEZE(x, y) (MODIFY_REG((x)->perh->CON, CAN_CON_DBGSTP_MSK, (y) << CAN_CON_DBGSTP_POS)) +#define CAN_TX_STAMP_ENABLE(x) (SET_BIT(hperh->perh->TxMailBox[(x)].TXFCON, CAN_TXFCON0_TXGT_MSK)) +#define CAN_TX_STAMP_DISABLE(x) (CLEAR_BIT(hperh->perh->TxMailBox[(x)].TXFCON, CAN_TXFCON0_TXGT_MSK)) +/** + * @} + */ + +/** @defgroup CAN_Private_Macros CAN Private Macros + * @{ + */ +#define IS_CAN_ALL(x) ((x) == CAN0) +#define IS_CAN_FILTER_NUMBER(x) ((x) <= 13) +#define IS_CAN_MODE(x) (((x) == CAN_MODE_NORMAL) || \ + ((x) == CAN_MODE_LOOPBACK) || \ + ((x) == CAN_MODE_SILENT) || \ + ((x) == CAN_MODE_SILENT_LOOPBACK)) +#define IS_CAN_SJW(x) (((x) == CAN_SJW_1) || \ + ((x) == CAN_SJW_2) || \ + ((x) == CAN_SJW_3) || \ + ((x) == CAN_SJW_4)) +#define IS_CAN_BS1(x) ((x) <= CAN_SEG1_16) +#define IS_CAN_BS2(x) ((x) <= CAN_SEG2_8) +#define IS_CAN_FILTER_MODE(x) (((x) == CAN_FILTER_MODE_MASK) || \ + ((x) == CAN_FILTER_MODE_LIST)) +#define IS_CAN_FILTER_SCALE(x) (((x) == CAN_FILTER_SCALE_16) || \ + ((x) == CAN_FILTER_SCALE_32)) +#define IS_CAN_FILTER_FIFO(x) (((x) == CAN_FILTER_FIFO0) || \ + ((x) == CAN_FILTER_FIFO1)) +#define IS_CAN_IDTYPE(x) (((x) == CAN_ID_STD) || \ + ((x) == CAN_ID_EXT)) +#define IS_CAN_RTR(x) (((x) == CAN_RTR_DATA) || ((x) == CAN_RTR_REMOTE)) +#define IS_CAN_FIFO(x) (((x) == CAN_RX_FIFO0) || ((x) == CAN_RX_FIFO1)) +#define IS_CAN_BANKNUMBER(x) ((x) <= 28) +#define IS_CAN_TX_MAILBOX(x) ((x) <= CAN_TX_MAILBOX_NONE) +#define IS_CAN_STDID(x) ((x) <= ((uint32_t)0x7FF)) +#define IS_CAN_EXTID(x) ((x) <= ((uint32_t)0x1FFFFFFF)) +#define IS_CAN_DATA_LEN(x) ((x) <= ((uint8_t)0x08)) +#define IS_CAN_PRESCALER(x) (((x) >= 1) && ((x) <= 1024)) +#define IS_CAN_GET_FLAG(x) (((x) == CAN_FLAG_SLPS) || \ + ((x) == CAN_FLAG_ERR) || \ + ((x) == CAN_FLAG_WK) || \ + ((x) == CAN_FLAG_SLP) || \ + ((x) == CAN_FLAG_M0REQC) || \ + ((x) == CAN_FLAG_M0TXC) || \ + ((x) == CAN_FLAG_M1REQC) || \ + ((x) == CAN_FLAG_M1TXC) || \ + ((x) == CAN_FLAG_M2REQC) || \ + ((x) == CAN_FLAG_M2TXC) || \ + ((x) == CAN_FLAG_TXM0) || \ + ((x) == CAN_FLAG_TXM1) || \ + ((x) == CAN_FLAG_TXM2) || \ + ((x) == CAN_FLAG_FF0) || \ + ((x) == CAN_FLAG_FOV0) || \ + ((x) == CAN_FLAG_FF1) || \ + ((x) == CAN_FLAG_FOV1) || \ + ((x) == CAN_FLAG_WARN) || \ + ((x) == CAN_FLAG_PERR) || \ + ((x) == CAN_FLAG_BOF)) +#define IS_CAN_CLEAR_FLAG(x) (((x) == CAN_FLAG_ERR) || \ + ((x) == CAN_FLAG_WK) || \ + ((x) == CAN_FLAG_SLP) || \ + ((x) == CAN_FLAG_M0REQC) || \ + ((x) == CAN_FLAG_M1REQC) || \ + ((x) == CAN_FLAG_M2REQC) || \ + ((x) == CAN_FLAG_FF0) || \ + ((x) == CAN_FLAG_FOV0) || \ + ((x) == CAN_FLAG_FF1) || \ + ((x) == CAN_FLAG_FOV1)) +#define IS_CAN_IT(x) (((x) == CAN_IT_TXM) || \ + ((x) == CAN_IT_FP0) || \ + ((x) == CAN_IT_FF0) || \ + ((x) == CAN_IT_FOV0) || \ + ((x) == CAN_IT_FP1) || \ + ((x) == CAN_IT_FF1) || \ + ((x) == CAN_IT_FOV1) || \ + ((x) == CAN_IT_WARN) || \ + ((x) == CAN_IT_PERR) || \ + ((x) == CAN_IT_BOF) || \ + ((x) == CAN_IT_PRERR) || \ + ((x) == CAN_IT_ERR) || \ + ((x) == CAN_IT_WK) || \ + ((x) == CAN_IT_SLP)) +#define CAN_TIMEOUT_VALUE 100 +#define CAN_STATE_TX_MASK (1U << 4) +#define CAN_STATE_RX_MASK (1U << 5) +/** + * @} + */ + +/** @addtogroup CAN_Public_Functions + * @{ + */ + +/** @addtogroup CAN_Public_Functions_Group1 + * @{ + */ +/* Initialization functions */ +void ald_can_reset(can_handle_t *hperh); +ald_status_t ald_can_init(can_handle_t *hperh); +ald_status_t ald_can_filter_config(can_handle_t *hperh, can_filter_t *config); +/** + * @} + */ + +/** @addtogroup CAN_Public_Functions_Group2 + * @{ + */ +/* IO operation functions */ +ald_status_t ald_can_send(can_handle_t *hperh, can_tx_msg_t *msg, uint32_t timeout); +ald_status_t ald_can_send_by_it(can_handle_t *hperh, can_tx_msg_t *msg); +ald_status_t ald_can_recv(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg, uint32_t timeout); +ald_status_t ald_can_recv_by_it(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg); +/** + * @} + */ + +/** @addtogroup CAN_Public_Functions_Group3 + * @{ + */ +/* Control function */ +ald_status_t ald_can_sleep(can_handle_t *hperh); +ald_status_t ald_can_wake_up(can_handle_t *hperh); +void ald_can_cancel_send(can_handle_t *hperh, can_tx_mailbox_t box); +void ald_can_irq_handler(can_handle_t *hperh); +type_bool_t ald_can_get_tx_status(can_handle_t *hperh, can_tx_mailbox_t box); +void ald_can_interrupt_config(can_handle_t *hperh, can_it_t it, type_func_t state); +it_status_t ald_can_get_it_status(can_handle_t *hperh, can_it_t it); +flag_status_t ald_can_get_flag_status(can_handle_t *hperh, can_flag_t flag); +void ald_can_clear_flag_status(can_handle_t *hperh, can_flag_t flag); +/** + * @} + */ + +/** @addtogroup CAN_Public_Functions_Group4 + * @{ + */ +/* State and Error functions */ +can_state_t ald_can_get_state(can_handle_t *hperh); +can_error_t ald_can_get_error(can_handle_t *hperh); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_CAN_H */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_cmu.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_cmu.h new file mode 100644 index 0000000000..5bcae0bd07 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_cmu.h @@ -0,0 +1,653 @@ +/** + ********************************************************************************* + * + * @file ald_cmu.h + * @brief Header file of CMU module driver. + * + * @version V1.0 + * @date 22 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ******************************************************************************** + */ + +#ifndef __ALD_CMU_H__ +#define __ALD_CMU_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" +#include "ald_syscfg.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup CMU + * @{ + */ + +/** @defgroup CMU_Public_Macros CMU Public Macros + * @{ + */ +#define CMU_LOSC_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LOSC_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LRC_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LRC_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_ULRC_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(CMU->CLKENR, CMU_CLKENR_ULRCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_ULRC_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_ULRCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) + +/* Low power mode control */ +#define CMU_LP_LRC_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(CMU->LPENR, CMU_LPENR_LRCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LP_LRC_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(CMU->LPENR, CMU_LPENR_LRCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LP_LOSC_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(CMU->LPENR, CMU_LPENR_LOSCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LP_LOSC_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(CMU->LPENR, CMU_LPENR_LOSCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LP_HRC_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(CMU->LPENR, CMU_LPENR_HRCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LP_HRC_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(CMU->LPENR, CMU_LPENR_HRCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LP_HOSC_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(CMU->LPENR, CMU_LPENR_HOSCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define CMU_LP_HOSC_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(CMU->LPENR, CMU_LPENR_HOSCEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +/** + * @} + */ + + +/** @defgroup CMU_Public_Types CMU Public Types + * @{ + */ +/** + * @brief CMU state structure definition + */ +typedef enum +{ + CMU_CLOCK_HRC = 0x1, /**< HRC */ + CMU_CLOCK_LRC = 0x2, /**< LRC */ + CMU_CLOCK_LOSC = 0x3, /**< LOSC */ + CMU_CLOCK_PLL1 = 0x4, /**< PLL1 */ + CMU_CLOCK_HOSC = 0x5, /**< HOSC */ +} cmu_clock_t; + +/** + * @brief PLL1 output clock + */ +typedef enum +{ + CMU_PLL1_OUTPUT_32M = 0x0, /**< x8 (32MHz) */ + CMU_PLL1_OUTPUT_48M = 0x1, /**< x12 (48MHz) */ +} cmu_pll1_output_t; + +/** + * @brief PLL1 referance clock + */ +typedef enum +{ + CMU_PLL1_INPUT_HRC_6 = 0x0, /**< HRC / 6 */ + CMU_PLL1_INPUT_PLL2 = 0x1, /**< PLL2 */ + CMU_PLL1_INPUT_HOSC = 0x2, /**< HOSC / 1 */ + CMU_PLL1_INPUT_HOSC_2 = 0x3, /**< HOSC / 2 */ + CMU_PLL1_INPUT_HOSC_3 = 0x4, /**< HOSC / 3 */ + CMU_PLL1_INPUT_HOSC_4 = 0x5, /**< HOSC / 4 */ + CMU_PLL1_INPUT_HOSC_5 = 0x6, /**< HOSC / 5 */ + CMU_PLL1_INPUT_HOSC_6 = 0x7, /**< HOSC / 6 */ +} cmu_pll1_input_t; + +/** + * @brief HOSC range + */ +typedef enum +{ + CMU_HOSC_2M = 0x0, + CMU_HOSC_4M = 0x1, + CMU_HOSC_8M = 0x2, + CMU_HOSC_16M = 0x3, + CMU_HOSC_24M = 0x4, +} cmu_hosc_range_t; + +/** + * @brief Auto-calibrate input + */ +typedef enum +{ + CMU_AUTO_CALIB_INPUT_LOSE = 0x0, + CMU_AUTO_CALIB_INPUT_HOSE = 0x1, +} cmu_auto_calib_input_t; + +/** + * @brief Auto-calibrate output + */ +typedef enum +{ + CMU_AUTO_CALIB_OUTPUT_24M = 0x0, + CMU_AUTO_CALIB_OUTPUT_2M = 0x1, +} cmu_auto_calib_output_t; + +/** + * @brief Frequency division select bit + */ +typedef enum +{ + CMU_DIV_1 = 0x0, /**< Division by 1 */ + CMU_DIV_2 = 0x1, /**< Division by 2 */ + CMU_DIV_4 = 0x2, /**< Division by 4 */ + CMU_DIV_8 = 0x3, /**< Division by 8 */ + CMU_DIV_16 = 0x4, /**< Division by 16 */ + CMU_DIV_32 = 0x5, /**< Division by 32 */ + CMU_DIV_64 = 0x6, /**< Division by 64 */ + CMU_DIV_128 = 0x7, /**< Division by 128 */ + CMU_DIV_256 = 0x8, /**< Division by 256 */ + CMU_DIV_512 = 0x9, /**< Division by 512 */ + CMU_DIV_1024 = 0xA, /**< Division by 1024 */ + CMU_DIV_2048 = 0xB, /**< Division by 2048 */ + CMU_DIV_4096 = 0xC, /**< Division by 4096 */ +} cmu_div_t; + +/** + * @brief Bus type + */ +typedef enum +{ + CMU_HCLK_1 = 0x0, /**< AHB1 bus */ + CMU_SYS = 0x1, /**< SYS bus */ + CMU_PCLK_1 = 0x2, /**< APB1 bus */ + CMU_PCLK_2 = 0x3, /**< APB2 bus */ +} cmu_bus_t; + +/** + * @brief Output high clock select + */ +typedef enum +{ + CMU_OUTPUT_HIGH_SEL_HOSC = 0x0, /**< Select HOSC */ + CMU_OUTPUT_HIGH_SEL_LOSC = 0x1, /**< Select LOSC */ + CMU_OUTPUT_HIGH_SEL_HRC = 0x2, /**< Select HRC */ + CMU_OUTPUT_HIGH_SEL_LRC = 0x3, /**< Select LRC */ + CMU_OUTPUT_HIGH_SEL_HOSM = 0x4, /**< Select HOSM */ + CMU_OUTPUT_HIGH_SEL_PLL1 = 0x5, /**< Select PLL1 */ + CMU_OUTPUT_HIGH_SEL_PLL2 = 0x6, /**< Select PLL2 */ + CMU_OUTPUT_HIGH_SEL_SYSCLK = 0x7, /**< Select SYSCLK */ +} cmu_output_high_sel_t; + +/** + * @brief Output frequency division + */ +typedef enum +{ + CMU_OUTPUT_DIV_1 = 0x0, /**< Division by 1 */ + CMU_OUTPUT_DIV_2 = 0x1, /**< Division by 2 */ + CMU_OUTPUT_DIV_4 = 0x2, /**< Division by 4 */ + CMU_OUTPUT_DIV_8 = 0x3, /**< Division by 8 */ + CMU_OUTPUT_DIV_16 = 0x4, /**< Division by 16 */ + CMU_OUTPUT_DIV_32 = 0x5, /**< Division by 32 */ + CMU_OUTPUT_DIV_64 = 0x6, /**< Division by 64 */ + CMU_OUTPUT_DIV_128 = 0x7, /**< Division by 128 */ +} cmu_output_high_div_t; + +/** + * @brief Output low clock select + */ +typedef enum +{ + CMU_OUTPUT_LOW_SEL_LOSC = 0x0, /**< Select LOSC */ + CMU_OUTPUT_LOW_SEL_LRC = 0x1, /**< Select LRC */ + CMU_OUTPUT_LOW_SEL_LOSM = 0x2, /**< Select LOSM */ + CMU_OUTPUT_LOW_SEL_BUZZ = 0x3, /**< Select BUZZ */ + CMU_OUTPUT_LOW_SEL_ULRC = 0x4, /**< Select ULRC */ +} cmu_output_low_sel_t; + +/** + * @brief BUZZ frequency division + */ +typedef enum +{ + CMU_BUZZ_DIV_2 = 0x0, /**< Division by 2 */ + CMU_BUZZ_DIV_4 = 0x1, /**< Division by 4 */ + CMU_BUZZ_DIV_8 = 0x2, /**< Division by 8 */ + CMU_BUZZ_DIV_16 = 0x3, /**< Division by 16 */ + CMU_BUZZ_DIV_32 = 0x4, /**< Division by 32 */ + CMU_BUZZ_DIV_64 = 0x5, /**< Division by 64 */ + CMU_BUZZ_DIV_128 = 0x6, /**< Division by 128 */ + CMU_BUZZ_DIV_256 = 0x7, /**< Division by 256 */ +} cmu_buzz_div_t; + +/** + * @brief Low power peripheral clock select + */ +typedef enum +{ + CMU_LP_PERH_CLOCK_SEL_PCLK2 = 0x0, /**< Select PCLK2 */ + CMU_LP_PERH_CLOCK_SEL_PLL1 = 0x1, /**< Select PLL1 */ + CMU_LP_PERH_CLOCK_SEL_PLL2 = 0x2, /**< Select PLL2 */ + CMU_LP_PERH_CLOCK_SEL_HRC = 0x3, /**< Select HRC */ + CMU_LP_PERH_CLOCK_SEL_HOSC = 0x4, /**< Select HOSC */ + CMU_LP_PERH_CLOCK_SEL_LRC = 0x5, /**< Select LRC */ + CMU_LP_PERH_CLOCK_SEL_LOSC = 0x6, /**< Select LOSC */ + CMU_LP_PERH_CLOCK_SEL_ULRC = 0x7, /**< Select ULRC */ + CMU_LP_PERH_CLOCK_SEL_HRC_1M = 0x8, /**< Select HRC down to 1MHz */ + CMU_LP_PERH_CLOCK_SEL_HOSC_1M = 0x9, /**< Select HOSC down to 1MHz */ + CMU_LP_PERH_CLOCK_SEL_LOSM = 0xA, /**< Select LOSM */ + CMU_LP_PERH_CLOCK_SEL_HOSM = 0xB, /**< Select HOSM */ +} cmu_lp_perh_clock_sel_t; + +/** + * @brief LCD clock select + */ +typedef enum +{ + CMU_LCD_SEL_LOSM = 0x0, /**< Select LOSM */ + CMU_LCD_SEL_LOSC = 0x1, /**< Select LOSC */ + CMU_LCD_SEL_LRC = 0x2, /**< Select LRC */ + CMU_LCD_SEL_ULRC = 0x3, /**< Select ULRC */ + CMU_LCD_SEL_HRC_1M = 0x4, /**< Select HRC down to 1MHz */ + CMU_LCD_SEL_HOSC_1M = 0x5, /**< Select HOSC down to 1MHz */ +} cmu_lcd_clock_sel_t; + +/** + * @brief Peripheral clock enable/disable + * @note ES32F065x: + * AD16C4T0--TIMER0 + * GP16C4T0--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + * + * ES32F033x: + * ES32F093x: + * GP16C4T0--TIMER0 + * GP16C4T1--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + */ +typedef enum +{ + CMU_PERH_GPIO = (1U << 0), /**< GPIO */ + CMU_PERH_CRC = (1U << 1), /**< CRC */ + CMU_PERH_CALC = (1U << 2), /**< CALC */ + CMU_PERH_CRYPT = (1U << 3), /**< CRYPT */ + CMU_PERH_TRNG = (1U << 4), /**< TRNG */ + CMU_PERH_PIS = (1U << 5), /**< PIS */ + CMU_PERH_TIMER0 = (1U << 0) | (1U << 27), /**< TIMER0 */ + CMU_PERH_TIMER1 = (1U << 1) | (1U << 27), /**< TIMER1 */ + CMU_PERH_TIMER2 = (1U << 2) | (1U << 27), /**< TIMER2 */ + CMU_PERH_TIMER3 = (1U << 3) | (1U << 27), /**< TIMER3 */ + CMU_PERH_TIMER4 = (1U << 4) | (1U << 27), /**< TIMER4 */ + CMU_PERH_TIMER5 = (1U << 5) | (1U << 27), /**< TIMER5 */ + CMU_PERH_TIMER6 = (1U << 6) | (1U << 27), /**< TIMER6 */ + CMU_PERH_TIMER7 = (1U << 7) | (1U << 27), /**< TIMER7 */ + CMU_PERH_UART0 = (1U << 8) | (1U << 27), /**< UART0 */ + CMU_PERH_UART1 = (1U << 9) | (1U << 27), /**< UART1 */ + CMU_PERH_UART2 = (1U << 10) | (1U << 27), /**< UART2 */ + CMU_PERH_UART3 = (1U << 11) | (1U << 27), /**< UART3 */ + CMU_PERH_USART0 = (1U << 12) | (1U << 27), /**< USART0 */ + CMU_PERH_USART1 = (1U << 13) | (1U << 27), /**< USART1 */ + CMU_PERH_SPI0 = (1U << 16) | (1U << 27), /**< SPI0 */ + CMU_PERH_SPI1 = (1U << 17) | (1U << 27), /**< SPI1 */ + CMU_PERH_SPI2 = (1U << 18) | (1U << 27), /**< SPI2 */ + CMU_PERH_I2C0 = (1U << 20) | (1U << 27), /**< I2C0 */ + CMU_PERH_I2C1 = (1U << 21) | (1U << 27), /**< I2C1 */ + CMU_PERH_CAN = (1U << 24) | (1U << 27), /**< CAN */ + CMU_PERH_LPTIM0 = (1U << 0) | (1U << 28), /**< LPTIM0 */ + CMU_PERH_LPUART0 = (1U << 2) | (1U << 28), /**< LPUART0 */ + CMU_PERH_ADC0 = (1U << 4) | (1U << 28), /**< ADC0 */ + CMU_PERH_ADC1 = (1U << 5) | (1U << 28), /**< ADC1 */ + CMU_PERH_ACMP0 = (1U << 6) | (1U << 28), /**< ACMP0 */ + CMU_PERH_ACMP1 = (1U << 7) | (1U << 28), /**< ACMP1 */ + CMU_PERH_OPAMP = (1U << 8) | (1U << 28), /**< OPAMP */ + CMU_PERH_DAC0 = (1U << 9) | (1U << 28), /**< DAC0 */ + CMU_PERH_WWDT = (1U << 12) | (1U << 28), /**< WWDT */ + CMU_PERH_LCD = (1U << 13) | (1U << 28), /**< LCD */ + CMU_PERH_IWDT = (1U << 14) | (1U << 28), /**< IWDT */ + CMU_PERH_RTC = (1U << 15) | (1U << 28), /**< RTC */ + CMU_PERH_TSENSE = (1U << 16) | (1U << 28), /**< TSENSE */ + CMU_PERH_BKPC = (1U << 17) | (1U << 28), /**< BKPC */ + CMU_PERH_BKRPAM = (1U << 18) | (1U << 28), /**< BKPRAM */ + CMU_PERH_DBGC = (1U << 19) | (1U << 28), /**< DBGC */ + CMU_PERH_ALL = (0x7FFFFFFF), /**< ALL */ +} cmu_perh_t; + +/** + * @brief CMU interrupt type + */ +typedef enum +{ + CMU_LOSC_STOP = 0x0, /**< LOSC STOP INTERRUPT */ + CMU_HOSC_STOP = 0x1, /**< HOSC STOP INTERRUPT */ + CMU_PLL1_UNLOCK = 0x2, /**< PLL1 UNLOCK INTERRUPT */ + CMU_LOSC_START = 0x3, /**< LOSC START INTERRUPT */ + CMU_HOSC_START = 0x4, /**< HOSC START INTERRUPT */ +} cmu_security_t; + +/** + * @brief CMU clock state type + */ +typedef enum +{ + CMU_CLOCK_STATE_HOSCACT = (1U << 0), /**< HOSC active */ + CMU_CLOCK_STATE_LOSCACT = (1U << 1), /**< LOSC active */ + CMU_CLOCK_STATE_HRCACT = (1U << 2), /**< HRC active */ + CMU_CLOCK_STATE_LRCACT = (1U << 3), /**< LRC active */ + CMU_CLOCK_STATE_ULRCACT = (1U << 4), /**< ULRC active */ + CMU_CLOCK_STATE_PLLACT = (1U << 8), /**< PLL active */ + CMU_CLOCK_STATE_HOSCRDY = (1U << 16), /**< HOSC ready */ + CMU_CLOCK_STATE_LOSCRDY = (1U << 17), /**< LOSC ready */ + CMU_CLOCK_STATE_HRCRDY = (1U << 18), /**< HRC ready */ + CMU_CLOCK_STATE_LRCRDY = (1U << 19), /**< LRC ready */ + CMU_CLOCK_STATE_PLLRDY = (1U << 24), /**< PLL ready */ +} cmu_clock_state_t; +/** + * @} + */ + +/** + * @defgroup CMU_Private_Macros CMU Private Macros + * @{ + */ +#define IS_CMU_CLOCK(x) (((x) == CMU_CLOCK_HRC) || \ + ((x) == CMU_CLOCK_LRC) || \ + ((x) == CMU_CLOCK_LOSC) || \ + ((x) == CMU_CLOCK_PLL1) || \ + ((x) == CMU_CLOCK_HOSC)) +#define IS_CMU_PLL1_OUTPUT(x) (((x) == CMU_PLL1_OUTPUT_32M) || \ + ((x) == CMU_PLL1_OUTPUT_48M)) +#define IS_CMU_PLL1_INPUT(x) (((x) == CMU_PLL1_INPUT_HRC_6) || \ + ((x) == CMU_PLL1_INPUT_PLL2) || \ + ((x) == CMU_PLL1_INPUT_HOSC) || \ + ((x) == CMU_PLL1_INPUT_HOSC_2) || \ + ((x) == CMU_PLL1_INPUT_HOSC_3) || \ + ((x) == CMU_PLL1_INPUT_HOSC_4) || \ + ((x) == CMU_PLL1_INPUT_HOSC_5) || \ + ((x) == CMU_PLL1_INPUT_HOSC_6)) +#define IS_CMU_HOSC_RANGE(x) (((x) == CMU_HOSC_2M) || \ + ((x) == CMU_HOSC_4M) || \ + ((x) == CMU_HOSC_8M) || \ + ((x) == CMU_HOSC_16M) || \ + ((x) == CMU_HOSC_24M)) +#define IS_CMU_DIV(x) (((x) == CMU_DIV_1) || \ + ((x) == CMU_DIV_2) || \ + ((x) == CMU_DIV_4) || \ + ((x) == CMU_DIV_8) || \ + ((x) == CMU_DIV_16) || \ + ((x) == CMU_DIV_32) || \ + ((x) == CMU_DIV_64) || \ + ((x) == CMU_DIV_128) || \ + ((x) == CMU_DIV_256) || \ + ((x) == CMU_DIV_512) || \ + ((x) == CMU_DIV_1024) || \ + ((x) == CMU_DIV_2048) || \ + ((x) == CMU_DIV_4096)) +#define IS_CMU_BUS(x) (((x) == CMU_HCLK_1) || \ + ((x) == CMU_SYS) || \ + ((x) == CMU_PCLK_1) || \ + ((x) == CMU_PCLK_2)) +#define IS_CMU_OUTPUT_HIGH_SEL(x) (((x) == CMU_OUTPUT_HIGH_SEL_HOSC) || \ + ((x) == CMU_OUTPUT_HIGH_SEL_LOSC) || \ + ((x) == CMU_OUTPUT_HIGH_SEL_HRC) || \ + ((x) == CMU_OUTPUT_HIGH_SEL_LRC) || \ + ((x) == CMU_OUTPUT_HIGH_SEL_HOSM) || \ + ((x) == CMU_OUTPUT_HIGH_SEL_PLL1) || \ + ((x) == CMU_OUTPUT_HIGH_SEL_PLL2) || \ + ((x) == CMU_OUTPUT_HIGH_SEL_SYSCLK)) +#define IS_CMU_OUTPUT_HIGH_DIV(x) (((x) == CMU_OUTPUT_DIV_1) || \ + ((x) == CMU_OUTPUT_DIV_2) || \ + ((x) == CMU_OUTPUT_DIV_4) || \ + ((x) == CMU_OUTPUT_DIV_8) || \ + ((x) == CMU_OUTPUT_DIV_16) || \ + ((x) == CMU_OUTPUT_DIV_32) || \ + ((x) == CMU_OUTPUT_DIV_64) || \ + ((x) == CMU_OUTPUT_DIV_128)) +#define IS_CMU_OUTPUT_LOW_SEL(x) (((x) == CMU_OUTPUT_LOW_SEL_LOSC) || \ + ((x) == CMU_OUTPUT_LOW_SEL_LRC ) || \ + ((x) == CMU_OUTPUT_LOW_SEL_LOSM) || \ + ((x) == CMU_OUTPUT_LOW_SEL_BUZZ) || \ + ((x) == CMU_OUTPUT_LOW_SEL_ULRC)) +#define IS_CMU_AUTO_CALIB_INPUT(x) (((x) == CMU_AUTO_CALIB_INPUT_LOSE) || \ + ((x) == CMU_AUTO_CALIB_INPUT_HOSE)) +#define IS_CMU_AUTO_CALIB_OUTPUT(x) (((x) == CMU_AUTO_CALIB_OUTPUT_24M) || \ + ((x) == CMU_AUTO_CALIB_OUTPUT_2M)) +#define IS_CMU_BUZZ_DIV(x) (((x) == CMU_BUZZ_DIV_2) || \ + ((x) == CMU_BUZZ_DIV_4) || \ + ((x) == CMU_BUZZ_DIV_8) || \ + ((x) == CMU_BUZZ_DIV_16) || \ + ((x) == CMU_BUZZ_DIV_32) || \ + ((x) == CMU_BUZZ_DIV_64) || \ + ((x) == CMU_BUZZ_DIV_128) || \ + ((x) == CMU_BUZZ_DIV_256)) +#define IS_CMU_LP_PERH_CLOCK_SEL(x) (((x) == CMU_LP_PERH_CLOCK_SEL_PCLK2) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_PLL1) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_PLL2) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_HRC) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_HOSC) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_LRC) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_LOSC) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_ULRC) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_HRC_1M) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_HOSC_1M) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_LOSM) || \ + ((x) == CMU_LP_PERH_CLOCK_SEL_HOSM)) +#define IS_CMU_LCD_CLOCK_SEL(x) (((x) == CMU_LCD_SEL_LOSM) || \ + ((x) == CMU_LCD_SEL_LOSC) || \ + ((x) == CMU_LCD_SEL_LRC) || \ + ((x) == CMU_LCD_SEL_ULRC) || \ + ((x) == CMU_LCD_SEL_HRC_1M) || \ + ((x) == CMU_LCD_SEL_HOSC_1M)) +#define IS_CMU_PERH(x) (((x) == CMU_PERH_GPIO) || \ + ((x) == CMU_PERH_CRC) || \ + ((x) == CMU_PERH_CALC) || \ + ((x) == CMU_PERH_CRYPT) || \ + ((x) == CMU_PERH_TRNG) || \ + ((x) == CMU_PERH_PIS) || \ + ((x) == CMU_PERH_TIMER0) || \ + ((x) == CMU_PERH_TIMER1) || \ + ((x) == CMU_PERH_TIMER2) || \ + ((x) == CMU_PERH_TIMER3) || \ + ((x) == CMU_PERH_TIMER4) || \ + ((x) == CMU_PERH_TIMER5) || \ + ((x) == CMU_PERH_TIMER6) || \ + ((x) == CMU_PERH_TIMER7) || \ + ((x) == CMU_PERH_UART0) || \ + ((x) == CMU_PERH_UART1) || \ + ((x) == CMU_PERH_UART2) || \ + ((x) == CMU_PERH_UART3) || \ + ((x) == CMU_PERH_USART0) || \ + ((x) == CMU_PERH_USART1) || \ + ((x) == CMU_PERH_SPI0) || \ + ((x) == CMU_PERH_SPI1) || \ + ((x) == CMU_PERH_SPI2) || \ + ((x) == CMU_PERH_I2C0) || \ + ((x) == CMU_PERH_I2C1) || \ + ((x) == CMU_PERH_CAN) || \ + ((x) == CMU_PERH_LPTIM0) || \ + ((x) == CMU_PERH_LPUART0) || \ + ((x) == CMU_PERH_ADC0) || \ + ((x) == CMU_PERH_ADC1) || \ + ((x) == CMU_PERH_ACMP0) || \ + ((x) == CMU_PERH_ACMP1) || \ + ((x) == CMU_PERH_OPAMP) || \ + ((x) == CMU_PERH_DAC0) || \ + ((x) == CMU_PERH_WWDT) || \ + ((x) == CMU_PERH_LCD) || \ + ((x) == CMU_PERH_IWDT) || \ + ((x) == CMU_PERH_RTC) || \ + ((x) == CMU_PERH_TSENSE) || \ + ((x) == CMU_PERH_BKPC) || \ + ((x) == CMU_PERH_BKRPAM ) || \ + ((x) == CMU_PERH_DBGC) || \ + ((x) == CMU_PERH_ALL)) +#define IS_CMU_CLOCK_STATE(x) (((x) == CMU_CLOCK_STATE_HOSCACT) || \ + ((x) == CMU_CLOCK_STATE_LOSCACT) || \ + ((x) == CMU_CLOCK_STATE_HRCACT) || \ + ((x) == CMU_CLOCK_STATE_LRCACT) || \ + ((x) == CMU_CLOCK_STATE_ULRCACT) || \ + ((x) == CMU_CLOCK_STATE_PLLACT) || \ + ((x) == CMU_CLOCK_STATE_HOSCRDY) || \ + ((x) == CMU_CLOCK_STATE_LOSCRDY) || \ + ((x) == CMU_CLOCK_STATE_HRCRDY) || \ + ((x) == CMU_CLOCK_STATE_LRCRDY) || \ + ((x) == CMU_CLOCK_STATE_PLLRDY)) +/** + * @} + */ + +/** @addtogroup CMU_Public_Functions + * @{ + */ +/** @addtogroup CMU_Public_Functions_Group1 + * @{ + */ +/* System clock configure */ +ald_status_t ald_cmu_clock_config_default(void); +ald_status_t ald_cmu_clock_config(cmu_clock_t clk, uint32_t clock); +void ald_cmu_pll1_config(cmu_pll1_input_t input, cmu_pll1_output_t output); +uint32_t ald_cmu_get_clock(void); +int32_t ald_cmu_auto_calib_clock(cmu_auto_calib_input_t input, cmu_auto_calib_output_t freq); +/** + * @} + */ + +/** @addtogroup CMU_Public_Functions_Group2 + * @{ + */ +/* BUS division control */ +void ald_cmu_div_config(cmu_bus_t bus, cmu_div_t div); +uint32_t ald_cmu_get_hclk1_clock(void); +uint32_t ald_cmu_get_sys_clock(void); +uint32_t ald_cmu_get_pclk1_clock(void); +uint32_t ald_cmu_get_pclk2_clock(void); +/** + * @} + */ + +/** @addtogroup CMU_Public_Functions_Group3 + * @{ + */ +/* Clock safe configure */ +void ald_cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status); +void ald_cmu_losc_safe_config(type_func_t status); +void ald_cmu_pll_safe_config(type_func_t status); +flag_status_t ald_cmu_get_clock_state(cmu_clock_state_t sr); +void ald_cmu_irq_handler(void); +void ald_cmu_irq_cbk(cmu_security_t se); +/** + * @} + */ + +/** @addtogroup CMU_Public_Functions_Group4 + * @{ + */ +/* Clock output configure */ +void ald_cmu_output_high_clock_config(cmu_output_high_sel_t sel, + cmu_output_high_div_t div, type_func_t status); +void ald_cmu_output_low_clock_config(cmu_output_low_sel_t sel, type_func_t status); +/** + * @} + */ + +/** @addtogroup CMU_Public_Functions_Group5 + * @{ + */ +/* Peripheral Clock configure */ +void ald_cmu_buzz_config(cmu_buzz_div_t div, uint16_t dat, type_func_t status); +void ald_cmu_lptim0_clock_select(cmu_lp_perh_clock_sel_t clock); +void ald_cmu_lpuart0_clock_select(cmu_lp_perh_clock_sel_t clock); +void ald_cmu_lcd_clock_select(cmu_lcd_clock_sel_t clock); +void ald_cmu_perh_clock_config(cmu_perh_t perh, type_func_t status); +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_CMU_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_conf.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_conf.h similarity index 100% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_conf.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_conf.h diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crc.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crc.h similarity index 37% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crc.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crc.h index 5562db71f4..e3281dc166 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crc.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crc.h @@ -41,10 +41,10 @@ extern "C" { */ typedef enum { - CRC_MODE_CCITT = 0, /**< Ccitt */ - CRC_MODE_8 = 1, /**< Crc8 */ - CRC_MODE_16 = 2, /**< Crc16 */ - CRC_MODE_32 = 3, /**< Crc32 */ + CRC_MODE_CCITT = 0, /**< Ccitt */ + CRC_MODE_8 = 1, /**< Crc8 */ + CRC_MODE_16 = 2, /**< Crc16 */ + CRC_MODE_32 = 3, /**< Crc32 */ } crc_mode_t; /** @@ -52,10 +52,10 @@ typedef enum */ typedef enum { - CRC_LEN_AUTO = 0, /**< Auto */ - CRC_DATASIZE_8 = 1, /**< Byte */ - CRC_DATASIZE_16 = 2, /**< Half word */ - CRC_DATASIZE_32 = 3, /**< Word */ + CRC_LEN_AUTO = 0, /**< Auto */ + CRC_DATASIZE_8 = 1, /**< Byte */ + CRC_DATASIZE_16 = 2, /**< Half word */ + CRC_DATASIZE_32 = 3, /**< Word */ } crc_datasize_t; /** @@ -63,8 +63,8 @@ typedef enum */ typedef enum { - CRC_WERR_NO = 0, /**< No error */ - CRC_WERR_ERR = 1, /**< Error */ + CRC_WERR_NO = 0, /**< No error */ + CRC_WERR_ERR = 1, /**< Error */ } crc_werr_t; /** @@ -72,10 +72,10 @@ typedef enum */ typedef enum { - CRC_STATE_RESET = 0x0, /**< Peripheral is not initialized */ - CRC_STATE_READY = 0x1, /**< Peripheral Initialized and ready for use */ - CRC_STATE_BUSY = 0x2, /**< An internal process is ongoing */ - CRC_STATE_ERROR = 0x4, /**< Error */ + CRC_STATE_RESET = 0x0, /**< Peripheral is not initialized */ + CRC_STATE_READY = 0x1, /**< Peripheral Initialized and ready for use */ + CRC_STATE_BUSY = 0x2, /**< An internal process is ongoing */ + CRC_STATE_ERROR = 0x4, /**< Error */ } crc_state_t; /** @@ -83,12 +83,12 @@ typedef enum */ typedef struct { - crc_mode_t mode; /**< CRC mode */ - type_func_t data_rev; /**< CRC data reverse or no */ - type_func_t data_inv; /**< CRC data inverse or no */ - type_func_t chs_rev; /**< CRC check sum reverse or no */ - type_func_t chs_inv; /**< CRC check sum inverse or no */ - uint32_t seed; /**< CRC seed */ + crc_mode_t mode; /**< CRC mode */ + type_func_t data_rev; /**< CRC data reverse or no */ + type_func_t data_inv; /**< CRC data inverse or no */ + type_func_t chs_rev; /**< CRC check sum reverse or no */ + type_func_t chs_inv; /**< CRC check sum inverse or no */ + uint32_t seed; /**< CRC seed */ } crc_init_t; /** @@ -96,18 +96,18 @@ typedef struct */ typedef struct crc_handle_s { - CRC_TypeDef *perh; /**< Register base address */ - crc_init_t init; /**< CRC required parameters */ - uint8_t *cal_buf; /**< The pointer of preparing buffer */ - uint32_t *cal_res; /**< The pointer of result */ + CRC_TypeDef *perh; /**< Register base address */ + crc_init_t init; /**< CRC required parameters */ + uint8_t *cal_buf; /**< The pointer of preparing buffer */ + uint32_t *cal_res; /**< The pointer of result */ #ifdef ALD_DMA - dma_handle_t hdma; /**< CRC DMA handle parameters */ + dma_handle_t hdma; /**< CRC DMA handle parameters */ #endif - lock_state_t lock; /**< Locking object */ - crc_state_t state; /**< CRC operation state */ + lock_state_t lock; /**< Locking object */ + crc_state_t state; /**< CRC operation state */ - void (*cal_cplt_cbk)(struct crc_handle_s *arg); /**< Calculate completed callback */ - void (*err_cplt_cbk)(struct crc_handle_s *arg); /**< Calculate error callback */ + void (*cal_cplt_cbk)(struct crc_handle_s *arg); /**< Calculate completed callback */ + void (*err_cplt_cbk)(struct crc_handle_s *arg); /**< Calculate error callback */ } crc_handle_t; /** * @} @@ -116,12 +116,12 @@ typedef struct crc_handle_s /** @defgroup CRC_Public_Macros CRC Public Macros * @{ */ -#define CRC_ENABLE(handle) (SET_BIT((handle)->perh->CR, CRC_CR_EN_MSK)) -#define CRC_DISABLE(handle) (CLEAR_BIT((handle)->perh->CR, CRC_CR_EN_MSK)) -#define CRC_RESET(handle) (SET_BIT((handle)->perh->CR, CRC_CR_RST_MSK)) -#define CRC_DMA_ENABLE(handle) (SET_BIT((handle)->perh->CR, CRC_CR_DMAEN_MSK)) -#define CRC_DMA_DISABLE(handle) (CLEAR_BIT((handle)->perh->CR, CRC_CR_DMAEN_MSK)) -#define CRC_CLEAR_ERROR_FLAG(handle) (SET_BIT((handle)->perh->CR, CRC_CR_WERR_MSK)) +#define CRC_ENABLE(handle) (SET_BIT((handle)->perh->CR, CRC_CR_EN_MSK)) +#define CRC_DISABLE(handle) (CLEAR_BIT((handle)->perh->CR, CRC_CR_EN_MSK)) +#define CRC_RESET(handle) (SET_BIT((handle)->perh->CR, CRC_CR_RST_MSK)) +#define CRC_DMA_ENABLE(handle) (SET_BIT((handle)->perh->CR, CRC_CR_DMAEN_MSK)) +#define CRC_DMA_DISABLE(handle) (CLEAR_BIT((handle)->perh->CR, CRC_CR_DMAEN_MSK)) +#define CRC_CLEAR_ERROR_FLAG(handle) (SET_BIT((handle)->perh->CR, CRC_CR_WERR_MSK)) /** * @} */ @@ -129,11 +129,11 @@ typedef struct crc_handle_s /** @defgroup CRC_Private_Macros CRC Private Macros * @{ */ -#define IS_CRC(x) ((x) == CRC) -#define IS_CRC_MODE(x) (((x) == CRC_MODE_CCITT) || \ - ((x) == CRC_MODE_8) || \ - ((x) == CRC_MODE_16) || \ - ((x) == CRC_MODE_32)) +#define IS_CRC(x) ((x) == CRC) +#define IS_CRC_MODE(x) (((x) == CRC_MODE_CCITT) || \ + ((x) == CRC_MODE_8) || \ + ((x) == CRC_MODE_16) || \ + ((x) == CRC_MODE_32)) /** * @} */ @@ -145,7 +145,8 @@ typedef struct crc_handle_s /** @addtogroup CRC_Public_Functions_Group1 * @{ */ -ald_status_t crc_init(crc_handle_t *hperh); +ald_status_t ald_crc_init(crc_handle_t *hperh); +void ald_crc_reset(crc_handle_t *hperh); /** * @} */ @@ -153,7 +154,9 @@ ald_status_t crc_init(crc_handle_t *hperh); /** @addtogroup CRC_Public_Functions_Group2 * @{ */ -uint32_t crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size); +uint32_t ald_crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size); +uint32_t ald_crc_calculate_halfword(crc_handle_t *hperh, uint16_t *buf, uint32_t size); +uint32_t ald_crc_calculate_word(crc_handle_t *hperh, uint32_t *buf, uint32_t size); /** * @} */ @@ -162,10 +165,12 @@ uint32_t crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size); /** @addtogroup CRC_Public_Functions_Group3 * @{ */ -ald_status_t crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *res, uint16_t size, uint8_t channel); -ald_status_t crc_dma_pause(crc_handle_t *hperh); -ald_status_t crc_dma_resume(crc_handle_t *hperh); -ald_status_t crc_dma_stop(crc_handle_t *hperh); +ald_status_t ald_crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *res, uint16_t size, uint8_t channel); +ald_status_t ald_crc_calculate_halfword_by_dma(crc_handle_t *hperh, uint16_t *buf, uint32_t *res, uint16_t size, uint8_t channel); +ald_status_t ald_crc_calculate_word_by_dma(crc_handle_t *hperh, uint32_t *buf, uint32_t *res, uint16_t size, uint8_t channel); +ald_status_t ald_crc_dma_pause(crc_handle_t *hperh); +ald_status_t ald_crc_dma_resume(crc_handle_t *hperh); +ald_status_t ald_crc_dma_stop(crc_handle_t *hperh); /** * @} */ @@ -173,7 +178,7 @@ ald_status_t crc_dma_stop(crc_handle_t *hperh); /** @addtogroup CRC_Public_Functions_Group4 * @{ */ -crc_state_t crc_get_state(crc_handle_t *hperh); +crc_state_t ald_crc_get_state(crc_handle_t *hperh); /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crypt.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crypt.h similarity index 30% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crypt.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crypt.h index f3a5ebaeb5..18340558a2 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crypt.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_crypt.h @@ -41,8 +41,8 @@ extern "C" { */ typedef enum { - CRYPT_DECRYPT = 0, /**< Decrypt */ - CRYPT_ENCRYPT = 1, /**< Encrypt */ + CRYPT_DECRYPT = 0, /**< Decrypt */ + CRYPT_ENCRYPT = 1, /**< Encrypt */ } crypt_encs_t; /** @@ -50,9 +50,9 @@ typedef enum */ typedef enum { - CRYPT_MODE_ECB = 0, /**< ECB */ - CRYPT_MODE_CBC = 1, /**< CBC */ - CRYPT_MODE_CTR = 2, /**< CTR */ + CRYPT_MODE_ECB = 0, /**< ECB */ + CRYPT_MODE_CBC = 1, /**< CBC */ + CRYPT_MODE_CTR = 2, /**< CTR */ } crypt_mode_t; /** @@ -60,10 +60,10 @@ typedef enum */ typedef enum { - CRYPT_DATA_CHANGE_NO = 0, /**< No exchange */ - CRYPT_DATA_CHANGE_16 = 1, /**< 16bit exchange */ - CRYPT_DATA_CHANGE_8 = 2, /**< 8bit exchange */ - CRYPT_DATA_CHANGE_1 = 3, /**< 1bit exchange */ + CRYPT_DATA_CHANGE_NO = 0, /**< No exchange */ + CRYPT_DATA_CHANGE_16 = 1, /**< 16bit exchange */ + CRYPT_DATA_CHANGE_8 = 2, /**< 8bit exchange */ + CRYPT_DATA_CHANGE_1 = 3, /**< 1bit exchange */ } crypt_datatype_t; /** @@ -71,7 +71,7 @@ typedef enum */ typedef enum { - CRYPT_IT_IT = 0x80, /**< Interrupt */ + CRYPT_IT_IT = 0x80, /**< Interrupt */ } crypt_it_t; /** @@ -79,8 +79,8 @@ typedef enum */ typedef enum { - CRYPT_FLAG_AESIF = 0x1, /**< Aes flag */ - CRYPT_FLAG_DONE = 0x100, /**< Complete flag */ + CRYPT_FLAG_AESIF = 0x1, /**< Aes flag */ + CRYPT_FLAG_DONE = 0x100, /**< Complete flag */ } crypt_flag_t; /** @@ -88,10 +88,10 @@ typedef enum */ typedef enum { - CRYPT_STATE_RESET = 0x0, /**< Peripheral is not initialized */ - CRYPT_STATE_READY = 0x1, /**< Peripheral Initialized and ready for use */ - CRYPT_STATE_BUSY = 0x2, /**< An internal process is ongoing */ - CRYPT_STATE_ERROR = 0x4, /**< Error */ + CRYPT_STATE_RESET = 0x0, /**< Peripheral is not initialized */ + CRYPT_STATE_READY = 0x1, /**< Peripheral Initialized and ready for use */ + CRYPT_STATE_BUSY = 0x2, /**< An internal process is ongoing */ + CRYPT_STATE_ERROR = 0x4, /**< Error */ } crypt_state_t; /** @@ -99,10 +99,10 @@ typedef enum */ typedef enum { - DATA_32_BIT = 0, /**< 32 bit data,don't swap */ - DATA_16_BIT = 1, /**< 16 bit data,swap */ - DATA_8_BIT = 2, /**< 8 bit data,swap */ - DATA_1_BIT = 3, /**< 1 bit data, swap */ + DATA_32_BIT = 0, /**< 32 bit data,don't swap */ + DATA_16_BIT = 1, /**< 16 bit data,swap */ + DATA_8_BIT = 2, /**< 8 bit data,swap */ + DATA_1_BIT = 3, /**< 1 bit data, swap */ } crypt_data_t; /** @@ -110,8 +110,8 @@ typedef enum */ typedef struct { - crypt_mode_t mode; /**< Crypt mode */ - crypt_data_t type; /**< Data type select */ + crypt_mode_t mode; /**< Crypt mode */ + crypt_data_t type; /**< Data type select */ } crypt_init_t; /** @@ -119,25 +119,25 @@ typedef struct */ typedef struct crypt_handle_s { - CRYPT_TypeDef *perh; /**< Register base address */ - crypt_init_t init; /**< CRYPT required parameters */ + CRYPT_TypeDef *perh; /**< Register base address */ + crypt_init_t init; /**< CRYPT required parameters */ #ifdef ALD_DMA - dma_handle_t hdma_m2p; /**< CRYPT DMA handle parameters memory to crypt module */ - dma_handle_t hdma_p2m; /**< CRYPT DMA handle parameters crypt module to memory */ + dma_handle_t hdma_m2p; /**< CRYPT DMA handle parameters memory to crypt module */ + dma_handle_t hdma_p2m; /**< CRYPT DMA handle parameters crypt module to memory */ #endif - uint8_t *plain_text; /**< Pointer to plain text */ - uint8_t *cipher_text; /**< Pointer to cipher text */ - uint32_t size; /**< The size of crypt data buf */ - uint32_t count; /**< The count of crypt data buf */ - uint32_t step; /**< The step of once crypt 4(aes) */ - uint32_t dir; /**< ENCRYPT or DECRYPT */ - uint32_t iv[4]; /**< The iv of crypt */ - uint32_t key[4]; /**< The key of crypt */ - lock_state_t lock; /**< Locking object */ - crypt_state_t state; /**< CRYPT operation state */ + uint8_t *plain_text; /**< Pointer to plain text */ + uint8_t *cipher_text; /**< Pointer to cipher text */ + uint32_t size; /**< The size of crypt data buf */ + uint32_t count; /**< The count of crypt data buf */ + uint32_t step; /**< The step of once crypt 4(aes) */ + uint32_t dir; /**< ENCRYPT or DECRYPT */ + uint32_t iv[4]; /**< The iv of crypt */ + uint32_t key[4]; /**< The key of crypt */ + lock_state_t lock; /**< Locking object */ + crypt_state_t state; /**< CRYPT operation state */ - void (*crypt_cplt_cbk)(struct crypt_handle_s *arg); /**< Crypt completed callback */ - void (*err_cplt_cbk)(struct crypt_handle_s *arg); /**< Crypt error callback */ + void (*crypt_cplt_cbk)(struct crypt_handle_s *arg); /**< Crypt completed callback */ + void (*err_cplt_cbk)(struct crypt_handle_s *arg); /**< Crypt error callback */ } crypt_handle_t; /** * @} @@ -146,19 +146,19 @@ typedef struct crypt_handle_s /** @defgroup CRYPT_Public_Macros CRYPT Public Macros * @{ */ -#define CRYPT_GO(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_GO_MSK)) -#define CRYPT_FIFOEN_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_FIFOEN_MSK)) -#define CRYPT_FIFOEN_DISABLE(handle) (CLEAR_BIT(handle)->perh->CON, CRYPT_CON_FIFOEN_MSK)) -#define CRYPT_IVEN_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_IVEN_MSK)) -#define CRYPT_IVEN_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_IVEN_MSK)) -#define CRYPT_IE_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_IE_MSK)) -#define CRYPT_IE_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_IE_MSK)) -#define CRYPT_DMA_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_DMAEN_MSK)) -#define CRYPT_DMA_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_DMAEN_MSK)) -#define CRYPT_SETDIR(handle, dir) do {(handle)->perh->CON &= ~(0x1 << CRYPT_CON_ENCS_POS); \ - (handle)->perh->CON |= (dir << CRYPT_CON_ENCS_POS);} while (0) +#define CRYPT_GO(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_GO_MSK)) +#define CRYPT_FIFOEN_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_FIFOEN_MSK)) +#define CRYPT_FIFOEN_DISABLE(handle) (CLEAR_BIT(handle)->perh->CON, CRYPT_CON_FIFOEN_MSK)) +#define CRYPT_IVEN_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_IVEN_MSK)) +#define CRYPT_IVEN_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_IVEN_MSK)) +#define CRYPT_IE_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_IE_MSK)) +#define CRYPT_IE_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_IE_MSK)) +#define CRYPT_DMA_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_DMAEN_MSK)) +#define CRYPT_DMA_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_DMAEN_MSK)) +#define CRYPT_SETDIR(handle, dir) do {(handle)->perh->CON &= ~(0x1 << CRYPT_CON_ENCS_POS); \ + (handle)->perh->CON |= (dir << CRYPT_CON_ENCS_POS);} while (0) #define CRYPT_WRITE_FIFO(handle, data) ((handle)->perh->FIFO = (data)) -#define CRYPT_READ_FIFO(handle) ((handle)->perh->FIFO) +#define CRYPT_READ_FIFO(handle) ((handle)->perh->FIFO) /** * @} */ @@ -166,15 +166,15 @@ typedef struct crypt_handle_s /** @defgroup CRYPT_Private_Macros CRYPT Private Macros * @{ */ -#define IS_CRYPT(x) ((x) == CRYPT) -#define IS_CRYPT_MODE(x) (((x) == CRYPT_MODE_ECB) || \ - ((x) == CRYPT_MODE_CBC) || \ - ((x) == CRYPT_MODE_CTR)) -#define IS_CRYPT_IT(x) ((x) == CRYPT_IT_IT) -#define IS_CRYPT_FLAG(x) (((x) == CRYPT_FLAG_AESIF) || \ - ((x) == CRYPT_FLAG_DONE)) -#define IS_CRYPT_IV_LEN(x) (((x) == IV_2_LEN) || \ - ((x) == IV_4_LEN)) +#define IS_CRYPT(x) ((x) == CRYPT) +#define IS_CRYPT_MODE(x) (((x) == CRYPT_MODE_ECB) || \ + ((x) == CRYPT_MODE_CBC) || \ + ((x) == CRYPT_MODE_CTR)) +#define IS_CRYPT_IT(x) ((x) == CRYPT_IT_IT) +#define IS_CRYPT_FLAG(x) (((x) == CRYPT_FLAG_AESIF) || \ + ((x) == CRYPT_FLAG_DONE)) +#define IS_CRYPT_IV_LEN(x) (((x) == IV_2_LEN) || \ + ((x) == IV_4_LEN)) /** * @} */ @@ -186,11 +186,11 @@ typedef struct crypt_handle_s /** @addtogroup CRYPT_Public_Functions_Group1 * @{ */ -ald_status_t crypt_init(crypt_handle_t *hperh); -ald_status_t crypt_write_key(crypt_handle_t *hperh, uint32_t *key); -ald_status_t crypt_read_key(crypt_handle_t *hperh, uint32_t *key); -ald_status_t crypt_write_ivr(crypt_handle_t *hperh, uint32_t *iv); -ald_status_t crypt_read_ivr(crypt_handle_t *hperh, uint32_t *iv); +ald_status_t ald_crypt_init(crypt_handle_t *hperh); +ald_status_t ald_crypt_write_key(crypt_handle_t *hperh, uint32_t *key); +ald_status_t ald_crypt_read_key(crypt_handle_t *hperh, uint32_t *key); +ald_status_t ald_crypt_write_ivr(crypt_handle_t *hperh, uint32_t *iv); +ald_status_t ald_crypt_read_ivr(crypt_handle_t *hperh, uint32_t *iv); /** * @} */ @@ -198,16 +198,16 @@ ald_status_t crypt_read_ivr(crypt_handle_t *hperh, uint32_t *iv); /** @addtogroup CRYPT_Public_Functions_Group2 * @{ */ -ald_status_t crypt_encrypt(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size); -ald_status_t crypt_decrypt(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size); -ald_status_t crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint32_t size, uint8_t *aadata, uint32_t alen, uint8_t *tag); -ald_status_t crypt_encrypt_by_it(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size); -ald_status_t crypt_decrypt_by_it(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size); +ald_status_t ald_crypt_encrypt(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size); +ald_status_t ald_crypt_decrypt(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size); +ald_status_t ald_crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint32_t size, uint8_t *aadata, uint32_t alen, uint8_t *tag); +ald_status_t ald_crypt_encrypt_by_it(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size); +ald_status_t ald_crypt_decrypt_by_it(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size); #ifdef ALD_DMA -ald_status_t crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, - uint8_t *cipher_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m); -ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, - uint8_t *plain_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m); +ald_status_t ald_crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, + uint8_t *cipher_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m); +ald_status_t ald_crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, + uint8_t *plain_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m); #endif /** * @} @@ -217,11 +217,11 @@ ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, * @{ */ #ifdef ALD_DMA -ald_status_t crypt_dma_pause(crypt_handle_t *hperh); -ald_status_t crypt_dma_resume(crypt_handle_t *hperh); -ald_status_t crypt_dma_stop(crypt_handle_t *hperh); +ald_status_t ald_crypt_dma_pause(crypt_handle_t *hperh); +ald_status_t ald_crypt_dma_resume(crypt_handle_t *hperh); +ald_status_t ald_crypt_dma_stop(crypt_handle_t *hperh); #endif -void crypt_irq_handle(crypt_handle_t *hperh); +void ald_crypt_irq_handler(crypt_handle_t *hperh); /** * @} */ @@ -229,10 +229,10 @@ void crypt_irq_handle(crypt_handle_t *hperh); /** @addtogroup CRYPT_Public_Functions_Group4 * @{ */ -void crypt_interrupt_config(crypt_handle_t *hperh, crypt_it_t it, type_func_t state); -flag_status_t crypt_get_flag_status(crypt_handle_t *hperh, crypt_flag_t flag); -void crypt_clear_flag_status(crypt_handle_t *hperh, crypt_flag_t flag); -it_status_t crypt_get_it_status(crypt_handle_t *hperh, crypt_it_t it); +void ald_crypt_interrupt_config(crypt_handle_t *hperh, crypt_it_t it, type_func_t state); +flag_status_t ald_crypt_get_flag_status(crypt_handle_t *hperh, crypt_flag_t flag); +void ald_crypt_clear_flag_status(crypt_handle_t *hperh, crypt_flag_t flag); +it_status_t ald_crypt_get_it_status(crypt_handle_t *hperh, crypt_it_t it); /** * @} */ @@ -240,7 +240,7 @@ it_status_t crypt_get_it_status(crypt_handle_t *hperh, crypt_it_t it); /** @addtogroup CRYPT_Public_Functions_Group5 * @{ */ -crypt_state_t crypt_get_state(crypt_handle_t *hperh); +crypt_state_t ald_crypt_get_state(crypt_handle_t *hperh); /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dbgc.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dbgc.h similarity index 58% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dbgc.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dbgc.h index 293997c04e..31b8dc6ca4 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dbgc.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dbgc.h @@ -43,10 +43,10 @@ extern "C" { */ typedef enum { - DEBC_MODE_SLEEP = (1u << 0), /**< Sleep mode */ - DEBC_MODE_STOP1 = (1u << 1), /**< STOP1 mode */ - DEBC_MODE_STOP2 = (1u << 2), /**< STOP2 mode */ - DEBC_MODE_STANDBY = (1u << 3), /**< Standby mode */ + DEBC_MODE_SLEEP = (1u << 0), /**< Sleep mode */ + DEBC_MODE_STOP1 = (1u << 1), /**< STOP1 mode */ + DEBC_MODE_STOP2 = (1u << 2), /**< STOP2 mode */ + DEBC_MODE_STANDBY = (1u << 3), /**< Standby mode */ } dbgc_mode_t; /** @@ -54,21 +54,21 @@ typedef enum */ typedef enum { - DEBC_PERH_TIMER0 = (1u << 0), /**< AD16C4T0 */ - DEBC_PERH_TIMER1 = (1u << 1), /**< BS16T0 */ - DEBC_PERH_TIMER2 = (1u << 2), /**< GP16C2T0 */ - DEBC_PERH_TIMER3 = (1u << 3), /**< GP16C2T1 */ - DEBC_PERH_TIMER4 = (1u << 4), /**< BS16T1 */ - DEBC_PERH_TIMER5 = (1u << 5), /**< BS16T2 */ - DEBC_PERH_TIMER6 = (1u << 6), /**< GP16C4T0 */ - DEBC_PERH_TIMER7 = (1u << 7), /**< BS16T3 */ - DEBC_PERH_I2C0 = (1u << 8), /**< I2C0 SMBUS */ - DEBC_PERH_I2C1 = (1u << 9), /**< I2C1 SMBUS */ - DEBC_PERH_CAN = (1u << 12), /**< CAN */ - DEBC_PERH_LPTIM0 = (1u << 0) | (1u << 16), /**< LPTIM0 */ - DEBC_PERH_IWDT = (1u << 8) | (1u << 16), /**< IWDT */ - DEBC_PERH_WWDT = (1u << 9) | (1u << 16), /**< WWDT */ - DEBC_PERH_RTC = (1u << 10) | (1u << 16), /**< RTC */ + DEBC_PERH_TIMER0 = (1u << 0), /**< AD16C4T0 */ + DEBC_PERH_TIMER1 = (1u << 1), /**< BS16T0 */ + DEBC_PERH_TIMER2 = (1u << 2), /**< GP16C2T0 */ + DEBC_PERH_TIMER3 = (1u << 3), /**< GP16C2T1 */ + DEBC_PERH_TIMER4 = (1u << 4), /**< BS16T1 */ + DEBC_PERH_TIMER5 = (1u << 5), /**< BS16T2 */ + DEBC_PERH_TIMER6 = (1u << 6), /**< GP16C4T0 */ + DEBC_PERH_TIMER7 = (1u << 7), /**< BS16T3 */ + DEBC_PERH_I2C0 = (1u << 8), /**< I2C0 SMBUS */ + DEBC_PERH_I2C1 = (1u << 9), /**< I2C1 SMBUS */ + DEBC_PERH_CAN = (1u << 12), /**< CAN */ + DEBC_PERH_LPTIM0 = (1u << 0) | (1u << 16), /**< LPTIM0 */ + DEBC_PERH_IWDT = (1u << 8) | (1u << 16), /**< IWDT */ + DEBC_PERH_WWDT = (1u << 9) | (1u << 16), /**< WWDT */ + DEBC_PERH_RTC = (1u << 10) | (1u << 16), /**< RTC */ } dbgc_perh_t; /** * @} @@ -81,7 +81,7 @@ typedef enum * @brief Gets version. * @retval Version */ -__INLINE uint32_t dbgc_get_rev_id(void) +__INLINE uint32_t ald_dbgc_get_rev_id(void) { return (DBGC->IDCODE >> 16); } @@ -90,7 +90,7 @@ __INLINE uint32_t dbgc_get_rev_id(void) * @brief Gets core id. * @retval Core id */ -__INLINE uint32_t dbgc_get_core_id(void) +__INLINE uint32_t ald_dbgc_get_core_id(void) { return (DBGC->IDCODE >> 12) & 0xF; } @@ -99,7 +99,7 @@ __INLINE uint32_t dbgc_get_core_id(void) * @brief Gets device id * @retval device id */ -__INLINE uint32_t dbgc_get_device_id(void) +__INLINE uint32_t ald_dbgc_get_device_id(void) { return DBGC->IDCODE & 0xFFF; } @@ -110,7 +110,7 @@ __INLINE uint32_t dbgc_get_device_id(void) * @param state: ENABLE/DISABLE * @retval None */ -__INLINE void dbgc_mode_config(dbgc_mode_t mode, type_func_t state) +__INLINE void ald_dbgc_mode_config(dbgc_mode_t mode, type_func_t state) { if (state) SET_BIT(DBGC->CR, mode); @@ -124,7 +124,7 @@ __INLINE void dbgc_mode_config(dbgc_mode_t mode, type_func_t state) * @param state: ENABLE/DISABLE * @retval None */ -__INLINE void dbgc_perh_config(dbgc_perh_t perh, type_func_t state) +__INLINE void ald_dbgc_perh_config(dbgc_perh_t perh, type_func_t state) { if ((perh >> 16) & 0x1) { diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dma.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dma.h new file mode 100644 index 0000000000..364f9e16cb --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_dma.h @@ -0,0 +1,409 @@ +/** + ********************************************************************************* + * + * @file ald_dma.h + * @brief DMA module Library. + * + * @version V1.0 + * @date 09 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ********************************************************************************* + */ + +#ifndef __ALD_DMA_H__ +#define __ALD_DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup DMA + * @{ + */ + +/** + * @defgroup DMA_Public_Macros DMA Public Macros + * @{ + */ +#define DMA_CH_COUNT 6 +#define DMA_ERR 31 +/** + * @} + */ + +/** + * @defgroup DMA_Public_Types DMA Public Types + * @{ + */ + +/** + * @brief Input source to DMA channel + * @note ES32F065x: + * AD16C4T0--TIMER0 + * GP16C4T0--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + * + * ES32F033x: + * ES32F093x: + * GP16C4T0--TIMER0 + * GP16C4T1--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + */ +typedef enum +{ + DMA_MSEL_NONE = 0x0, /**< NONE */ + DMA_MSEL_GPIO = 0x1, /**< GPIO */ + DMA_MSEL_CRYPT = 0x2, /**< CRYPT */ + DMA_MSEL_ACMP = 0x3, /**< ACMP */ + DMA_MSEL_DAC0 = 0x4, /**< DAC0 */ + DMA_MSEL_ADC0 = 0x6, /**< ADC0 */ + DMA_MSEL_CRC = 0x7, /**< CRC */ + DMA_MSEL_UART0 = 0x8, /**< UART0 */ + DMA_MSEL_UART1 = 0x9, /**< UART1 */ + DMA_MSEL_UART2 = 0xA, /**< UART2 */ + DMA_MSEL_UART3 = 0xB, /**< UART3 */ + DMA_MSEL_USART0 = 0xC, /**< USART0 */ + DMA_MSEL_USART1 = 0xD, /**< USART1 */ + DMA_MSEL_SPI0 = 0xE, /**< SPI0 */ + DMA_MSEL_SPI1 = 0xF, /**< SPI1 */ + DMA_MSEL_I2C0 = 0x10, /**< I2C0 */ + DMA_MSEL_I2C1 = 0x11, /**< I2C1 */ + DMA_MSEL_TIMER0 = 0x12, /**< TIMER0 */ + DMA_MSEL_TIMER1 = 0x13, /**< TIMER1 */ + DMA_MSEL_TIMER2 = 0x14, /**< TIMER2 */ + DMA_MSEL_TIMER3 = 0x15, /**< TIMER3 */ + DMA_MSEL_RTC = 0x16, /**< RTC */ + DMA_MSEL_LPTIM0 = 0x17, /**< LPTIM0 */ + DMA_MSEL_LPUART0 = 0x18, /**< LPUART0 */ + DMA_MSEL_DMA = 0x19, /**< DMA */ + DMA_MSEL_SPI2 = 0x1A, /**< SPI2 */ + DMA_MSEL_TIMER4 = 0x1B, /**< TIMER4 */ + DMA_MSEL_TIMER5 = 0x1C, /**< TIMER5 */ + DMA_MSEL_TIMER6 = 0x1D, /**< TIMER6 */ + DMA_MSEL_TIMER7 = 0x1E, /**< TIMER7 */ + DMA_MSEL_ADC1 = 0x1F, /**< ADC1 */ + DMA_MSEL_PIS = 0x20, /**< PIS */ + DMA_MSEL_TRNG = 0x21, /**< TRNG */ +} dma_msel_t; + +/** + * @brief Input signal to DMA channel + */ +typedef enum +{ + DMA_MSIGSEL_NONE = 0x0, /**< NONE */ + DMA_MSIGSEL_EXTI_0 = 0x0, /**< External interrupt 0 */ + DMA_MSIGSEL_EXTI_1 = 0x1, /**< External interrupt 1 */ + DMA_MSIGSEL_EXTI_2 = 0x2, /**< External interrupt 2 */ + DMA_MSIGSEL_EXTI_3 = 0x3, /**< External interrupt 3 */ + DMA_MSIGSEL_EXTI_4 = 0x4, /**< External interrupt 4 */ + DMA_MSIGSEL_EXTI_5 = 0x5, /**< External interrupt 5 */ + DMA_MSIGSEL_EXTI_6 = 0x6, /**< External interrupt 6 */ + DMA_MSIGSEL_EXTI_7 = 0x7, /**< External interrupt 7 */ + DMA_MSIGSEL_EXTI_8 = 0x8, /**< External interrupt 8 */ + DMA_MSIGSEL_EXTI_9 = 0x9, /**< External interrupt 9 */ + DMA_MSIGSEL_EXTI_10 = 0xA, /**< External interrupt 10 */ + DMA_MSIGSEL_EXTI_11 = 0xB, /**< External interrupt 11 */ + DMA_MSIGSEL_EXTI_12 = 0xC, /**< External interrupt 12 */ + DMA_MSIGSEL_EXTI_13 = 0xD, /**< External interrupt 13 */ + DMA_MSIGSEL_EXTI_14 = 0xE, /**< External interrupt 14 */ + DMA_MSIGSEL_EXTI_15 = 0xF, /**< External interrupt 15 */ + DMA_MSIGSEL_CRYPT_WRITE = 0x0, /**< CRYPT write mode */ + DMA_MSIGSEL_CRYPT_READ = 0x1, /**< CRYPT read mode */ + DMA_MSIGSEL_CALC_WRITE = 0x0, /**< CALC write mode */ + DMA_MSIGSEL_CALC_READ = 0x1, /**< CALC read mode */ + DMA_MSIGSEL_DAC0_CH0 = 0x0, /**< DAC0 channel 0 complete */ + DMA_MSIGSEL_DAC0_CH1 = 0x1, /**< DAC0 channel 1 complete */ + DMA_MSIGSEL_ADC = 0x0, /**< ADC mode */ + DMA_MSIGSEL_UART_TXEMPTY = 0x0, /**< UART transmit */ + DMA_MSIGSEL_UART_RNR = 0x1, /**< UART receive */ + DMA_MSIGSEL_USART_RNR = 0x0, /**< USART reveive */ + DMA_MSIGSEL_USART_TXEMPTY = 0x1, /**< USART transmit */ + DMA_MSIGSEL_SPI_RNR = 0x0, /**< SPI receive */ + DMA_MSIGSEL_SPI_TXEMPTY = 0x1, /**< SPI transmit */ + DMA_MSIGSEL_I2C_RNR = 0x0, /**< I2C receive */ + DMA_MSIGSEL_I2C_TXEMPTY = 0x1, /**< I2C transmit */ + DMA_MSIGSEL_TIMER_CH1 = 0x0, /**< TIM channal 1 */ + DMA_MSIGSEL_TIMER_CH2 = 0x1, /**< TIM channal 2 */ + DMA_MSIGSEL_TIMER_CH3 = 0x2, /**< TIM channal 3 */ + DMA_MSIGSEL_TIMER_CH4 = 0x3, /**< TIM channal 4 */ + DMA_MSIGSEL_TIMER_TRI = 0x4, /**< TIM trigger */ + DMA_MSIGSEL_TIMER_COMP = 0x5, /**< TIM compare */ + DMA_MSIGSEL_TIMER_UPDATE = 0x6, /**< TIM update */ + DMA_MSIGSEL_LPUART_RNR = 0x0, /**< LPUART receive */ + DMA_MSIGSEL_LPUART_TXEMPTY = 0x1, /**< LPUART transmit */ + DMA_MSIGSEL_PIS_CH0 = 0x0, /**< PIS channal 0 */ + DMA_MSIGSEL_PIS_CH1 = 0x1, /**< PIS channal 1 */ + DMA_MSIGSEL_PIS_CH2 = 0x2, /**< PIS channal 2 */ + DMA_MSIGSEL_PIS_CH3 = 0x3, /**< PIS channal 3 */ + DMA_MSIGSEL_PIS_CH4 = 0x4, /**< PIS channal 4 */ + DMA_MSIGSEL_PIS_CH5 = 0x5, /**< PIS channal 5 */ + DMA_MSIGSEL_PIS_CH6 = 0x6, /**< PIS channal 6 */ + DMA_MSIGSEL_PIS_CH7 = 0x7, /**< PIS channal 7 */ + DMA_MSIGSEL_PIS_CH8 = 0x8, /**< PIS channal 8 */ + DMA_MSIGSEL_PIS_CH9 = 0x9, /**< PIS channal 9 */ + DMA_MSIGSEL_PIS_CH10 = 0xA, /**< PIS channal 10 */ + DMA_MSIGSEL_PIS_CH11 = 0xB, /**< PIS channal 11 */ + DMA_MSIGSEL_PIS_CH12 = 0xC, /**< PIS channal 12 */ + DMA_MSIGSEL_PIS_CH13 = 0xD, /**< PIS channal 13 */ + DMA_MSIGSEL_PIS_CH14 = 0xE, /**< PIS channal 14 */ + DMA_MSIGSEL_PIS_CH15 = 0xF, /**< PIS channal 15 */ +} dma_msigsel_t; + +/** + * @brief DMA Descriptor control type + */ +typedef union +{ + struct + { + uint32_t cycle_ctrl : 3; /**< DMA operating mode @ref dma_cycle_ctrl_t */ + uint32_t next_useburst : 1; /**< Uses the alternate data structure when complete a DMA cycle */ + uint32_t n_minus_1 : 10; /**< Represent the total number of DMA transfers that DMA cycle contains. */ + uint32_t R_power : 4; /**< Control how many DMA transfers can occur before re-arbitrates. @ref dma_arbiter_config_t */ + uint32_t src_prot_ctrl : 3; /**< Control the state of HPROT when reads the source data. */ + uint32_t dst_prot_ctrl : 3; /**< Control the state of HPROT when writes the destination data */ + uint32_t src_size : 2; /**< Source data size @ref dma_data_size_t */ + uint32_t src_inc : 2; /**< Control the source address increment. @ref dma_data_inc_t */ + uint32_t dst_size : 2; /**< Destination data size. @ref dma_data_size_t */ + uint32_t dst_inc : 2; /**< Destination address increment. @ref dma_data_inc_t */ + }; + uint32_t word; +} dma_ctrl_t; + +/** + * @brief Channel control data structure + */ +typedef struct +{ + void *src; /**< Source data end pointer */ + void *dst; /**< Destination data end pointer */ + dma_ctrl_t ctrl; /**< Control data configuration @ref dma_ctrl_t */ + uint32_t use; /**< Reserve for user */ +} dma_descriptor_t; + +/** + * @brief data increment + */ +typedef enum +{ + DMA_DATA_INC_BYTE = 0x0, /**< Address increment by byte */ + DMA_DATA_INC_HALFWORD = 0x1, /**< Address increment by halfword */ + DMA_DATA_INC_WORD = 0x2, /**< Address increment by word */ + DMA_DATA_INC_NONE = 0x3, /**< No increment */ +} dma_data_inc_t; + +/** + * @brief Data size + */ +typedef enum +{ + DMA_DATA_SIZE_BYTE = 0x0, /**< Byte */ + DMA_DATA_SIZE_HALFWORD = 0x1, /**< Halfword */ + DMA_DATA_SIZE_WORD = 0x2, /**< Word */ +} dma_data_size_t; + +/** + * @brief The operating mode of the DMA cycle + */ +typedef enum +{ + DMA_CYCLE_CTRL_NONE = 0x0, /**< Stop */ + DMA_CYCLE_CTRL_BASIC = 0x1, /**< Basic */ + DMA_CYCLE_CTRL_AUTO = 0x2, /**< Auto-request */ + DMA_CYCLE_CTRL_PINGPONG = 0x3, /**< Ping-pong */ + DMA_CYCLE_CTRL_MEM_SCATTER_GATHER = 0x4, /**< Memory scatter/gather */ + DMA_CYCLE_CTRL_PER_SCATTER_GATHER = 0x6, /**< Peripheral scatter/gather */ +} dma_cycle_ctrl_t; + +/** + * @brief Control how many DMA transfers can occur + * before the controller re-arbitrates + */ +typedef enum +{ + DMA_R_POWER_1 = 0x0, /**< Arbitrates after each DMA transfer */ + DMA_R_POWER_2 = 0x1, /**< Arbitrates after 2 DMA transfer */ + DMA_R_POWER_4 = 0x2, /**< Arbitrates after 4 DMA transfer */ + DMA_R_POWER_8 = 0x3, /**< Arbitrates after 8 DMA transfer */ + DMA_R_POWER_16 = 0x4, /**< Arbitrates after 16 DMA transfer */ + DMA_R_POWER_32 = 0x5, /**< Arbitrates after 32 DMA transfer */ + DMA_R_POWER_64 = 0x6, /**< Arbitrates after 64 DMA transfer */ + DMA_R_POWER_128 = 0x7, /**< Arbitrates after 128 DMA transfer */ + DMA_R_POWER_256 = 0x8, /**< Arbitrates after 256 DMA transfer */ + DMA_R_POWER_512 = 0x9, /**< Arbitrates after 512 DMA transfer */ + DMA_R_POWER_1024 = 0xA, /**< Arbitrates after 1024 DMA transfer */ +} dma_arbiter_config_t; + +/** + * @brief Callback function pointer and param + */ +typedef struct +{ + void (*cplt_cbk)(void *arg); /**< DMA transfers complete callback */ + void (*err_cbk)(void *arg); /**< DMA occurs error callback */ + void *cplt_arg; /**< The parameter of cplt_cbk() */ + void *err_arg; /**< The parameter of err_cbk() */ +} dma_call_back_t; + +/** + * @brief DMA channal configure structure + */ +typedef struct +{ + void *src; /**< Source data begin pointer */ + void *dst; /**< Destination data begin pointer */ + uint16_t size; /**< The total number of DMA transfers that DMA cycle contains */ + dma_data_size_t data_width; /**< Data width, @ref dma_data_size_t */ + dma_data_inc_t src_inc; /**< Source increment type. @ref dma_data_inc_t */ + dma_data_inc_t dst_inc; /**< Destination increment type. @ref dma_data_inc_t */ + dma_arbiter_config_t R_power; /**< Control how many DMA transfers can occur before re-arbitrates. @ref dma_arbiter_config_t */ + type_func_t primary; /**< Use primary descriptor or alternate descriptor */ + type_func_t burst; /**< Uses the alternate data structure when complete a DMA cycle */ + type_func_t high_prio; /**< High priority or default priority */ + type_func_t iterrupt; /**< Enable/disable interrupt */ + dma_msel_t msel; /**< Input source to DMA channel @ref dma_msel_t */ + dma_msigsel_t msigsel; /**< Input signal to DMA channel @ref dma_msigsel_t */ + uint8_t channel; /**< Channel index */ +} dma_config_t; + +/** + * @brief DMA handle structure definition + */ +typedef struct +{ + DMA_TypeDef *perh; /**< DMA registers base address */ + dma_config_t config; /**< Channel configure structure. @ref dma_config_t */ + void (*cplt_cbk)(void *arg); /**< DMA transfers complete callback */ + void (*err_cbk)(void *arg); /**< DMA bus occurs error callback */ + void *cplt_arg; /**< The parameter of cplt_cbk() */ + void *err_arg; /**< The parameter of err_cbk() */ +} dma_handle_t; +/** + * @} + */ + +/** + * @defgroup DMA_Private_Macros DMA Private Macros + * @{ + */ +#define IS_DMA_MSEL_TYPE(x) ((x) <= DMA_MSEL_TRNG) +#define IS_DMA_MSIGSEL_TYPE(x) ((x) <= 0xF) +#define IS_DMA_DATAINC_TYPE(x) (((x) == DMA_DATA_INC_BYTE) || \ + ((x) == DMA_DATA_INC_HALFWORD) || \ + ((x) == DMA_DATA_INC_WORD) || \ + ((x) == DMA_DATA_INC_NONE)) +#define IS_DMA_DATASIZE_TYPE(x) (((x) == DMA_DATA_SIZE_BYTE) || \ + ((x) == DMA_DATA_SIZE_HALFWORD) || \ + ((x) == DMA_DATA_SIZE_WORD)) +#define IS_CYCLECTRL_TYPE(x) (((x) == DMA_CYCLE_CTRL_NONE) || \ + ((x) == DMA_CYCLE_CTRL_BASIC) || \ + ((x) == DMA_CYCLE_CTRL_AUTO) || \ + ((x) == DMA_CYCLE_CTRL_PINGPONG) || \ + ((x) == DMA_CYCLE_CTRL_MEM_SCATTER_GATHER) || \ + ((x) == DMA_CYCLE_CTRL_PER_SCATTER_GATHER)) +#define IS_DMA_ARBITERCONFIG_TYPE(x) (((x) == DMA_R_POWER_1) || \ + ((x) == DMA_R_POWER_2) || \ + ((x) == DMA_R_POWER_4) || \ + ((x) == DMA_R_POWER_8) || \ + ((x) == DMA_R_POWER_16) || \ + ((x) == DMA_R_POWER_32) || \ + ((x) == DMA_R_POWER_64) || \ + ((x) == DMA_R_POWER_128) || \ + ((x) == DMA_R_POWER_256) || \ + ((x) == DMA_R_POWER_512) || \ + ((x) == DMA_R_POWER_1024)) +#define IS_DMA(x) ((x) == DMA0) +#define IS_DMA_CHANNEL(x) ((x) <= 5) +#define IS_DMA_DATA_SIZE(x) ((x) <= 1024) +#define IS_DMA_IT_TYPE(x) (((x) <= 5) || ((x) == 31)) +/** + * @} + */ + +/** + * @addtogroup DMA_Public_Functions + * @{ + */ + +/** @addtogroup DMA_Public_Functions_Group1 + * @{ + */ +/* Initialization functions */ +extern void ald_dma_reset(DMA_TypeDef *DMAx); +extern void ald_dma_init(DMA_TypeDef *DMAx); +extern void ald_dma_config_struct(dma_config_t *p); +/** + * @} + */ + + +/** @addtogroup DMA_Public_Functions_Group2 + * @{ + */ +/* Configure DMA channel functions */ +extern void ald_dma_config_auto(dma_handle_t *hperh); +extern void ald_dma_restart_auto(dma_handle_t *hperh, void *src, void *dst, uint16_t size); +extern void ald_dma_config_auto_easy(DMA_TypeDef *DMAx, void *src, void *dst, + uint16_t size, uint8_t channel, void (*cbk)(void *arg)); +extern void ald_dma_config_basic(dma_handle_t *hperh); +extern void ald_dma_restart_basic(dma_handle_t *hperh, void *src, void *dst, uint16_t size); +extern void ald_dma_config_basic_easy(DMA_TypeDef *DMAx, void *src, void *dst, uint16_t size, dma_msel_t msel, + dma_msigsel_t msigsel, uint8_t channel, void (*cbk)(void *arg)); +/** + * @} + */ + +/** @addtogroup DMA_Public_Functions_Group3 + * @{ + */ +/* DMA control functions */ +extern void ald_dma_channel_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state); +extern void ald_dma_interrupt_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state); +extern it_status_t ald_dma_get_it_status(DMA_TypeDef *DMAx, uint8_t channel); +extern flag_status_t ald_dma_get_flag_status(DMA_TypeDef *DMAx, uint8_t channel); +extern void ald_dma_clear_flag_status(DMA_TypeDef *DMAx, uint8_t channel); +void ald_dma_irq_handler(void); +/** + * @} + */ + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__ALD_DMA_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_flash.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_flash.h similarity index 32% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_flash.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_flash.h index 71449f946b..9a4a66b068 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_flash.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_flash.h @@ -35,41 +35,41 @@ extern "C" { * @defgroup FLASH_Private_Macros FLASH Private Macros * @{ */ -#define FLASH_REG_UNLOCK() \ -do { \ - if (op_cmd == OP_FLASH) { \ - WRITE_REG(MSC->FLASHKEY, 0x8ACE0246); \ - WRITE_REG(MSC->FLASHKEY, 0x9BDF1357); \ - } \ - else { \ - WRITE_REG(MSC->INFOKEY, 0x7153BFD9); \ - WRITE_REG(MSC->INFOKEY, 0x0642CEA8); \ - } \ -} while (0) -#define FLASH_REQ() (SET_BIT(MSC->FLASHCR, MSC_FLASHCR_FLASHREQ_MSK)) -#define FLASH_REQ_FIN() (CLEAR_BIT(MSC->FLASHCR, MSC_FLASHCR_FLASHREQ_MSK)) -#define FLASH_IAP_ENABLE() (SET_BIT(MSC->FLASHCR, MSC_FLASHCR_IAPEN_MSK)) -#define FLASH_IAP_DISABLE() (CLEAR_BIT(MSC->FLASHCR, MSC_FLASHCR_IAPEN_MSK)) -#define FLASH_BASE_ADDR 0x00000000 -#define FLASH_PAGE_SIZE 1024UL -#define FLASH_WORD_SIZE 8UL -#define FLASH_TOTAL_SIZE 256UL -#define FLASH_PAGE_MASK (FLASH_PAGE_SIZE - 1) -#define FLASH_WORD_MASK (FLASH_WORD_SIZE - 1) -#define IS_FLASH_ADDRESS(ADDR) ((ADDR) < (FLASH_BASE_ADDR + FLASH_PAGE_SIZE * FLASH_TOTAL_SIZE)) -#define IS_4BYTES_ALIGN(ADDR) (((uint32_t)(ADDR) & 0x3) == 0 ? 1 : 0) -#define FLASH_PAGE_ADDR(ADDR) ((ADDR) & (~FLASH_PAGE_MASK)) -#define FLASH_PAGEEND_ADDR(ADDR) ((ADDR) | FLASH_PAGE_MASK) -#define FLASH_WORD_ADDR(ADDR) ((ADDR) & (~FLASH_WORD_MASK)) -#define FLASH_WORDEND_ADDR(ADDR) ((ADDR) | FLASH_WORD_MASK) -#define INFO_PAGE_SIZE 1024UL -#define INFO_PAGE_MASK (INFO_PAGE_SIZE - 1) -#define INFO_PAGE_ADDR(ADDR) ((ADDR) & (~INFO_PAGE_MASK)) +#define FLASH_REG_UNLOCK() \ + do { \ + if (op_cmd == OP_FLASH) { \ + WRITE_REG(MSC->FLASHKEY, 0x8ACE0246); \ + WRITE_REG(MSC->FLASHKEY, 0x9BDF1357); \ + } \ + else { \ + WRITE_REG(MSC->INFOKEY, 0x7153BFD9); \ + WRITE_REG(MSC->INFOKEY, 0x0642CEA8); \ + } \ + } while (0) +#define FLASH_REQ() (SET_BIT(MSC->FLASHCR, MSC_FLASHCR_FLASHREQ_MSK)) +#define FLASH_REQ_FIN() (CLEAR_BIT(MSC->FLASHCR, MSC_FLASHCR_FLASHREQ_MSK)) +#define FLASH_IAP_ENABLE() (SET_BIT(MSC->FLASHCR, MSC_FLASHCR_IAPEN_MSK)) +#define FLASH_IAP_DISABLE() (CLEAR_BIT(MSC->FLASHCR, MSC_FLASHCR_IAPEN_MSK)) +#define FLASH_BASE_ADDR 0x00000000 +#define FLASH_PAGE_SIZE 1024UL +#define FLASH_WORD_SIZE 8UL +#define FLASH_TOTAL_SIZE 256UL +#define FLASH_PAGE_MASK (FLASH_PAGE_SIZE - 1) +#define FLASH_WORD_MASK (FLASH_WORD_SIZE - 1) +#define IS_FLASH_ADDRESS(ADDR) ((ADDR) < (FLASH_BASE_ADDR + FLASH_PAGE_SIZE * FLASH_TOTAL_SIZE)) +#define IS_4BYTES_ALIGN(ADDR) (((uint32_t)(ADDR) & 0x3) == 0 ? 1 : 0) +#define FLASH_PAGE_ADDR(ADDR) ((ADDR) & (~FLASH_PAGE_MASK)) +#define FLASH_PAGEEND_ADDR(ADDR) ((ADDR) | FLASH_PAGE_MASK) +#define FLASH_WORD_ADDR(ADDR) ((ADDR) & (~FLASH_WORD_MASK)) +#define FLASH_WORDEND_ADDR(ADDR) ((ADDR) | FLASH_WORD_MASK) +#define INFO_PAGE_SIZE 1024UL +#define INFO_PAGE_MASK (INFO_PAGE_SIZE - 1) +#define INFO_PAGE_ADDR(ADDR) ((ADDR) & (~INFO_PAGE_MASK)) #ifdef USE_FLASH_FIFO -#define FLASH_FIFO 1 +#define FLASH_FIFO 1 #else -#define FLASH_FIFO 0 +#define FLASH_FIFO 0 #endif /** * @} @@ -80,19 +80,27 @@ do { \ */ typedef enum { - FLASH_CMD_AE = 0x000051AE, /**< Program area erase all */ - FLASH_CMD_PE = 0x00005EA1, /**< Page erase */ - FLASH_CMD_WP = 0x00005DA2, /**< Word program */ - FLASH_CMD_DATAPE = 0x00005BA4, /**< Data flash page page erase */ - FLASH_CMD_DATAWP = 0x00005AA5, /**< Data flash word program */ + FLASH_CMD_AE = 0x000051AE, /**< Program area erase all */ + FLASH_CMD_PE = 0x00005EA1, /**< Page erase */ + FLASH_CMD_WP = 0x00005DA2, /**< Word program */ + FLASH_CMD_DATAPE = 0x00005BA4, /**< Data flash page page erase */ + FLASH_CMD_DATAWP = 0x00005AA5, /**< Data flash word program */ } flash_cmd_type; typedef enum { - OP_FLASH = 0, /**< Operate Pragram area */ - OP_INFO = 1, /**< Operate info area */ + OP_FLASH = 0, /**< Operate Pragram area */ + OP_INFO = 1, /**< Operate info area */ } op_cmd_type; +/** + * @} + */ +/** @addtogroup Flash_Private_Functions + * @{ + */ +ald_status_t flash_page_erase(uint32_t addr); +ald_status_t flash_word_program(uint32_t addr, uint32_t *data, uint32_t len, uint32_t fifo); /** * @} */ @@ -100,13 +108,12 @@ typedef enum /** @addtogroup Flash_Public_Functions * @{ */ -ald_status_t flash_write(uint32_t addr, uint8_t *buf, uint16_t len); -ald_status_t flash_erase(uint32_t addr, uint16_t len); -ald_status_t flash_read(uint32_t *ram_addr, uint32_t addr, uint16_t len); +ald_status_t ald_flash_read(uint32_t *ram_addr, uint32_t addr, uint16_t len); +ald_status_t ald_flash_write(uint32_t addr, uint8_t *buf, uint16_t len); +ald_status_t ald_flash_erase(uint32_t addr, uint16_t len); /** * @} */ - /** * @} */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_gpio.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_gpio.h new file mode 100644 index 0000000000..a8a2e9ebe0 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_gpio.h @@ -0,0 +1,288 @@ +/** + ********************************************************************************* + * + * @file ald_gpio.h + * @brief Header file of GPIO module driver + * + * @version V1.0 + * @date 07 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ********************************************************************************* + */ + +#ifndef __ALD_GPIO_H__ +#define __ALD_GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/** + * @defgroup GPIO_Public_Macros GPIO Public Macros + * @{ + */ +#define GPIO_PIN_0 (1U << 0) +#define GPIO_PIN_1 (1U << 1) +#define GPIO_PIN_2 (1U << 2) +#define GPIO_PIN_3 (1U << 3) +#define GPIO_PIN_4 (1U << 4) +#define GPIO_PIN_5 (1U << 5) +#define GPIO_PIN_6 (1U << 6) +#define GPIO_PIN_7 (1U << 7) +#define GPIO_PIN_8 (1U << 8) +#define GPIO_PIN_9 (1U << 9) +#define GPIO_PIN_10 (1U << 10) +#define GPIO_PIN_11 (1U << 11) +#define GPIO_PIN_12 (1U << 12) +#define GPIO_PIN_13 (1U << 13) +#define GPIO_PIN_14 (1U << 14) +#define GPIO_PIN_15 (1U << 15) +#define GPIO_PIN_ALL (0xFFFF) +/** + * @} + */ + +/** + * @defgroup GPIO_Public_Types GPIO Public Types + * @{ + */ + +/** + * @brief GPIO mode + */ +typedef enum +{ + GPIO_MODE_CLOSE = 0x0, /**< Digital close Analog open */ + GPIO_MODE_INPUT = 0x1, /**< Input */ + GPIO_MODE_OUTPUT = 0x2, /**< Output */ +} gpio_mode_t; + +/** + * @brief GPIO open-drain or push-pull + */ +typedef enum +{ + GPIO_PUSH_PULL = 0x0, /**< Push-Pull */ + GPIO_OPEN_DRAIN = 0x2, /**< Open-Drain */ + GPIO_OPEN_SOURCE = 0x3, /**< Open-Source */ +} gpio_odos_t; + +/** + * @brief GPIO push-up or push-down + */ +typedef enum +{ + GPIO_FLOATING = 0x0,/**< Floating */ + GPIO_PUSH_UP = 0x1,/**< Push-Up */ + GPIO_PUSH_DOWN = 0x2,/**< Push-Down */ + GPIO_PUSH_UP_DOWN = 0x3,/**< Push-Up and Push-Down */ +} gpio_push_t; + +/** + * @brief GPIO output drive + */ +typedef enum +{ + GPIO_OUT_DRIVE_NORMAL = 0x0, /**< Normal current flow */ + GPIO_OUT_DRIVE_STRONG = 0x1, /**< Strong current flow */ +} gpio_out_drive_t; + +/** + * @brief GPIO filter + */ +typedef enum +{ + GPIO_FILTER_DISABLE = 0x0, /**< Disable filter */ + GPIO_FILTER_ENABLE = 0x1, /**< Enable filter */ +} gpio_filter_t; + +/** + * @brief GPIO type + */ +typedef enum +{ + GPIO_TYPE_CMOS = 0x0, /**< CMOS Type */ + GPIO_TYPE_TTL = 0x1, /**< TTL Type */ +} gpio_type_t; + +/** + * @brief GPIO functions + */ +typedef enum +{ + GPIO_FUNC_0 = 0, /**< function #0 */ + GPIO_FUNC_1 = 1, /**< function #1 */ + GPIO_FUNC_2 = 2, /**< function #2 */ + GPIO_FUNC_3 = 3, /**< function #3 */ + GPIO_FUNC_4 = 4, /**< function #4 */ + GPIO_FUNC_5 = 5, /**< function #5 */ + GPIO_FUNC_6 = 6, /**< function #6 */ + GPIO_FUNC_7 = 7, /**< function #7 */ +} gpio_func_t; + + +/** + * @brief GPIO Init Structure definition + */ +typedef struct +{ + gpio_mode_t mode; /**< Specifies the operating mode for the selected pins. + This parameter can be any value of @ref gpio_mode_t */ + gpio_odos_t odos; /**< Specifies the Open-Drain or Push-Pull for the selected pins. + This parameter can be a value of @ref gpio_odos_t */ + gpio_push_t pupd; /**< Specifies the Pull-up or Pull-Down for the selected pins. + This parameter can be a value of @ref gpio_push_t */ + gpio_out_drive_t odrv; /**< Specifies the output driver for the selected pins. + This parameter can be a value of @ref gpio_out_drive_t */ + gpio_filter_t flt; /**< Specifies the input filter for the selected pins. + This parameter can be a value of @ref gpio_filter_t */ + gpio_type_t type; /**< Specifies the type for the selected pins. + This parameter can be a value of @ref gpio_type_t */ + gpio_func_t func; /**< Specifies the function for the selected pins. + This parameter can be a value of @ref gpio_func_t */ +} gpio_init_t; + +/** + * @brief EXTI trigger style + */ +typedef enum +{ + EXTI_TRIGGER_RISING_EDGE = 0, /**< Rising edge trigger */ + EXTI_TRIGGER_TRAILING_EDGE = 1, /**< Trailing edge trigger */ + EXTI_TRIGGER_BOTH_EDGE = 2, /**< Rising and trailing edge trigger */ +} exti_trigger_style_t; + +/** + * @brief EXTI filter clock select + */ +typedef enum +{ + EXTI_FILTER_CLOCK_10K = 0, /**< cks = 10KHz */ + EXTI_FILTER_CLOCK_32K = 1, /**< cks = 32KHz */ +} exti_filter_clock_t; + +/** + * @brief EXTI Init Structure definition + */ +typedef struct +{ + type_func_t filter; /**< Enable filter. */ + exti_filter_clock_t cks; /**< Filter clock select. */ + uint8_t filter_time; /**< Filter duration */ +} exti_init_t; +/** + * @} + */ + +/** + * @defgroup GPIO_Private_Macros GPIO Private Macros + * @{ + */ +#define PIN_MASK 0xFFFF +#define UNLOCK_KEY 0x55AA + +#define IS_GPIO_PIN(x) ((((x) & (uint16_t)0x00) == 0) && ((x) != (uint16_t)0x0)) +#define IS_GPIO_PORT(GPIOx) ((GPIOx == GPIOA) || \ + (GPIOx == GPIOB) || \ + (GPIOx == GPIOC) || \ + (GPIOx == GPIOD) || \ + (GPIOx == GPIOE) || \ + (GPIOx == GPIOF) || \ + (GPIOx == GPIOG) || \ + (GPIOx == GPIOH)) +#define IS_GPIO_MODE(x) (((x) == GPIO_MODE_CLOSE) || \ + ((x) == GPIO_MODE_INPUT) || \ + ((x) == GPIO_MODE_OUTPUT)) +#define IS_GPIO_ODOS(x) (((x) == GPIO_PUSH_PULL) || \ + ((x) == GPIO_OPEN_DRAIN) || \ + ((x) == GPIO_OPEN_SOURCE)) +#define IS_GPIO_PUPD(x) (((x) == GPIO_FLOATING) || \ + ((x) == GPIO_PUSH_UP) || \ + ((x) == GPIO_PUSH_DOWN) || \ + ((x) == GPIO_PUSH_UP_DOWN)) +#define IS_GPIO_ODRV(x) (((x) == GPIO_OUT_DRIVE_NORMAL) || \ + ((x) == GPIO_OUT_DRIVE_STRONG)) +#define IS_GPIO_FLT(x) (((x) == GPIO_FILTER_DISABLE) || \ + ((x) == GPIO_FILTER_ENABLE)) +#define IS_GPIO_TYPE(x) (((x) == GPIO_TYPE_TTL) || \ + ((x) == GPIO_TYPE_CMOS)) +#define IS_TRIGGER_STYLE(x) (((x) == EXTI_TRIGGER_RISING_EDGE) || \ + ((x) == EXTI_TRIGGER_TRAILING_EDGE) || \ + ((x) == EXTI_TRIGGER_BOTH_EDGE)) +#define IS_EXTI_FLTCKS_TYPE(x) (((x) == EXTI_FILTER_CLOCK_10K) || \ + ((x) == EXTI_FILTER_CLOCK_32K)) +#define IS_GPIO_FUNC(x) ((x) <= 7) +/** + * @} + */ + +/** @addtogroup GPIO_Public_Functions + * @{ + */ + +/** @addtogroup GPIO_Public_Functions_Group1 + * @{ + */ +void ald_gpio_init(GPIO_TypeDef *GPIOx, uint16_t pin, gpio_init_t *init); +void ald_gpio_init_default(GPIO_TypeDef *GPIOx, uint16_t pin); +void ald_gpio_func_default(GPIO_TypeDef *GPIOx); +void ald_gpio_exti_init(GPIO_TypeDef *GPIOx, uint16_t pin, exti_init_t *init); +/** + * @} + */ + +/** @addtogroup GPIO_Public_Functions_Group2 + * @{ + */ +uint8_t ald_gpio_read_pin(GPIO_TypeDef *GPIOx, uint16_t pin); +void ald_gpio_write_pin(GPIO_TypeDef *GPIOx, uint16_t pin, uint8_t val); +void ald_gpio_toggle_pin(GPIO_TypeDef *GPIOx, uint16_t pin); +void ald_gpio_toggle_dir(GPIO_TypeDef *GPIOx, uint16_t pin); +void ald_gpio_lock_pin(GPIO_TypeDef *GPIOx, uint16_t pin); +uint16_t ald_gpio_read_port(GPIO_TypeDef *GPIOx); +void ald_gpio_write_port(GPIO_TypeDef *GPIOx, uint16_t val); +/** + * @} + */ + +/** @addtogroup GPIO_Public_Functions_Group3 + * @{ + */ +void ald_gpio_exti_interrupt_config(uint16_t pin, exti_trigger_style_t style, type_func_t status); +flag_status_t ald_gpio_exti_get_flag_status(uint16_t pin); +void ald_gpio_exti_clear_flag_status(uint16_t pin); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_GPIO_H__ */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_i2c.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_i2c.h new file mode 100644 index 0000000000..a05aaf0ebb --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_i2c.h @@ -0,0 +1,534 @@ +/** + ********************************************************************************* + * + * @file ald_i2c.h + * @brief Header file of I2C driver + * + * @version V1.0 + * @date 15 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ******************************************************************************** + */ + +#ifndef __ALD_I2C_H__ +#define __ALD_I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" +#include "ald_dma.h" +#include "ald_cmu.h" + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/** @defgroup I2C_Public_Types I2C Public Types + * @{ + */ +/** + * @brief I2C Error Code + */ +typedef enum +{ + I2C_ERROR_NONE = 0x0, /**< No error */ + I2C_ERROR_BERR = 0x1, /**< Berr error */ + I2C_ERROR_ARLO = 0x2, /**< Arlo error */ + I2C_ERROR_AF = 0x4, /**< Af error */ + I2C_ERROR_OVR = 0x8, /**< Ovr error */ + I2C_ERROR_DMA = 0x10, /**< Dma error */ + I2C_ERROR_TIMEOUT = 0x20, /**< Timeout error */ +} i2c_error_t; + +/** + * @brief I2C state structure definition + */ +typedef enum +{ + I2C_STATE_RESET = 0x0, /**< Peripheral is not yet Initialized */ + I2C_STATE_READY = 0x1, /**< Peripheral Initialized and ready for use */ + I2C_STATE_BUSY = 0x2, /**< An internal process is ongoing */ + I2C_STATE_BUSY_TX = 0x3, /**< Data Transmission process is ongoing */ + I2C_STATE_BUSY_RX = 0x4, /**< Data Reception process is ongoing */ + I2C_STATE_TIMEOUT = 0x5, /**< timeout state */ + I2C_STATE_ERROR = 0x6, /**< Error */ +} i2c_state_t; + +/** + * @brief I2C Duty Cycle + */ +typedef enum +{ + I2C_DUTYCYCLE_2 = 0x0, /**< duty cycle is 2 */ + I2C_DUTYCYCLE_16_9 = 0x4000, /**< duty cycle is 16/9 */ +} i2c_duty_t; + +/** + * @brief I2C Addressing Mode + */ +typedef enum +{ + I2C_ADDR_7BIT = 0x1, /**< 7 bit address */ + I2C_ADDR_10BIT = 0x2, /**< 10 bit address */ +} i2c_addr_t; + +/** + * @brief I2C Dual Addressing Mode + */ +typedef enum +{ + I2C_DUALADDR_DISABLE = 0x0, /**< dual address is disable */ + I2C_DUALADDR_ENABLE = 0x1, /**< dual address is enable */ +} i2c_dual_addr_t; + +/** + * @brief I2C General Call Addressing mode + */ +typedef enum +{ + I2C_GENERALCALL_DISABLE = 0x0, /**< feneral call address is disable */ + I2C_GENERALCALL_ENABLE = 0x40, /**< feneral call address is enable */ +} i2c_general_addr_t; + +/** + * @brief I2C Nostretch Mode + */ +typedef enum +{ + I2C_NOSTRETCH_DISABLE = 0x0, /**< Nostretch disable */ + I2C_NOSTRETCH_ENABLE = 0x80, /**< Nostretch enable */ +} i2c_nostretch_t; + +/** + * @brief I2C Memory Address Size + */ +typedef enum +{ + I2C_MEMADD_SIZE_8BIT = 0x1, /**< 8 bit memory address size */ + I2C_MEMADD_SIZE_16BIT = 0x10 /**< 10 bit memory address size */ +} i2c_addr_size_t; + +/** + * @brief I2C Flag Definition + */ +typedef enum +{ + I2C_FLAG_SB = (1U << 0), + I2C_FLAG_ADDR = (1U << 1), + I2C_FLAG_BTF = (1U << 2), + I2C_FLAG_ADD10 = (1U << 3), + I2C_FLAG_STOPF = (1U << 4), + I2C_FLAG_RXNE = (1U << 6), + I2C_FLAG_TXE = (1U << 7), + I2C_FLAG_BERR = (1U << 8), + I2C_FLAG_ARLO = (1U << 9), + I2C_FLAG_AF = (1U << 10), + I2C_FLAG_OVR = (1U << 11), + I2C_FLAG_PECERR = (1U << 12), + I2C_FLAG_TIMEOUT = (1U << 14), + I2C_FLAG_SMBALERT = (1U << 15), + I2C_FLAG_MSL = (1U << 16), + I2C_FLAG_BUSY = (1U << 17), + I2C_FLAG_TRA = (1U << 18), + I2C_FLAG_GENCALL = (1U << 20), + I2C_FLAG_SMBDEFAULT = (1U << 21), + I2C_FLAG_SMBHOST = (1U << 22), + I2C_FLAG_DUALF = (1U << 23), +} i2c_flag_t; + +/** + * @brief I2C mode structure definition + */ +typedef enum +{ + I2C_MODE_NONE = 0x0, /**< No I2C communication on going */ + I2C_MODE_MASTER = 0x10, /**< I2C communication is in Master mode */ + I2C_MODE_SLAVE = 0x20, /**< I2C communication is in Slave mode */ + I2C_MODE_MEM = 0x40, /**< I2C communication is in Memory mode */ +} i2c_mode_t; + +/** + * @brief I2C Clock + */ +typedef enum +{ + I2C_STANDARD_MODE_MAX_CLK = 100000, /**< Standard mode clock */ + I2C_FAST_MODE_MAX_CLK = 400000, /**< Fast mode clock */ +} i2c_clock_t; + +/** + * @brief Interrupt Configuration Definition + */ +typedef enum +{ + I2C_IT_BUF = (1U << 10), /**< Buffer interrupt */ + I2C_IT_EVT = (1U << 9), /**< Event interrupt */ + I2C_IT_ERR = (1U << 8), /**< Error interrupt */ +} i2c_interrupt_t; + +/** + * @brief I2C CON1 Register + */ +typedef enum +{ + I2C_CON1_PEN = (1U << 0), /**< PEN BIT */ + I2C_CON1_PMOD = (1U << 1), /**< PMOD BIT */ + I2C_CON1_SMBMOD = (1U << 3), /**< SMBMOD BIT */ + I2C_CON1_ARPEN = (1U << 4), /**< ARPEN BIT */ + I2C_CON1_PECEN = (1U << 5), /**< PECEN BIT */ + I2C_CON1_GCEN = (1U << 6), /**< GCEN BIT */ + I2C_CON1_DISCS = (1U << 7), /**< DISCS BIT */ + I2C_CON1_START = (1U << 8), /**< START BIT */ + I2C_CON1_STOP = (1U << 9), /**< STOP BIT */ + I2C_CON1_ACKEN = (1U << 10), /**< ACKEN BIT */ + I2C_CON1_POSAP = (1U << 11), /**< POSAP BIT */ + I2C_CON1_TRPEC = (1U << 12), /**< TRPEC BIT */ + I2C_CON1_ALARM = (1U << 13), /**< ALARM BIT */ + I2C_CON1_SRST = (1U << 15), /**< SRST BIT */ +} i2c_con1_t; + +/** + * @brief I2C CON2 Register + */ +typedef enum +{ + I2C_CON2_CLKF = 0x3F, /**< CLKF BITS */ + I2C_CON2_CLKF_0 = (1U << 0), /**< CLKF_0 BIT */ + I2C_CON2_CLKF_1 = (1U << 1), /**< CLKF_1 BIT */ + I2C_CON2_CLKF_2 = (1U << 2), /**< CLKF_2 BIT */ + I2C_CON2_CLKF_3 = (1U << 3), /**< CLKF_3 BIT */ + I2C_CON2_CLKF_4 = (1U << 4), /**< CLKF_4 BIT */ + I2C_CON2_CLKF_5 = (1U << 5), /**< CLKF_5 BIT */ + I2C_CON2_ERRIE = (1U << 8), /**< ERRIE BIT */ + I2C_CON2_EVTIE = (1U << 9), /**< EVTIE BIT */ + I2C_CON2_BUFIE = (1U << 10), /**< BUFIE BIT */ + I2C_CON2_DMAEN = (1U << 11), /**< DMAEN BIT */ + I2C_CON2_LDMA = (1U << 12), /**< LDMA BIT */ +} i2c_con2_t; + +/** + * @brief I2C ADDR1 Register + */ +typedef enum +{ + I2C_ADDR1_ADDH0 = (1U << 0), /**< ADDH0 BIT */ + I2C_ADDR1_ADDH1 = (1U << 1), /**< ADDH1 BIT */ + I2C_ADDR1_ADDH2 = (1U << 2), /**< ADDH2 BIT */ + I2C_ADDR1_ADDH3 = (1U << 3), /**< ADDH3 BIT */ + I2C_ADDR1_ADDH4 = (1U << 4), /**< ADDH4 BIT */ + I2C_ADDR1_ADDH5 = (1U << 5), /**< ADDH5 BIT */ + I2C_ADDR1_ADDH6 = (1U << 6), /**< ADDH6 BIT */ + I2C_ADDR1_ADDH7 = (1U << 7), /**< ADDH7 BIT */ + I2C_ADDR1_ADDH8 = (1U << 8), /**< ADDH8 BIT */ + I2C_ADDR1_ADDH9 = (1U << 9), /**< ADDH9 BIT */ + I2C_ADDR1_ADDTYPE = (1U << 15), /**< ADDTYPE BIT */ +} i2c_addr1_t; + +/** + * @brief I2C ADDR2 Register + */ +typedef enum +{ + I2C_ADDR2_DUALEN = (1U << 0), /**< DUALEN BIT */ + I2C_ADDR2_ADD = (1U << 1), /**< ADD BIT */ +} i2c_addr2_t; + +/** + * @brief I2C STAT1 Register + */ +typedef enum +{ + I2C_STAT1_SB = (1U << 0), /**< SB BIT */ + I2C_STAT1_ADDR = (1U << 1), /**< ADDR BIT */ + I2C_STAT1_BTC = (1U << 2), /**< BTC BIT */ + I2C_STAT1_SENDADD10 = (1U << 3), /**< SENDADD10 BIT */ + I2C_STAT1_DETSTP = (1U << 4), /**< DETSTP BIT */ + I2C_STAT1_RXBNE = (1U << 6), /**< RXBNE BIT */ + I2C_STAT1_TXBE = (1U << 7), /**< TXBE BIT */ + I2C_STAT1_BUSERR = (1U << 8), /**< BUSERR BIT */ + I2C_STAT1_LARB = (1U << 9), /**< LARB BIT */ + I2C_STAT1_ACKERR = (1U << 10), /**< ACKERR BIT */ + I2C_STAT1_ROUERR = (1U << 11), /**< ROUERR BIT */ + I2C_STAT1_PECERR = (1U << 12), /**< PECERR BIT */ + I2C_STAT1_SMBTO = (1U << 14), /**< SMBTO BIT */ + I2C_STAT1_SMBALARM = (1U << 15), /**< SMBALARM BIT */ +} i2c_stat1_t; + +/** + * @brief I2C STAT2 Register + */ +typedef enum +{ + I2C_STAT2_MASTER = (1U << 0), /**< MASTER BIT */ + I2C_STAT2_BSYF = (1U << 1), /**< BSYF BIT */ + I2C_STAT2_TRF = (1U << 2), /**< TRF BIT */ + I2C_STAT2_RXGCF = (1U << 4), /**< RXGCF BIT */ + I2C_STAT2_SMBDEF = (1U << 5), /**< SMBDEF BIT */ + I2C_STAT2_SMBHH = (1U << 6), /**< SMBHH BIT */ + I2C_STAT2_DUALF = (1U << 7), /**< DMF BIT */ + I2C_STAT2_PECV = (1U << 8), /**< PECV BIT */ +} i2c_stat2_t; + +/** + * @brief I2C CKCFG Register + */ +typedef enum +{ + I2C_CKCFG_CLKSET = 0xFFF, /**< CLKSET BITS */ + I2C_CKCFG_DUTY = (1U << 14), /**< DUTY BIT */ + I2C_CKCFG_CLKMOD = (1U << 15), /**< CLKMOD BIT */ +} i2c_ckcfg_t; + +/** + * @brief I2C RT Register + */ +typedef enum +{ + I2C_RT_RISET = 0x3F, /**< RISET BITS */ +} i2c_trise_t; + +/** + * @brief I2C Configuration Structure definition + */ +typedef struct +{ + uint32_t clk_speed; /**< Specifies the clock frequency */ + i2c_duty_t duty; /**< Specifies the I2C fast mode duty cycle */ + uint32_t own_addr1; /**< Specifies the first device own address */ + i2c_addr_t addr_mode; /**< Specifies addressing mode */ + i2c_dual_addr_t dual_addr; /**< Specifies if dual addressing mode is selected */ + uint32_t own_addr2; /**< Specifies the second device own address */ + i2c_general_addr_t general_call; /**< Specifies if general call mode is selected */ + i2c_nostretch_t no_stretch; /**< Specifies if nostretch mode is selected */ +} i2c_init_t; + +/** + * @brief I2C handle Structure definition + */ +typedef struct i2c_handle_s +{ + I2C_TypeDef *perh; /**< I2C registers base address */ + i2c_init_t init; /**< I2C communication parameters */ + uint8_t *p_buff; /**< Pointer to I2C transfer buffer */ + uint16_t xfer_size; /**< I2C transfer size */ + __IO uint16_t xfer_count; /**< I2C transfer counter */ +#ifdef ALD_DMA + dma_handle_t hdmatx; /**< I2C Tx DMA handle parameters */ + dma_handle_t hdmarx; /**< I2C Rx DMA handle parameters */ +#endif + lock_state_t lock; /**< I2C locking object */ + __IO i2c_state_t state; /**< I2C communication state */ + __IO i2c_mode_t mode; /**< I2C communication mode */ + __IO uint32_t error_code; /**< I2C Error code */ + + void (*master_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Master Tx completed callback */ + void (*master_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Master Rx completed callback */ + void (*slave_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Slave Tx completed callback */ + void (*slave_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Slave Rx completed callback */ + void (*mem_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Tx to Memory completed callback */ + void (*mem_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Rx from Memory completed callback */ + void (*error_callback)(struct i2c_handle_s *arg); /**< Error callback */ +} i2c_handle_t; + +/** + * @} + */ + +/** @defgroup I2C_Public_Macro I2C Public Macros + * @{ + */ +#define I2C_RESET_HANDLE_STATE(x) ((x)->state = I2C_STATE_RESET) +#define I2C_CLEAR_ADDRFLAG(x) \ + do { \ + __IO uint32_t tmpreg; \ + tmpreg = (x)->perh->STAT1; \ + tmpreg = (x)->perh->STAT2; \ + UNUSED(tmpreg); \ + } while (0) +#define __I2C_CLEAR_STOPFLAG(x) \ + do { \ + __IO uint32_t tmpreg; \ + tmpreg = (x)->perh->STAT1; \ + tmpreg = SET_BIT((x)->perh->CON1, I2C_CON1_PEN); \ + UNUSED(tmpreg); \ + } while (0) +#define I2C_ENABLE(x) (SET_BIT((x)->perh->CON1, I2C_CON1_PEN_MSK)) +#define I2C_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, I2C_CON1_PEN_MSK)) +/** + * @} + */ + +/** @defgroup I2C_Private_Macro I2C Private Macros + * @{ + */ +#define IS_I2C_TYPE(x) (((x) == I2C0) || \ + ((x) == I2C1)) +#define IS_I2C_ADDRESSING_MODE(x) (((x) == I2C_ADDR_7BIT) || \ + ((x) == I2C_ADDR_10BIT)) +#define IS_I2C_DUAL_ADDRESS(x) (((x) == I2C_DUALADDR_DISABLE) || \ + ((x) == I2C_DUALADDR_ENABLE)) +#define IS_I2C_GENERAL_CALL(x) (((x) == I2C_GENERALCALL_DISABLE) || \ + ((x) == I2C_GENERALCALL_ENABLE)) +#define IS_I2C_MEMADD_size(x) (((x) == I2C_MEMADD_SIZE_8BIT) || \ + ((x) == I2C_MEMADD_SIZE_16BIT)) +#define IS_I2C_NO_STRETCH(x) (((x) == I2C_NOSTRETCH_DISABLE) || \ + ((x) == I2C_NOSTRETCH_ENABLE)) +#define IS_I2C_OWN_ADDRESS1(x) (((x) & (uint32_t)(0xFFFFFC00)) == 0) +#define IS_I2C_OWN_ADDRESS2(x) (((x) & (uint32_t)(0xFFFFFF01)) == 0) +#define IS_I2C_CLOCK_SPEED(x) (((x) > 0) && ((x) <= I2C_FAST_MODE_MAX_CLK)) +#define IS_I2C_DUTY_CYCLE(x) (((x) == I2C_DUTYCYCLE_2) || \ + ((x) == I2C_DUTYCYCLE_16_9)) +#define IS_I2C_IT_TYPE(x) (((x) == I2C_IT_BUF) || \ + ((x) == I2C_IT_EVT) || \ + ((x) == I2C_IT_ERR)) +#define IS_I2C_FLAG(x) (((x) == I2C_FLAG_SB) || \ + ((x) == I2C_FLAG_ADDR) || \ + ((x) == I2C_FLAG_BTF) || \ + ((x) == I2C_FLAG_ADD10) || \ + ((x) == I2C_FLAG_STOPF) || \ + ((x) == I2C_FLAG_RXNE) || \ + ((x) == I2C_FLAG_TXE) || \ + ((x) == I2C_FLAG_BERR) || \ + ((x) == I2C_FLAG_ARLO) || \ + ((x) == I2C_FLAG_AF) || \ + ((x) == I2C_FLAG_OVR) || \ + ((x) == I2C_FLAG_PECERR) || \ + ((x) == I2C_FLAG_TIMEOUT) || \ + ((x) == I2C_FLAG_SMBALERT) || \ + ((x) == I2C_FLAG_MSL) || \ + ((x) == I2C_FLAG_BUSY) || \ + ((x) == I2C_FLAG_TRA) || \ + ((x) == I2C_FLAG_GENCALL) || \ + ((x) == I2C_FLAG_SMBDEFAULT) || \ + ((x) == I2C_FLAG_SMBHOST) || \ + ((x) == I2C_FLAG_DUALF)) + +#define I2C_FREQ_RANGE(x) ((x) / 1000000) +#define I2C_RISE_TIME(x, u) (((u) <= I2C_STANDARD_MODE_MAX_CLK) ? ((x) + 1) :\ + ((((x) * 300) / 1000) + 1)) +#define I2C_SPEED_STANDARD(x, y) (((((x) / ((y) << 1)) & I2C_CKCFG_CLKSET) < 4) ? 4:\ + ((x) / ((y) << 1))) +#define I2C_SPEED_FAST(x, y, z) (((z) == I2C_DUTYCYCLE_2) ? ((x) / ((y) * 3)) :\ + (((x) / ((y) * 25)) | I2C_DUTYCYCLE_16_9)) +#define I2C_SPEED(x, y, z) (((y) <= 100000) ? (I2C_SPEED_STANDARD((x), (y))) :\ + ((I2C_SPEED_FAST((x), (y), (z)) & I2C_CKCFG_CLKSET) == 0) ? 1 : \ + ((I2C_SPEED_FAST((x), (y), (z))) | I2C_CKCFG_CLKMOD)) +#define I2C_MEM_ADD_MSB(x) ((uint8_t)((uint16_t)(((uint16_t)((x) &\ + (uint16_t)(0xFF00))) >> 8))) +#define I2C_MEM_ADD_LSB(x) ((uint8_t)((uint16_t)((x) & (uint16_t)(0x00FF)))) +#define I2C_7BIT_ADD_WRITE(x) ((uint8_t)((x) & (~I2C_ADDR1_ADDH0))) +#define I2C_7BIT_ADD_READ(x) ((uint8_t)((x) | I2C_ADDR1_ADDH0)) +#define I2C_10BIT_ADDRESS(x) ((uint8_t)((uint16_t)((x) & (uint16_t)(0x00FF)))) +#define I2C_10BIT_HEADER_WRITE(x) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((x) &\ + (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF0)))) +#define I2C_10BIT_HEADER_READ(x) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((x) &\ + (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF1)))) +/** + * @} + */ + +/** @addtogroup I2C_Public_Functions + * @{ + */ + +/** @addtogroup I2C_Public_Functions_Group1 + * @{ + */ +ald_status_t ald_i2c_init(i2c_handle_t *hperh); +ald_status_t ald_i2c_reset(i2c_handle_t *hperh); + +/** + * @} + */ + +/** @addtogroup I2C_Public_Functions_Group2 + * @{ + */ +/** Blocking mode: Polling */ +ald_status_t ald_i2c_master_send(i2c_handle_t *hperh, uint16_t dev_addr, + uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_i2c_master_recv(i2c_handle_t *hperh, uint16_t dev_addr, + uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_i2c_slave_send(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_i2c_slave_recv(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_i2c_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, + i2c_addr_size_t add_size, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_i2c_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, + i2c_addr_size_t add_size, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_i2c_is_device_ready(i2c_handle_t *hperh, uint16_t dev_addr, uint32_t trials, uint32_t timeout); + +/** Non-Blocking mode: Interrupt */ +ald_status_t ald_i2c_master_send_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint16_t size); +ald_status_t ald_i2c_master_recv_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint16_t size); +ald_status_t ald_i2c_slave_send_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_i2c_slave_recv_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_i2c_mem_write_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, + i2c_addr_size_t add_size, uint8_t *buf, uint16_t size); +ald_status_t ald_i2c_mem_read_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, + i2c_addr_size_t add_size, uint8_t *buf, uint16_t size); + +#ifdef ALD_DMA +/** Non-Blocking mode: DMA */ +ald_status_t ald_i2c_master_send_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, + uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_i2c_master_recv_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, + uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_i2c_slave_send_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_i2c_slave_recv_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_i2c_mem_write_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size, + uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_i2c_mem_read_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, + i2c_addr_size_t add_size, uint8_t *buf, uint16_t size, uint8_t channel); +#endif +/** + * @} + */ + +/** @addtogroup I2C_Public_Functions_Group3 + * @{ + */ +i2c_state_t ald_i2c_get_state(i2c_handle_t *hperh); +uint32_t ald_i2c_get_error(i2c_handle_t *hperh); +flag_status_t ald_i2c_get_flag_status(i2c_handle_t *hperh, i2c_flag_t flag); +flag_status_t ald_i2c_get_it_status(i2c_handle_t *hperh, i2c_interrupt_t it); +void ald_i2c_clear_flag_status(i2c_handle_t *hperh, i2c_flag_t flag); +/** + * @} + */ + +/** @addtogroup I2C_Public_Functions_Group4 + * @{ + */ +void ald_i2c_interrupt_config(i2c_handle_t *hperh, i2c_interrupt_t it, type_func_t state); +void ald_i2c_ev_irq_handler(i2c_handle_t *hperh); +void ald_i2c_er_irq_handler(i2c_handle_t *hperh); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_I2C_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_iap.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_iap.h similarity index 74% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_iap.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_iap.h index 4109bed4b1..7a841e7c2a 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_iap.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_iap.h @@ -36,10 +36,10 @@ extern "C" { * @defgroup IAP_Private_Macros IAP Private Macros * @{ */ -#define IAP_WSP_ADDR 0x10000000 -#define IAP_PE_ADDR 0x10000004 -#define IAP_WP_ADDR 0x10000008 -#define IAP_DWP_ADDR 0x1000000c +#define IAP_WSP_ADDR 0x10000000 +#define IAP_PE_ADDR 0x10000004 +#define IAP_WP_ADDR 0x10000008 +#define IAP_DWP_ADDR 0x1000000c /** * @} */ @@ -58,10 +58,10 @@ typedef uint32_t (*IAP_WSP)(uint32_t addr, uint8_t *data, uint32_t len, uint32_t /** @addtogroup IAP_Public_Functions * @{ */ -uint32_t iap_erase_page(uint32_t addr); -uint32_t iap_program_word(uint32_t addr, uint32_t data); -uint32_t iap_program_dword(uint32_t addr, uint32_t data_l, uint32_t data_h); -uint32_t iap_program_words(uint32_t addr, uint8_t *data, uint32_t len, uint32_t erase); +uint32_t ald_iap_erase_page(uint32_t addr); +uint32_t ald_iap_program_word(uint32_t addr, uint32_t data); +uint32_t ald_iap_program_dword(uint32_t addr, uint32_t data_l, uint32_t data_h); +uint32_t ald_iap_program_words(uint32_t addr, uint8_t *data, uint32_t len, uint32_t erase); /** * @} */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pis.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pis.h new file mode 100644 index 0000000000..a40bc998d1 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pis.h @@ -0,0 +1,692 @@ +/** + ********************************************************************************* + * + * @file ald_pis.h + * @brief Header file of PIS driver. + * + * @version V1.0 + * @date 27 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ********************************************************************************* + */ + +#ifndef __ALD_PIS_H__ +#define __ALD_PIS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup PIS + * @{ + */ + +/** @defgroup PIS_Public_Types PIS Public Types + * @{ + */ +/** + * @brief Producer entry + * @note ES32F065x: + * AD16C4T0--TIMER0 + * GP16C4T0--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + * + * ES32F033x: + * ES32F093x: + * GP16C4T0--TIMER0 + * GP16C4T1--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + */ +typedef enum +{ + PIS_NON = 0x0, /**< No async */ + PIS_GPIO_PIN0 = 0x10, /**< Pin0, level,support async */ + PIS_GPIO_PIN1 = 0x11, /**< Pin1, level,support async */ + PIS_GPIO_PIN2 = 0x12, /**< Pin2, level,support async */ + PIS_GPIO_PIN3 = 0x13, /**< Pin3, level,support async */ + PIS_GPIO_PIN4 = 0x14, /**< Pin4, level,support async */ + PIS_GPIO_PIN5 = 0x15, /**< Pin5, level,support async */ + PIS_GPIO_PIN6 = 0x16, /**< Pin6, level,support async */ + PIS_GPIO_PIN7 = 0x17, /**< Pin7, level,support async */ + PIS_GPIO_PIN8 = 0x18, /**< Pin8, level,support async */ + PIS_GPIO_PIN9 = 0x19, /**< Pin9, level,support async */ + PIS_GPIO_PIN10 = 0x1a, /**< Pin10, level,support async */ + PIS_GPIO_PIN11 = 0x1b, /**< Pin11, level,support async */ + PIS_GPIO_PIN12 = 0x1c, /**< Pin12, level,support async */ + PIS_GPIO_PIN13 = 0x1d, /**< Pin13, level,support async */ + PIS_GPIO_PIN14 = 0x1e, /**< Pin14, level,support async */ + PIS_GPIO_PIN15 = 0x1f, /**< Pin15, level,support async */ + PIS_ACMP_OUT0 = 0x30, /**< Acmp0 output, level,support async */ + PIS_ACMP_OUT1 = 0x31, /**< Acmp1 output, level,support async */ + PIS_DAC0_CH0 = 0x40, /**< Dac0 channel 0, pclk2 pulse,support async */ + PIS_DAC0_CH1 = 0x41, /**< Dac0 channel 1, pclk2 pulse,support async */ + PIS_ADC0_INJECT = 0x60, /**< Adc0 inject, pclk2 pulse,support async */ + PIS_ADC0_REGULAT = 0x61, /**< Adc0 regulat, pclk2 pulse,support async */ + PIS_ADC0_WINDOW = 0x62, /**< Adc0 window, no have */ + PIS_LVD = 0x70, /**< Lvd, level,support async */ + PIS_UART0_ASY_SEND = 0x80, /**< Uart0 asy send, pulse,support async */ + PIS_UART0_ASY_RECV = 0x81, /**< Uart0 asy recv, pulse,support async */ + PIS_UART0_IRDAOUT = 0x82, /**< Uart0 irdaout, level,support async */ + PIS_UART0_RTSOUT = 0x83, /**< Uart0 rtsout, level,support async */ + PIS_UART0_TXOUT = 0x84, /**< Uart0 txout, level,support async */ + PIS_UART0_SYN_SEND = 0x85, /**< Uart0 syn send, pulse,support async */ + PIS_UART0_SYN_RECV = 0x86, /**< Uart0 syn recv, pulse,support async */ + PIS_UART1_ASY_SEND = 0x90, /**< Uart1 asy send, pulse,support async */ + PIS_UART1_ASY_RECV = 0x91, /**< Uart1 asy recv, pulse,support async */ + PIS_UART1_IRDA = 0x92, /**< Uart1 irdaout, level,support async */ + PIS_UART1_RTS = 0x93, /**< Uart1 rtsout, level,support async */ + PIS_UART1_TXOUT = 0x94, /**< Uart1 txout, level,support async */ + PIS_UART1_SYN_SEND = 0x95, /**< Uart1 syn send, pulse,support async */ + PIS_UART1_SYN_RECV = 0x96, /**< Uart1 syn recv, pulse,support async */ + PIS_UART2_ASY_SEND = 0xa0, /**< Uart2 asy send, pulse,support async */ + PIS_UART2_ASY_RECV = 0xa1, /**< Uart2 asy recv, pulse,support async */ + PIS_UART2_IRDA = 0xa2, /**< Uart2 irdaout, level,support async */ + PIS_UART2_RTS = 0xa3, /**< Uart2 rtsout, level,support async */ + PIS_UART2_TXOUT = 0xa4, /**< Uart2 txout, level,support async */ + PIS_UART2_SYN_SEND = 0xa5, /**< Uart2 syn send, pulse,support async */ + PIS_UART2_SYN_RECV = 0xa6, /**< Uart2 syn recv, pulse,support async */ + PIS_UART3_ASY_SEND = 0xb1, /**< Uart3 asy send, pulse,support async */ + PIS_UART3_ASY_RECV = 0xb2, /**< Uart3 asy recv, pulse,support async */ + PIS_UART3_IRDA = 0xb3, /**< Uart3 irdaout, level,support async */ + PIS_UART3_RTS = 0xb4, /**< Uart3 rtsout, level,support async */ + PIS_UART3_TXOUT = 0xb5, /**< Uart3 txout, level,support async */ + PIS_UART3_SYN_SEND = 0xb6, /**< Uart3 syn send, pulse,support async */ + PIS_UART3_SYN_RECV = 0xb7, /**< Uart3 syn recv, pulse,support async */ + PIS_EUART0_RECV = 0xc0, /**< Euart0 recv, plck1 pulse */ + PIS_EUART0_SEND = 0xc1, /**< Euart0 send, plck1 pulse */ + PIS_EUART0_TXOUT = 0xc2, /**< Euart0 txout, plck1 level */ + PIS_EUART1_RECV = 0xd0, /**< Euart1 recv, plck1 pulse */ + PIS_EUART1_SEND = 0xd1, /**< Euart1 send, plck1 pulse */ + PIS_EUART1_TXOUT = 0xd2, /**< Euart1 txout, plck1 level */ + PIS_SPI0_RECV = 0xe0, /**< Spi0 recv, plck1 pulse */ + PIS_SPI0_SEND = 0xe1, /**< Spi0 send, plck1 pulse */ + PIS_SPI0_NE = 0xe2, /**< Spi0 ne, plck1 level */ + PIS_SPI1_RECV = 0xf0, /**< Spi1 recv, plck1 pulse */ + PIS_SPI1_SEND = 0xf1, /**< Spi1 send, plck1 pulse */ + PIS_SPI1_NE = 0xf2, /**< Spi1 ne, plck1 level */ + PIS_I2C0_RECV = 0x100, /**< I2c0 recv, plck1 level */ + PIS_I2C0_SEND = 0x101, /**< I2c0 send, plck1 level */ + PIS_I2C1_RECV = 0x110, /**< I2c1 recv, plck1 level */ + PIS_I2C1_SEND = 0x111, /**< I2c1 send, plck1 level */ + PIS_TIMER0_UPDATA = 0x120, /**< Timer0 updata, plck1 pulse */ + PIS_TIMER0_TRIG = 0x121, /**< Timer0 trig, plck1 pulse */ + PIS_TIMER0_INPUT = 0x122, /**< Timer0 input, plck1 pulse */ + PIS_TIMER0_OUTPUT = 0x123, /**< Timer0 output, plck1 pulse */ + PIS_TIMER1_UPDATA = 0x130, /**< Timer1 updata, plck1 pulse */ + PIS_TIMER1_TRIG = 0x131, /**< Timer1 trig, plck1 pulse */ + PIS_TIMER1_INPUT = 0x132, /**< Timer1 input, plck1 pulse */ + PIS_TIMER1_OUTPUT = 0x133, /**< Timer1 output, plck1 pulse */ + PIS_TIMER2_UPDATA = 0x140, /**< Timer2 updata, plck1 pulse */ + PIS_TIMER2_TRIG = 0x141, /**< Timer2 trig, plck1 pulse */ + PIS_TIMER2_INPUT = 0x142, /**< Timer2 input, plck1 pulse */ + PIS_TIMER2_OUTPUT = 0x143, /**< Timer2 output, plck1 pulse */ + PIS_TIMER3_UPDATA = 0x150, /**< Timer0 updata, plck1 pulse */ + PIS_TIMER3_TRIG = 0x151, /**< Timer0 trig, plck1 pulse */ + PIS_TIMER3_INPUT = 0x152, /**< Timer0 input, plck1 pulse */ + PIS_TIMER3_OUTPUT = 0x153, /**< Timer0 output, plck1 pulse */ + PIS_RTC_CLOCK = 0x160, /**< Rtc clock, pulse,support async */ + PIS_RTC_ALARM = 0x161, /**< Rtc alarm, pulse,support async */ + PIS_LPTIM0_SYN_UPDATA = 0x170, /**< Lptimer0 syn updata, pulse,support async */ + PIS_LPTIM0_ASY_UPDATA = 0x171, /**< Lptimer0 asy updata, pulse,support async */ + PIS_LPUART0_ASY_RECV = 0x180, /**< Lpuart0 asy recv, pulse,support async */ + PIS_LPUART0_ASY_SEND = 0x181, /**< Lpuart0 asy send, pulse,support async */ + PIS_LPUART0_SYN_RECV = 0x182, /**< Lpuart0 syn recv, pulse,support async */ + PIS_LPUART0_SYN_SEND = 0x183, /**< Lpuart0 syn recv, pulse,support async */ + PIS_DMA = 0x190, /**< Dma, pulse,support async */ + PIS_ADC1_INJECT = 0x1a0, /**< Adc1 inject, pclk2 pulse,support async */ + PIS_ADC1_REGULAT = 0x1a1, /**< Adc1 regulat, pclk2 pulse,support async */ + PIS_ADC1_WINDOW = 0x1a2, /**< Adc1 window, no have */ +} pis_src_t; + +/** + * @brief Consumer entry + * @note ES32F065x: + * AD16C4T0--TIMER0 + * GP16C4T0--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + * + * ES32F033x: + * ES32F093x: + * GP16C4T0--TIMER0 + * GP16C4T1--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + */ +typedef enum +{ + PIS_CH0_TIMER0_BRKIN = 0x0400, /**< Timer0 brkin */ + PIS_CH0_SPI1_CLK = 0x0F10, /**< Spi1 clk */ + PIS_CH0_LPTIM0_EXT0 = 0x0030, /**< Lptimer0 ext0 */ + PIS_CH0_ADC1_NORMAL = 0x0030, /**< Adc1 normal */ + PIS_CH1_TIMER0_CH1IN = 0x0001, /**< Timer0 ch1in */ + PIS_CH1_TIMER2_CH1IN = 0x1001, /**< Timer2 ch1in */ + PIS_CH1_TIMER3_CH1IN = 0x1801, /**< Timer3 ch1in */ + PIS_CH1_LPTIM0_EXT1 = 0x0031, /**< Lptime0 ext1 */ + PIS_CH1_UART0_RX_IRDA = 0x0011, /**< Uart0 rx irda */ + PIS_CH1_ADC1_INSERT = 0x0031, /**< Adc1 insert */ + PIS_CH2_TIMER0_CH2IN = 0x0102, /**< Timer0 ch2in */ + PIS_CH2_TIMER2_CH2IN = 0x1102, /**< Timer2 ch2in */ + PIS_CH2_TIMER3_CH2IN = 0x1902, /**< Timer3 ch2in */ + PIS_CH2_LPTIM0_EXT2 = 0x0032, /**< Lptime0 ext2 */ + PIS_CH2_UART1_RX_IRDA = 0x0112, /**< Uart1 rx irda */ + PIS_CH3_TIMER0_CH3IN = 0x0203, /**< Timer0 ch3in */ + PIS_CH3_LPTIM0_EXT3 = 0x0033, /**< Lptime0 ext3 */ + PIS_CH3_UART2_RX_IRDA = 0x0213, /**< Uart2 rx irda */ + PIS_CH4_TIMER0_CH4IN = 0x0004, /**< Timer0 ch4in */ + PIS_CH4_TIMER0_ITR0 = 0x0034, /**< Timer0 itr0 */ + PIS_CH4_TIMER2_ITR0 = 0x0034, /**< Timer2 itr0 */ + PIS_CH4_TIMER3_ITR0 = 0x0034, /**< Timer3 itr0 */ + PIS_CH4_LPTIM0_EXT4 = 0x0434, /**< Lptime0 ext4 */ + PIS_CH4_UART3_RX_IRDA = 0x0314, /**< Uart3 rx irda */ + PIS_CH5_SPI0_RX = 0x0C15, /**< Spi0 rx */ + PIS_CH5_LPTIM0_EXT5 = 0x0035, /**< Lptime0 ext5 */ + PIS_CH5_EUART0_RX = 0x0615, /**< Euart0 rx */ + PIS_CH5_TIMER0_ITR1 = 0x0035, /**< Timer0 itr1 */ + PIS_CH5_TIMER2_ITR1 = 0x0035, /**< Timer2 itr1 */ + PIS_CH5_TIMER3_ITR1 = 0x0035, /**< Timer3 itr1 */ + PIS_CH6_SPI0_CLK = 0x0D16, /**< Spi0 clk */ + PIS_CH6_ADC0_NORMAL = 0x0036, /**< Adc0 normal */ + PIS_CH6_LPTIM0_EXT6 = 0x0036, /**< Lptime0 ext6 */ + PIS_CH6_EUART1_RX = 0x0716, /**< Euart1 rx */ + PIS_CH6_TIMER0_ITR2 = 0x0036, /**< Timer0 itr2 */ + PIS_CH6_TIMER2_ITR2 = 0x0036, /**< Timer2 itr2 */ + PIS_CH6_TIMER3_ITR2 = 0x0036, /**< Timer3 itr2 */ + PIS_CH6_DAC_CH1 = 0x0036, /**< Dac channel 1 */ + PIS_CH7_SPI1_RX = 0x0E17, /**< Spi1 rx */ + PIS_CH7_ADC0_INSERT = 0x0037, /**< Adc0 insert */ + PIS_CH7_LPTIM0_EXT7 = 0x0037, /**< Lptime0 ext7 */ + PIS_CH7_DMA = 0x0037, /**< Dma */ + PIS_CH7_TIMER0_ITR3 = 0x0037, /**< Timer0 itr3 */ + PIS_CH7_TIMER2_ITR3 = 0x0037, /**< Timer2 itr3 */ + PIS_CH7_TIMER3_ITR3 = 0x0037, /**< Timer3 itr3 */ + PIS_CH7_LPUART_RX = 0x0817, /**< Lpuart rx */ + PIS_CH7_DAC_CH0 = 0x0037, /**< Dac channel 0 */ +} pis_trig_t; + +/** + * @brief Clock select + */ +typedef enum +{ + PIS_CLK_PCLK1 = 0, /**< Pclock1 */ + PIS_CLK_PCLK2 = 1, /**< Pclock2 */ + PIS_CLK_SYS = 2, /**< Sys clock */ + PIS_CLK_LP = 3, /**< Low power clock */ +} pis_clock_t; + +/** + * @brief Level select + */ +typedef enum +{ + PIS_EDGE_NONE = 0, /**< None edge */ + PIS_EDGE_UP = 1, /**< Up edge */ + PIS_EDGE_DOWN = 2, /**< Down edge */ + PIS_EDGE_UP_DOWN = 3, /**< Up and down edge */ +} pis_edge_t; + +/** + * @brief Output style + */ +typedef enum +{ + PIS_OUT_LEVEL = 0, /**< Level */ + PIS_OUT_PULSE = 1, /**< Pulse */ +} pis_output_t; +/** + * @brief Sync select + */ +typedef enum +{ + PIS_SYN_DIRECT = 0, /**< Direct */ + PIS_SYN_ASY_PCLK1 = 1, /**< Asy pclk1 */ + PIS_SYN_ASY_PCLK2 = 2, /**< Asy pclk2 */ + PIS_SYN_ASY_PCLK = 3, /**< Asy pclk */ + PIS_SYN_PCLK2_PCLK1 = 4, /**< Pclk2 to pclk1 */ + PIS_SYN_PCLK1_PCLK2 = 5, /**< Pclk1 to pclk2 */ + PIS_SYN_PCLK12_SYS = 6, /**< Pclk1 or pclk2 to sysclk */ +} pis_syncsel_t; + +/** + * @brief Pis channel + */ +typedef enum +{ + PIS_CH_0 = 0, /**< Channel 0 */ + PIS_CH_1 = 1, /**< Channel 1 */ + PIS_CH_2 = 2, /**< Channel 2 */ + PIS_CH_3 = 3, /**< Channel 3 */ + PIS_CH_4 = 4, /**< Channel 4 */ + PIS_CH_5 = 5, /**< Channel 5 */ + PIS_CH_6 = 6, /**< Channel 6 */ + PIS_CH_7 = 7, /**< Channel 7 */ +} pis_ch_t; + +/** + * @brief Pis output channel + */ +typedef enum +{ + PIS_OUT_CH_0 = 0, /**< Channel 0 */ + PIS_OUT_CH_1 = 1, /**< Channel 1 */ + PIS_OUT_CH_2 = 2, /**< Channel 2 */ + PIS_OUT_CH_3 = 3, /**< Channel 3 */ +} pis_out_ch_t; + +/** + * @brief Indirect value,no care of it. + */ +typedef enum +{ + PIS_CON_0 = 0, /**< Con 0 */ + PIS_CON_1 = 1, /**< Con 1 */ + PIS_CON_NONE = 2, /**< None */ +} pis_con_t; + +/** + * @brief Indirect value,no care of it. + */ +typedef union +{ + struct + { + uint8_t ch : 4; /**< Channel */ + uint8_t con : 4; /**< Contorl */ + uint8_t shift : 8; /**< Shift */ + }; + uint16_t HalfWord; +} pis_divide_t; + +/** + * @brief PIS state structures definition + */ +typedef enum +{ + PIS_STATE_RESET = 0x00, /**< Peripheral is not initialized */ + PIS_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + PIS_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + PIS_STATE_TIMEOUT = 0x03, /**< Timeout state */ + PIS_STATE_ERROR = 0x04, /**< Error */ +} pis_state_t; + +/** + * @brief PIS modulate target + */ +typedef enum +{ + PIS_UART0_TX = 0, /**< Modulate uart0 tx */ + PIS_UART1_TX = 1, /**< Modulate uart1 tx */ + PIS_UART2_TX = 2, /**< Modulate uart2 tx */ + PIS_UART3_TX = 3, /**< Modulate uart3 tx */ + PIS_LPUART0_TX = 4, /**< Modulate lpuart0 tx */ +} pis_modu_targ_t; + +/** + * @brief PIS modulate level + */ +typedef enum +{ + PIS_LOW_LEVEL = 0, /**< Modulate low level */ + PIS_HIGH_LEVEL = 1, /**< Modulate high level */ +} pis_modu_level_t; + +/** + * @brief PIS modulate source + * @note ES32F065x: + * AD16C4T0--TIMER0 + * GP16C4T0--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + * + * ES32F033x: + * ES32F093x: + * GP16C4T0--TIMER0 + * GP16C4T1--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + */ +typedef enum +{ + PIS_SRC_NONE = 0, /**< Stop modulate */ + PIS_SRC_TIMER0 = 1, /**< Modulate source is TIMER0 */ + PIS_SRC_TIMER1 = 2, /**< Modulate source is TIMER1 */ + PIS_SRC_TIMER2 = 3, /**< Modulate source is TIMER2 */ + PIS_SRC_TIMER3 = 4, /**< Modulate source is TIMER3 */ + PIS_SRC_TIMER6 = 5, /**< Modulate source is TIMER6 */ + PIS_SRC_TIMER7 = 6, /**< Modulate source is TIMER7 */ + PIS_SRC_LPTIM0 = 7, /**< Modulate source is LPTIM0 */ + PIS_SRC_BUZ = 8, /**< Modulate source is buz */ +} pis_modu_src_t; + +/** + * @brief PIS modulate channel + */ +typedef enum +{ + PIS_TIMER_CH1 = 0, /**< Src is TIMERx and choose channel 1 */ + PIS_TIMER_CH2 = 1, /**< Src is TIMERx and choose channel 2 */ + PIS_TIMER_CH3 = 2, /**< Src is TIMERx and choose channel 3 */ + PIS_TIMER_CH4 = 3, /**< Src is TIMERx and choose channel 4 */ +} pis_modu_channel_t; + +/** + * @brief PIS init structure definition + */ +typedef struct +{ + pis_src_t producer_src; /**< Producer entry */ + pis_clock_t producer_clk; /**< Producer module clock */ + pis_edge_t producer_edge; /**< Producer module pin output edge */ + pis_trig_t consumer_trig; /**< Consumer entry */ + pis_clock_t consumer_clk; /**< Consumer clock */ +} pis_init_t; + +/** + * @brief PIS modulate config structure definition + */ +typedef struct +{ + pis_modu_targ_t target; /**< Modulate target */ + pis_modu_level_t level; /**< Modulate level */ + pis_modu_src_t src; /**< Modulate src */ + pis_modu_channel_t channel; /**< Modulate channel */ +} pis_modulate_config_t; + +/** + * @brief PIS Handle Structure definition + */ +typedef struct pis_handle_s +{ + PIS_TypeDef *perh; /**< Register base address */ + pis_init_t init; /**< PIS required parameters */ + pis_ch_t consumer_ch; /**< Indirect value, no care of it */ + pis_con_t consumer_con; /**< Indirect value, no care of it */ + uint8_t consumer_pos; /**< Indirect value, no care of it */ + uint32_t check_info; /**< When destroy a handle ,user need check whether is right that ready to destroy */ + lock_state_t lock; /**< Locking object */ + pis_state_t state; /**< PIS operation state */ +} pis_handle_t; +/** + * @} + */ + + +/** @defgroup PIS_Private_Macros PIS Private Macros + * @{ + */ +#define IS_PIS(x) (((x) == PIS)) +#define IS_PIS_SRC(x) (((x) == PIS_NON) || \ + ((x) == PIS_GPIO_PIN0) || \ + ((x) == PIS_GPIO_PIN1) || \ + ((x) == PIS_GPIO_PIN2) || \ + ((x) == PIS_GPIO_PIN3) || \ + ((x) == PIS_GPIO_PIN4) || \ + ((x) == PIS_GPIO_PIN5) || \ + ((x) == PIS_GPIO_PIN6) || \ + ((x) == PIS_GPIO_PIN7) || \ + ((x) == PIS_GPIO_PIN8) || \ + ((x) == PIS_GPIO_PIN9) || \ + ((x) == PIS_GPIO_PIN10) || \ + ((x) == PIS_GPIO_PIN11) || \ + ((x) == PIS_GPIO_PIN12) || \ + ((x) == PIS_GPIO_PIN13) || \ + ((x) == PIS_GPIO_PIN14) || \ + ((x) == PIS_GPIO_PIN15) || \ + ((x) == PIS_ACMP_OUT0) || \ + ((x) == PIS_ACMP_OUT1) || \ + ((x) == PIS_DAC0_CH1) || \ + ((x) == PIS_ACMP_OUT1) || \ + ((x) == PIS_ADC0_INJECT) || \ + ((x) == PIS_ADC0_REGULAT) || \ + ((x) == PIS_ADC0_WINDOW) || \ + ((x) == PIS_LVD) || \ + ((x) == PIS_UART0_ASY_SEND) || \ + ((x) == PIS_UART0_ASY_RECV) || \ + ((x) == PIS_UART0_IRDAOUT) || \ + ((x) == PIS_UART0_RTSOUT) || \ + ((x) == PIS_UART0_TXOUT) || \ + ((x) == PIS_UART0_SYN_SEND) || \ + ((x) == PIS_UART0_SYN_RECV) || \ + ((x) == PIS_UART1_ASY_SEND) || \ + ((x) == PIS_UART1_ASY_RECV) || \ + ((x) == PIS_UART1_IRDA) || \ + ((x) == PIS_UART1_RTS) || \ + ((x) == PIS_UART1_TXOUT) || \ + ((x) == PIS_UART1_SYN_SEND) || \ + ((x) == PIS_UART1_SYN_RECV) || \ + ((x) == PIS_UART2_ASY_SEND) || \ + ((x) == PIS_UART2_ASY_RECV) || \ + ((x) == PIS_UART2_IRDA) || \ + ((x) == PIS_UART2_RTS) || \ + ((x) == PIS_UART2_TXOUT) || \ + ((x) == PIS_UART2_SYN_SEND) || \ + ((x) == PIS_UART2_SYN_RECV) || \ + ((x) == PIS_UART3_ASY_SEND) || \ + ((x) == PIS_UART3_ASY_RECV) || \ + ((x) == PIS_UART3_IRDA) || \ + ((x) == PIS_UART3_RTS) || \ + ((x) == PIS_UART3_TXOUT) || \ + ((x) == PIS_UART3_SYN_SEND) || \ + ((x) == PIS_UART3_SYN_RECV) || \ + ((x) == PIS_EUART0_RECV) || \ + ((x) == PIS_EUART0_SEND) || \ + ((x) == PIS_EUART0_TXOUT) || \ + ((x) == PIS_EUART1_RECV) || \ + ((x) == PIS_EUART1_SEND) || \ + ((x) == PIS_EUART1_TXOUT) || \ + ((x) == PIS_SPI0_RECV) || \ + ((x) == PIS_SPI0_SEND) || \ + ((x) == PIS_SPI0_NE) || \ + ((x) == PIS_SPI1_RECV) || \ + ((x) == PIS_SPI1_SEND) || \ + ((x) == PIS_SPI1_NE) || \ + ((x) == PIS_I2C0_RECV) || \ + ((x) == PIS_I2C0_SEND) || \ + ((x) == PIS_I2C1_RECV) || \ + ((x) == PIS_I2C1_SEND) || \ + ((x) == PIS_TIMER0_UPDATA) || \ + ((x) == PIS_TIMER0_TRIG) || \ + ((x) == PIS_TIMER0_INPUT) || \ + ((x) == PIS_TIMER0_OUTPUT) || \ + ((x) == PIS_TIMER1_UPDATA) || \ + ((x) == PIS_TIMER1_TRIG) || \ + ((x) == PIS_TIMER1_INPUT) || \ + ((x) == PIS_TIMER1_OUTPUT) || \ + ((x) == PIS_TIMER2_UPDATA) || \ + ((x) == PIS_TIMER2_TRIG) || \ + ((x) == PIS_TIMER2_INPUT) || \ + ((x) == PIS_TIMER2_OUTPUT) || \ + ((x) == PIS_TIMER3_UPDATA) || \ + ((x) == PIS_TIMER3_TRIG) || \ + ((x) == PIS_TIMER3_INPUT) || \ + ((x) == PIS_TIMER3_OUTPUT) || \ + ((x) == PIS_RTC_CLOCK) || \ + ((x) == PIS_RTC_ALARM) || \ + ((x) == PIS_LPTIM0_SYN_UPDATA) || \ + ((x) == PIS_LPTIM0_ASY_UPDATA) || \ + ((x) == PIS_LPUART0_ASY_RECV) || \ + ((x) == PIS_LPUART0_ASY_SEND) || \ + ((x) == PIS_LPUART0_SYN_RECV) || \ + ((x) == PIS_LPUART0_SYN_SEND) || \ + ((x) == PIS_DMA) || \ + ((x) == PIS_ADC1_INJECT) || \ + ((x) == PIS_ADC1_REGULAT) || \ + ((x) == PIS_ADC1_WINDOW)) +#define IS_PIS_TRIG(x) (((x) == PIS_CH0_TIMER0_BRKIN) || \ + ((x) == PIS_CH0_SPI1_CLK) || \ + ((x) == PIS_CH0_LPTIM0_EXT0) || \ + ((x) == PIS_CH0_ADC1_NORMAL) || \ + ((x) == PIS_CH1_TIMER0_CH1IN) || \ + ((x) == PIS_CH1_TIMER2_CH1IN) || \ + ((x) == PIS_CH1_TIMER3_CH1IN) || \ + ((x) == PIS_CH1_UART0_RX_IRDA) || \ + ((x) == PIS_CH1_LPTIM0_EXT1) || \ + ((x) == PIS_CH1_ADC1_INSERT) || \ + ((x) == PIS_CH2_TIMER0_CH2IN) || \ + ((x) == PIS_CH2_TIMER2_CH2IN) || \ + ((x) == PIS_CH2_TIMER3_CH2IN) || \ + ((x) == PIS_CH2_LPTIM0_EXT2) || \ + ((x) == PIS_CH2_UART1_RX_IRDA) || \ + ((x) == PIS_CH3_TIMER0_CH3IN) || \ + ((x) == PIS_CH3_LPTIM0_EXT3) || \ + ((x) == PIS_CH3_UART2_RX_IRDA) || \ + ((x) == PIS_CH4_TIMER0_CH4IN) || \ + ((x) == PIS_CH4_TIMER0_ITR0) || \ + ((x) == PIS_CH4_TIMER2_ITR0) || \ + ((x) == PIS_CH4_TIMER3_ITR0) || \ + ((x) == PIS_CH4_LPTIM0_EXT4) || \ + ((x) == PIS_CH4_UART3_RX_IRDA) || \ + ((x) == PIS_CH5_SPI0_RX) || \ + ((x) == PIS_CH5_LPTIM0_EXT5) || \ + ((x) == PIS_CH5_EUART0_RX) || \ + ((x) == PIS_CH5_TIMER0_ITR1) || \ + ((x) == PIS_CH5_TIMER2_ITR1) || \ + ((x) == PIS_CH5_TIMER3_ITR1) || \ + ((x) == PIS_CH6_SPI0_CLK) || \ + ((x) == PIS_CH6_ADC0_NORMAL) || \ + ((x) == PIS_CH6_LPTIM0_EXT6) || \ + ((x) == PIS_CH6_EUART1_RX) || \ + ((x) == PIS_CH6_TIMER0_ITR2) || \ + ((x) == PIS_CH6_TIMER2_ITR2) || \ + ((x) == PIS_CH6_TIMER3_ITR2) || \ + ((x) == PIS_CH6_DAC_CH1) || \ + ((x) == PIS_CH7_SPI1_RX) || \ + ((x) == PIS_CH7_ADC0_INSERT) || \ + ((x) == PIS_CH7_LPTIM0_EXT7) || \ + ((x) == PIS_CH7_DMA) || \ + ((x) == PIS_CH7_TIMER0_ITR3) || \ + ((x) == PIS_CH7_TIMER2_ITR3) || \ + ((x) == PIS_CH7_TIMER3_ITR3) || \ + ((x) == PIS_CH7_DAC_CH0) || \ + ((x) == PIS_CH7_LPUART_RX)) +#define IS_PIS_CLOCK(x) (((x) == PIS_CLK_PCLK1) || \ + ((x) == PIS_CLK_PCLK2) || \ + ((x) == PIS_CLK_SYS) || \ + ((x) == PIS_CLK_LP)) +#define IS_PIS_EDGE(x) (((x) == PIS_EDGE_NONE) || \ + ((x) == PIS_EDGE_UP) || \ + ((x) == PIS_EDGE_DOWN) || \ + ((x) == PIS_EDGE_UP_DOWN)) +#define IS_PIS_OUTPUT(x) (((x) == PIS_OUT_LEVEL) || \ + ((x) == PIS_OUT_PULSE)) +#define IS_PIS_OUPUT_CH(x) (((x) == PIS_OUT_CH_0) || \ + ((x) == PIS_OUT_CH_1) || \ + ((x) == PIS_OUT_CH_2) || \ + ((x) == PIS_OUT_CH_3)) +#define IS_PIS_MODU_TARGET(x) (((x) == PIS_UART0_TX) || \ + ((x) == PIS_UART1_TX) || \ + ((x) == PIS_UART2_TX) || \ + ((x) == PIS_UART3_TX) || \ + ((x) == PIS_LPUART0_TX)) +#define IS_PIS_MODU_LEVEL(x) (((x) == PIS_LOW_LEVEL) || \ + ((x) == PIS_HIGH_LEVEL)) +#define IS_PIS_MODU_SRC(x) (((x) == PIS_SRC_NONE) || \ + ((x) == PIS_SRC_TIMER0) || \ + ((x) == PIS_SRC_TIMER1) || \ + ((x) == PIS_SRC_TIMER2) || \ + ((x) == PIS_SRC_TIMER3) || \ + ((x) == PIS_SRC_TIMER6) || \ + ((x) == PIS_SRC_TIMER7) || \ + ((x) == PIS_SRC_LPTIM0) || \ + ((x) == PIS_SRC_BUZ)) +#define IS_PIS_MODU_CHANNEL(x) (((x) == PIS_TIMER_CH1) || \ + ((x) == PIS_TIMER_CH2) || \ + ((x) == PIS_TIMER_CH3) || \ + ((x) == PIS_TIMER_CH4)) +/** + * @} + */ + +/** @addtogroup PIS_Public_Functions + * @{ + */ + +/** @addtogroup PIS_Public_Functions_Group1 + * @{ + */ +ald_status_t ald_pis_create(pis_handle_t *hperh); +ald_status_t ald_pis_destroy(pis_handle_t *hperh); +/** + * @} + */ + +/** @addtogroup PIS_Public_Functions_Group2 + * @{ + */ +ald_status_t ald_pis_output_start(pis_handle_t *hperh, pis_out_ch_t ch); +ald_status_t ald_pis_output_stop(pis_handle_t *hperh, pis_out_ch_t ch); +/** + * @} + */ + +/** @addtogroup PIS_Public_Functions_Group3 + * @{ + */ +pis_state_t ald_pis_get_state(pis_handle_t *hperh); +/** + * @} + */ + +/** @addtogroup PIS_Public_Functions_Group4 + * @{ + */ +ald_status_t ald_pis_modu_config(pis_handle_t *hperh, pis_modulate_config_t *config); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_PIS_H__ */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pmu.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pmu.h new file mode 100644 index 0000000000..85c9626578 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_pmu.h @@ -0,0 +1,211 @@ +/** + ********************************************************************************* + * + * @file ald_pmu.h + * @brief Header file of PMU module driver. + * + * @version V1.0 + * @date 04 Dec 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ******************************************************************************** + */ + +#ifndef __ALD_PMU_H__ +#define __ALD_PMU_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" +#include "ald_syscfg.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup PMU + * @{ + */ + +/** @defgroup PMU_Public_Macros PMU Public Macros + * @{ + */ +#define PMU_SRAM0_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(PMU->PWRCR, BIT(PMU_PWRCR_SRAM_POSS)); \ + SYSCFG_LOCK(); \ + } while (0) +#define PMU_SRAM0_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(PMU->PWRCR, BIT(PMU_PWRCR_SRAM_POSS));\ + SYSCFG_LOCK(); \ + } while (0) +#define PMU_SRAM1_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(PMU->PWRCR, BIT(PMU_PWRCR_SRAM_POSE)); \ + SYSCFG_LOCK(); \ + } while (0) +#define PMU_SRAM1_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(PMU->PWRCR, BIT(PMU_PWRCR_SRAM_POSE));\ + SYSCFG_LOCK(); \ + } while (0) +#define PMU_BXCAN_ENABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(PMU->PWRCR, PMU_PWRCR_BXCAN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) +#define PMU_BXCAN_DISABLE() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(PMU->PWRCR, PMU_PWRCR_BXCAN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) + +#define PMU_GET_LVD_STATUS() (READ_BITS(PMU->LVDCR, PMU_LVDCR_LVDO_MSK, PMU_LVDCR_LVDO_POS)) +/** + * @} + */ + + +/** @defgroup PMU_Public_Types PMU Public Types + * @{ + */ +/** + * @brief Low power mode + */ +typedef enum +{ + PMU_LP_STOP1 = 0x0, /**< Stop1 */ + PMU_LP_STOP2 = 0x1, /**< Stop2 */ +} pmu_lp_mode_t; + +typedef enum +{ + PMU_SR_WUF = (1U << 0), +} pmu_status_t; + +/** + * @brief LVD voltage select + */ +typedef enum +{ + PMU_LVD_VOL_SEL_2_0 = 0x0, /**< 2.0V ~ 2.05V */ + PMU_LVD_VOL_SEL_2_1 = 0x1, /**< 2.1V ~ 2.15V */ + PMU_LVD_VOL_SEL_2_2 = 0x2, /**< 2.2V ~ 2.25V */ + PMU_LVD_VOL_SEL_2_4 = 0x3, /**< 2.4V ~ 2.45V */ + PMU_LVD_VOL_SEL_2_6 = 0x4, /**< 2.6V ~ 2.65V */ + PMU_LVD_VOL_SEL_2_8 = 0x5, /**< 2.8V ~ 2.85V */ + PMU_LVD_VOL_SEL_3_0 = 0x6, /**< 3.0V ~ 3.05V */ + PMU_LVD_VOL_SEL_3_6 = 0x7, /**< 3.6V ~ 3.65V */ + PMU_LVD_VOL_SEL_4_0 = 0x8, /**< 4.0V ~ 4.05V */ + PMU_LVD_VOL_SEL_4_6 = 0x9, /**< 4.6V ~ 4.65V */ + PMU_LVD_VOL_SEL_2_3 = 0xA, /**< 2.3V ~ 2.35V */ + PMU_LVD_VOL_SEL_EXT = 0xF, /**< Select external input. It must be 1.2V */ +} pmu_lvd_voltage_sel_t; + +/** + * @brief LVD trigger mode + */ +typedef enum +{ + PMU_LVD_TRIGGER_RISING_EDGE = 0x0, /**< Rising edge */ + PMU_LVD_TRIGGER_FALLING_EDGE = 0x1, /**< Falling edge */ + PMU_LVD_TRIGGER_HIGH_LEVEL = 0x2, /**< High level */ + PMU_LVD_TRIGGER_LOW_LEVEL = 0x3, /**< Low level */ + PMU_LVD_TRIGGER_RISING_FALLING = 0x4, /**< Rising and falling edge */ +} pmu_lvd_trigger_mode_t; + +/** + * @} + */ + +/** + * @defgroup PMU_Private_Macros PMU Private Macros + * @{ + */ +#define IS_PMU_LP_MODE(x) (((x) == PMU_LP_STOP1) || \ + ((x) == PMU_LP_STOP2)) +#define IS_PMU_STATUS(x) ((x) == PMU_SR_WUF) +#define IS_PMU_LVD_VOL_SEL(x) (((x) == PMU_LVD_VOL_SEL_2_0) || \ + ((x) == PMU_LVD_VOL_SEL_2_1) || \ + ((x) == PMU_LVD_VOL_SEL_2_2) || \ + ((x) == PMU_LVD_VOL_SEL_2_4) || \ + ((x) == PMU_LVD_VOL_SEL_2_6) || \ + ((x) == PMU_LVD_VOL_SEL_2_8) || \ + ((x) == PMU_LVD_VOL_SEL_3_0) || \ + ((x) == PMU_LVD_VOL_SEL_3_6) || \ + ((x) == PMU_LVD_VOL_SEL_4_0) || \ + ((x) == PMU_LVD_VOL_SEL_4_6) || \ + ((x) == PMU_LVD_VOL_SEL_2_3) || \ + ((x) == PMU_LVD_VOL_SEL_EXT)) +#define IS_PMU_LVD_TRIGGER_MODE(x) (((x) == PMU_LVD_TRIGGER_RISING_EDGE) || \ + ((x) == PMU_LVD_TRIGGER_FALLING_EDGE) || \ + ((x) == PMU_LVD_TRIGGER_HIGH_LEVEL) || \ + ((x) == PMU_LVD_TRIGGER_LOW_LEVEL) || \ + ((x) == PMU_LVD_TRIGGER_RISING_FALLING)) +/** + * @} + */ + +/** @addtogroup PMU_Public_Functions + * @{ + */ +/** @addtogroup PMU_Public_Functions_Group1 + * @{ + */ +/* Low power mode select */ +__STATIC_INLINE__ void ald_pmu_sleep() +{ + __WFI(); +} + +__STATIC_INLINE__ void ald_pmu_sleep_deep() +{ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + __WFI(); +} + +void ald_pmu_stop1_enter(void); +void ald_pmu_stop2_enter(void); +flag_status_t ald_pmu_get_status(pmu_status_t sr); +void ald_pmu_clear_status(pmu_status_t sr); +/** + * @} + */ +/** @addtogroup PMU_Public_Functions_Group2 + * @{ + */ +/* LVD configure */ +void ald_pmu_lvd_config(pmu_lvd_voltage_sel_t sel, pmu_lvd_trigger_mode_t mode, type_func_t state); +void ald_lvd_irq_handler(void); +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_PMU_H__ */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rmu.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rmu.h new file mode 100644 index 0000000000..b6a7060e4e --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rmu.h @@ -0,0 +1,285 @@ +/** + ********************************************************************************* + * + * @file ald_rmu.h + * @brief Header file of RMU module driver. + * + * @version V1.0 + * @date 04 Dec 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ******************************************************************************** + */ + +#ifndef __ALD_RMU_H__ +#define __ALD_RMU_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup RMU + * @{ + */ + +/** @defgroup RMU_Public_Types RMU Public Types + * @{ + */ +/** + * @brief RMU BOR fliter + */ +typedef enum +{ + RMU_BORFLT_1 = 0x1, /**< 1 cycle */ + RMU_BORFLT_2 = 0x2, /**< 2 cycles */ + RMU_BORFLT_3 = 0x3, /**< 3 cycles */ + RMU_BORFLT_4 = 0x4, /**< 4 cycles */ + RMU_BORFLT_5 = 0x5, /**< 5 cycles */ + RMU_BORFLT_6 = 0x6, /**< 6 cycles */ + RMU_BORFLT_7 = 0x7, /**< 7 cycles */ +} rmu_bor_filter_t; + +/** + * @brief RMU BOR voltage + */ +typedef enum +{ + RMU_VOL_1_7 = 0x0, /**< 1.7V */ + RMU_VOL_2_0 = 0x1, /**< 2.0V */ + RMU_VOL_2_1 = 0x2, /**< 2.1V */ + RMU_VOL_2_2 = 0x3, /**< 2.2V */ + RMU_VOL_2_3 = 0x4, /**< 2.3V */ + RMU_VOL_2_4 = 0x5, /**< 2.4V */ + RMU_VOL_2_5 = 0x6, /**< 2.5V */ + RMU_VOL_2_6 = 0x7, /**< 2.6V */ + RMU_VOL_2_8 = 0x8, /**< 2.8V */ + RMU_VOL_3_0 = 0x9, /**< 3.0V */ + RMU_VOL_3_1 = 0xA, /**< 3.1V */ + RMU_VOL_3_3 = 0xB, /**< 3.3V */ + RMU_VOL_3_6 = 0xC, /**< 3.6V */ + RMU_VOL_3_7 = 0xD, /**< 3.7V */ + RMU_VOL_4_0 = 0xE, /**< 4.0V */ + RMU_VOL_4_3 = 0xF, /**< 4.3V */ +} rmu_bor_vol_t; + +/** + * @brief RMU reset status + */ +typedef enum +{ + RMU_RST_POR = (1U << 0), /**< POR */ + RMU_RST_WAKEUP = (1U << 1), /**< WAKEUP */ + RMU_RST_BOR = (1U << 2), /**< BOR */ + RMU_RST_NMRST = (1U << 3), /**< NMRST */ + RMU_RST_IWDT = (1U << 4), /**< IWDT */ + RMU_RST_WWDT = (1U << 5), /**< WWDT */ + RMU_RST_LOCKUP = (1U << 6), /**< LOCKUP */ + RMU_RST_CHIP = (1U << 7), /**< CHIP */ + RMU_RST_MCU = (1U << 8), /**< MCU */ + RMU_RST_CPU = (1U << 9), /**< CPU */ + RMU_RST_CFG = (1U << 10), /**< CFG */ + RMU_RST_CFGERR = (1U << 16), /**< CFG Error */ +} rmu_state_t; + +/** + * @brief RMU periperal select bit + * @note ES32F065x: + * AD16C4T0--TIMER0 + * GP16C4T0--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + * + * ES32F033x: + * ES32F093x: + * GP16C4T0--TIMER0 + * GP16C4T1--TIMER6 + * GP16C2T0--TIMER2 + * GP16C2T1--TIMER3 + * BS16T0----TIMER1 + * BS16T1----TIMER4 + * BS16T2----TIMER5 + * BS16T3----TIMER7 + */ +typedef enum +{ + RMU_PERH_GPIO = (1U << 0), /**< AHB1: GPIO */ + RMU_PERH_CRC = (1U << 1), /**< AHB1: CRC */ + RMU_PERH_CALC = (1U << 2), /**< AHB1: CALC */ + RMU_PERH_CRYPT = (1U << 3), /**< AHB1: CRYPT */ + RMU_PERH_TRNG = (1U << 4), /**< AHB1: TRNG */ + RMU_PERH_PIS = (1U << 5), /**< AHB1: PIS */ + RMU_PERH_CHIP = (1U << 0) | (1U << 27), /**< AHB2: CHIP */ + RMU_PERH_CPU = (1U << 1) | (1U << 27), /**< AHB2: CPU */ + RMU_PERH_TIMER0 = (1U << 0) | (1U << 28), /**< APB1: TIMER0 */ + RMU_PERH_TIMER1 = (1U << 1) | (1U << 28), /**< APB1: TIMER1 */ + RMU_PERH_TIMER2 = (1U << 2) | (1U << 28), /**< APB1: TIMER2 */ + RMU_PERH_TIMER3 = (1U << 3) | (1U << 28), /**< APB1: TIMER3 */ + RMU_PERH_TIMER4 = (1U << 4) | (1U << 28), /**< APB1: TIMER4 */ + RMU_PERH_TIMER5 = (1U << 5) | (1U << 28), /**< APB1: TIMER5 */ + RMU_PERH_TIMER6 = (1U << 6) | (1U << 28), /**< APB1: TIMER6 */ + RMU_PERH_TIMER7 = (1U << 7) | (1U << 28), /**< APB1: TIMER7 */ + RMU_PERH_UART0 = (1U << 8) | (1U << 28), /**< APB1: UART0 */ + RMU_PERH_UART1 = (1U << 9) | (1U << 28), /**< APB1: UART1 */ + RMU_PERH_UART2 = (1U << 10) | (1U << 28), /**< APB1: UART2 */ + RMU_PERH_UART3 = (1U << 11) | (1U << 28), /**< APB1: UART3 */ + RMU_PERH_USART0 = (1U << 12) | (1U << 28), /**< APB1: EUART0 */ + RMU_PERH_USART1 = (1U << 13) | (1U << 28), /**< APB1: EUART1 */ + RMU_PERH_SPI0 = (1U << 16) | (1U << 28), /**< APB1: SPI0 */ + RMU_PERH_SPI1 = (1U << 17) | (1U << 28), /**< APB1: SPI1 */ + RMU_PERH_SPI2 = (1U << 18) | (1U << 28), /**< APB1: SPI2 */ + RMU_PERH_I2C0 = (1U << 20) | (1U << 28), /**< APB1: I2C0 */ + RMU_PERH_I2C1 = (1U << 21) | (1U << 28), /**< APB1: I2C1 */ + RMU_PERH_CAN0 = (1U << 24) | (1U << 28), /**< APB1: CAN0 */ + RMU_PERH_LPTIM0 = (1U << 0) | (1U << 29), /**< APB2: LPTIM0 */ + RMU_PERH_LPUART0 = (1U << 2) | (1U << 29), /**< APB2: LPUART */ + RMU_PERH_ADC0 = (1U << 4) | (1U << 29), /**< APB2: ADC0 */ + RMU_PERH_ADC1 = (1U << 5) | (1U << 29), /**< APB2: ADC1 */ + RMU_PERH_ACMP0 = (1U << 6) | (1U << 29), /**< APB2: ACMP0 */ + RMU_PERH_ACMP1 = (1U << 7) | (1U << 29), /**< APB2: ACMP1 */ + RMU_PERH_OPAMP = (1U << 8) | (1U << 29), /**< APB2: OPAMP */ + RMU_PERH_DAC0 = (1U << 9) | (1U << 29), /**< APB2: DAC0 */ + RMU_PERH_WWDT = (1U << 12) | (1U << 29), /**< APB2: WWDT */ + RMU_PERH_LCD = (1U << 13) | (1U << 29), /**< APB2: LCD */ + RMU_PERH_IWDT = (1U << 14) | (1U << 29), /**< APB2: IWDT */ + RMU_PERH_RTC = (1U << 15) | (1U << 29), /**< APB2: RTC */ + RMU_PERH_TSENSE = (1U << 16) | (1U << 29), /**< APB2: TSENSE */ + RMU_PERH_BKPC = (1U << 17) | (1U << 29), /**< APB2: BKPC */ + RMU_PERH_BKPRAM = (1U << 18) | (1U << 29), /**< APB2: BKPRAM */ +} rmu_peripheral_t; +/** + * @} + */ + +/** + * @defgroup RMU_Private_Macros RMU Private Macros + * @{ + */ +#define IS_RMU_BORFLT(x) (((x) == RMU_BORFLT_1) || \ + ((x) == RMU_BORFLT_2) || \ + ((x) == RMU_BORFLT_3) || \ + ((x) == RMU_BORFLT_4) || \ + ((x) == RMU_BORFLT_5) || \ + ((x) == RMU_BORFLT_6) || \ + ((x) == RMU_BORFLT_7)) +#define IS_RMU_BORVOL(x) (((x) == RMU_VOL_1_7) || \ + ((x) == RMU_VOL_2_0) || \ + ((x) == RMU_VOL_2_1) || \ + ((x) == RMU_VOL_2_2) || \ + ((x) == RMU_VOL_2_3) || \ + ((x) == RMU_VOL_2_4) || \ + ((x) == RMU_VOL_2_5) || \ + ((x) == RMU_VOL_2_6) || \ + ((x) == RMU_VOL_2_8) || \ + ((x) == RMU_VOL_3_0) || \ + ((x) == RMU_VOL_3_1) || \ + ((x) == RMU_VOL_3_3) || \ + ((x) == RMU_VOL_3_6) || \ + ((x) == RMU_VOL_3_7) || \ + ((x) == RMU_VOL_4_0) || \ + ((x) == RMU_VOL_4_3)) +#define IS_RMU_STATE(x) (((x) == RMU_RST_POR) || \ + ((x) == RMU_RST_WAKEUP) || \ + ((x) == RMU_RST_BOR) || \ + ((x) == RMU_RST_NMRST) || \ + ((x) == RMU_RST_IWDT) || \ + ((x) == RMU_RST_WWDT) || \ + ((x) == RMU_RST_LOCKUP) || \ + ((x) == RMU_RST_CHIP) || \ + ((x) == RMU_RST_MCU) || \ + ((x) == RMU_RST_CPU) || \ + ((x) == RMU_RST_CFG) || \ + ((x) == RMU_RST_CFGERR)) +#define IS_RMU_STATE_CLEAR(x) (((x) == RMU_RST_POR) || \ + ((x) == RMU_RST_WAKEUP) || \ + ((x) == RMU_RST_BOR) || \ + ((x) == RMU_RST_NMRST) || \ + ((x) == RMU_RST_IWDT) || \ + ((x) == RMU_RST_WWDT) || \ + ((x) == RMU_RST_LOCKUP) || \ + ((x) == RMU_RST_CHIP) || \ + ((x) == RMU_RST_MCU) || \ + ((x) == RMU_RST_CPU) || \ + ((x) == RMU_RST_CFG)) +#define IS_RMU_PERH(x) (((x) == RMU_PERH_GPIO) || \ + ((x) == RMU_PERH_CRC) || \ + ((x) == RMU_PERH_CALC) || \ + ((x) == RMU_PERH_CRYPT) || \ + ((x) == RMU_PERH_TRNG) || \ + ((x) == RMU_PERH_PIS) || \ + ((x) == RMU_PERH_CHIP) || \ + ((x) == RMU_PERH_CPU) || \ + ((x) == RMU_PERH_TIMER0) || \ + ((x) == RMU_PERH_TIMER1) || \ + ((x) == RMU_PERH_TIMER2) || \ + ((x) == RMU_PERH_TIMER3) || \ + ((x) == RMU_PERH_TIMER4) || \ + ((x) == RMU_PERH_TIMER5) || \ + ((x) == RMU_PERH_TIMER6) || \ + ((x) == RMU_PERH_TIMER7) || \ + ((x) == RMU_PERH_UART0) || \ + ((x) == RMU_PERH_UART1) || \ + ((x) == RMU_PERH_UART2) || \ + ((x) == RMU_PERH_UART3) || \ + ((x) == RMU_PERH_USART0) || \ + ((x) == RMU_PERH_USART1) || \ + ((x) == RMU_PERH_SPI0) || \ + ((x) == RMU_PERH_SPI1) || \ + ((x) == RMU_PERH_SPI2) || \ + ((x) == RMU_PERH_I2C0) || \ + ((x) == RMU_PERH_I2C1) || \ + ((x) == RMU_PERH_CAN0) || \ + ((x) == RMU_PERH_LPTIM0) || \ + ((x) == RMU_PERH_LPUART0) || \ + ((x) == RMU_PERH_ADC0) || \ + ((x) == RMU_PERH_ADC1) || \ + ((x) == RMU_PERH_ACMP0) || \ + ((x) == RMU_PERH_ACMP1) || \ + ((x) == RMU_PERH_OPAMP) || \ + ((x) == RMU_PERH_DAC0) || \ + ((x) == RMU_PERH_WWDT) || \ + ((x) == RMU_PERH_LCD) || \ + ((x) == RMU_PERH_IWDT) || \ + ((x) == RMU_PERH_RTC) || \ + ((x) == RMU_PERH_TSENSE) || \ + ((x) == RMU_PERH_BKPC) || \ + ((x) == RMU_PERH_BKPRAM)) +/** + * @} + */ + +/** @addtogroup RMU_Public_Functions + * @{ + */ +void ald_rmu_bor_config(rmu_bor_filter_t flt, rmu_bor_vol_t vol, type_func_t state); +flag_status_t ald_rmu_get_reset_status(rmu_state_t state); +void ald_rmu_clear_reset_status(rmu_state_t state); +void ald_rmu_reset_periperal(rmu_peripheral_t perh); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_RMU_H__ */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rtc.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rtc.h new file mode 100644 index 0000000000..e14f542363 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_rtc.h @@ -0,0 +1,699 @@ +/** + ****************************************************************************** + * @file ald_rtc.h + * @brief Header file of RTC Module driver. + * + * @version V1.0 + * @date 16 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ******************************************************************************* + */ + +#ifndef __ALD_RTC_H__ +#define __ALD_RTC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup RTC + * @{ + */ + +/** @defgroup RTC_Public_Types RTC Public Types + * @{ + */ + +/** + * @brief Hours format + */ +typedef enum +{ + RTC_HOUR_FORMAT_24 = 0x0, /**< 24-hours format */ + RTC_HOUR_FORMAT_12 = 0x1, /**< 12-hours format */ +} rtc_hour_format_t; + +/** + * @brief Output mode + */ +typedef enum +{ + RTC_OUTPUT_DISABLE = 0x0, /**< Disable output */ + RTC_OUTPUT_ALARM_A = 0x1, /**< Output alarm_a signal */ + RTC_OUTPUT_ALARM_B = 0x2, /**< Output alarm_b signal */ + RTC_OUTPUT_WAKEUP = 0x3, /**< Output wakeup signal */ +} rtc_output_select_t; + +/** + * @brief Output polarity + */ +typedef enum +{ + RTC_OUTPUT_POLARITY_HIGH = 0x0, /**< Polarity is high */ + RTC_OUTPUT_POLARITY_LOW = 0x0, /**< Polarity is low */ +} rtc_output_polarity_t; + +/** + * @brief Initialization structure + */ +typedef struct +{ + rtc_hour_format_t hour_format; /**< Hours format */ + uint32_t asynch_pre_div; /**< Asynchronous predivider value */ + uint32_t synch_pre_div; /**< Synchronous predivider value */ + rtc_output_select_t output; /**< Output signal type */ + rtc_output_polarity_t output_polarity; /**< Output polarity */ +} rtc_init_t; + +/** + * @brief Source select + */ +typedef enum +{ + RTC_SOURCE_LOSC = 0x0, /**< LOSC */ + RTC_SOURCE_LRC = 0x1, /**< LRC */ + RTC_SOURCE_HRC_DIV_1M = 0x2, /**< HRC divide to 1MHz */ + RTC_SOURCE_HOSC_DIV_1M = 0x3, /**< HOSC divide to 1MHz */ +} rtc_source_sel_t; + +/** + * @brief Time structure + */ +typedef struct +{ + uint8_t hour; /**< Hours */ + uint8_t minute; /**< Minutes */ + uint8_t second; /**< Seconds */ + uint16_t sub_sec; /**< Sub-seconds */ +} rtc_time_t; + +/** + * @brief Date structure + */ +typedef struct +{ + uint8_t week; /**< Weeks */ + uint8_t day; /**< days */ + uint8_t month; /**< months */ + uint8_t year; /**< years */ +} rtc_date_t; + +/** + * @brief Data format + */ +typedef enum +{ + RTC_FORMAT_DEC = 0, + RTC_FORMAT_BCD = 1, +} rtc_format_t; + +/** + * @brief Index of alarm + */ +typedef enum +{ + RTC_ALARM_A = 0x0, /**< Alarm-A */ + RTC_ALARM_B = 0x1, /**< Alarm-B */ +} rtc_alarm_idx_t; + +/** + * @brief Alarm mask + */ +typedef enum +{ + RTC_ALARM_MASK_NONE = 0x0, /**< Mask is disable */ + RTC_ALARM_MASK_WEEK_DAY = (1U << 30), /**< Mask week or day */ + RTC_ALARM_MASK_HOUR = (1U << 23), /**< Mask hour */ + RTC_ALARM_MASK_MINUTE = (1U << 15), /**< Mask minute */ + RTC_ALARM_MASK_SECOND = (1U << 7), /**< Mask second */ + RTC_ALARM_MASK_ALL = 0x40808080, /**< Mask all */ +} rtc_alarm_mask_t; + +/** + * @brief Alarm sub-second mask + */ +typedef enum +{ + RTC_ALARM_SS_MASK_NONE = 0xF, /**< Mask is disable */ + RTC_ALARM_SS_MASK_14_1 = 0x1, /**< Mask bit(1-14) */ + RTC_ALARM_SS_MASK_14_2 = 0x2, /**< Mask bit(2-14) */ + RTC_ALARM_SS_MASK_14_3 = 0x3, /**< Mask bit(3-14) */ + RTC_ALARM_SS_MASK_14_4 = 0x4, /**< Mask bit(4-14) */ + RTC_ALARM_SS_MASK_14_5 = 0x5, /**< Mask bit(5-14) */ + RTC_ALARM_SS_MASK_14_6 = 0x6, /**< Mask bit(6-14) */ + RTC_ALARM_SS_MASK_14_7 = 0x7, /**< Mask bit(7-14) */ + RTC_ALARM_SS_MASK_14_8 = 0x8, /**< Mask bit(8-14) */ + RTC_ALARM_SS_MASK_14_9 = 0x9, /**< Mask bit(9-14) */ + RTC_ALARM_SS_MASK_14_10 = 0xA, /**< Mask bit(10-14) */ + RTC_ALARM_SS_MASK_14_11 = 0xB, /**< Mask bit(11-14) */ + RTC_ALARM_SS_MASK_14_12 = 0xC, /**< Mask bit(12-14) */ + RTC_ALARM_SS_MASK_14_13 = 0xD, /**< Mask bit(13-14) */ + RTC_ALARM_SS_MASK_14 = 0xE, /**< Mask bit14 */ + RTC_ALARM_SS_MASK_ALL = 0x0, /**< Mask bit(0-14) */ +} rtc_sub_second_mask_t; + +/** + * @brief Alarm select week or day */ +typedef enum +{ + RTC_SELECT_DAY = 0x0, /**< Alarm select day */ + RTC_SELECT_WEEK = 0x1, /**< Alarm select week */ +} rtc_week_day_sel_t; + +/** + * @brief Alarm structure + */ +typedef struct +{ + rtc_alarm_idx_t idx; /**< Index of alarm */ + rtc_time_t time; /**< Time structure */ + uint32_t mask; /**< Alarm mask */ + rtc_sub_second_mask_t ss_mask; /**< Alarm sub-second mask */ + rtc_week_day_sel_t sel; /**< Select week or day */ + + union + { + uint8_t week; /**< Alarm select week */ + uint8_t day; /**< Alarm select day */ + }; +} rtc_alarm_t; + +/** + * @brief Time stamp signel select + */ +typedef enum +{ + RTC_TS_SIGNAL_SEL_TAMPER0 = 0, /**< Select tamper0 */ + RTC_TS_SIGNAL_SEL_TAMPER1 = 1, /**< Select tamper1 */ +} rtc_ts_signal_sel_t; + +/** + * @brief Time stamp trigger style + */ +typedef enum +{ + RTC_TS_RISING_EDGE = 0, /**< Rising edge */ + RTC_TS_FALLING_EDGE = 1, /**< Falling edge */ +} rtc_ts_trigger_style_t; + +/** + * @brief Index of tamper + */ +typedef enum +{ + RTC_TAMPER_0 = 0, /**< Tamper0 */ + RTC_TAMPER_1 = 1, /**< Tamper1 */ +} rtc_tamper_idx_t; + +/** + * @brief Tamper trigger type + */ +typedef enum +{ + RTC_TAMPER_TRIGGER_LOW = 0, /**< High trigger */ + RTC_TAMPER_TRIGGER_HIGH = 1, /**< Low trigger */ +} rtc_tamper_trigger_t; + +/** + * @brief Tamper sampling frequency + */ +typedef enum +{ + RTC_TAMPER_SAMPLING_FREQ_32768 = 0, /**< RTCCLK / 32768 */ + RTC_TAMPER_SAMPLING_FREQ_16384 = 1, /**< RTCCLK / 16384 */ + RTC_TAMPER_SAMPLING_FREQ_8192 = 2, /**< RTCCLK / 8192 */ + RTC_TAMPER_SAMPLING_FREQ_4096 = 3, /**< RTCCLK / 4096 */ + RTC_TAMPER_SAMPLING_FREQ_2048 = 4, /**< RTCCLK / 2048 */ + RTC_TAMPER_SAMPLING_FREQ_1024 = 5, /**< RTCCLK / 1024 */ + RTC_TAMPER_SAMPLING_FREQ_512 = 6, /**< RTCCLK / 512 */ + RTC_TAMPER_SAMPLING_FREQ_256 = 7, /**< RTCCLK / 256 */ +} rtc_tamper_sampling_freq_t; + +/** + * @brief Tamper filter time + */ +typedef enum +{ + RTC_TAMPER_DURATION_1 = 0, /**< Duration 1 sampling */ + RTC_TAMPER_DURATION_2 = 1, /**< Duration 2 sampling */ + RTC_TAMPER_DURATION_4 = 2, /**< Duration 4 sampling */ + RTC_TAMPER_DURATION_8 = 3, /**< Duration 8 sampling */ +} rtc_tamper_duration_t; + +/** + * @brief Tamper structure + */ +typedef struct +{ + rtc_tamper_idx_t idx; /**< Index of tamper */ + rtc_tamper_trigger_t trig; /**< Trigger type */ + rtc_tamper_sampling_freq_t freq; /**< Sampling frequency */ + rtc_tamper_duration_t dur; /**< Filter time */ + type_func_t ts; /**< Enable/Disable trigger time stamp event */ +} rtc_tamper_t; + +/** + * @brief Wake-up clock + */ +typedef enum +{ + RTC_WAKEUP_CLOCK_DIV_16 = 0, /**< RTCCLK / 16 */ + RTC_WAKEUP_CLOCK_DIV_8 = 1, /**< RTCCLK / 8 */ + RTC_WAKEUP_CLOCK_DIV_4 = 2, /**< RTCCLK / 4 */ + RTC_WAKEUP_CLOCK_DIV_2 = 3, /**< RTCCLK / 2 */ + RTC_WAKEUP_CLOCK_1HZ = 4, /**< 1Hz */ + RTC_WAKEUP_CLOCK_1HZ_PULS = 6, /**< 1Hz and WUT + 65536 */ +} rtc_wakeup_clock_t; + +/** + * @brief RTC clock output type + */ +typedef enum +{ + RTC_CLOCK_OUTPUT_32768 = 0, /**< 32768Hz */ + RTC_CLOCK_OUTPUT_1024 = 1, /**< 1024Hz */ + RTC_CLOCK_OUTPUT_32 = 2, /**< 32Hz */ + RTC_CLOCK_OUTPUT_1 = 3, /**< 1Hz */ + RTC_CLOCK_OUTPUT_CAL_1 = 4, /**< 1Hz after calibration */ + RTC_CLOCK_OUTPUT_EXA_1 = 5, /**< Exact 1Hz */ +} rtc_clock_output_t; + +/** + * @ Calibration frequency + */ +typedef enum +{ + RTC_CALI_FREQ_10_SEC = 0, /**< Calibrate every 10 seconds */ + RTC_CALI_FREQ_20_SEC = 1, /**< Calibrate every 20 seconds */ + RTC_CALI_FREQ_1_MIN = 2, /**< Calibrate every 1 minute */ + RTC_CALI_FREQ_2_MIN = 3, /**< Calibrate every 2 minutes */ + RTC_CALI_FREQ_5_MIN = 4, /**< Calibrate every 5 minutes */ + RTC_CALI_FREQ_10_MIN = 5, /**< Calibrate every 10 minutes */ + RTC_CALI_FREQ_20_MIN = 6, /**< Calibrate every 20 minutes */ + RTC_CALI_FREQ_1_SEC = 7, /**< Calibrate every 1 second */ +} rtc_cali_freq_t; + +/** + * @brief Temperature compensate type + */ +typedef enum +{ + RTC_CALI_TC_NONE = 0, /**< Temperature compensate disable */ + RTC_CALI_TC_AUTO_BY_HW = 1, /**< Temperature compensate by hardware */ + RTC_CALI_TC_AUTO_BY_SF = 2, /**< Temperature compensate by software */ + RTC_CALI_TC_AUTO_BY_HW_SF = 3, /**< Temperature compensate by hardware, trigger by software */ +} rtc_cali_tc_t; + +/** + * @ Calculate frequency + */ +typedef enum +{ + RTC_CALI_CALC_FREQ_10_SEC = 0, /**< Calculate every 10 seconds */ + RTC_CALI_CALC_FREQ_20_SEC = 1, /**< Calculate every 20 seconds */ + RTC_CALI_CALC_FREQ_1_MIN = 2, /**< Calculate every 1 minute */ + RTC_CALI_CALC_FREQ_2_MIN = 3, /**< Calculate every 2 minutes */ + RTC_CALI_CALC_FREQ_5_MIN = 4, /**< Calculate every 5 minutes */ + RTC_CALI_CALC_FREQ_10_MIN = 5, /**< Calculate every 10 minutes */ + RTC_CALI_CALC_FREQ_20_MIN = 6, /**< Calculate every 20 minutes */ + RTC_CALI_CALC_FREQ_1_HOUR = 7, /**< Calculate every 1 hour */ +} rtc_cali_calc_freq_t; + +/** + * @brief Calibration algorithm + */ +typedef enum +{ + RTC_CALI_CALC_4 = 0, /**< 4-polynomial */ + RTC_CALI_CALC_2 = 1, /**< 2-parabola */ +} rtc_cali_calc_t; + +/** + * @brief Calibration structure + */ +typedef struct +{ + rtc_cali_freq_t cali_freq; /**< calibrate frequency */ + rtc_cali_tc_t tc; /**< Temperature compensate type */ + rtc_cali_calc_freq_t calc_freq; /**< Calculate frequency */ + rtc_cali_calc_t calc; /**< algorithm */ + type_func_t acc; /**< Enable/Disable decimal accumulate */ +} rtc_cali_t; + +/** + * @brief Interrupt type + */ +typedef enum +{ + RTC_IT_SEC = (1U << 0), /**< Second */ + RTC_IT_MIN = (1U << 1), /**< Minute */ + RTC_IT_HR = (1U << 2), /**< Hour */ + RTC_IT_DAY = (1U << 3), /**< Day */ + RTC_IT_MON = (1U << 4), /**< Month */ + RTC_IT_YR = (1U << 5), /**< Year */ + RTC_IT_ALMA = (1U << 8), /**< Alarm-A */ + RTC_IT_ALMB = (1U << 9), /**< Alarm-B */ + RTC_IT_TS = (1U << 10), /**< Time stamp */ + RTC_IT_TSOV = (1U << 11), /**< Time stamp overflow */ + RTC_IT_TP0 = (1U << 12), /**< Tamper-0 */ + RTC_IT_TP1 = (1U << 13), /**< Tamper-1 */ + RTC_IT_RSC = (1U << 16), /**< Synchronous complete */ + RTC_IT_SFC = (1U << 17), /**< Shift complete */ + RTC_IT_WU = (1U << 18), /**< Wake-up */ + RTC_IT_TCC = (1U << 24), /**< Temperature compensate complete */ + RTC_IT_TCE = (1U << 25), /**< Temperature compensate error */ +} rtc_it_t; + +/** + * @brief Interrupt flag + */ +typedef enum +{ + RTC_IF_SEC = (1U << 0), /**< Second */ + RTC_IF_MIN = (1U << 1), /**< Minute */ + RTC_IF_HR = (1U << 2), /**< Hour */ + RTC_IF_DAY = (1U << 3), /**< Day */ + RTC_IF_MON = (1U << 4), /**< Month */ + RTC_IF_YR = (1U << 5), /**< Year */ + RTC_IF_ALMA = (1U << 8), /**< Alarm-A */ + RTC_IF_ALMB = (1U << 9), /**< Alarm-B */ + RTC_IF_TS = (1U << 10), /**< Time stamp */ + RTC_IF_TSOV = (1U << 11), /**< Time stamp overflow */ + RTC_IF_TP0 = (1U << 12), /**< Tamper-0 */ + RTC_IF_TP1 = (1U << 13), /**< Tamper-1 */ + RTC_IF_RSC = (1U << 16), /**< Synchronous complete */ + RTC_IF_SFC = (1U << 17), /**< Shift complete */ + RTC_IF_WU = (1U << 18), /**< Wake-up */ + RTC_IF_TCC = (1U << 24), /**< Temperature compensate complete */ + RTC_IF_TCE = (1U << 25), /**< Temperature compensate error */ +} rtc_flag_t; +/** + * @} + */ + +/** @defgroup RTC_Public_Macro RTC Public Macros + * @{ + */ +#define RTC_UNLOCK() (WRITE_REG(RTC->WPR, 0x55AAAA55)) +#define RTC_LOCK() (WRITE_REG(RTC->WPR, 0x0)) +#define RTC_BY_PASS_ENABLE() \ + do { \ + RTC_UNLOCK(); \ + SET_BIT(RTC->CON, RTC_CON_SHDBP_MSK); \ + RTC_LOCK(); \ + } while (0) +#define RTC_BY_PASS_DISABLE() \ + do { \ + RTC_UNLOCK(); \ + CLEAR_BIT(RTC->CON, RTC_CON_SHDBP_MSK); \ + RTC_LOCK(); \ + } while (0) +#define RTC_SUMMER_TIME_ENABLE() \ + do { \ + RTC_UNLOCK(); \ + SET_BIT(RTC->CON, RTC_CON_ADD1H_MSK); \ + RTC_LOCK(); \ + } while (0) +#define RTC_SUMMER_TIME_DISABLE() \ + do { \ + RTC_UNLOCK(); \ + CLEAR_BIT(RTC->CON, RTC_CON_ADD1H_MSK); \ + RTC_LOCK(); \ + } while (0) +#define RTC_WINTER_TIME_ENABLE() \ + do { \ + RTC_UNLOCK(); \ + SET_BIT(RTC->CON, RTC_CON_SUB1H_MSK); \ + RTC_LOCK(); \ + } while (0) +#define RTC_WINTER_TIME_DISABLE() \ + do { \ + RTC_UNLOCK(); \ + CLEAR_BIT(RTC->CON, RTC_CON_SUB1H_MSK); \ + RTC_LOCK(); \ + } while (0) +/** + * @} + */ + +/** @defgroup CAN_Private_Macros CAN Private Macros + * @{ + */ +#define RTC_CALI_UNLOCK() (WRITE_REG(RTC->CALWPR, 0x699655AA)) +#define RTC_CALI_LOCK() (WRITE_REG(RTC->CALWPR, 0x0)) +#define ALARM_MASK_ALL 0x40808080 +#define RTC_TIMEOUT_VALUE 100 + +#define IS_SHIFT_SUB_SS(x) ((x) < (1U << 15)) +#define IS_RTC_HOUR_FORMAT(x) (((x) == RTC_HOUR_FORMAT_24) || \ + ((x) == RTC_HOUR_FORMAT_12)) +#define IS_RTC_OUTPUT_SEL(x) (((x) == RTC_OUTPUT_DISABLE) || \ + ((x) == RTC_OUTPUT_ALARM_A) || \ + ((x) == RTC_OUTPUT_ALARM_B) || \ + ((x) == RTC_OUTPUT_WAKEUP)) +#define IS_RTC_OUTPUT_POLARITY(x) (((x) == RTC_OUTPUT_POLARITY_HIGH) || \ + ((x) == RTC_OUTPUT_POLARITY_LOW)) +#define IS_RTC_SOURCE_SEL(x) (((x) == RTC_SOURCE_LOSC) || \ + ((x) == RTC_SOURCE_LRC) || \ + ((x) == RTC_SOURCE_HRC_DIV_1M ) || \ + ((x) == RTC_SOURCE_HOSC_DIV_1M)) +#define IS_RTC_ALARM(x) (((x) == RTC_ALARM_A) || \ + ((x) == RTC_ALARM_B)) +#define IS_RTC_ALARM_SEL(x) (((x) == RTC_SELECT_DAY) || \ + ((x) == RTC_SELECT_WEEK)) +#define IS_RTC_ALARM_MASK(x) (((x) == RTC_ALARM_MASK_NONE) || \ + ((x) == RTC_ALARM_MASK_WEEK_DAY) || \ + ((x) == RTC_ALARM_MASK_HOUR) || \ + ((x) == RTC_ALARM_MASK_MINUTE) || \ + ((x) == RTC_ALARM_MASK_SECOND) || \ + ((x) == RTC_ALARM_MASK_ALL)) +#define IS_RTC_ALARM_SS_MASK(x) (((x) == RTC_ALARM_SS_MASK_NONE) || \ + ((x) == RTC_ALARM_SS_MASK_14_1) || \ + ((x) == RTC_ALARM_SS_MASK_14_2) || \ + ((x) == RTC_ALARM_SS_MASK_14_3) || \ + ((x) == RTC_ALARM_SS_MASK_14_4) || \ + ((x) == RTC_ALARM_SS_MASK_14_5) || \ + ((x) == RTC_ALARM_SS_MASK_14_6) || \ + ((x) == RTC_ALARM_SS_MASK_14_7) || \ + ((x) == RTC_ALARM_SS_MASK_14_8) || \ + ((x) == RTC_ALARM_SS_MASK_14_9) || \ + ((x) == RTC_ALARM_SS_MASK_14_10) || \ + ((x) == RTC_ALARM_SS_MASK_14_11) || \ + ((x) == RTC_ALARM_SS_MASK_14_12) || \ + ((x) == RTC_ALARM_SS_MASK_14_13) || \ + ((x) == RTC_ALARM_SS_MASK_14) || \ + ((x) == RTC_ALARM_SS_MASK_ALL)) +#define IS_RTC_TS_SIGNAL(x) (((x) == RTC_TS_SIGNAL_SEL_TAMPER0) || \ + ((x) == RTC_TS_SIGNAL_SEL_TAMPER1)) +#define IS_RTC_TS_STYLE(x) (((x) == RTC_TS_RISING_EDGE) || \ + ((x) == RTC_TS_FALLING_EDGE)) +#define IS_RTC_FORMAT(x) (((x) == RTC_FORMAT_DEC) || \ + ((x) == RTC_FORMAT_BCD)) +#define IS_RTC_TAMPER(x) (((x) == RTC_TAMPER_0) || \ + ((x) == RTC_TAMPER_1)) +#define IS_RTC_TAMPER_TRIGGER(x) (((x) == RTC_TAMPER_TRIGGER_LOW) || \ + ((x) == RTC_TAMPER_TRIGGER_HIGH)) +#define IS_RTC_TAMPER_SAMPLING_FREQ(x) (((x) == RTC_TAMPER_SAMPLING_FREQ_32768) || \ + ((x) == RTC_TAMPER_SAMPLING_FREQ_16384) || \ + ((x) == RTC_TAMPER_SAMPLING_FREQ_8192) || \ + ((x) == RTC_TAMPER_SAMPLING_FREQ_4096) || \ + ((x) == RTC_TAMPER_SAMPLING_FREQ_2048) || \ + ((x) == RTC_TAMPER_SAMPLING_FREQ_1024) || \ + ((x) == RTC_TAMPER_SAMPLING_FREQ_512) || \ + ((x) == RTC_TAMPER_SAMPLING_FREQ_256)) +#define IS_RTC_TAMPER_DURATION(x) (((x) == RTC_TAMPER_DURATION_1) || \ + ((x) == RTC_TAMPER_DURATION_2) || \ + ((x) == RTC_TAMPER_DURATION_4) || \ + ((x) == RTC_TAMPER_DURATION_8)) +#define IS_RTC_WAKEUP_CLOCK(x) (((x) == RTC_WAKEUP_CLOCK_DIV_16) || \ + ((x) == RTC_WAKEUP_CLOCK_DIV_8) || \ + ((x) == RTC_WAKEUP_CLOCK_DIV_4) || \ + ((x) == RTC_WAKEUP_CLOCK_DIV_2) || \ + ((x) == RTC_WAKEUP_CLOCK_1HZ) || \ + ((x) == RTC_WAKEUP_CLOCK_1HZ_PULS)) +#define IS_RTC_CLOCK_OUTPUT(x) (((x) == RTC_CLOCK_OUTPUT_32768) || \ + ((x) == RTC_CLOCK_OUTPUT_1024) || \ + ((x) == RTC_CLOCK_OUTPUT_32) || \ + ((x) == RTC_CLOCK_OUTPUT_1) || \ + ((x) == RTC_CLOCK_OUTPUT_CAL_1) || \ + ((x) == RTC_CLOCK_OUTPUT_EXA_1)) +#define IS_RTC_CALI_FREQ(x) (((x) == RTC_CALI_FREQ_10_SEC) || \ + ((x) == RTC_CALI_FREQ_20_SEC) || \ + ((x) == RTC_CALI_FREQ_1_MIN) || \ + ((x) == RTC_CALI_FREQ_2_MIN) || \ + ((x) == RTC_CALI_FREQ_5_MIN) || \ + ((x) == RTC_CALI_FREQ_10_MIN) || \ + ((x) == RTC_CALI_FREQ_20_MIN) || \ + ((x) == RTC_CALI_FREQ_1_SEC)) +#define IS_RTC_CALI_TC(x) (((x) == RTC_CALI_TC_NONE) || \ + ((x) == RTC_CALI_TC_AUTO_BY_HW) || \ + ((x) == RTC_CALI_TC_AUTO_BY_SF) || \ + ((x) == RTC_CALI_TC_AUTO_BY_HW_SF)) +#define IS_RTC_CALC_FREQ(x) (((x) == RTC_CALI_CALC_FREQ_10_SEC) || \ + ((x) == RTC_CALI_CALC_FREQ_20_SEC) || \ + ((x) == RTC_CALI_CALC_FREQ_1_MIN) || \ + ((x) == RTC_CALI_CALC_FREQ_2_MIN) || \ + ((x) == RTC_CALI_CALC_FREQ_5_MIN) || \ + ((x) == RTC_CALI_CALC_FREQ_10_MIN) || \ + ((x) == RTC_CALI_CALC_FREQ_20_MIN) || \ + ((x) == RTC_CALI_CALC_FREQ_1_HOUR)) +#define IS_RTC_CALI_CALC(x) (((x) == RTC_CALI_CALC_4) || \ + ((x) == RTC_CALI_CALC_2)) +#define IS_RTC_IT(x) (((x) == RTC_IT_SEC) || \ + ((x) == RTC_IT_MIN) || \ + ((x) == RTC_IT_HR) || \ + ((x) == RTC_IT_DAY) || \ + ((x) == RTC_IT_MON) || \ + ((x) == RTC_IT_YR) || \ + ((x) == RTC_IT_ALMA) || \ + ((x) == RTC_IT_ALMB) || \ + ((x) == RTC_IT_TS) || \ + ((x) == RTC_IT_TSOV) || \ + ((x) == RTC_IT_TP0) || \ + ((x) == RTC_IT_TP1) || \ + ((x) == RTC_IT_RSC) || \ + ((x) == RTC_IT_SFC) || \ + ((x) == RTC_IT_WU) || \ + ((x) == RTC_IT_TCC) || \ + ((x) == RTC_IT_TCE)) +#define IS_RTC_IF(x) (((x) == RTC_IF_SEC) || \ + ((x) == RTC_IF_MIN) || \ + ((x) == RTC_IF_HR) || \ + ((x) == RTC_IF_DAY) || \ + ((x) == RTC_IF_MON) || \ + ((x) == RTC_IF_YR) || \ + ((x) == RTC_IF_ALMA) || \ + ((x) == RTC_IF_ALMB) || \ + ((x) == RTC_IF_TS) || \ + ((x) == RTC_IF_TSOV) || \ + ((x) == RTC_IF_TP0) || \ + ((x) == RTC_IF_TP1) || \ + ((x) == RTC_IF_RSC) || \ + ((x) == RTC_IF_SFC) || \ + ((x) == RTC_IF_WU) || \ + ((x) == RTC_IF_TCC) || \ + ((x) == RTC_IF_TCE)) +#define IS_RTC_SECOND(x) ((x) < 60) +#define IS_RTC_MINUTE(x) ((x) < 60) +#define IS_RTC_HOUR(x) ((x) < 24) +#define IS_RTC_DAY(x) (((x) > 0) && ((x) < 32)) +#define IS_RTC_MONTH(x) (((x) > 0) && ((x) < 13)) +#define IS_RTC_YEAR(x) ((x) < 100) +/** + * @} + */ + +/** @addtogroup RTC_Public_Functions + * @{ + */ + +/** @addtogroup RTC_Public_Functions_Group1 + * @{ + */ +/* Initialization functions */ +void ald_rtc_reset(void); +void ald_rtc_init(rtc_init_t *init); +void ald_rtc_source_select(rtc_source_sel_t sel); +/** + * @} + */ +/** @addtogroup RTC_Public_Functions_Group2 + * @{ + */ +/* Time and date operation functions */ +ald_status_t ald_rtc_set_time(rtc_time_t *time, rtc_format_t format); +ald_status_t ald_rtc_set_date(rtc_date_t *date, rtc_format_t format); +void ald_rtc_get_time(rtc_time_t *time, rtc_format_t format); +void ald_rtc_get_date(rtc_date_t *date, rtc_format_t format); +int32_t ald_rtc_get_date_time(rtc_date_t *date, rtc_time_t *time, rtc_format_t format); +/** + * @} + */ +/** @addtogroup RTC_Public_Functions_Group3 + * @{ + */ +/* Alarm functions */ +void ald_rtc_set_alarm(rtc_alarm_t *alarm, rtc_format_t format); +void ald_rtc_get_alarm(rtc_alarm_t *alarm, rtc_format_t format); +/** + * @} + */ +/** @addtogroup RTC_Public_Functions_Group4 + * @{ + */ +/* Time stamp functions */ +void ald_rtc_set_time_stamp(rtc_ts_signal_sel_t sel, rtc_ts_trigger_style_t style); +void ald_rtc_cancel_time_stamp(void); +void ald_rtc_get_time_stamp(rtc_time_t *ts_time, rtc_date_t *ts_date, rtc_format_t format); +/** + * @} + */ +/** @addtogroup RTC_Public_Functions_Group5 + * @{ + */ +/* Tamper functions */ +void ald_rtc_set_tamper(rtc_tamper_t *tamper); +void ald_rtc_cancel_tamper(rtc_tamper_idx_t idx); +/** + * @} + */ +/** @addtogroup RTC_Public_Functions_Group6 + * @{ + */ +/* Wakeup functions */ +void ald_rtc_set_wakeup(rtc_wakeup_clock_t clock, uint16_t value); +void ald_rtc_cancel_wakeup(void); +uint16_t ald_rtc_get_wakeup_timer_value(void); +/** + * @} + */ +/** @addtogroup RTC_Public_Functions_Group7 + * @{ + */ +/* Clock output functions */ +ald_status_t ald_rtc_set_clock_output(rtc_clock_output_t clock); +void ald_rtc_cancel_clock_output(void); +/** + * @} + */ +/** @addtogroup RTC_Public_Functions_Group8 + * @{ + */ +/* Control functions */ +void ald_rtc_interrupt_config(rtc_it_t it, type_func_t state); +void ald_rtc_alarm_cmd(rtc_alarm_idx_t idx, type_func_t state); +ald_status_t ald_rtc_set_shift(type_func_t add_1s, uint16_t sub_ss); +void ald_rtc_set_cali(rtc_cali_t *config); +void ald_rtc_cancel_cali(void); +ald_status_t ald_rtc_get_cali_status(void); +void ald_rtc_write_temp(uint16_t temp); +it_status_t ald_rtc_get_it_status(rtc_it_t it); +flag_status_t ald_rtc_get_flag_status(rtc_flag_t flag); +void ald_rtc_clear_flag_status(rtc_flag_t flag); +/** + * @} + */ +/** + * @} + */ +/** + * @} + */ +/** + * @} + */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_smartcard.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_smartcard.h similarity index 34% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_smartcard.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_smartcard.h index 1d5564bd76..b04380ee6d 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_smartcard.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_smartcard.h @@ -43,12 +43,12 @@ extern "C" { */ typedef enum { - SMARTCARD_ERROR_NONE = ((uint32_t)0x00), /**< No error */ - SMARTCARD_ERROR_PE = ((uint32_t)0x01), /**< Parity error */ - SMARTCARD_ERROR_NE = ((uint32_t)0x02), /**< Noise error */ - SMARTCARD_ERROR_FE = ((uint32_t)0x04), /**< frame error */ - SMARTCARD_ERROR_ORE = ((uint32_t)0x08), /**< Overrun error */ - SMARTCARD_ERROR_DMA = ((uint32_t)0x10), /**< DMA transfer error */ + SMARTCARD_ERROR_NONE = ((uint32_t)0x00), /**< No error */ + SMARTCARD_ERROR_PE = ((uint32_t)0x01), /**< Parity error */ + SMARTCARD_ERROR_NE = ((uint32_t)0x02), /**< Noise error */ + SMARTCARD_ERROR_FE = ((uint32_t)0x04), /**< frame error */ + SMARTCARD_ERROR_ORE = ((uint32_t)0x08), /**< Overrun error */ + SMARTCARD_ERROR_DMA = ((uint32_t)0x10), /**< DMA transfer error */ } smartcard_error_t; /** @@ -56,37 +56,37 @@ typedef enum */ typedef enum { - SMARTCARD_PRESCALER_SYSCLK_DIV2 = ((uint32_t)0x1), /**< SYSCLK divided by 2 */ - SMARTCARD_PRESCALER_SYSCLK_DIV4 = ((uint32_t)0x2), /**< SYSCLK divided by 4 */ - SMARTCARD_PRESCALER_SYSCLK_DIV6 = ((uint32_t)0x3), /**< SYSCLK divided by 6 */ - SMARTCARD_PRESCALER_SYSCLK_DIV8 = ((uint32_t)0x4), /**< SYSCLK divided by 8 */ - SMARTCARD_PRESCALER_SYSCLK_DIV10 = ((uint32_t)0x5), /**< SYSCLK divided by 10 */ - SMARTCARD_PRESCALER_SYSCLK_DIV12 = ((uint32_t)0x6), /**< SYSCLK divided by 12 */ - SMARTCARD_PRESCALER_SYSCLK_DIV14 = ((uint32_t)0x7), /**< SYSCLK divided by 14 */ - SMARTCARD_PRESCALER_SYSCLK_DIV16 = ((uint32_t)0x8), /**< SYSCLK divided by 16 */ - SMARTCARD_PRESCALER_SYSCLK_DIV18 = ((uint32_t)0x9), /**< SYSCLK divided by 18 */ - SMARTCARD_PRESCALER_SYSCLK_DIV20 = ((uint32_t)0xA), /**< SYSCLK divided by 20 */ - SMARTCARD_PRESCALER_SYSCLK_DIV22 = ((uint32_t)0xB), /**< SYSCLK divided by 22 */ - SMARTCARD_PRESCALER_SYSCLK_DIV24 = ((uint32_t)0xC), /**< SYSCLK divided by 24 */ - SMARTCARD_PRESCALER_SYSCLK_DIV26 = ((uint32_t)0xD), /**< SYSCLK divided by 26 */ - SMARTCARD_PRESCALER_SYSCLK_DIV28 = ((uint32_t)0xE), /**< SYSCLK divided by 28 */ - SMARTCARD_PRESCALER_SYSCLK_DIV30 = ((uint32_t)0xF), /**< SYSCLK divided by 30 */ - SMARTCARD_PRESCALER_SYSCLK_DIV32 = ((uint32_t)0x10), /**< SYSCLK divided by 32 */ - SMARTCARD_PRESCALER_SYSCLK_DIV34 = ((uint32_t)0x11), /**< SYSCLK divided by 34 */ - SMARTCARD_PRESCALER_SYSCLK_DIV36 = ((uint32_t)0x12), /**< SYSCLK divided by 36 */ - SMARTCARD_PRESCALER_SYSCLK_DIV38 = ((uint32_t)0x13), /**< SYSCLK divided by 38 */ - SMARTCARD_PRESCALER_SYSCLK_DIV40 = ((uint32_t)0x14), /**< SYSCLK divided by 40 */ - SMARTCARD_PRESCALER_SYSCLK_DIV42 = ((uint32_t)0x15), /**< SYSCLK divided by 42 */ - SMARTCARD_PRESCALER_SYSCLK_DIV44 = ((uint32_t)0x16), /**< SYSCLK divided by 44 */ - SMARTCARD_PRESCALER_SYSCLK_DIV46 = ((uint32_t)0x17), /**< SYSCLK divided by 46 */ - SMARTCARD_PRESCALER_SYSCLK_DIV48 = ((uint32_t)0x18), /**< SYSCLK divided by 48 */ - SMARTCARD_PRESCALER_SYSCLK_DIV50 = ((uint32_t)0x19), /**< SYSCLK divided by 50 */ - SMARTCARD_PRESCALER_SYSCLK_DIV52 = ((uint32_t)0x1A), /**< SYSCLK divided by 52 */ - SMARTCARD_PRESCALER_SYSCLK_DIV54 = ((uint32_t)0x1B), /**< SYSCLK divided by 54 */ - SMARTCARD_PRESCALER_SYSCLK_DIV56 = ((uint32_t)0x1C), /**< SYSCLK divided by 56 */ - SMARTCARD_PRESCALER_SYSCLK_DIV58 = ((uint32_t)0x1D), /**< SYSCLK divided by 58 */ - SMARTCARD_PRESCALER_SYSCLK_DIV60 = ((uint32_t)0x1E), /**< SYSCLK divided by 60 */ - SMARTCARD_PRESCALER_SYSCLK_DIV62 = ((uint32_t)0x1F), /**< SYSCLK divided by 62 */ + SMARTCARD_PRESCALER_SYSCLK_DIV2 = ((uint32_t)0x1), /**< SYSCLK divided by 2 */ + SMARTCARD_PRESCALER_SYSCLK_DIV4 = ((uint32_t)0x2), /**< SYSCLK divided by 4 */ + SMARTCARD_PRESCALER_SYSCLK_DIV6 = ((uint32_t)0x3), /**< SYSCLK divided by 6 */ + SMARTCARD_PRESCALER_SYSCLK_DIV8 = ((uint32_t)0x4), /**< SYSCLK divided by 8 */ + SMARTCARD_PRESCALER_SYSCLK_DIV10 = ((uint32_t)0x5), /**< SYSCLK divided by 10 */ + SMARTCARD_PRESCALER_SYSCLK_DIV12 = ((uint32_t)0x6), /**< SYSCLK divided by 12 */ + SMARTCARD_PRESCALER_SYSCLK_DIV14 = ((uint32_t)0x7), /**< SYSCLK divided by 14 */ + SMARTCARD_PRESCALER_SYSCLK_DIV16 = ((uint32_t)0x8), /**< SYSCLK divided by 16 */ + SMARTCARD_PRESCALER_SYSCLK_DIV18 = ((uint32_t)0x9), /**< SYSCLK divided by 18 */ + SMARTCARD_PRESCALER_SYSCLK_DIV20 = ((uint32_t)0xA), /**< SYSCLK divided by 20 */ + SMARTCARD_PRESCALER_SYSCLK_DIV22 = ((uint32_t)0xB), /**< SYSCLK divided by 22 */ + SMARTCARD_PRESCALER_SYSCLK_DIV24 = ((uint32_t)0xC), /**< SYSCLK divided by 24 */ + SMARTCARD_PRESCALER_SYSCLK_DIV26 = ((uint32_t)0xD), /**< SYSCLK divided by 26 */ + SMARTCARD_PRESCALER_SYSCLK_DIV28 = ((uint32_t)0xE), /**< SYSCLK divided by 28 */ + SMARTCARD_PRESCALER_SYSCLK_DIV30 = ((uint32_t)0xF), /**< SYSCLK divided by 30 */ + SMARTCARD_PRESCALER_SYSCLK_DIV32 = ((uint32_t)0x10), /**< SYSCLK divided by 32 */ + SMARTCARD_PRESCALER_SYSCLK_DIV34 = ((uint32_t)0x11), /**< SYSCLK divided by 34 */ + SMARTCARD_PRESCALER_SYSCLK_DIV36 = ((uint32_t)0x12), /**< SYSCLK divided by 36 */ + SMARTCARD_PRESCALER_SYSCLK_DIV38 = ((uint32_t)0x13), /**< SYSCLK divided by 38 */ + SMARTCARD_PRESCALER_SYSCLK_DIV40 = ((uint32_t)0x14), /**< SYSCLK divided by 40 */ + SMARTCARD_PRESCALER_SYSCLK_DIV42 = ((uint32_t)0x15), /**< SYSCLK divided by 42 */ + SMARTCARD_PRESCALER_SYSCLK_DIV44 = ((uint32_t)0x16), /**< SYSCLK divided by 44 */ + SMARTCARD_PRESCALER_SYSCLK_DIV46 = ((uint32_t)0x17), /**< SYSCLK divided by 46 */ + SMARTCARD_PRESCALER_SYSCLK_DIV48 = ((uint32_t)0x18), /**< SYSCLK divided by 48 */ + SMARTCARD_PRESCALER_SYSCLK_DIV50 = ((uint32_t)0x19), /**< SYSCLK divided by 50 */ + SMARTCARD_PRESCALER_SYSCLK_DIV52 = ((uint32_t)0x1A), /**< SYSCLK divided by 52 */ + SMARTCARD_PRESCALER_SYSCLK_DIV54 = ((uint32_t)0x1B), /**< SYSCLK divided by 54 */ + SMARTCARD_PRESCALER_SYSCLK_DIV56 = ((uint32_t)0x1C), /**< SYSCLK divided by 56 */ + SMARTCARD_PRESCALER_SYSCLK_DIV58 = ((uint32_t)0x1D), /**< SYSCLK divided by 58 */ + SMARTCARD_PRESCALER_SYSCLK_DIV60 = ((uint32_t)0x1E), /**< SYSCLK divided by 60 */ + SMARTCARD_PRESCALER_SYSCLK_DIV62 = ((uint32_t)0x1F), /**< SYSCLK divided by 62 */ } smartcard_prescaler_t; /** @@ -102,25 +102,25 @@ typedef enum */ typedef struct { - uint32_t baud; /**< This member configures the SmartCard communication baud rate. */ + uint32_t baud; /**< This member configures the SmartCard communication baud rate. */ usart_word_length_t word_length;/**< Specifies the number of data bits transmitted or received in a frame. */ - usart_stop_bits_t stop_bits; /**< Specifies the number of stop bits transmitted. */ - usart_parity_t parity; /**< Specifies the parity mode. - @note When parity is enabled, the computed parity is inserted + usart_stop_bits_t stop_bits; /**< Specifies the number of stop bits transmitted. */ + usart_parity_t parity; /**< Specifies the parity mode. + @note When parity is enabled, the computed parity is inserted at the MSB position of the transmitted data (9th bit when the word length is set to 9 data bits; 8th bit when the word length is set to 8 data bits).*/ - usart_mode_t mode; /**< Specifies whether the Receive or Transmit mode is enabled or disabled. */ - usart_cpol_t polarity; /**< Specifies the steady state of the serial clock. */ - usart_cpha_t phase; /**< Specifies the clock transition on which the bit capture is made.*/ - usart_last_bit_t last_bit; /**< Specifies whether the clock pulse corresponding to the last transmitted - data bit (MSB) has to be output on the SCLK pin in synchronous mode. + usart_mode_t mode; /**< Specifies whether the Receive or Transmit mode is enabled or disabled. */ + usart_cpol_t polarity; /**< Specifies the steady state of the serial clock. */ + usart_cpha_t phase; /**< Specifies the clock transition on which the bit capture is made.*/ + usart_last_bit_t last_bit; /**< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. This parameter can be a value of @ref usart_last_bit_t */ smartcard_prescaler_t prescaler;/**< Specifies the SmartCard Prescaler value used for dividing the system clock - to provide the smartcard clock. The value given in the register (5 significant bits) - is multiplied by 2 to give the division factor of the source clock frequency. */ - uint32_t guard_time; /**< Specifies the SmartCard Guard Time value in terms of number of baud clocks */ - type_func_t nack; /**< Specifies the SmartCard NACK Transmission state. */ + to provide the smartcard clock. The value given in the register (5 significant bits) + is multiplied by 2 to give the division factor of the source clock frequency. */ + uint32_t guard_time; /**< Specifies the SmartCard Guard Time value in terms of number of baud clocks */ + type_func_t nack; /**< Specifies the SmartCard NACK Transmission state. */ } smartcard_init_t; /** @@ -128,14 +128,14 @@ typedef struct */ typedef enum { - SMARTCARD_STATE_RESET = 0x00, /**< Peripheral is not yet Initialized */ - SMARTCARD_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ - SMARTCARD_STATE_BUSY = 0x02, /**< an internal process is ongoing */ - SMARTCARD_STATE_BUSY_TX = 0x11, /**< Data Transmission process is ongoing */ - SMARTCARD_STATE_BUSY_RX = 0x21, /**< Data Reception process is ongoing */ - SMARTCARD_STATE_BUSY_TX_RX = 0x31, /**< Data Transmission and Reception process is ongoing */ - SMARTCARD_STATE_TIMEOUT = 0x03, /**< Timeout state */ - SMARTCARD_STATE_ERROR = 0x04 /**< Error */ + SMARTCARD_STATE_RESET = 0x00, /**< Peripheral is not yet Initialized */ + SMARTCARD_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + SMARTCARD_STATE_BUSY = 0x02, /**< an internal process is ongoing */ + SMARTCARD_STATE_BUSY_TX = 0x11, /**< Data Transmission process is ongoing */ + SMARTCARD_STATE_BUSY_RX = 0x21, /**< Data Reception process is ongoing */ + SMARTCARD_STATE_BUSY_TX_RX = 0x31, /**< Data Transmission and Reception process is ongoing */ + SMARTCARD_STATE_TIMEOUT = 0x03, /**< Timeout state */ + SMARTCARD_STATE_ERROR = 0x04 /**< Error */ } smartcard_state_t; @@ -144,25 +144,25 @@ typedef enum */ typedef struct smartcard_handle_s { - USART_TypeDef *perh; /**< USART registers base address */ - smartcard_init_t init; /**< SmartCard communication parameters */ - uint8_t *tx_buf; /**< Pointer to SmartCard Tx transfer Buffer */ - uint16_t tx_size; /**< SmartCard Tx Transfer size */ - uint16_t tx_count; /**< SmartCard Tx Transfer Counter */ - uint8_t *rx_buf; /**< Pointer to SmartCard Rx transfer Buffer */ - uint16_t rx_size; /**< SmartCard Rx Transfer size */ - uint16_t rx_count; /**< SmartCard Rx Transfer Counter */ + USART_TypeDef *perh; /**< USART registers base address */ + smartcard_init_t init; /**< SmartCard communication parameters */ + uint8_t *tx_buf; /**< Pointer to SmartCard Tx transfer Buffer */ + uint16_t tx_size; /**< SmartCard Tx Transfer size */ + uint16_t tx_count; /**< SmartCard Tx Transfer Counter */ + uint8_t *rx_buf; /**< Pointer to SmartCard Rx transfer Buffer */ + uint16_t rx_size; /**< SmartCard Rx Transfer size */ + uint16_t rx_count; /**< SmartCard Rx Transfer Counter */ #ifdef ALD_DMA - dma_handle_t hdmatx; /**< SmartCard Tx DMA Handle parameters */ - dma_handle_t hdmarx; /**< SmartCard Rx DMA Handle parameters */ + dma_handle_t hdmatx; /**< SmartCard Tx DMA Handle parameters */ + dma_handle_t hdmarx; /**< SmartCard Rx DMA Handle parameters */ #endif - lock_state_t lock; /**< Locking object */ - smartcard_state_t state; /**< SmartCard communication state */ - uint32_t err_code; /**< SmartCard Error code */ + lock_state_t lock; /**< Locking object */ + smartcard_state_t state; /**< SmartCard communication state */ + uint32_t err_code; /**< SmartCard Error code */ - void (*tx_cplt_cbk)(struct smartcard_handle_s *arg); /**< Tx completed callback */ - void (*rx_cplt_cbk)(struct smartcard_handle_s *arg); /**< Rx completed callback */ - void (*error_cbk)(struct smartcard_handle_s *arg); /**< error callback */ + void (*tx_cplt_cbk)(struct smartcard_handle_s *arg); /**< Tx completed callback */ + void (*rx_cplt_cbk)(struct smartcard_handle_s *arg); /**< Rx completed callback */ + void (*error_cbk)(struct smartcard_handle_s *arg); /**< error callback */ } smartcard_handle_t; /** @@ -192,7 +192,7 @@ typedef struct smartcard_handle_s /** @defgroup SMARTCARD_Public_Macros_3 SMARTCARD enable * @{ */ -#define SMARTCARD_ENABLE(handle) (SET_BIT((handle)->perh->CON0, USART_CON0_EN_MSK)) +#define SMARTCARD_ENABLE(handle) (SET_BIT((handle)->perh->CON0, USART_CON0_EN_MSK)) /** * @} */ @@ -200,7 +200,7 @@ typedef struct smartcard_handle_s /** @defgroup SMARTCARD_Public_Macros_4 SMARTCARD disable * @{ */ -#define SMARTCARD_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON0, USART_CON0_EN_MSK)) +#define SMARTCARD_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON0, USART_CON0_EN_MSK)) /** * @} */ @@ -214,7 +214,7 @@ typedef struct smartcard_handle_s */ #define IS_SMARTCARD_PRESCALER(x) (((x) >= SMARTCARD_PRESCALER_SYSCLK_DIV2) && \ - ((x) <= SMARTCARD_PRESCALER_SYSCLK_DIV62)) + ((x) <= SMARTCARD_PRESCALER_SYSCLK_DIV62)) /** * @} */ @@ -227,8 +227,8 @@ typedef struct smartcard_handle_s * @{ */ /* Initialization functions */ -ald_status_t smartcard_init(smartcard_handle_t *hperh); -ald_status_t smartcard_reset(smartcard_handle_t *hperh); +ald_status_t ald_smartcard_init(smartcard_handle_t *hperh); +ald_status_t ald_smartcard_reset(smartcard_handle_t *hperh); /** * @} */ @@ -237,15 +237,15 @@ ald_status_t smartcard_reset(smartcard_handle_t *hperh); * @{ */ /* IO operation functions */ -ald_status_t smartcard_send(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t smartcard_recv(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t smartcard_send_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t smartcard_recv_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_smartcard_send(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_smartcard_recv(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_smartcard_send_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_smartcard_recv_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size); #ifdef ALD_DMA -ald_status_t smartcard_send_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t smartcard_recv_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_smartcard_send_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_smartcard_recv_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); #endif -void smartcard_irq_handle(smartcard_handle_t *hperh); +void ald_smartcard_irq_handler(smartcard_handle_t *hperh); /** * @} */ @@ -254,8 +254,8 @@ void smartcard_irq_handle(smartcard_handle_t *hperh); * @{ */ /* Peripheral State and Errors functions functions */ -smartcard_state_t smartcard_get_state(smartcard_handle_t *hperh); -uint32_t smartcard_get_error(smartcard_handle_t *hperh); +smartcard_state_t ald_smartcard_get_state(smartcard_handle_t *hperh); +uint32_t ald_smartcard_get_error(smartcard_handle_t *hperh); /** * @} */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_spi.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_spi.h new file mode 100644 index 0000000000..d92aefb219 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_spi.h @@ -0,0 +1,398 @@ +/** + ********************************************************************************* + * + * @file ald_spi.c + * @brief Header file of SPI module driver. + * + * @version V1.0 + * @date 13 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ********************************************************************************* + */ + +#ifndef __ALD_SPI_H__ +#define __ALD_SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" +#include "ald_dma.h" + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup SPI + * @{ + */ + +/** @defgroup SPI_Public_Types SPI Public Types + * @{ + */ + +/** + * @brief clock phase + */ +typedef enum +{ + SPI_CPHA_FIRST = 0, /**< Transiting data in the first edge */ + SPI_CPHA_SECOND = 1, /**< Transiting data in the seconde edge */ +} spi_cpha_t; + +/** + * @brief clock polarity + */ +typedef enum +{ + SPI_CPOL_LOW = 0, /**< Polarity hold low when spi-bus is idle */ + SPI_CPOL_HIGH = 1, /**< Polarity hold high when spi-bus is idle */ +} spi_cpol_t; + +/** + * @brief master selection + */ +typedef enum +{ + SPI_MODE_SLAVER = 0, /**< Slave mode */ + SPI_MODE_MASTER = 1, /**< Master mode */ +} spi_mode_t; + +/** + * @brief baud rate control + */ +typedef enum +{ + SPI_BAUD_2 = 0, /**< fpclk/2 */ + SPI_BAUD_4 = 1, /**< fpclk/4 */ + SPI_BAUD_8 = 2, /**< fpclk/8 */ + SPI_BAUD_16 = 3, /**< fpclk/16 */ + SPI_BAUD_32 = 4, /**< fpclk/32 */ + SPI_BAUD_64 = 5, /**< fpclk/64 */ + SPI_BAUD_128 = 6, /**< fpclk/128 */ + SPI_BAUD_256 = 7, /**< fpclk/256 */ +} spi_baud_t; + +/** + * @brief frame format + */ +typedef enum +{ + SPI_FIRSTBIT_MSB = 0, /**< MSB transmitted first */ + SPI_FIRSTBIT_LSB = 1, /**< LSB transmitted first */ +} spi_firstbit_t; + +/** + * @brief data frame format + */ +typedef enum +{ + SPI_DATA_SIZE_8 = 0, /**< 8-bit data frame format is selected for transmission/reception */ + SPI_DATA_SIZE_16 = 1, /**< 16-bit data frame format is selected for transmission/reception */ +} spi_datasize_t; + +/** + * @brief interrupt control + */ +typedef enum +{ + SPI_IT_ERR = (1U << 5), /**< error interrupt */ + SPI_IT_RXBNE = (1U << 6), /**< rx buffer not empty interrupt */ + SPI_IT_TXBE = (1U << 7), /**< tx buffer empty interrupt */ +} spi_it_t; + +/** + * @brief interrupt flag + */ +typedef enum +{ + SPI_IF_RXBNE = (1U << 0), /**< receive buffer not empty */ + SPI_IF_TXBE = (1U << 1), /**< transmit buffer empty */ + SPI_IF_CRCERR = (1U << 4), /**< crc error flag */ + SPI_IF_MODF = (1U << 5), /**< mode fault */ + SPI_IF_OVE = (1U << 6), /**< overrun flag */ + SPI_IF_BUSY = (1U << 7), /**< busy flag */ +} spi_flag_t; + +/** + * @brief SPI error status + */ +typedef enum +{ + SPI_ERROR_NONE = 0, /**< none */ + SPI_ERROR_MODF = 1, /**< mode fault */ + SPI_ERROR_CRC = 2, /**< crc error */ + SPI_ERROR_OVE = 4, /**< overrun error */ + SPI_ERROR_DMA = 8, /**< dma error */ + SPI_ERROR_FLAG = 0x10, /**< interrupt flag error */ +} spi_error_t; + + + +/** + * @brief SPI state structures definition + */ +typedef enum +{ + SPI_STATE_RESET = 0x00, /**< Peripheral is not initialized */ + SPI_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + SPI_STATE_BUSY = 0x02, /**< an internal process is ongoing */ + SPI_STATE_BUSY_TX = 0x11, /**< transmit is ongoing */ + SPI_STATE_BUSY_RX = 0x21, /**< receive is ongoing */ + SPI_STATE_BUSY_TX_RX = 0x31, /**< transmit and receive are ongoing */ + SPI_STATE_TIMEOUT = 0x03, /**< Timeout state */ + SPI_STATE_ERROR = 0x04, /**< Error */ +} spi_state_t; + +/** + * @brief SPI status definition + */ +typedef enum +{ + SPI_STATUS_RXBNE = (1U << 0), /**< Receive not empty status */ + SPI_STATUS_TXBE = (1U << 1), /**< Transmit empty status */ + SPI_STATUS_CRCERR = (1U << 4), /**< CRC error status */ + SPI_STATUS_MODEERR = (1U << 5), /**< Mode error status */ + SPI_STATUS_OVERR = (1U << 6), /**< Overflow status */ + SPI_STATUS_BUSY = (1U << 7), /**< Busy status */ + +} spi_status_t; + +/** + * @brief SPI direction definition + */ +typedef enum +{ + SPI_DIRECTION_2LINES = 0, /**< 2 lines */ + SPI_DIRECTION_2LINES_RXONLY = 1, /**< 2 lines only rx */ + SPI_DIRECTION_1LINE = 2, /**< 1 line */ + SPI_DIRECTION_1LINE_RX = 3, /**< 1 line only rx */ +} spi_direction_t; + +/** + * @brief SPI dma request definition + */ +typedef enum +{ + SPI_DMA_REQ_TX = 0, /**< TX dma request */ + SPI_DMA_REQ_RX = 1, /**< RX dma request */ +} spi_dma_req_t; + +/** + * @brief SPI TXE/RXNE status definition + */ +typedef enum +{ + SPI_SR_TXBE = 0, /**< SR.TXE set */ + SPI_SR_RXBNE = 1, /**< SR.RXNE set */ + SPI_SR_TXBE_RXBNE = 2, /**< SR.TXE and SR.RXNE set */ +} spi_sr_status_t; + +/** + * @brief SPI init structure definition + */ +typedef struct +{ + spi_mode_t mode; /**< SPI mode */ + spi_direction_t dir; /**< SPI direction */ + spi_datasize_t data_size; /**< SPI data size */ + spi_baud_t baud; /**< SPI baudrate prescaler */ + spi_cpha_t phase; /**< SPI clock phase */ + spi_cpol_t polarity; /**< SPI clock polarity */ + spi_firstbit_t first_bit; /**< SPI first bit */ + type_func_t ss_en; /**< SPI ssm enable or disable */ + type_func_t crc_calc; /**< SPI crc calculation */ + uint16_t crc_poly; /**< SPI crc polynomial */ +} spi_init_t; + +/** + * @brief SPI handle structure definition + */ +typedef struct spi_handle_s +{ + SPI_TypeDef *perh; /**< SPI registers base address */ + spi_init_t init; /**< SPI communication parameters */ + uint8_t *tx_buf; /**< Pointer to SPI Tx transfer buffer */ + uint16_t tx_size; /**< SPI Tx transfer size */ + uint16_t tx_count; /**< SPI Tx transfer counter */ + uint8_t *rx_buf; /**< Pointer to SPI Rx transfer buffer */ + uint16_t rx_size; /**< SPI Rx Transfer size */ + uint16_t rx_count; /**< SPI Rx Transfer Counter */ +#ifdef ALD_DMA + dma_handle_t hdmatx; /**< SPI Tx DMA handle parameters */ + dma_handle_t hdmarx; /**< SPI Rx DMA handle parameters */ +#endif + lock_state_t lock; /**< Locking object */ + spi_state_t state; /**< SPI communication state */ + uint32_t err_code; /**< SPI error code */ + + void (*tx_cplt_cbk)(struct spi_handle_s *arg); /**< Tx completed callback */ + void (*rx_cplt_cbk)(struct spi_handle_s *arg); /**< Rx completed callback */ + void (*tx_rx_cplt_cbk)(struct spi_handle_s *arg); /**< Tx & Rx completed callback */ + void (*err_cbk)(struct spi_handle_s *arg); /**< error callback */ +} spi_handle_t; +/** + * @} + */ + +/** @defgroup SPI_Public_Macros SPI Public Macros + * @{ + */ +#define SPI_RESET_HANDLE_STATE(x) ((x)->state = SPI_STATE_RESET) +#define SPI_ENABLE(x) ((x)->perh->CON1 |= (1 << SPI_CON1_SPIEN_POS)) +#define SPI_DISABLE(x) ((x)->perh->CON1 &= ~(1 << SPI_CON1_SPIEN_POS)) +#define SPI_CRC_RESET(x) \ + do { \ + CLEAR_BIT((x)->perh->CON1, SPI_CON1_CRCEN_MSK); \ + SET_BIT((x)->perh->CON1, SPI_CON1_CRCEN_MSK); \ + } while (0) +#define SPI_CRCNEXT_ENABLE(x) (SET_BIT((x)->perh->CON1, SPI_CON1_NXTCRC_MSK)) +#define SPI_CRCNEXT_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_NXTCRC_MSK)) +#define SPI_RXONLY_ENABLE(x) (SET_BIT((x)->perh->CON1, SPI_CON1_RXO_MSK)) +#define SPI_RXONLY_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_RXO_MSK)) +#define SPI_1LINE_TX(x) (SET_BIT((x)->perh->CON1, SPI_CON1_BIDOEN_MSK)) +#define SPI_1LINE_RX(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_BIDOEN_MSK)) +#define SPI_SSI_HIGH(x) (SET_BIT((x)->perh->CON1, SPI_CON1_SSOUT_MSK)) +#define SPI_SSI_LOW(x) (CLEAR_BIT((x)->perh->CON1, SPI_CON1_SSOUT_MSK)) +#define SPI_SSOE_ENABLE(x) (SET_BIT((x)->perh->CON2, SPI_CON2_NSSOE_MSK)) +#define SPI_SSOE_DISABLE(x) (CLEAR_BIT((x)->perh->CON2, SPI_CON2_NSSOE_MSK)) +/** + * @} + */ + +/** @defgroup SPI_Private_Macros SPI Private Macros + * @{ + */ +#define IS_SPI(x) (((x) == SPI0) || \ + ((x) == SPI1) || \ + ((x) == SPI2)) +#define IS_SPI_CPHA(x) (((x) == SPI_CPHA_FIRST) || \ + ((x) == SPI_CPHA_SECOND)) +#define IS_SPI_CPOL(x) (((x) == SPI_CPOL_LOW) || \ + ((x) == SPI_CPOL_HIGH)) +#define IS_SPI_MODE(x) (((x) == SPI_MODE_SLAVER) || \ + ((x) == SPI_MODE_MASTER)) +#define IS_SPI_BAUD(x) (((x) == SPI_BAUD_2) || \ + ((x) == SPI_BAUD_4) || \ + ((x) == SPI_BAUD_8) || \ + ((x) == SPI_BAUD_16) || \ + ((x) == SPI_BAUD_32) || \ + ((x) == SPI_BAUD_64) || \ + ((x) == SPI_BAUD_128) || \ + ((x) == SPI_BAUD_256)) +#define IS_SPI_DATASIZE(x) (((x) == SPI_DATA_SIZE_8) || \ + ((x) == SPI_DATA_SIZE_16)) +#define IS_SPI_BIDOE(x) (((x) == SPI_BID_RX) || \ + ((x) == SPI_BID_TX)) +#define IS_SPI_BIDMODE(x) (((x) == SPI_BIDMODE_DUAL) || \ + ((x) == SPI_BIDMODE_SOLE)) +#define IS_SPI_DIRECTION(x) (((x) == SPI_DIRECTION_2LINES) || \ + ((x) == SPI_DIRECTION_2LINES_RXONLY) || \ + ((x) == SPI_DIRECTION_1LINE) || \ + ((x) == SPI_DIRECTION_1LINE_RX)) +#define IS_SPI_DMA_REQ(x) (((x) == SPI_DMA_REQ_TX) || \ + ((x) == SPI_DMA_REQ_RX)) +#define IS_SPI_SR_STATUS(x) (((x) == SPI_SR_TXBE) || \ + ((x) == SPI_SR_RXBNE) || \ + ((x) == SPI_SR_TXBE_RXBNE)) +#define IS_SPI_IT(x) (((x) == SPI_IT_ERR) || \ + ((x) == SPI_IT_RXBNE) || \ + ((x) == SPI_IT_TXBE)) +#define IS_SPI_IF(x) (((x) == SPI_IF_RXBNE) || \ + ((x) == SPI_IF_TXBE) || \ + ((x) == SPI_IF_CRCERR) || \ + ((x) == SPI_IF_MODF) || \ + ((x) == SPI_IF_OVE) || \ + ((x) == SPI_IF_BUSY)) +#define IS_SPI_STATUS(x) (((x) == SPI_STATUS_RXBNE) || \ + ((x) == SPI_STATUS_TXBE) || \ + ((x) == SPI_STATUS_CRCERR) || \ + ((x) == SPI_STATUS_MODEERR) || \ + ((x) == SPI_STATUS_OVERR) || \ + ((x) == SPI_STATUS_BUSY)) +/** + * @} + */ + +/** @addtogroup SPI_Public_Functions + * @{ + */ + +/** @addtogroup SPI_Public_Functions_Group1 + * @{ + */ + +ald_status_t ald_spi_init(spi_handle_t *hperh); +void ald_spi_reset(spi_handle_t *hperh); +/** + * @} + */ + +/** @addtogroup SPI_Public_Functions_Group2 + * @{ + */ +int32_t ald_spi_send_byte_fast(spi_handle_t *hperh, uint8_t data); +int32_t ald_spi_send_byte_fast_1line(spi_handle_t *hperh, uint8_t data); +uint8_t ald_spi_recv_byte_fast(spi_handle_t *hperh); +ald_status_t ald_spi_send(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_spi_send_recv(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout); +ald_status_t ald_spi_send_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_spi_recv_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_spi_send_recv_by_it(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size); +#ifdef ALD_DMA +ald_status_t ald_spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel); +ald_status_t ald_spi_dma_pause(spi_handle_t *hperh); +ald_status_t ald_spi_dma_resume(spi_handle_t *hperh); +ald_status_t ald_spi_dma_stop(spi_handle_t *hperh); +#endif +/** + * @} + */ + +/** @addtogroup SPI_Public_Functions_Group3 + * @{ + */ +void ald_spi_irq_handler(spi_handle_t *hperh); +void ald_spi_interrupt_config(spi_handle_t *hperh, spi_it_t it, type_func_t state); +void ald_spi_speed_config(spi_handle_t *hperh, spi_baud_t speed); +void ald_spi_dma_req_config(spi_handle_t *hperh, spi_dma_req_t req, type_func_t state); +it_status_t ald_spi_get_it_status(spi_handle_t *hperh, spi_it_t it); +flag_status_t spi_get_status(spi_handle_t *hperh, spi_status_t status); +flag_status_t ald_spi_get_flag_status(spi_handle_t *hperh, spi_flag_t flag); +void ald_spi_clear_flag_status(spi_handle_t *hperh, spi_flag_t flag); +/** + * @} + */ + +/** @addtogroup SPI_Public_Functions_Group4 + * @{ + */ +spi_state_t ald_spi_get_state(spi_handle_t *hperh); +uint32_t ald_spi_get_error(spi_handle_t *hperh); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_syscfg.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_syscfg.h similarity index 50% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_syscfg.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_syscfg.h index 22ef750f70..d173be011f 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_syscfg.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_syscfg.h @@ -36,33 +36,33 @@ extern "C" { /** @defgroup SYSCFG_Public_Macros SYSCFG Public Macros * @{ */ -#define SYSCFG_LOCK() WRITE_REG(SYSCFG->PROT, 0x0) -#define SYSCFG_UNLOCK() WRITE_REG(SYSCFG->PROT, 0x55AA6996) -#define GET_SYSCFG_LOCK() READ_BIT(SYSCFG->PROT, SYSCFG_PROT_PROT_MSK) - -#define BOOT_FROM_BOOT_ROM() \ -do { \ - SYSCFG_UNLOCK(); \ - SET_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BRRMPEN_MSK); \ - CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BFRMPEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) - -#define BOOT_FROM_BOOT_FLASH() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BRRMPEN_MSK); \ - SET_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BFRMPEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) - -#define BOOT_FROM_FLASH() \ -do { \ - SYSCFG_UNLOCK(); \ - CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BRRMPEN_MSK); \ - CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BFRMPEN_MSK); \ - SYSCFG_LOCK(); \ -} while (0) +#define SYSCFG_LOCK() WRITE_REG(SYSCFG->PROT, 0x0) +#define SYSCFG_UNLOCK() WRITE_REG(SYSCFG->PROT, 0x55AA6996) +#define GET_SYSCFG_LOCK() READ_BIT(SYSCFG->PROT, SYSCFG_PROT_PROT_MSK) + +#define BOOT_FROM_BOOT_ROM() \ + do { \ + SYSCFG_UNLOCK(); \ + SET_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BRRMPEN_MSK); \ + CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BFRMPEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) + +#define BOOT_FROM_BOOT_FLASH() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BRRMPEN_MSK); \ + SET_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BFRMPEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) + +#define BOOT_FROM_FLASH() \ + do { \ + SYSCFG_UNLOCK(); \ + CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BRRMPEN_MSK); \ + CLEAR_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_BFRMPEN_MSK); \ + SYSCFG_LOCK(); \ + } while (0) /** * @} */ @@ -71,7 +71,7 @@ do { \ /** @defgroup SYSCFG_Public_Functions SYSCFG Public Functions * @{ */ -__STATIC_INLINE__ void vtor_config(uint32_t offset, type_func_t status) +__STATIC_INLINE__ void ald_vtor_config(uint32_t offset, type_func_t status) { SYSCFG_UNLOCK(); diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_timer.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_timer.h new file mode 100644 index 0000000000..9fe5ee6d64 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_timer.h @@ -0,0 +1,1193 @@ +/** + ********************************************************************************* + * + * @file ald_timer.h + * @brief TIMER module driver. + * This is the common part of the TIMER initialization + * + * @version V1.0 + * @date 06 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ********************************************************************************* + */ + +#ifndef __ALD_TIMER_H__ +#define __ALD_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" +#include "ald_dma.h" + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup TIMER + * @{ + */ + +/** @defgroup TIMER_Public_Types TIMER Public Types + * @{ + */ + +/** + * @brief TIMER counter mode + */ +typedef enum +{ + TIMER_CNT_MODE_UP = 0, /**< Counter mode up */ + TIMER_CNT_MODE_DOWN = 1, /**< Counter mode down */ + TIMER_CNT_MODE_CENTER1 = 2, /**< Counter mode center1 */ + TIMER_CNT_MODE_CENTER2 = 3, /**< Counter mode center2 */ + TIMER_CNT_MODE_CENTER3 = 4, /**< Counter mode center3 */ +} timer_cnt_mode_t; + +/** + * @brief TIMER clock division + */ +typedef enum +{ + TIMER_CLOCK_DIV1 = 0, /**< No prescaler is used */ + TIMER_CLOCK_DIV2 = 1, /** Clock is divided by 2 */ + TIMER_CLOCK_DIV4 = 2, /** Clock is divided by 4 */ +} timer_clock_division_t; + +/** + * @brief TIMER output compare and PWM modes + */ +typedef enum +{ + TIMER_OC_MODE_TIMERING = 0, /**< Output compare mode is timering */ + TIMER_OC_MODE_ACTIVE = 1, /**< Output compare mode is active */ + TIMER_OC_MODE_INACTIVE = 2, /**< Output compare mode is inactive */ + TIMER_OC_MODE_TOGGLE = 3, /**< Output compare mode is toggle */ + TIMER_OC_MODE_FORCE_INACTIVE = 4, /**< Output compare mode is force inactive */ + TIMER_OC_MODE_FORCE_ACTIVE = 5, /**< Output compare mode is force active */ + TIMER_OC_MODE_PWM1 = 6, /**< Output compare mode is pwm1 */ + TIMER_OC_MODE_PWM2 = 7, /**< Output compare mode is pwm2 */ +} timer_oc_mode_t; + +/** + * @brief TIMER output compare polarity + */ +typedef enum +{ + TIMER_OC_POLARITY_HIGH = 0, /**< Output compare polarity is high */ + TIMER_OC_POLARITY_LOW = 1, /**< Output compare polarity is low */ +} timer_oc_polarity_t; + +/** + * @brief TIMER complementary output compare polarity + */ +typedef enum +{ + TIMER_OCN_POLARITY_HIGH = 0, /**< Complementary output compare polarity is high */ + TIMER_OCN_POLARITY_LOW = 1, /**< Complementary output compare polarity is low */ +} timer_ocn_polarity_t; + +/** + * @brief TIMER output compare idle state + */ +typedef enum +{ + TIMER_OC_IDLE_RESET = 0, /**< Output compare idle state is reset */ + TIMER_OC_IDLE_SET = 1, /**< Output compare idle state is set */ +} timer_oc_idle_t; + +/** + * @brief TIMER complementary output compare idle state + */ +typedef enum +{ + TIMER_OCN_IDLE_RESET = 0, /**< Complementary output compare idle state is reset */ + TIMER_OCN_IDLE_SET = 1, /**< Complementary output compare idle state is set */ +} timer_ocn_idle_t; + +/** + * @brief TIMER channel + */ +typedef enum +{ + TIMER_CHANNEL_1 = 0, /**< Channel 1 */ + TIMER_CHANNEL_2 = 1, /**< Channel 2 */ + TIMER_CHANNEL_3 = 2, /**< Channel 3 */ + TIMER_CHANNEL_4 = 4, /**< Channel 4 */ + TIMER_CHANNEL_ALL = 0xF, /**< All channel */ +} timer_channel_t; + +/** + * @brief TIMER one pulse mode + */ +typedef enum +{ + TIMER_OP_MODE_REPEAT = 0, /**< Repetitive */ + TIMER_OP_MODE_SINGLE = 1, /**< single */ +} timer_op_mode_t; + +/** + * @brief TIMER one pulse output channel + */ +typedef enum +{ + TIMER_OP_OUTPUT_CHANNEL_1 = 0, /**< One pulse output channal 1 */ + TIMER_OP_OUTPUT_CHANNEL_2 = 1, /**< One pulse output channal 2 */ +} timer_op_output_channel_t; + +/** + * @brief TIMER time base configuration structure definition + */ +typedef struct +{ + uint32_t prescaler; /**< Specifies the prescaler value used to divide the TIMER clock. */ + timer_cnt_mode_t mode; /**< Specifies the counter mode. */ + uint32_t period; /**< Specifies the period value to be loaded into ARR at the next update event. */ + timer_clock_division_t clk_div; /**< Specifies the clock division.*/ + uint32_t re_cnt; /**< Specifies the repetition counter value. */ +} timer_base_init_t; + +/** + * @brief TIMER output compare configuration structure definition + */ +typedef struct +{ + timer_oc_mode_t oc_mode; /**< Specifies the TIMER mode. */ + uint32_t pulse; /**< Specifies the pulse value to be loaded into the Capture Compare Register. */ + timer_oc_polarity_t oc_polarity; /**< Specifies the output polarity. */ + timer_ocn_polarity_t ocn_polarity; /**< Specifies the complementary output polarity. */ + type_func_t oc_fast_en; /**< Specifies the Fast mode state. */ + timer_oc_idle_t oc_idle; /**< Specifies the TIMER Output Compare pin state during Idle state. */ + timer_ocn_idle_t ocn_idle; /**< Specifies the TIMER Output Compare pin state during Idle state. */ +} timer_oc_init_t; + +/** + * @brief State structures definition + */ +typedef enum +{ + TIMER_STATE_RESET = 0x00, /**< Peripheral not yet initialized or disabled */ + TIMER_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + TIMER_STATE_BUSY = 0x02, /**< An internal process is ongoing */ + TIMER_STATE_TIMEREOUT = 0x03, /**< Timeout state */ + TIMER_STATE_ERROR = 0x04, /**< Reception process is ongoing */ +} timer_state_t; + +/** + * @brief Active channel structures definition + */ +typedef enum +{ + TIMER_ACTIVE_CHANNEL_1 = 0x01, /**< The active channel is 1 */ + TIMER_ACTIVE_CHANNEL_2 = 0x02, /**< The active channel is 2 */ + TIMER_ACTIVE_CHANNEL_3 = 0x04, /**< The active channel is 3 */ + TIMER_ACTIVE_CHANNEL_4 = 0x08, /**< The active channel is 4 */ + TIMER_ACTIVE_CHANNEL_CLEARED = 0x00, /**< All active channels cleared */ +} timer_active_channel_t; + +/** + * @brief TIMER time base handle structure definition + */ +typedef struct timer_handle_s +{ + TIMER_TypeDef *perh; /**< Register base address */ + timer_base_init_t init; /**< TIMER Time Base required parameters */ + timer_active_channel_t ch; /**< Active channel */ + lock_state_t lock; /**< Locking object */ + timer_state_t state; /**< TIMER operation state */ + + void (*period_elapse_cbk)(struct timer_handle_s *arg); /**< Period elapse callback */ + void (*delay_elapse_cbk)(struct timer_handle_s *arg); /**< Delay_elapse callback */ + void (*capture_cbk)(struct timer_handle_s *arg); /**< Capture callback */ + void (*pwm_pulse_finish_cbk)(struct timer_handle_s *arg); /**< PWM_pulse_finish callback */ + void (*trigger_cbk)(struct timer_handle_s *arg); /**< Trigger callback */ + void (*break_cbk)(struct timer_handle_s *arg); /**< Break callback */ + void (*com_cbk)(struct timer_handle_s *arg); /**< commutation callback */ + void (*error_cbk)(struct timer_handle_s *arg); /**< Error callback */ +} timer_handle_t; + + +/** + * @brief TIMER encoder mode + */ +typedef enum +{ + TIMER_ENC_MODE_TI1 = 1, /**< encoder mode 1 */ + TIMER_ENC_MODE_TI2 = 2, /**< encoder mode 2 */ + TIMER_ENC_MODE_TI12 = 3, /**< encoder mode 3 */ +} timer_encoder_mode_t; + +/** + * @brief TIMER input capture polarity + */ +typedef enum +{ + TIMER_IC_POLARITY_RISE = 0, /**< Input capture polarity rising */ + TIMER_IC_POLARITY_FALL = 1, /**< Input capture polarity falling */ +} timer_ic_polarity_t; + +/** + *@brief TIMER input capture selection + */ +typedef enum +{ + TIMER_IC_SEL_DIRECT = 1, /**< IC1 -- TI1 */ + TIMER_IC_SEL_INDIRECT = 2, /**< IC1 -- TI2 */ + TIMER_IC_SEL_TRC = 3, /**< IC1 -- TRC */ +} timer_ic_select_t; + +/** + * @brief TIMER input capture prescaler + */ +typedef enum +{ + TIMER_IC_PSC_DIV1 = 0, /**< Capture performed once every 1 events */ + TIMER_IC_PSC_DIV2 = 1, /**< Capture performed once every 2 events */ + TIMER_IC_PSC_DIV4 = 2, /**< Capture performed once every 4 events */ + TIMER_IC_PSC_DIV8 = 3, /**< Capture performed once every 4 events */ +} timer_ic_prescaler_t; + +/** + * @brief TIMER encoder configuration structure definition + */ +typedef struct +{ + timer_encoder_mode_t mode; /**< Specifies the encoder mode */ + timer_ic_polarity_t ic1_polarity; /**< Specifies the active edge of the input signal */ + timer_ic_select_t ic1_sel; /**< Specifies the input */ + timer_ic_prescaler_t ic1_psc; /**< Specifies the Input Capture Prescaler */ + uint32_t ic1_filter; /**< Specifies the input capture filter */ + timer_ic_polarity_t ic2_polarity; /**< Specifies the active edge of the input signal */ + timer_ic_select_t ic2_sel; /**< Specifies the input */ + timer_ic_prescaler_t ic2_psc; /**< Specifies the Input Capture Prescaler */ + uint32_t ic2_filter; /**< Specifies the input capture filter */ +} timer_encoder_init_t; + +/** + * @brief TIMER input capture configuration structure definition + */ +typedef struct +{ + timer_ic_polarity_t polarity; /**< Specifies the active edge of the input signal */ + timer_ic_select_t sel; /**< Specifies the input */ + timer_ic_prescaler_t psc; /**< Specifies the Input Capture Prescaler */ + uint32_t filter; /**< Specifies the input capture filter */ +} timer_ic_init_t; + +/** + * @brief TIMER one pulse mode configuration structure definition + */ +typedef struct +{ + timer_oc_mode_t mode; /**< Specifies the TIMER mode */ + uint16_t pulse; /**< Specifies the pulse value */ + timer_oc_polarity_t oc_polarity; /**< Specifies the output polarity */ + timer_ocn_polarity_t ocn_polarity; /**< Specifies the complementary output polarity */ + timer_oc_idle_t oc_idle; /**< Specifies the TIMER Output Compare pin state during Idle state */ + timer_ocn_idle_t ocn_idle; /**< Specifies the TIMER Output Compare pin state during Idle state */ + timer_ic_polarity_t polarity; /**< Specifies the active edge of the input signal */ + timer_ic_select_t sel; /**< Specifies the input */ + uint32_t filter; /**< Specifies the input capture filter */ +} timer_one_pulse_init_t; + +/** @brief TIMER clear input source + */ +typedef enum +{ + TIMER_INPUT_NONE = 0, /**< Clear input none */ + TIMER_INPUT_ETR = 1, /**< Clear input etr */ +} timer_clear_input_source_t; + +/** @brief TIMER clear input polarity + */ +typedef enum +{ + TIMER_POLARITY_NO_INV = 0, /**< Polarity for ETRx pin */ + TIMER_POLARITY_INV = 1, /**< Polarity for ETRx pin */ +} timer_clear_input_polarity_t; + +/** @brief TIMER clear input polarity + */ +typedef enum +{ + TIMER_ETR_PSC_DIV1 = 0, /**< No prescaler is used */ + TIMER_ETR_PSC_DIV2 = 1, /**< ETR input source is divided by 2 */ + TIMER_ETR_PSC_DIV4 = 2, /**< ETR input source is divided by 4 */ + TIMER_ETR_PSC_DIV8 = 3, /**< ETR input source is divided by 8 */ +} timer_etr_psc_t; + +/** + * @brief TIMER clear input configuration handle structure definition + */ +typedef struct +{ + type_func_t state; /**< TIMER clear Input state */ + timer_clear_input_source_t source; /**< TIMER clear Input sources */ + timer_clear_input_polarity_t polarity; /**< TIMER Clear Input polarity */ + timer_etr_psc_t psc; /**< TIMER Clear Input prescaler */ + uint32_t filter; /**< TIMER Clear Input filter */ +} timer_clear_input_config_t; + +/** @brief TIMER clock source + */ +typedef enum +{ + TIMER_SRC_ETRMODE2 = 0, /**< Clock source is etr mode2 */ + TIMER_SRC_INTER = 1, /**< Clock source is etr internal */ + TIMER_SRC_ITR0 = 2, /**< Clock source is etr itr0 */ + TIMER_SRC_ITR1 = 3, /**< Clock source is etr itr1 */ + TIMER_SRC_ITR2 = 4, /**< Clock source is etr itr2 */ + TIMER_SRC_ITR3 = 5, /**< Clock source is etr itr3 */ + TIMER_SRC_TI1ED = 6, /**< Clock source is etr ti1ed */ + TIMER_SRC_TI1 = 7, /**< Clock source is etr ti1 */ + TIMER_SRC_TI2 = 8, /**< Clock source is etr ti2 */ + TIMER_SRC_ETRMODE1 = 9, /**< Clock source is etr mode1 */ +} timer_clock_source_t; + +/** @brief TIMER clock polarity + */ +typedef enum +{ + TIMER_CLK_POLARITY_INV = 1, /**< Polarity for ETRx clock sources */ + TIMER_CLK_POLARITY_NO_INV = 0, /**< Polarity for ETRx clock sources */ + TIMER_CLK_POLARITY_RISE = 0, /**< Polarity for TIx clock sources */ + TIMER_CLK_POLARITY_FALL = 1, /**< Polarity for TIx clock sources */ + TIMER_CLK_POLARITY_BOTH = 3, /**< Polarity for TIx clock sources */ +} timer_clock_polarity_t; + +/** + * @brief TIMER clock config structure definition + */ +typedef struct +{ + timer_clock_source_t source; /**< TIMER clock sources */ + timer_clock_polarity_t polarity; /**< TIMER clock polarity */ + timer_etr_psc_t psc; /**< TIMER clock prescaler */ + uint32_t filter; /**< TIMER clock filter */ +} timer_clock_config_t; + +/** + * @brief TIMER slave mode + */ +typedef enum +{ + TIMER_MODE_DISABLE = 0, /**< Slave mode is disable */ + TIMER_MODE_ENC1 = 1, /**< Slave mode is encoder1 */ + TIMER_MODE_ENC2 = 2, /**< Slave mode is encoder2 */ + TIMER_MODE_ENC3 = 3, /**< Slave mode is encoder3 */ + TIMER_MODE_RESET = 4, /**< Slave mode is reset */ + TIMER_MODE_GATED = 5, /**< Slave mode is gated */ + TIMER_MODE_TRIG = 6, /**< Slave mode is trigger */ + TIMER_MODE_EXTERNAL1 = 7, /**< Slave mode is external1 */ +} timer_slave_mode_t; + +/** + * @brief TIMER ts definition + */ +typedef enum +{ + TIMER_TS_ITR0 = 0, /**< ITR0 */ + TIMER_TS_ITR1 = 1, /**< ITR1 */ + TIMER_TS_ITR2 = 2, /**< ITR2 */ + TIMER_TS_ITR3 = 3, /**< ITR3 */ + TIMER_TS_TI1F_ED = 4, /**< TI1F_ED */ + TIMER_TS_TI1FP1 = 5, /**< TI1FP1 */ + TIMER_TS_TI2FP2 = 6, /**< TI2FP2 */ + TIMER_TS_ETRF = 7, /**< ETRF */ +} timer_ts_t; + +/** + * @brief TIMER slave configuration structure definition + */ +typedef struct +{ + timer_slave_mode_t mode; /**< Slave mode selection */ + timer_ts_t input; /**< Input Trigger source */ + timer_clock_polarity_t polarity; /**< Input Trigger polarity */ + timer_etr_psc_t psc; /**< Input trigger prescaler */ + uint32_t filter; /**< Input trigger filter */ +} timer_slave_config_t; + +/** + * @brief TIMER hall sensor configuretion structure definition + */ +typedef struct +{ + timer_ic_polarity_t polarity; /**< Specifies the active edge of the input signal */ + timer_ic_prescaler_t psc; /**< Specifies the Input Capture Prescaler */ + uint32_t filter; /**< Specifies the input capture filter [0x0, 0xF] */ + uint32_t delay; /**< Specifies the pulse value to be loaded into the register [0x0, 0xFFFF] */ +} timer_hall_sensor_init_t; + +/** + * @brief TIMER lock level + */ +typedef enum +{ + TIMER_LOCK_LEVEL_OFF = 0, /**< Lock off */ + TIMER_LOCK_LEVEL_1 = 1, /**< Lock level 1 */ + TIMER_LOCK_LEVEL_2 = 2, /**< Lock level 2 */ + TIMER_LOCK_LEVEL_3 = 3, /**< Lock level 3 */ +} timer_lock_level_t; + +/** + * @brief TIMER break polarity + */ +typedef enum +{ + TIMER_BREAK_POLARITY_LOW = 0, /**< LOW */ + TIMER_BREAK_POLARITY_HIGH = 1, /**< HIGH */ +} timer_break_polarity_t; + +/** + * @brief TIMER break and dead time configuretion structure definition + */ +typedef struct +{ + type_func_t off_run; /**< Enalbe/Disable off state in run mode */ + type_func_t off_idle; /**< Enalbe/Disable off state in idle mode */ + timer_lock_level_t lock_level; /**< Lock level */ + uint32_t dead_time; /**< Dead time, [0x0, 0xFF] */ + type_func_t break_state; /**< Break state */ + timer_break_polarity_t polarity; /**< Break input polarity */ + type_func_t auto_out; /**< Enalbe/Disable automatic output */ +} timer_break_dead_time_t; + +/** + * @brief TIMER commutation event channel configuretion structure definition + */ +typedef struct +{ + type_func_t en; /**< Enalbe/Disable the channel */ + type_func_t n_en; /**< Enalbe/Disable the complementary channel */ + timer_oc_mode_t mode; /**< Mode of the channel */ +} timer_channel_config_t; + +/** + * @brief TIMER commutation event configuretion structure definition + */ +typedef struct +{ + timer_channel_config_t ch[3]; /**< Configure of channel */ +} timer_com_channel_config_t; + +/** + * @brief TIMER master mode selection + */ +typedef enum +{ + TIMER_TRGO_RESET = 0, /**< RESET */ + TIMER_TRGO_ENABLE = 1, /**< ENABLE */ + TIMER_TRGO_UPDATE = 2, /**< UPDATE */ + TIMER_TRGO_OC1 = 3, /**< OC1 */ + TIMER_TRGO_OC1REF = 4, /**< OC1REF */ + TIMER_TRGO_OC2REF = 5, /**< OC2REF */ + TIMER_TRGO_OC3REF = 6, /**< OC3REF */ + TIMER_TRGO_OC4REF = 7, /**< OC4REF */ +} timer_master_mode_sel_t; + +/** + * @brief TIMER master configuretion structure definition + */ +typedef struct +{ + timer_master_mode_sel_t sel; /**< Specifies the active edge of the input signal */ + type_func_t master_en; /**< Master/Slave mode selection */ +} timer_master_config_t; + +/** + * @brief Specifies the event source + */ +typedef enum +{ + TIMER_SRC_UPDATE = (1U << 0), /**< Event source is update */ + TIMER_SRC_CC1 = (1U << 1), /**< Event source is channel1 */ + TIMER_SRC_CC2 = (1U << 2), /**< Event source is channel2 */ + TIMER_SRC_CC3 = (1U << 3), /**< Event source is channel3 */ + TIMER_SRC_CC4 = (1U << 4), /**< Event source is channel4 */ + TIMER_SRC_COM = (1U << 5), /**< Event source is compare */ + TIMER_SRC_TRIG = (1U << 6), /**< Event source is trigger */ + TIMER_SRC_BREAK = (1U << 7), /**< Event source is break */ +} timer_event_source_t; + +/** + * @brief TIMER interrupt definition + */ +typedef enum +{ + TIMER_IT_UPDATE = (1U << 0), /**< Update interrupt bit */ + TIMER_IT_CC1 = (1U << 1), /**< Channel1 interrupt bit */ + TIMER_IT_CC2 = (1U << 2), /**< Channel2 interrupt bit */ + TIMER_IT_CC3 = (1U << 3), /**< Channel3 interrupt bit */ + TIMER_IT_CC4 = (1U << 4), /**< Channel4 interrupt bit */ + TIMER_IT_COM = (1U << 5), /**< compare interrupt bit */ + TIMER_IT_TRIGGER = (1U << 6), /**< Trigger interrupt bit */ + TIMER_IT_BREAK = (1U << 7), /**< Break interrupt bit */ +} timer_it_t; + +/** + * @brief TIMER DMA request + */ +typedef enum +{ + TIMER_DMA_UPDATE = (1U << 8), /**< DMA request from update */ + TIMER_DMA_CC1 = (1U << 9), /**< DMA request from channel1 */ + TIMER_DMA_CC2 = (1U << 10), /**< DMA request from channel2 */ + TIMER_DMA_CC3 = (1U << 11), /**< DMA request from channel3 */ + TIMER_DMA_CC4 = (1U << 12), /**< DMA request from channel4 */ + TIMER_DMA_COM = (1U << 13), /**< DMA request from compare */ + TIMER_DMA_TRIGGER = (1U << 14), /**< DMA request from trigger */ +} timer_dma_req_t; + +/** + * @brief TIMER flag definition + */ +typedef enum +{ + TIMER_FLAG_UPDATE = (1U << 0), /**< Update interrupt flag */ + TIMER_FLAG_CC1 = (1U << 1), /**< Channel1 interrupt flag */ + TIMER_FLAG_CC2 = (1U << 2), /**< Channel2 interrupt flag */ + TIMER_FLAG_CC3 = (1U << 3), /**< Channel3 interrupt flag */ + TIMER_FLAG_CC4 = (1U << 4), /**< Channel4 interrupt flag */ + TIMER_FLAG_COM = (1U << 5), /**< Compare interrupt flag */ + TIMER_FLAG_TRIGGER = (1U << 6), /**< Trigger interrupt flag */ + TIMER_FLAG_BREAK = (1U << 7), /**< Break interrupt flag */ + TIMER_FLAG_CC1OF = (1U << 9), /**< Channel1 override state flag */ + TIMER_FLAG_CC2OF = (1U << 10), /**< Channel2 override state flag */ + TIMER_FLAG_CC3OF = (1U << 11), /**< Channel3 override state flag */ + TIMER_FLAG_CC4OF = (1U << 12), /**< Channel4 override state flag */ +} timer_flag_t; +/** + * @} + */ + +/** @defgroup TIMER_Public_Macros TIMER Public Macros + * @{ + */ +#define CCER_CCxE_MASK ((1U << 0) | (1U << 4) | (1U << 8) | (1U << 12)) +#define CCER_CCxNE_MASK ((1U << 2) | (1U << 6) | (1U << 10)) + +/** + * @brief Reset TIMER handle state + */ +#define TIMER_RESET_HANDLE_STATE(hperh) ((hperh)->state = TIMER_STATE_RESET) + +/** + * @brief Enable the TIMER peripheral. + */ +#define TIMER_ENABLE(hperh) (SET_BIT((hperh)->perh->CON1, TIMER_CON1_CNTEN_MSK)) + +/** + * @brief Enable the TIMER main output. + */ +#define TIMER_MOE_ENABLE(hperh) (SET_BIT((hperh)->perh->BDCFG, TIMER_BDCFG_GOEN_MSK)) + +/** + * @brief Disable the TIMER peripheral. + */ +#define TIMER_DISABLE(hperh) \ + do { \ + if ((((hperh)->perh->CCEP & CCER_CCxE_MASK) == 0) \ + && (((hperh)->perh->CCEP & CCER_CCxNE_MASK) == 0)) \ + CLEAR_BIT((hperh)->perh->CON1, TIMER_CON1_CNTEN_MSK); \ + } while (0) + +/** + * @brief Disable the TIMER main output. + * @note The Main Output Enable of a timer instance is disabled only if + * all the CCx and CCxN channels have been disabled + */ +#define TIMER_MOE_DISABLE(hperh) \ + do { \ + if ((((hperh)->perh->CCEP & CCER_CCxE_MASK) == 0) \ + && (((hperh)->perh->CCEP & CCER_CCxNE_MASK) == 0)) \ + CLEAR_BIT((hperh)->perh->BDCFG, TIMER_BDCFG_GOEN_MSK); \ + } while (0) + +/** + * @brief Sets the TIMER autoreload register value on runtime without calling + * another time any Init function. + */ +#define TIMER_SET_AUTORELOAD(handle, AUTORELOAD) \ + do { \ + (handle)->perh->AR = (AUTORELOAD); \ + (handle)->init.period = (AUTORELOAD); \ + } while (0) + +/** + * @brief Gets the TIMER autoreload register value on runtime + */ +#define TIMER_GET_AUTORELOAD(handle) ((handle)->perh->AR) + +/** + * @brief Gets the TIMER count register value on runtime + */ +#define TIMER_GET_CNT(handle) ((handle)->perh->COUNT) + +/** + * @brief Gets the TIMER count direction value on runtime + */ +#define TIMER_GET_DIR(handle) (READ_BITS((handle)->perh->CON1, TIMER_CON1_DIRSEL_MSK, TIMER_CON1_DIRSEL_POS)) + +/** + * @brief CCx DMA request sent when CCx event occurs + */ +#define TIMER_CCx_DMA_REQ_CCx(handle) (CLEAR_BIT((handle)->perh->CON2, TIMER_CON2_CCDMASEL_MSK)) + +/** + * @brief CCx DMA request sent when update event occurs + */ +#define TIMER_CCx_DMA_REQ_UPDATE(handle) (SET_BIT((handle)->perh->CON2, TIMER_CON2_CCDMASEL_MSK)) + +/** + * @brief Enable channel + * @param handle: TIMER handle + * @param ch: Must be one of this: + * TIMER_CHANNEL_1 + * TIMER_CHANNEL_2 + * TIMER_CHANNEL_3 + * TIMER_CHANNEL_4 + */ +#define TIMER_CCx_ENABLE(handle, ch) (((ch) == TIMER_CHANNEL_4) ? \ + (SET_BIT((handle)->perh->CCEP, TIMER_CCEP_CC4POL_MSK)) : (WRITE_REG(((handle)->perh->CCEP), (((handle)->perh->CCEP) | (1 << ((ch) << 2)))))) + +/** + * @brief Disable channel + * @param handle: TIMER handle + * @param ch: Must be one of this: + * TIMER_CHANNEL_1 + * TIMER_CHANNEL_2 + * TIMER_CHANNEL_3 + * TIMER_CHANNEL_4 + */ +#define TIMER_CCx_DISABLE(handle, ch) (((ch) == TIMER_CHANNEL_4) ? \ + (CLEAR_BIT((handle)->perh->CCEP, TIMER_CCEP_CC4EN_MSK)) : ((handle)->perh->CCEP &= ~(1 << ((ch) << 2)))) + +/** + * @brief Enable complementary channel + * @param handle: TIMER handle + * @param ch: Must be one of this: + * TIMER_CHANNEL_1 + * TIMER_CHANNEL_2 + * TIMER_CHANNEL_3 + */ +#define TIMER_CCxN_ENABLE(handle, ch) ((handle)->perh->CCEP |= (1 << (((ch) << 2) + 2))) + +/** + * @brief Disable complementary channel + * @param handle: TIMER handle + * @param ch: Must be one of this: + * TIMER_CHANNEL_1 + * TIMER_CHANNEL_2 + * TIMER_CHANNEL_3 + */ +#define TIMER_CCxN_DISABLE(handle, ch) ((handle)->perh->CCEP &= ~(1 << (((ch) << 2) + 2))) +/** + * @} + */ + +/** @defgroup TIMER_Private_Macros TIMER Private Macros + * @{ + */ +#if defined (ES32F065x) +#define IS_TIMER_INSTANCE(x) (((x) == AD16C4T0) || \ + ((x) == GP16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1) || \ + ((x) == BS16T0) || \ + ((x) == BS16T1) || \ + ((x) == BS16T2) || \ + ((x) == BS16T3)) +#define IS_ADTIMER_INSTANCE(x) ((x) == AD16C4T0) +#define IS_TIMER_XOR_INSTANCE(x) (((x) == AD16C4T0) || ((x) == GP16C4T0)) +#define IS_TIMER_COM_EVENT_INSTANCE(x) (((x) == AD16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1)) +#define IS_TIMER_CC2_INSTANCE(x) (((x) == AD16C4T0) || \ + ((x) == GP16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1)) +#define IS_TIMER_CC4_INSTANCE(x) (((x) == AD16C4T0) || \ + ((x) == GP16C4T0)) +#define IS_TIMER_BREAK_INSTANCE(x) (((x) == AD16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1)) +#define IS_TIMER_PWM_INPUT_INSTANCE(x, y) ((((x) == AD16C4T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C2T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C2T1) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == AD16C4T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2)))) +#define IS_TIMER_CCX_INSTANCE(x, y) ((((x) == AD16C4T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2) || \ + ((y) == TIMER_CHANNEL_3) || \ + ((y) == TIMER_CHANNEL_4))) || \ + (((x) == GP16C2T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C2T1) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C4T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2) || \ + ((y) == TIMER_CHANNEL_3) || \ + ((y) == TIMER_CHANNEL_4)))) +#define IS_TIMER_CCXN_INSTANCE(x, y) ((((x) == AD16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1)) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2) || \ + ((y) == TIMER_CHANNEL_3) || \ + ((y) == TIMER_CHANNEL_4))) +#define IS_TIMER_REPETITION_COUNTER_INSTANCE(x) (((x) == AD16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1)) +#define IS_TIMER_CLOCK_DIVISION_INSTANCE(x) IS_TIMER_CC2_INSTANCE(x) + +#elif defined (ES32F033x) || defined (ES32F093x) + +#define IS_TIMER_INSTANCE(x) (((x) == GP16C4T0) || \ + ((x) == BS16T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1) || \ + ((x) == BS16T1) || \ + ((x) == BS16T2) || \ + ((x) == GP16C4T1) || \ + ((x) == BS16T3)) +#define IS_ADTIMER_INSTANCE(x) ((x) == AD16C4T0) +#define IS_TIMER_XOR_INSTANCE(x) (((x) == GP16C4T0) || ((x) == GP16C4T1)) +#define IS_TIMER_COM_EVENT_INSTANCE(x) (((x) == GP16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1)) +#define IS_TIMER_CC2_INSTANCE(x) (((x) == GP16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1) || \ + ((x) == GP16C4T1)) +#define IS_TIMER_CC4_INSTANCE(x) (((x) == GP16C4T0) || \ + ((x) == GP16C4T1)) +#define IS_TIMER_BREAK_INSTANCE(x) (((x) == GP16C4T0)) +#define IS_TIMER_PWM_INPUT_INSTANCE(x, y) ((((x) == GP16C4T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C2T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C2T1) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C4T1) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2)))) +#define IS_TIMER_CCX_INSTANCE(x, y) ((((x) == GP16C4T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2) || \ + ((y) == TIMER_CHANNEL_3) || \ + ((y) == TIMER_CHANNEL_4))) || \ + (((x) == GP16C2T0) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C2T1) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2))) || \ + (((x) == GP16C4T1) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2) || \ + ((y) == TIMER_CHANNEL_3) || \ + ((y) == TIMER_CHANNEL_4)))) +#define IS_TIMER_CCXN_INSTANCE(x, y) ((((x) == GP16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1)) && \ + (((y) == TIMER_CHANNEL_1) || \ + ((y) == TIMER_CHANNEL_2) || \ + ((y) == TIMER_CHANNEL_3) || \ + ((y) == TIMER_CHANNEL_4))) +#define IS_TIMER_REPETITION_COUNTER_INSTANCE(x) (((x) == GP16C4T0) || \ + ((x) == GP16C2T0) || \ + ((x) == GP16C2T1)) +#define IS_TIMER_CLOCK_DIVISION_INSTANCE(x) IS_TIMER_CC2_INSTANCE(x) +#endif + +#define IS_TIMER_COUNTER_MODE(x) (((x) == TIMER_CNT_MODE_UP) || \ + ((x) == TIMER_CNT_MODE_DOWN) || \ + ((x) == TIMER_CNT_MODE_CENTER1) || \ + ((x) == TIMER_CNT_MODE_CENTER2) || \ + ((x) == TIMER_CNT_MODE_CENTER3)) +#define IS_TIMER_CLOCK_DIVISION(x) (((x) == TIMER_CLOCK_DIV1) || \ + ((x) == TIMER_CLOCK_DIV2) || \ + ((x) == TIMER_CLOCK_DIV4)) +#define IS_TIMER_PWM_MODE(x) (((x) == TIMER_OC_MODE_PWM1) || \ + ((x) == TIMER_OC_MODE_PWM2)) +#define IS_TIMER_OC_MODE(x) (((x) == TIMER_OC_MODE_TIMERING) || \ + ((x) == TIMER_OC_MODE_ACTIVE) || \ + ((x) == TIMER_OC_MODE_INACTIVE) || \ + ((x) == TIMER_OC_MODE_TOGGLE) || \ + ((x) == TIMER_OC_MODE_FORCE_ACTIVE) || \ + ((x) == TIMER_OC_MODE_FORCE_INACTIVE) || \ + ((x) == TIMER_OC_MODE_PWM1) || \ + ((x) == TIMER_OC_MODE_PWM2)) +#define IS_TIMER_OC_POLARITY(x) (((x) == TIMER_OC_POLARITY_HIGH) || \ + ((x) == TIMER_OC_POLARITY_LOW)) +#define IS_TIMER_OCN_POLARITY(x) (((x) == TIMER_OCN_POLARITY_HIGH) || \ + ((x) == TIMER_OCN_POLARITY_LOW)) +#define IS_TIMER_OCIDLE_STATE(x) (((x) == TIMER_OC_IDLE_RESET) || \ + ((x) == TIMER_OC_IDLE_SET)) +#define IS_TIMER_OCNIDLE_STATE(x) (((x) == TIMER_OCN_IDLE_RESET) || \ + ((x) == TIMER_OCN_IDLE_SET)) +#define IS_TIMER_CHANNELS(x) (((x) == TIMER_CHANNEL_1) || \ + ((x) == TIMER_CHANNEL_2) || \ + ((x) == TIMER_CHANNEL_3) || \ + ((x) == TIMER_CHANNEL_4) || \ + ((x) == TIMER_CHANNEL_ALL)) +#define IS_TIMER_OP_MODE(x) (((x) == TIMER_OP_MODE_REPEAT) || \ + ((x) == TIMER_OP_MODE_SINGLE)) +#define IS_TIMER_OP_OUTPUT_CH(x) (((x) == TIMER_OP_OUTPUT_CHANNEL_1) || \ + ((x) == TIMER_OP_OUTPUT_CHANNEL_2)) +#define IS_TIMER_ENCODER_MODE(x) (((x) == TIMER_ENC_MODE_TI1) || \ + ((x) == TIMER_ENC_MODE_TI2) || \ + ((x) == TIMER_ENC_MODE_TI12)) +#define IS_TIMER_IC_POLARITY(x) (((x) == TIMER_IC_POLARITY_RISE) || \ + ((x) == TIMER_IC_POLARITY_FALL)) +#define IS_TIMER_IC_SELECT(x) (((x) == TIMER_IC_SEL_DIRECT) || \ + ((x) == TIMER_IC_SEL_INDIRECT) || \ + ((x) == TIMER_IC_SEL_TRC)) +#define IS_TIMER_IC_PSC(x) (((x) == TIMER_IC_PSC_DIV1) || \ + ((x) == TIMER_IC_PSC_DIV2) || \ + ((x) == TIMER_IC_PSC_DIV4) || \ + ((x) == TIMER_IC_PSC_DIV8)) +#define IS_TIMER_IC_FILTER(x) ((x) <= 0xF) +#define IS_TIMER_DEAD_TIMERE(x) ((x) <= 0xFF) +#define IS_TIMER_CLEAR_INPUT_SOURCE(x) (((x) == TIMER_INPUT_NONE) || \ + ((x) == TIMER_INPUT_ETR)) +#define IS_TIMER_CLEAR_INPUT_POLARITY(x) (((x) == TIMER_POLARITY_NO_INV) || \ + ((x) == TIMER_POLARITY_INV)) +#define IS_TIMER_ETR_PSC(x) (((x) == TIMER_ETR_PSC_DIV1) || \ + ((x) == TIMER_ETR_PSC_DIV2) || \ + ((x) == TIMER_ETR_PSC_DIV4) || \ + ((x) == TIMER_ETR_PSC_DIV8)) +#define IS_TIMER_CLOCK_SOURCE(x) (((x) == TIMER_SRC_ETRMODE2) || \ + ((x) == TIMER_SRC_INTER) || \ + ((x) == TIMER_SRC_ITR0) || \ + ((x) == TIMER_SRC_ITR1) || \ + ((x) == TIMER_SRC_ITR2) || \ + ((x) == TIMER_SRC_ITR3) || \ + ((x) == TIMER_SRC_TI1ED) || \ + ((x) == TIMER_SRC_TI1) || \ + ((x) == TIMER_SRC_TI2) || \ + ((x) == TIMER_SRC_ETRMODE1)) +#define IS_TIMER_CLOCK_POLARITY(x) (((x) == TIMER_CLK_POLARITY_INV) || \ + ((x) == TIMER_CLK_POLARITY_NO_INV) || \ + ((x) == TIMER_CLK_POLARITY_RISE) || \ + ((x) == TIMER_CLK_POLARITY_FALL) || \ + ((x) == TIMER_CLK_POLARITY_BOTH)) +#define IS_TIMER_SLAVE_MODE(x) (((x) == TIMER_MODE_DISABLE) || \ + ((x) == TIMER_MODE_ENC1) || \ + ((x) == TIMER_MODE_ENC2) || \ + ((x) == TIMER_MODE_ENC3) || \ + ((x) == TIMER_MODE_RESET) || \ + ((x) == TIMER_MODE_GATED) || \ + ((x) == TIMER_MODE_TRIG) || \ + ((x) == TIMER_MODE_EXTERNAL1)) +#define IS_TIMER_EVENT_SOURCE(x) (((x) == TIMER_SRC_UPDATE) || \ + ((x) == TIMER_SRC_CC1) || \ + ((x) == TIMER_SRC_CC2) || \ + ((x) == TIMER_SRC_CC3) || \ + ((x) == TIMER_SRC_CC4) || \ + ((x) == TIMER_SRC_COM) || \ + ((x) == TIMER_SRC_TRIG) || \ + ((x) == TIMER_SRC_BREAK)) +#define IS_TIMER_TS(x) (((x) == TIMER_TS_ITR0) || \ + ((x) == TIMER_TS_ITR1) || \ + ((x) == TIMER_TS_ITR2) || \ + ((x) == TIMER_TS_ITR3) || \ + ((x) == TIMER_TS_TI1F_ED) || \ + ((x) == TIMER_TS_TI1FP1) || \ + ((x) == TIMER_TS_TI2FP2) || \ + ((x) == TIMER_TS_ETRF)) +#define IS_TIMER_CLOCK_LEVEL(x) (((x) == TIMER_LOCK_LEVEL_OFF) || \ + ((x) == TIMER_LOCK_LEVEL_1) || \ + ((x) == TIMER_LOCK_LEVEL_2) || \ + ((x) == TIMER_LOCK_LEVEL_3)) +#define IS_TIMER_BREAK_POLARITY(x) (((x) == TIMER_BREAK_POLARITY_LOW) || \ + ((x) == TIMER_BREAK_POLARITY_HIGH)) +#define IS_TIMER_MASTER_MODE_SEL(x) (((x) == TIMER_TRGO_RESET) || \ + ((x) == TIMER_TRGO_ENABLE) || \ + ((x) == TIMER_TRGO_UPDATE) || \ + ((x) == TIMER_TRGO_OC1) || \ + ((x) == TIMER_TRGO_OC1REF) || \ + ((x) == TIMER_TRGO_OC2REF) || \ + ((x) == TIMER_TRGO_OC3REF) || \ + ((x) == TIMER_TRGO_OC4REF)) +#define IS_TIMER_IT(x) (((x) == TIMER_IT_UPDATE) || \ + ((x) == TIMER_IT_CC1) || \ + ((x) == TIMER_IT_CC2) || \ + ((x) == TIMER_IT_CC3) || \ + ((x) == TIMER_IT_CC4) || \ + ((x) == TIMER_IT_COM) || \ + ((x) == TIMER_IT_TRIGGER) || \ + ((x) == TIMER_IT_BREAK)) +#define IS_TIMER_DMA_REQ(x) (((x) == TIMER_DMA_UPDATE) || \ + ((x) == TIMER_DMA_CC1) || \ + ((x) == TIMER_DMA_CC2) || \ + ((x) == TIMER_DMA_CC3) || \ + ((x) == TIMER_DMA_CC4) || \ + ((x) == TIMER_DMA_COM) || \ + ((x) == TIMER_DMA_TRIGGER)) +#define IS_TIMER_FLAG(x) (((x) == TIMER_FLAG_UPDATE) || \ + ((x) == TIMER_FLAG_CC1) || \ + ((x) == TIMER_FLAG_CC2) || \ + ((x) == TIMER_FLAG_CC3) || \ + ((x) == TIMER_FLAG_CC4) || \ + ((x) == TIMER_FLAG_COM) || \ + ((x) == TIMER_FLAG_TRIGGER) || \ + ((x) == TIMER_FLAG_BREAK) || \ + ((x) == TIMER_FLAG_CC1OF) || \ + ((x) == TIMER_FLAG_CC2OF) || \ + ((x) == TIMER_FLAG_CC3OF) || \ + ((x) == TIMER_FLAG_CC4OF)) +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions + * @{ + */ +/** @addtogroup TIMER_Public_Functions_Group1 + * @{ + */ +/* Time Base functions */ +ald_status_t ald_timer_base_init(timer_handle_t *hperh); +void ald_timer_base_reset(timer_handle_t *hperh); +void ald_timer_base_start(timer_handle_t *hperh); +void ald_timer_base_stop(timer_handle_t *hperh); +void ald_timer_base_start_by_it(timer_handle_t *hperh); +void ald_timer_base_stop_by_it(timer_handle_t *hperh); +#ifdef ALD_DMA +ald_status_t ald_timer_base_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, + uint16_t *buf, uint32_t len, uint8_t dma_ch); +void ald_timer_base_stop_by_dma(timer_handle_t *hperh); +#endif +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group2 + * @{ + */ +/* Timer Output Compare functions */ +ald_status_t ald_timer_oc_init(timer_handle_t *hperh); +void ald_timer_oc_start(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_oc_stop(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_oc_start_by_it(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_oc_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); +#ifdef ALD_DMA +ald_status_t ald_timer_oc_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, + dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch); +void ald_timer_oc_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); +#endif +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group3 + * @{ + */ +/* Timer PWM functions */ +ald_status_t ald_timer_pwm_init(timer_handle_t *hperh); +void ald_timer_pwm_start(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_pwm_stop(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_pwm_start_by_it(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_pwm_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_pwm_set_freq(timer_handle_t *hperh, uint16_t freq); +void ald_timer_pwm_set_duty(timer_handle_t *hperh, timer_channel_t ch, uint16_t duty); +void ald_timer_pwm_set_input(timer_handle_t *hperh, timer_channel_t ch); +#ifdef ALD_DMA +ald_status_t ald_timer_pwm_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, + dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch); +void ald_timer_pwm_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); +#endif +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group4 + * @{ + */ +/* Timer Input Capture functions */ +ald_status_t ald_timer_ic_init(timer_handle_t *hperh); +void ald_timer_ic_start(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_ic_stop(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_ic_start_by_it(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_ic_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); +#ifdef ALD_DMA +ald_status_t ald_timer_ic_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, + dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch); +void ald_timer_ic_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); +#endif +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group5 + * @{ + */ +/* Timer One Pulse functions */ +ald_status_t ald_timer_one_pulse_init(timer_handle_t *hperh, timer_op_mode_t mode); +void ald_timer_one_pulse_start(timer_handle_t *hperh, timer_op_output_channel_t ch); +void ald_timer_one_pulse_stop(timer_handle_t *hperh, timer_op_output_channel_t ch); +void ald_timer_one_pulse_start_by_it(timer_handle_t *hperh, timer_op_output_channel_t ch); +void ald_timer_one_pulse_stop_by_it(timer_handle_t *hperh, timer_op_output_channel_t ch); +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group6 + * @{ + */ +/* Timer encoder functions */ +ald_status_t ald_timer_encoder_init(timer_handle_t *hperh, timer_encoder_init_t *config); +void ald_timer_encoder_start(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_encoder_stop(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_encoder_start_by_it(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_encoder_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); +#ifdef ALD_DMA +ald_status_t ald_timer_encoder_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, + dma_handle_t *hdma1, dma_handle_t *hdma2, uint16_t *buf1, + uint16_t *buf2, uint32_t len, uint8_t dma_ch1, uint8_t dma_ch2); +void ald_timer_encoder_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); +#endif +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group7 + * @{ + */ +/* Timer hall sensor functions */ +ald_status_t ald_timer_hall_sensor_init(timer_handle_t *hperh, timer_hall_sensor_init_t *config); +void ald_timer_hall_sensor_start(timer_handle_t *hperh); +void ald_timer_hall_sensor_stop(timer_handle_t *hperh); +void ald_timer_hall_sensor_start_by_it(timer_handle_t *hperh); +void ald_timer_hall_sensor_stop_by_it(timer_handle_t *hperh); +#ifdef ALD_DMA +ald_status_t ald_timer_hall_sensor_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, + uint16_t *buf, uint32_t len, uint8_t dma_ch); +void ald_timer_hall_sensor_stop_by_dma(timer_handle_t *hperh); +#endif +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group8 + * @{ + */ +/* Timer complementary output compare functions */ +void ald_timer_ocn_start(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_ocn_stop(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_ocn_start_by_it(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_ocn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); +#ifdef ALD_DMA +ald_status_t ald_timer_ocn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, + timer_channel_t ch, uint16_t *buf, uint32_t len, uint8_t dma_ch); +void ald_timer_ocn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); +#endif +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group9 + * @{ + */ +/* Timer complementary PWM functions */ +void ald_timer_pwmn_start(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_pwmn_stop(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_pwmn_start_by_it(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_pwmn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); +#ifdef ALD_DMA +ald_status_t ald_timer_pwmn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, + timer_channel_t ch, uint16_t *buf, uint32_t len, uint8_t dma_ch); +void ald_timer_pwmn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch); +#endif +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group10 + * @{ + */ +/* Timer complementary one pulse functions */ +void ald_timer_one_pulse_n_start(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_one_pulse_n_stop(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_one_pulse_n_start_by_it(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_one_pulse_n_stop_by_it(timer_handle_t *hperh, timer_channel_t ch); +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group11 + * @{ + */ +/* Control functions */ +ald_status_t ald_timer_oc_config_channel(timer_handle_t *hperh, timer_oc_init_t *config, timer_channel_t ch); +ald_status_t ald_timer_ic_config_channel(timer_handle_t *hperh, timer_ic_init_t *config, timer_channel_t ch); +ald_status_t ald_timer_one_pulse_config_channel(timer_handle_t *hperh, timer_one_pulse_init_t *config, + timer_channel_t ch_out, timer_channel_t ch_in); +ald_status_t ald_timer_config_oc_ref_clear(timer_handle_t *hperh, timer_clear_input_config_t *config, timer_channel_t ch); +ald_status_t ald_timer_config_clock_source(timer_handle_t *hperh, timer_clock_config_t *config); +ald_status_t ald_timer_config_ti1_input(timer_handle_t *hperh, uint32_t ti1_select); +ald_status_t ald_timer_slave_config_sync(timer_handle_t *hperh, timer_slave_config_t *config); +ald_status_t ald_timer_slave_config_sync_by_it(timer_handle_t *hperh, timer_slave_config_t *config); +ald_status_t ald_timer_generate_event(timer_handle_t *hperh, timer_event_source_t event); +uint32_t ald_timer_read_capture_value(timer_handle_t *hperh, timer_channel_t ch); +void ald_timer_set_output_mode(timer_handle_t *hperh, timer_oc_mode_t mode, timer_channel_t ch); +void ald_timer_com_change_config(timer_handle_t *hperh, timer_com_channel_config_t *config); +void ald_timer_com_event_config(timer_handle_t *hperh, timer_ts_t ts, type_func_t trgi); +void ald_timer_com_event_config_it(timer_handle_t *hperh, timer_ts_t ts, type_func_t trgi); +void ald_timer_break_dead_time_config(timer_handle_t *hperh, timer_break_dead_time_t *config); +void ald_timer_master_sync_config(timer_handle_t *hperh, timer_master_config_t *config); +void ald_timer_irq_handler(timer_handle_t *hperh); +void ald_timer_dma_req_config(timer_handle_t *hperh, timer_dma_req_t req, type_func_t state); +void ald_timer_interrupt_config(timer_handle_t *hperh, timer_it_t it, type_func_t state); +it_status_t ald_timer_get_it_status(timer_handle_t *hperh, timer_it_t it); +flag_status_t ald_timer_get_flag_status(timer_handle_t *hperh, timer_flag_t flag); +void ald_timer_clear_flag_status(timer_handle_t *hperh, timer_flag_t flag); +/** + * @} + */ + +/** @addtogroup TIMER_Public_Functions_Group12 + * @{ + */ +/* State functions */ +timer_state_t ald_timer_get_state(timer_handle_t *hperh); +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_TIMER_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_trng.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_trng.h similarity index 39% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_trng.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_trng.h index 072f892184..a1142838eb 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_trng.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_trng.h @@ -32,17 +32,6 @@ extern "C" { * @{ */ -/** @defgroup TRNG_Public_Macros TRNG Public Macros - * @{ - */ -#define TRNG_ENABLE() (SET_BIT(TRNG->CR, TRNG_CR_TRNGEN_MSK)) -#define TRNG_DISABLE() (CLEAR_BIT(TRNG->CR, TRNG_CR_TRNGEN_MSK)) -#define TRNG_ADJM_ENABLE() (SET_BIT(TRNG->CR, TRNG_CR_ADJM_MSK)) -#define TRNG_ADJM_DISABLE() (CLEAR_BIT(TRNG->CR, TRNG_CR_ADJM_MSK)) -/** - * @} - */ - /** @defgroup TRNG_Public_Types TRNG Public Types * @{ */ @@ -51,10 +40,10 @@ extern "C" { */ typedef enum { - TRNG_DSEL_1B = 0x0, /**< 1-bit */ - TRNG_DSEL_8B = 0x1, /**< 8-bit */ - TRNG_DSEL_16B = 0x2, /**< 16-bit */ - TRNG_DSEL_32B = 0x3, /**< 32-bit */ + TRNG_DSEL_1B = 0x0, /**< 1-bit */ + TRNG_DSEL_8B = 0x1, /**< 8-bit */ + TRNG_DSEL_16B = 0x2, /**< 16-bit */ + TRNG_DSEL_32B = 0x3, /**< 32-bit */ } trng_data_width_t; /** @@ -62,10 +51,10 @@ typedef enum */ typedef enum { - TRNG_SEED_TYPE_0 = 0x0, /**< Using 0 as seed */ - TRNG_SEED_TYPE_1 = 0x1, /**< Using 1 as seed */ - TRNG_SEED_TYPE_LAST = 0x2, /**< Using last seed */ - TRNG_SEED_TYPE_SEED = 0x3, /**< Using value of register */ + TRNG_SEED_TYPE_0 = 0x0, /**< Using 0 as seed */ + TRNG_SEED_TYPE_1 = 0x1, /**< Using 1 as seed */ + TRNG_SEED_TYPE_LAST = 0x2, /**< Using last seed */ + TRNG_SEED_TYPE_SEED = 0x3, /**< Using value of register */ } trng_seed_type_t; /** @@ -73,22 +62,33 @@ typedef enum */ typedef struct { - trng_data_width_t data_width; /**< The width of data */ - trng_seed_type_t seed_type; /**< The seed type */ - uint32_t seed; /**< The value of seed */ - uint16_t t_start; /**< T(start) = T(hclk) * (t_start + 1), T(start) > 1ms */ - uint8_t adjc; /**< Adjust parameter */ - uint8_t posten; + trng_data_width_t data_width; /**< The width of data */ + trng_seed_type_t seed_type; /**< The seed type */ + uint32_t seed; /**< The value of seed */ + uint16_t t_start; /**< T(start) = T(hclk) * (t_start + 1), T(start) > 1ms */ + uint8_t adjc; /**< Adjust parameter */ + type_func_t posten; /**< Data back handle function */ } trng_init_t; +/** + * @brief TRNG state structures definition + */ +typedef enum +{ + TRNG_STATE_RESET = 0x0, /**< Peripheral is not initialized */ + TRNG_STATE_READY = 0x1, /**< Peripheral Initialized and ready for use */ + TRNG_STATE_BUSY = 0x2, /**< An internal process is ongoing */ + TRNG_STATE_ERROR = 0x4, /**< Error */ +} trng_state_t; + /** * @brief State type */ typedef enum { - TRNG_STATUS_START = (1U << 0), /**< Start state */ - TRNG_STATUS_DAVLD = (1U << 1), /**< Data valid state */ - TRNG_STATUS_SERR = (1U << 2), /**< Error state */ + TRNG_STATUS_START = (1U << 0), /**< Start state */ + TRNG_STATUS_DAVLD = (1U << 1), /**< Data valid state */ + TRNG_STATUS_SERR = (1U << 2), /**< Error state */ } trng_status_t; /** @@ -96,9 +96,9 @@ typedef enum */ typedef enum { - TRNG_IT_START = (1U << 0), /**< Start */ - TRNG_IT_DAVLD = (1U << 1), /**< Data valid */ - TRNG_IT_SERR = (1U << 2), /**< Error */ + TRNG_IT_START = (1U << 0), /**< Start */ + TRNG_IT_DAVLD = (1U << 1), /**< Data valid */ + TRNG_IT_SERR = (1U << 2), /**< Error */ } trng_it_t; /** @@ -106,10 +106,37 @@ typedef enum */ typedef enum { - TRNG_IF_START = (1U << 0), /**< Start */ - TRNG_IF_DAVLD = (1U << 1), /**< Data valid */ - TRNG_IF_SERR = (1U << 2), /**< Error */ + TRNG_IF_START = (1U << 0), /**< Start */ + TRNG_IF_DAVLD = (1U << 1), /**< Data valid */ + TRNG_IF_SERR = (1U << 2), /**< Error */ } trng_flag_t; + +/** + * @brief TRNG Handle Structure definition + */ +typedef struct trng_handle_s +{ + TRNG_TypeDef *perh; /**< Register base address */ + trng_init_t init; /**< TRNG required parameters */ + uint32_t data; /**< result data */ + lock_state_t lock; /**< Locking object */ + trng_state_t state; /**< TRNG operation state */ + + void (*trng_cplt_cbk)(struct trng_handle_s *arg); /**< Trng completed callback */ + void (*err_cplt_cbk)(struct trng_handle_s *arg); /**< Trng error callback */ + void (*init_cplt_cbk)(struct trng_handle_s *arg); /**< Trng init completed callback */ +} trng_handle_t; +/** + * @} + */ + +/** @defgroup TRNG_Public_Macros TRNG Public Macros + * @{ + */ +#define TRNG_ENABLE() (SET_BIT(TRNG->CR, TRNG_CR_TRNGEN_MSK)) +#define TRNG_DISABLE() (CLEAR_BIT(TRNG->CR, TRNG_CR_TRNGEN_MSK)) +#define TRNG_ADJM_ENABLE() (SET_BIT(TRNG->CR, TRNG_CR_ADJM_MSK)) +#define TRNG_ADJM_DISABLE() (CLEAR_BIT(TRNG->CR, TRNG_CR_ADJM_MSK)) /** * @} */ @@ -118,24 +145,24 @@ typedef enum * @defgroup TRNG_Private_Macros TRNG Private Macros * @{ */ -#define IS_TRNG_DATA_WIDTH(x) (((x) == TRNG_DSEL_1B) || \ +#define IS_TRNG_DATA_WIDTH(x) (((x) == TRNG_DSEL_1B) || \ ((x) == TRNG_DSEL_8B) || \ ((x) == TRNG_DSEL_16B) || \ ((x) == TRNG_DSEL_32B)) -#define IS_TRNG_SEED_TYPE(x) (((x) == TRNG_SEED_TYPE_0) || \ +#define IS_TRNG_SEED_TYPE(x) (((x) == TRNG_SEED_TYPE_0) || \ ((x) == TRNG_SEED_TYPE_1) || \ ((x) == TRNG_SEED_TYPE_LAST) || \ ((x) == TRNG_SEED_TYPE_SEED)) -#define IS_TRNG_STATUS(x) (((x) == TRNG_STATUS_START) || \ - ((x) == TRNG_STATUS_DAVLD) || \ - ((x) == TRNG_STATUS_SERR)) -#define IS_TRNG_IT(x) (((x) == TRNG_IT_START) || \ +#define IS_TRNG_STATUS(x) (((x) == TRNG_STATUS_START) || \ + ((x) == TRNG_STATUS_DAVLD) || \ + ((x) == TRNG_STATUS_SERR)) +#define IS_TRNG_IT(x) (((x) == TRNG_IT_START) || \ ((x) == TRNG_IT_DAVLD) || \ ((x) == TRNG_IT_SERR)) -#define IS_TRNG_FLAG(x) (((x) == TRNG_IF_START) || \ +#define IS_TRNG_FLAG(x) (((x) == TRNG_IF_START) || \ ((x) == TRNG_IF_DAVLD) || \ ((x) == TRNG_IF_SERR)) -#define IS_TRNG_ADJC(x) ((x) < 4) +#define IS_TRNG_ADJC(x) ((x) < 4) /** * @} */ @@ -147,7 +174,7 @@ typedef enum * @{ */ /* Initialization functions */ -extern void trng_init(trng_init_t *init); +extern ald_status_t ald_trng_init(trng_handle_t *hperh); /** * @} */ @@ -155,12 +182,13 @@ extern void trng_init(trng_init_t *init); * @{ */ /* Control functions */ -extern uint32_t trng_get_result(void); -extern void trng_interrupt_config(trng_it_t it, type_func_t state); -extern flag_status_t trng_get_status(trng_status_t status); -extern it_status_t trng_get_it_status(trng_it_t it); -extern flag_status_t trng_get_flag_status(trng_flag_t flag); -extern void trng_clear_flag_status(trng_flag_t flag); +extern uint32_t ald_trng_get_result(trng_handle_t *hperh); +extern void ald_trng_interrupt_config(trng_handle_t *hperh, trng_it_t it, type_func_t state); +extern flag_status_t ald_trng_get_status(trng_handle_t *hperh, trng_status_t status); +extern it_status_t ald_trng_get_it_status(trng_handle_t *hperh, trng_it_t it); +extern flag_status_t ald_trng_get_flag_status(trng_handle_t *hperh, trng_flag_t flag); +extern void ald_trng_clear_flag_status(trng_handle_t *hperh, trng_flag_t flag); +extern void ald_trng_irq_handler(trng_handle_t *hperh); /** * @} */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_tsense.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_tsense.h new file mode 100644 index 0000000000..0f55db2a29 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_tsense.h @@ -0,0 +1,227 @@ +/** + ********************************************************************************* + * + * @file ald_tsense.h + * @brief Header file of TSENSE module driver. + * + * @version V1.0 + * @date 15 Dec 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ******************************************************************************** + */ + +#ifndef __ALD_TSENSE_H__ +#define __ALD_TSENSE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup TSENSE + * @{ + */ + +/** @defgroup TSENSE_Public_Macros TSENSE Public Macros + * @{ + */ +#define TSENSE_LOCK() (WRITE_REG(TSENSE->WPR, 0x0)) +#define TSENSE_UNLOCK() (WRITE_REG(TSENSE->WPR, 0xA55A9669)) +#define TSENSE_ENABLE() \ + do { \ + TSENSE_UNLOCK(); \ + SET_BIT(TSENSE->CR, TSENSE_CR_EN_MSK); \ + TSENSE_LOCK(); \ + } while (0) +#define TSENSE_DISABLE() \ + do { \ + TSENSE_UNLOCK(); \ + CLEAR_BIT(TSENSE->CR, TSENSE_CR_EN_MSK); \ + TSENSE_LOCK(); \ + } while (0) +#define TSENSE_REQ_ENABLE() \ + do { \ + TSENSE_UNLOCK(); \ + SET_BIT(TSENSE->CR, TSENSE_CR_REQEN_MSK); \ + TSENSE_LOCK(); \ + } while (0) +#define TSENSE_REQ_DISABLE() \ + do { \ + TSENSE_UNLOCK(); \ + CLEAR_BIT(TSENSE->CR, TSENSE_CR_REQEN_MSK); \ + TSENSE_LOCK(); \ + } while (0) +#define TSENSE_CTN_ENABLE() \ + do { \ + TSENSE_UNLOCK(); \ + SET_BIT(TSENSE->CR, TSENSE_CR_CTN_MSK); \ + TSENSE_LOCK(); \ + } while (0) +#define TSENSE_CTN_DISABLE() \ + do { \ + TSENSE_UNLOCK(); \ + CLEAR_BIT(TSENSE->CR, TSENSE_CR_CTN_MSK); \ + TSENSE_LOCK(); \ + } while (0) +#define TSENSE_RESET() \ + do { \ + TSENSE_UNLOCK(); \ + SET_BIT(TSENSE->CR, TSENSE_CR_RST_MSK); \ + TSENSE_LOCK(); \ + } while (0) +#define TSENSE_LTGR_WR(data) \ + do { \ + TSENSE_UNLOCK(); \ + WRITE_REG(TSENSE->LTGR, (data)); \ + TSENSE_LOCK(); \ + } while(0) +#define TSENSE_HTGR_WR(data) \ + do { \ + TSENSE_UNLOCK(); \ + WRITE_REG(TSENSE->HTGR, (data)); \ + TSENSE_LOCK(); \ + } while(0) +#define TSENSE_TBDR_WR(data) \ + do { \ + TSENSE_UNLOCK(); \ + WRITE_REG(TSENSE->TBDR, (data)); \ + TSENSE_LOCK(); \ + } while(0) +#define TSENSE_TCALBDR_WR(data) \ + do { \ + TSENSE_UNLOCK(); \ + WRITE_REG(TSENSE->TCALBDR, (data)); \ + TSENSE_LOCK(); \ + } while(0) +/** + * @} + */ + +/** @defgroup TSENSE_Public_Types TSENSE Public Types + * @{ + */ +/** + * @brief Temperature update time + */ +typedef enum +{ + TSENSE_UPDATE_CYCLE_3 = 0x3, /**< 3 Cycles */ + TSENSE_UPDATE_CYCLE_4 = 0x4, /**< 4 Cycles */ + TSENSE_UPDATE_CYCLE_5 = 0x5, /**< 5 Cycles */ + TSENSE_UPDATE_CYCLE_6 = 0x6, /**< 6 Cycles */ + TSENSE_UPDATE_CYCLE_7 = 0x7, /**< 7 Cycles */ +} tsense_update_cycle_t; + +/** + * @brief Temperature output mode + */ +typedef enum +{ + TSENSE_OUTPUT_MODE_200 = 0x0, /**< 200 cycles update one temperature */ + TSENSE_OUTPUT_MODE_400 = 0x1, /**< 400 cycles update one temperature */ + TSENSE_OUTPUT_MODE_800 = 0x2, /**< 800 cycles update one temperature */ + TSENSE_OUTPUT_MODE_1600 = 0x3, /**< 1600 cycles update one temperature */ + TSENSE_OUTPUT_MODE_3200 = 0x4, /**< 3200 cycles update one temperature */ +} tsense_output_mode_t; + +/** + * @brief Source select + */ +typedef enum +{ + TSENSE_SOURCE_LOSC = 0x0, /**< LOSC */ + TSENSE_SOURCE_LRC = 0x1, /**< LRC */ + TSENSE_SOURCE_HRC_DIV_1M = 0x2, /**< HRC divide to 1MHz */ + TSENSE_SOURCE_HOSC_DIV_1M = 0x3, /**< HOSC divide to 1MHz */ +} tsense_source_sel_t; + + +/** + * @brief TSENSE init structure definition + */ +typedef struct +{ + tsense_update_cycle_t cycle; /**< Temperature update time */ + tsense_output_mode_t mode; /**< Temperature output mode */ + type_func_t ctn; /**< Continue mode */ + uint8_t psc; /**< Perscaler */ +} tsense_init_t; + +/** + * @brief Define callback function type + */ +typedef void (*tsense_cbk)(uint16_t value, ald_status_t status); +/** + * @} + */ + +/** + * @defgroup TSENSE_Private_Macros TSENSE Private Macros + * @{ + */ +#define IS_TSENSE_UPDATE_CYCLE(x) (((x) == TSENSE_UPDATE_CYCLE_3) || \ + ((x) == TSENSE_UPDATE_CYCLE_4) || \ + ((x) == TSENSE_UPDATE_CYCLE_5) || \ + ((x) == TSENSE_UPDATE_CYCLE_6) || \ + ((x) == TSENSE_UPDATE_CYCLE_7)) +#define IS_TSENSE_OUTPUT_MODE(x) (((x) == TSENSE_OUTPUT_MODE_200) || \ + ((x) == TSENSE_OUTPUT_MODE_400) || \ + ((x) == TSENSE_OUTPUT_MODE_800) || \ + ((x) == TSENSE_OUTPUT_MODE_1600) || \ + ((x) == TSENSE_OUTPUT_MODE_3200)) +#define IS_TSENSE_SOURCE_SEL(x) (((x) == TSENSE_SOURCE_LOSC) || \ + ((x) == TSENSE_SOURCE_LRC) || \ + ((x) == TSENSE_SOURCE_HRC_DIV_1M ) || \ + ((x) == TSENSE_SOURCE_HOSC_DIV_1M)) +/** + * @} + */ + +/** @addtogroup TSENSE_Public_Functions + * @{ + */ +/** @addtogroup TSENSE_Public_Functions_Group1 + * @{ + */ +/* Initialization functions */ +extern void ald_tsense_init(tsense_init_t *init); +extern void ald_tsense_source_select(tsense_source_sel_t sel); +/** + * @} + */ +/** @addtogroup TSENSE_Public_Functions_Group2 + * @{ + */ +/* Control functions */ +extern ald_status_t ald_tsense_get_value(uint16_t *tsense); +extern void ald_tsense_get_value_by_it(tsense_cbk cbk); +extern void ald_tsense_irq_handler(void); +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_TSENSE_H__ */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_uart.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_uart.h new file mode 100644 index 0000000000..49cc24d9ef --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_uart.h @@ -0,0 +1,478 @@ +/** + ********************************************************************************* + * + * @file ald_uart.h + * @brief Header file of UART module library. + * + * @version V1.0 + * @date 21 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + * + ********************************************************************************* + */ + +#ifndef __ALD_UART_H__ +#define __ALD_UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "utils.h" +#include "ald_dma.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @addtogroup UART + * @{ + */ + +/** + * @defgroup UART_Public_Macros UART Public Macros + * @{ + */ +#define UART_RX_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_RXEN_MSK)) +#define UART_RX_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_RXEN_MSK)) +#define UART_BRR_WRITE_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_BRWEN_MSK)) +#define UART_BRR_WRITE_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_BRWEN_MSK)) +#define UART_RX_TIMEOUT_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_RTOEN_MSK)) +#define UART_RX_TIMEOUT_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_RTOEN_MSK)) +#define UART_MSB_FIRST_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_MSBFIRST_MSK)) +#define UART_MSB_FIRST_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_MSBFIRST_MSK)) +#define UART_DATA_INV_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_DATAINV_MSK)) +#define UART_DATA_INV_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_DATAINV_MSK)) +#define UART_RX_INV_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_RXINV_MSK)) +#define UART_RX_INV_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_RXINV_MSK)) +#define UART_TX_INV_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_TXINV_MSK)) +#define UART_TX_INV_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_TXINV_MSK)) +#define UART_TX_RX_SWAP_ENABLE(hperh) (SET_BIT((hperh)->perh->LCR, UART_LCR_SWAP_MSK)) +#define UART_TX_RX_SWAP_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->LCR, UART_LCR_SWAP_MSK)) +#define UART_HDSEL_ENABLE(hperh) (SET_BIT((hperh)->perh->MCR, UART_MCR_HDSEL_MSK)) +#define UART_HDSEL_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->MCR, UART_MCR_HDSEL_MSK)) +#define UART_FIFO_TX_RESET(hperh) (SET_BIT((hperh)->perh->FCR, UART_FCR_TFRST_MSK)) +#define UART_FIFO_RX_RESET(hperh) (SET_BIT((hperh)->perh->FCR, UART_FCR_RFRST_MSK)) +#define UART_LPBMOD_ENABLE(hperh) (SET_BIT((hperh)->perh->MCR, UART_MCR_LBEN_MSK)) +#define UART_LPBMOD_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->MCR, UART_MCR_LBEN_MSK)) +#define UART_AUTOBR_ENABLE(hperh) (SET_BIT((hperh)->perh->MCR, UART_MCR_ABREN_MSK)) +#define UART_AUTOBR_DISABLE(hperh) (CLEAR_BIT((hperh)->perh->MCR, UART_MCR_ABREN_MSK)) +#define UART_AUTOBR_RESTART(hperh) (SET_BIT((hperh)->perh->MCR, UART_MCR_ABRRS_MSK)) +#define UART_GET_BRR_VALUE(hperh) (READ_REG((hperh)->perh->BRR)) +#define UART_SET_TIMEOUT_VALUE(x, y) (MODIFY_REG((x)->perh->RTOR, UART_RTOR_RTO_MSK, (y) << UART_RTOR_RTO_POSS)) +/** + * @} + */ + +/** @defgroup UART_Public_Types UART Public Types + * @{ + */ +/** + * @brief UART word length + */ +typedef enum +{ + UART_WORD_LENGTH_5B = 0x0, /**< 5-bits */ + UART_WORD_LENGTH_6B = 0x1, /**< 6-bits */ + UART_WORD_LENGTH_7B = 0x2, /**< 7-bits */ + UART_WORD_LENGTH_8B = 0x3, /**< 8-bits */ +} uart_word_length_t; + +/** + * @brief UART stop bits + */ +typedef enum +{ + UART_STOP_BITS_1 = 0x0, /**< 1-bits */ + UART_STOP_BITS_2 = 0x1, /**< 2-bits */ + UART_STOP_BITS_0_5 = 0x0, /**< 0.5-bits, using smartcard mode */ + UART_STOP_BITS_1_5 = 0x1, /**< 1.5-bits, using smartcard mode */ +} uart_stop_bits_t; + +/** + * @brief UART parity + */ +typedef enum +{ + UART_PARITY_NONE = 0x0, /**< Not parity */ + UART_PARITY_ODD = 0x1, /**< Odd parity */ + UART_PARITY_EVEN = 0x3, /**< Even parity */ +} uart_parity_t; + +/** + * @brief UART mode + */ +typedef enum +{ + UART_MODE_UART = 0x0, /**< UART */ + UART_MODE_LIN = 0x1, /**< LIN */ + UART_MODE_IrDA = 0x2, /**< IrDA */ + UART_MODE_RS485 = 0x3, /**< RS485 */ + UART_MODE_HDSEL = 0x4, /**< Single-wire half-duplex */ +} uart_mode_t; + +/** + * @brief UART hardware flow control + */ +typedef enum +{ + UART_HW_FLOW_CTL_DISABLE = 0x0, /**< Auto-flow-control disable */ + UART_HW_FLOW_CTL_ENABLE = 0x1, /**< Auto-flow-control enable */ +} uart_hw_flow_ctl_t; + +/** + * @brief ALD UART state + */ +typedef enum +{ + UART_STATE_RESET = 0x00, /**< Peripheral is not initialized */ + UART_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + UART_STATE_BUSY = 0x02, /**< an internal process is ongoing */ + UART_STATE_BUSY_TX = 0x11, /**< Data Transmission process is ongoing */ + UART_STATE_BUSY_RX = 0x21, /**< Data Reception process is ongoing */ + UART_STATE_BUSY_TX_RX = 0x31, /**< Data Transmission Reception process is ongoing */ + UART_STATE_TIMEOUT = 0x03, /**< Timeout state */ + UART_STATE_ERROR = 0x04, /**< Error */ +} uart_state_t; + +/** + * @brief UART error codes + */ +typedef enum +{ + UART_ERROR_NONE = ((uint32_t)0x00), /**< No error */ + UART_ERROR_PE = ((uint32_t)0x01), /**< Parity error */ + UART_ERROR_NE = ((uint32_t)0x02), /**< Noise error */ + UART_ERROR_FE = ((uint32_t)0x04), /**< frame error */ + UART_ERROR_ORE = ((uint32_t)0x08), /**< Overrun error */ + UART_ERROR_DMA = ((uint32_t)0x10), /**< DMA transfer error */ +} uart_error_t; + +/** + * @brief UART init structure definition + */ +typedef struct +{ + uint32_t baud; /**< Specifies the uart communication baud rate */ + uart_word_length_t word_length; /**< Specifies the number of data bits transmitted or received in a frame */ + uart_stop_bits_t stop_bits; /**< Specifies the number of stop bits transmitted */ + uart_parity_t parity; /**< Specifies the parity mode */ + uart_mode_t mode; /**< Specifies uart mode */ + uart_hw_flow_ctl_t fctl; /**< Specifies wether the hardware flow control mode is enabled or disabled */ +} uart_init_t; + +/** + * @brief UART handle structure definition + */ +typedef struct uart_handle_s +{ + UART_TypeDef *perh; /**< UART registers base address */ + uart_init_t init; /**< UART communication parameters */ + uint8_t *tx_buf; /**< Pointer to UART Tx transfer Buffer */ + uint16_t tx_size; /**< UART Tx Transfer size */ + uint16_t tx_count; /**< UART Tx Transfer Counter */ + uint8_t *rx_buf; /**< Pointer to UART Rx transfer Buffer */ + uint16_t rx_size; /**< UART Rx Transfer size */ + uint16_t rx_count; /**< UART Rx Transfer Counter */ +#ifdef ALD_DMA + dma_handle_t hdmatx; /**< UART Tx DMA Handle parameters */ + dma_handle_t hdmarx; /**< UART Rx DMA Handle parameters */ +#endif + lock_state_t lock; /**< Locking object */ + uart_state_t state; /**< UART communication state */ + uart_error_t err_code; /**< UART Error code */ + + void (*tx_cplt_cbk)(struct uart_handle_s *arg); /**< Tx completed callback */ + void (*rx_cplt_cbk)(struct uart_handle_s *arg); /**< Rx completed callback */ + void (*error_cbk)(struct uart_handle_s *arg); /**< error callback */ +} uart_handle_t; + +/** + * @brief UART RS485 configure structure definition + */ +typedef struct +{ + type_func_t normal; /**< Normal mode */ + type_func_t dir; /**< Auto-direction mode */ + type_func_t invert; /**< Address detection invert */ + uint8_t addr; /**< Address for compare */ +} uart_rs485_config_t; + +/** + * @brief LIN detection break length + */ +typedef enum +{ + LIN_BREAK_LEN_10B = 0x0, /**< 10-bit break */ + LIN_BREAK_LEN_11B = 0x1, /**< 11-bit break */ +} uart_lin_break_len_t; + +/** + * @brief UART TXFIFO size + */ +typedef enum +{ + UART_TXFIFO_EMPTY = 0x0, /**< Empty */ + UART_TXFIFO_2BYTE = 0x1, /**< 2-Bytes */ + UART_TXFIFO_4BYTE = 0x2, /**< 4-Bytes */ + UART_TXFIFO_8BYTE = 0x3, /**< 8-Bytes */ +} uart_txfifo_t; + +/** + * @brief UART RXFIFO size + */ +typedef enum +{ + UART_RXFIFO_1BYTE = 0x0, /**< 1-Byte */ + UART_RXFIFO_4BYTE = 0x1, /**< 4-Bytes */ + UART_RXFIFO_8BYTE = 0x2, /**< 8-Bytes */ + UART_RXFIFO_14BYTE = 0x3, /**< 14-Bytes */ +} uart_rxfifo_t; + +/** + * @brief UART auto-baud mode + */ +typedef enum +{ + UART_ABRMOD_1_TO_0 = 0x0, /**< Detect bit0:1, bit1:0 */ + UART_ABRMOD_1 = 0x1, /**< Detect bit0:1 */ + UART_ABRMOD_0_TO_1 = 0x2, /**< Detect bit0:0, bit1:1 */ +} uart_auto_baud_mode_t; + +/** + * @brief UART status types + */ +typedef enum +{ + UART_STATUS_DR = (1U << 0), /**< Data ready */ + UART_STATUS_OE = (1U << 1), /**< Overrun error */ + UART_STATUS_PE = (1U << 2), /**< Parity error */ + UART_STATUS_FE = (1U << 3), /**< Framing error */ + UART_STATUS_BI = (1U << 4), /**< Break interrupt */ + UART_STATUS_TBEM = (1U << 5), /**< Transmit buffer empty */ + UART_STATUS_TEM = (1U << 6), /**< Transmitter empty */ + UART_STATUS_RFE = (1U << 7), /**< Reveiver FIFO data error */ + UART_STATUS_BUSY = (1U << 8), /**< UART busy */ + UART_STATUS_TFNF = (1U << 9), /**< Transmit FIFO not full */ + UART_STATUS_TFEM = (1U << 10), /**< Transmit FIFO not empty */ + UART_STATUS_RFNE = (1U << 11), /**< Receive FIFO not empty */ + UART_STATUS_RFF = (1U << 12), /**< Receive FIFO full */ + UART_STATUS_DCTS = (1U << 14), /**< Delta clear to send */ + UART_STATUS_CTS = (1U << 15), /**< Clear to send */ +} uart_status_t; + +/** + * @brief UART interrupt types + */ +typedef enum +{ + UART_IT_RXRD = (1U << 0), /**< Receive data available */ + UART_IT_TXS = (1U << 1), /**< Tx empty status */ + UART_IT_RXS = (1U << 2), /**< Rx line status */ + UART_IT_MDS = (1U << 3), /**< Modem status */ + UART_IT_RTO = (1U << 4), /**< Receiver timeout */ + UART_IT_BZ = (1U << 5), /**< Busy status */ + UART_IT_ABE = (1U << 6), /**< Auto-baud rate detection end */ + UART_IT_ABTO = (1U << 7), /**< Auto-baud rate detection timeout */ + UART_IT_LINBK = (1U << 8), /**< Lin break detection */ + UART_IT_TC = (1U << 9), /**< Transmission complete */ + UART_IT_EOB = (1U << 10), /**< End of block */ + UART_IT_CM = (1U << 11), /**< Character match */ +} uart_it_t; + +/** + * @brief UART flags types + */ +typedef enum +{ + UART_IF_RXRD = (1U << 0), /**< Receive data available */ + UART_IF_TXS = (1U << 1), /**< Tx empty status */ + UART_IF_RXS = (1U << 2), /**< Rx line status */ + UART_IF_MDS = (1U << 3), /**< Modem status */ + UART_IF_RTO = (1U << 4), /**< Receiver timeout */ + UART_IF_BZ = (1U << 5), /**< Busy status */ + UART_IF_ABE = (1U << 6), /**< Auto-baud rate detection end */ + UART_IF_ABTO = (1U << 7), /**< Auto-baud rate detection timeout */ + UART_IF_LINBK = (1U << 8), /**< Lin break detection */ + UART_IF_TC = (1U << 9), /**< Transmission complete */ + UART_IF_EOB = (1U << 10), /**< End of block */ + UART_IF_CM = (1U << 11), /**< Character match */ +} uart_flag_t; +/** + * @} + */ + +/** @defgroup UART_Private_Macros UART Private Macros + * @{ + */ +#define IS_UART_ALL(x) (((x) == UART0) || \ + ((x) == UART1) || \ + ((x) == UART2) || \ + ((x) == UART3)) +#define IS_UART_WORD_LENGTH(x) (((x) == UART_WORD_LENGTH_5B) || \ + ((x) == UART_WORD_LENGTH_6B) || \ + ((x) == UART_WORD_LENGTH_7B) || \ + ((x) == UART_WORD_LENGTH_8B)) +#define IS_UART_STOPBITS(x) (((x) == UART_STOP_BITS_1) || \ + ((x) == UART_STOP_BITS_2) || \ + ((x) == UART_STOP_BITS_0_5) || \ + ((x) == UART_STOP_BITS_1_5)) +#define IS_UART_PARITY(x) (((x) == UART_PARITY_NONE) || \ + ((x) == UART_PARITY_ODD) || \ + ((x) == UART_PARITY_EVEN)) +#define IS_UART_MODE(x) (((x) == UART_MODE_UART) || \ + ((x) == UART_MODE_LIN) || \ + ((x) == UART_MODE_IrDA) || \ + ((x) == UART_MODE_RS485) || \ + ((x) == UART_MODE_HDSEL)) +#define IS_UART_HARDWARE_FLOW_CONTROL(x) \ + (((x) == UART_HW_FLOW_CTL_DISABLE) || \ + ((x) == UART_HW_FLOW_CTL_ENABLE)) +#define IS_UART_LIN_BREAK_LEN(x) (((x) == LIN_BREAK_LEN_10B) || \ + ((x) == LIN_BREAK_LEN_11B)) +#define IS_UART_TXFIFO_TYPE(x) (((x) == UART_TXFIFO_EMPTY) || \ + ((x) == UART_TXFIFO_2BYTE) || \ + ((x) == UART_TXFIFO_4BYTE) || \ + ((x) == UART_TXFIFO_8BYTE)) +#define IS_UART_RXFIFO_TYPE(x) (((x) == UART_RXFIFO_1BYTE) || \ + ((x) == UART_RXFIFO_4BYTE) || \ + ((x) == UART_RXFIFO_8BYTE) || \ + ((x) == UART_RXFIFO_14BYTE)) +#define IS_UART_AUTO_BAUD_MODE(x) (((x) == UART_ABRMOD_1_TO_0) || \ + ((x) == UART_ABRMOD_1) || \ + ((x) == UART_ABRMOD_0_TO_1)) +#define IS_UART_STATUS(x) (((x) == UART_STATUS_DR) || \ + ((x) == UART_STATUS_OE) || \ + ((x) == UART_STATUS_PE) || \ + ((x) == UART_STATUS_FE) || \ + ((x) == UART_STATUS_BI) || \ + ((x) == UART_STATUS_TBEM) || \ + ((x) == UART_STATUS_TEM) || \ + ((x) == UART_STATUS_RFE) || \ + ((x) == UART_STATUS_BUSY) || \ + ((x) == UART_STATUS_TFNF) || \ + ((x) == UART_STATUS_TFEM) || \ + ((x) == UART_STATUS_RFNE) || \ + ((x) == UART_STATUS_RFF) || \ + ((x) == UART_STATUS_DCTS) || \ + ((x) == UART_STATUS_CTS)) +#define IS_UART_IT(x) (((x) == UART_IT_RXRD) || \ + ((x) == UART_IT_TXS) || \ + ((x) == UART_IT_RXS) || \ + ((x) == UART_IT_MDS) || \ + ((x) == UART_IT_RTO) || \ + ((x) == UART_IT_BZ) || \ + ((x) == UART_IT_ABE) || \ + ((x) == UART_IT_ABTO) || \ + ((x) == UART_IT_LINBK) || \ + ((x) == UART_IT_TC) || \ + ((x) == UART_IT_EOB) || \ + ((x) == UART_IT_CM)) +#define IS_UART_IF(x) (((x) == UART_IF_RXRD) || \ + ((x) == UART_IF_TXS) || \ + ((x) == UART_IF_RXS) || \ + ((x) == UART_IF_MDS) || \ + ((x) == UART_IF_RTO) || \ + ((x) == UART_IF_BZ) || \ + ((x) == UART_IF_ABE) || \ + ((x) == UART_IF_ABTO) || \ + ((x) == UART_IF_LINBK) || \ + ((x) == UART_IF_TC) || \ + ((x) == UART_IF_EOB) || \ + ((x) == UART_IF_CM)) +#define IS_UART_BAUDRATE(x) (((x) > 0) && ((x) < 0x44AA21)) +#define IS_UART_DATA(x) ((x) <= 0x1FF) + +#define UART_STATE_TX_MASK (1U << 4) +#define UART_STATE_RX_MASK (1U << 5) +/** + * @} + */ + +/** @addtogroup UART_Public_Functions + * @{ + */ + +/** @addtogroup UART_Public_Functions_Group1 + * @{ + */ +/* Initialization functions */ +void ald_uart_init(uart_handle_t *hperh); +void ald_uart_reset(uart_handle_t *hperh); +void ald_uart_rs485_config(uart_handle_t *hperh, uart_rs485_config_t *config); +/** + * @} + */ + +/** @addtogroup UART_Public_Functions_Group2 + * @{ + */ +/* IO operation functions */ +ald_status_t ald_uart_send(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_uart_recv(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_uart_send_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_uart_recv_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size); +#ifdef ALD_DMA +ald_status_t ald_uart_send_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_uart_recv_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_uart_dma_pause(uart_handle_t *hperh); +ald_status_t ald_uart_dma_resume(uart_handle_t *hperh); +ald_status_t ald_uart_dma_stop(uart_handle_t *hperh); +#endif +void ald_uart_irq_handler(uart_handle_t *hperh); +/** + * @} + */ + +/** @addtogroup UART_Public_Functions_Group3 + * @{ + */ +/* Peripheral Control functions */ +void ald_uart_interrupt_config(uart_handle_t *hperh, uart_it_t it, type_func_t state); +void ald_uart_dma_req_config(uart_handle_t *hperh, type_func_t state); +void ald_uart_tx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t level); +void ald_uart_rx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t level); +void ald_uart_lin_send_break(uart_handle_t *hperh); +void ald_uart_lin_detect_break_len_config(uart_handle_t *hperh, uart_lin_break_len_t len); +void ald_uart_auto_baud_config(uart_handle_t *hperh, uart_auto_baud_mode_t mode); +ald_status_t ald_uart_rs485_send_addr(uart_handle_t *hperh, uint16_t addr, uint32_t timeout); +it_status_t ald_uart_get_it_status(uart_handle_t *hperh, uart_it_t it); +flag_status_t ald_uart_get_status(uart_handle_t *hperh, uart_status_t status); +flag_status_t ald_uart_get_flag_status(uart_handle_t *hperh, uart_flag_t flag); +flag_status_t ald_uart_get_mask_flag_status(uart_handle_t *hperh, uart_flag_t flag); +void ald_uart_clear_flag_status(uart_handle_t *hperh, uart_flag_t flag); +/** + * @} + */ + +/** @addtogroup UART_Public_Functions_Group4 + * @{ + */ +/* Peripheral State and Errors functions */ +uart_state_t ald_uart_get_state(uart_handle_t *hperh); +uint32_t ald_uart_get_error(uart_handle_t *hperh); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ALD_UART_H__ */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_usart.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_usart.h similarity index 43% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_usart.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_usart.h index 07aac584f1..62214b2a08 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_usart.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_usart.h @@ -42,8 +42,8 @@ extern "C" { */ typedef enum { - USART_WORD_LENGTH_8B = 0x0, /**< Word length is 8-bits */ - USART_WORD_LENGTH_9B = 0x1, /**< Word length is 9-bits */ + USART_WORD_LENGTH_8B = 0x0, /**< Word length is 8-bits */ + USART_WORD_LENGTH_9B = 0x1, /**< Word length is 9-bits */ } usart_word_length_t; /** @@ -51,10 +51,10 @@ typedef enum */ typedef enum { - USART_STOP_BITS_1 = 0x0, /**< Stop bits is 1-bits */ - USART_STOP_BITS_0_5 = 0x1, /**< Stop bits is 0.5-bits */ - USART_STOP_BITS_2 = 0x2, /**< Stop bits is 2-bits */ - USART_STOP_BITS_1_5 = 0x3, /**< Stop bits is 1.5-bits */ + USART_STOP_BITS_1 = 0x0, /**< Stop bits is 1-bits */ + USART_STOP_BITS_0_5 = 0x1, /**< Stop bits is 0.5-bits */ + USART_STOP_BITS_2 = 0x2, /**< Stop bits is 2-bits */ + USART_STOP_BITS_1_5 = 0x3, /**< Stop bits is 1.5-bits */ } usart_stop_bits_t; /** @@ -62,9 +62,9 @@ typedef enum */ typedef enum { - USART_PARITY_NONE = 0x0, /**< Not parity */ - USART_PARITY_EVEN = 0x2, /**< Even parity */ - USART_PARITY_ODD = 0x3, /**< Odd parity */ + USART_PARITY_NONE = 0x0, /**< Not parity */ + USART_PARITY_EVEN = 0x2, /**< Even parity */ + USART_PARITY_ODD = 0x3, /**< Odd parity */ } usart_parity_t; /** @@ -72,9 +72,9 @@ typedef enum */ typedef enum { - USART_MODE_RX = 0x1, /**< TX mode */ - USART_MODE_TX = 0x2, /**< RX mode */ - USART_MODE_TX_RX = 0x3, /**< TX & RX mode */ + USART_MODE_RX = 0x1, /**< TX mode */ + USART_MODE_TX = 0x2, /**< RX mode */ + USART_MODE_TX_RX = 0x3, /**< TX & RX mode */ } usart_mode_t; /** @@ -82,10 +82,10 @@ typedef enum */ typedef enum { - USART_HW_FLOW_CTL_NONE = 0x0, /**< Not flow control */ - USART_HW_FLOW_CTL_RTS = 0x1, /**< RTS flow control */ - USART_HW_FLOW_CTL_CTS = 0x2, /**< CTS flow control */ - USART_HW_FLOW_CTL_RTS_CTS = 0x3, /**< RTS & CTS flow control */ + USART_HW_FLOW_CTL_NONE = 0x0, /**< Not flow control */ + USART_HW_FLOW_CTL_RTS = 0x1, /**< RTS flow control */ + USART_HW_FLOW_CTL_CTS = 0x2, /**< CTS flow control */ + USART_HW_FLOW_CTL_RTS_CTS = 0x3, /**< RTS & CTS flow control */ } usart_hw_flow_ctl_t; /** @@ -93,8 +93,8 @@ typedef enum */ typedef enum { - USART_CLOCK_DISABLE = 0x0, /**< Disable clock output */ - USART_CLOCK_ENABLE = 0x1, /**< Enable clock output */ + USART_CLOCK_DISABLE = 0x0, /**< Disable clock output */ + USART_CLOCK_ENABLE = 0x1, /**< Enable clock output */ } usart_clock_t; /** @@ -102,8 +102,8 @@ typedef enum */ typedef enum { - USART_CPOL_LOW = 0x0, /**< Clock polarity low */ - USART_CPOL_HIGH = 0x1, /**< Clock polarity high */ + USART_CPOL_LOW = 0x0, /**< Clock polarity low */ + USART_CPOL_HIGH = 0x1, /**< Clock polarity high */ } usart_cpol_t; /** @@ -111,8 +111,8 @@ typedef enum */ typedef enum { - USART_CPHA_1EDGE = 0x0, /**< Clock phase first edge */ - USART_CPHA_2EDGE = 0x1, /**< Clock phase second edge */ + USART_CPHA_1EDGE = 0x0, /**< Clock phase first edge */ + USART_CPHA_2EDGE = 0x1, /**< Clock phase second edge */ } usart_cpha_t; /** @@ -120,8 +120,8 @@ typedef enum */ typedef enum { - USART_LAST_BIT_DISABLE = 0x0, /**< Disable last bit clock output */ - USART_LAST_BIT_ENABLE = 0x1, /**< Enable last bit clock output */ + USART_LAST_BIT_DISABLE = 0x0, /**< Disable last bit clock output */ + USART_LAST_BIT_ENABLE = 0x1, /**< Enable last bit clock output */ } usart_last_bit_t; /** @@ -129,14 +129,14 @@ typedef enum */ typedef enum { - USART_STATE_RESET = 0x00, /**< Peripheral is not initialized */ - USART_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ - USART_STATE_BUSY = 0x02, /**< an internal process is ongoing */ - USART_STATE_BUSY_TX = 0x11, /**< Data Transmission process is ongoing */ - USART_STATE_BUSY_RX = 0x21, /**< Data Reception process is ongoing */ - USART_STATE_BUSY_TX_RX = 0x31, /**< Data Transmission Reception process is ongoing */ - USART_STATE_TIMEOUT = 0x03, /**< Timeout state */ - USART_STATE_ERROR = 0x04, /**< Error */ + USART_STATE_RESET = 0x00, /**< Peripheral is not initialized */ + USART_STATE_READY = 0x01, /**< Peripheral Initialized and ready for use */ + USART_STATE_BUSY = 0x02, /**< an internal process is ongoing */ + USART_STATE_BUSY_TX = 0x11, /**< Data Transmission process is ongoing */ + USART_STATE_BUSY_RX = 0x21, /**< Data Reception process is ongoing */ + USART_STATE_BUSY_TX_RX = 0x31, /**< Data Transmission Reception process is ongoing */ + USART_STATE_TIMEOUT = 0x03, /**< Timeout state */ + USART_STATE_ERROR = 0x04, /**< Error */ } usart_state_t; /** @@ -144,12 +144,12 @@ typedef enum */ typedef enum { - USART_ERROR_NONE = ((uint32_t)0x00), /**< No error */ - USART_ERROR_PE = ((uint32_t)0x01), /**< Parity error */ - USART_ERROR_NE = ((uint32_t)0x02), /**< Noise error */ - USART_ERROR_FE = ((uint32_t)0x04), /**< frame error */ - USART_ERROR_ORE = ((uint32_t)0x08), /**< Overrun error */ - USART_ERROR_DMA = ((uint32_t)0x10), /**< DMA transfer error */ + USART_ERROR_NONE = ((uint32_t)0x00), /**< No error */ + USART_ERROR_PE = ((uint32_t)0x01), /**< Parity error */ + USART_ERROR_NE = ((uint32_t)0x02), /**< Noise error */ + USART_ERROR_FE = ((uint32_t)0x04), /**< frame error */ + USART_ERROR_ORE = ((uint32_t)0x08), /**< Overrun error */ + USART_ERROR_DMA = ((uint32_t)0x10), /**< DMA transfer error */ } usart_error_t; @@ -158,17 +158,17 @@ typedef enum */ typedef struct { - uint32_t baud; /**< This member configures the Usart communication baud rate. */ + uint32_t baud; /**< This member configures the Usart communication baud rate. */ usart_word_length_t word_length;/**< Specifies the number of data bits transmitted or received in a frame. */ - usart_stop_bits_t stop_bits; /**< Specifies the number of stop bits transmitted. */ - usart_parity_t parity; /**< Specifies the parity mode. - @note When parity is enabled, the computed parity is inserted - at the MSB position of the transmitted data (9th bit when - the word length is set to 9 data bits; 8th bit when the - word length is set to 8 data bits). */ - usart_mode_t mode; /**< Specifies wether the Receive or Transmit mode is enabled or disabled. */ - usart_hw_flow_ctl_t fctl; /**< Specifies wether the hardware flow control mode is enabled or disabled. */ - type_func_t over_sampling; /**< Specifies whether the Over sampling 8 is enabled or disabled. */ + usart_stop_bits_t stop_bits; /**< Specifies the number of stop bits transmitted. */ + usart_parity_t parity; /**< Specifies the parity mode. + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + usart_mode_t mode; /**< Specifies wether the Receive or Transmit mode is enabled or disabled. */ + usart_hw_flow_ctl_t fctl; /**< Specifies wether the hardware flow control mode is enabled or disabled. */ + type_func_t over_sampling; /**< Specifies whether the Over sampling 8 is enabled or disabled. */ } usart_init_t; /** @@ -176,26 +176,26 @@ typedef struct */ typedef struct usart_handle_s { - USART_TypeDef *perh; /**< USART registers base address */ - usart_init_t init; /**< USART communication parameters */ - uint8_t *tx_buf; /**< Pointer to USART Tx transfer buffer */ - uint16_t tx_size; /**< USART Tx transfer size */ - uint16_t tx_count; /**< USART Tx transfer counter */ - uint8_t *rx_buf; /**< Pointer to USART Rx transfer buffer */ - uint16_t rx_size; /**< USART Rx Transfer size */ - uint16_t rx_count; /**< USART Rx Transfer Counter */ + USART_TypeDef *perh; /**< USART registers base address */ + usart_init_t init; /**< USART communication parameters */ + uint8_t *tx_buf; /**< Pointer to USART Tx transfer buffer */ + uint16_t tx_size; /**< USART Tx transfer size */ + uint16_t tx_count; /**< USART Tx transfer counter */ + uint8_t *rx_buf; /**< Pointer to USART Rx transfer buffer */ + uint16_t rx_size; /**< USART Rx Transfer size */ + uint16_t rx_count; /**< USART Rx Transfer Counter */ #ifdef ALD_DMA - dma_handle_t hdmatx; /**< USART Tx DMA handle parameters */ - dma_handle_t hdmarx; /**< USART Rx DMA handle parameters */ + dma_handle_t hdmatx; /**< USART Tx DMA handle parameters */ + dma_handle_t hdmarx; /**< USART Rx DMA handle parameters */ #endif - lock_state_t lock; /**< Locking object */ - usart_state_t state; /**< USART communication state */ - uint32_t err_code; /**< USART error code */ - - void (*tx_cplt_cbk)(struct usart_handle_s *arg); /**< Tx completed callback */ - void (*rx_cplt_cbk)(struct usart_handle_s *arg); /**< Rx completed callback */ - void (*tx_rx_cplt_cbk)(struct usart_handle_s *arg); /**< Tx & Rx completed callback */ - void (*error_cbk)(struct usart_handle_s *arg); /**< error callback */ + lock_state_t lock; /**< Locking object */ + usart_state_t state; /**< USART communication state */ + uint32_t err_code; /**< USART error code */ + + void (*tx_cplt_cbk)(struct usart_handle_s *arg); /**< Tx completed callback */ + void (*rx_cplt_cbk)(struct usart_handle_s *arg); /**< Rx completed callback */ + void (*tx_rx_cplt_cbk)(struct usart_handle_s *arg); /**< Tx & Rx completed callback */ + void (*error_cbk)(struct usart_handle_s *arg); /**< error callback */ } usart_handle_t; @@ -204,11 +204,11 @@ typedef struct usart_handle_s */ typedef struct { - usart_clock_t clk; /**< Pecifies whether the USART clock is enable or disable. */ - usart_cpol_t polarity; /**< Specifies the steady state of the serial clock. */ - usart_cpha_t phase; /**< Specifies the clock transition on which the bit capture is made. */ - usart_last_bit_t last_bit; /**< Specifies whether the clock pulse corresponding to the last transmitted - data bit (MSB) has to be output on the SCLK pin in synchronous mode. */ + usart_clock_t clk; /**< Pecifies whether the USART clock is enable or disable. */ + usart_cpol_t polarity; /**< Specifies the steady state of the serial clock. */ + usart_cpha_t phase; /**< Specifies the clock transition on which the bit capture is made. */ + usart_last_bit_t last_bit; /**< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. */ } usart_clock_init_t; @@ -217,8 +217,8 @@ typedef struct */ typedef enum { - USART_DMA_REQ_TX = (1U << 7), /**< TX dma bit */ - USART_DMA_REQ_RX = (1U << 6), /**< RX dma bit */ + USART_DMA_REQ_TX = (1U << 7), /**< TX dma bit */ + USART_DMA_REQ_RX = (1U << 6), /**< RX dma bit */ } usart_dma_req_t; /** @@ -226,8 +226,8 @@ typedef enum */ typedef enum { - USART_WAKEUP_IDLE = 0x0, /**< Wake up the machine when bus-line is idle */ - USART_WAKEUP_ADDR = 0x1, /**< Wake up the machine when match the address */ + USART_WAKEUP_IDLE = 0x0, /**< Wake up the machine when bus-line is idle */ + USART_WAKEUP_ADDR = 0x1, /**< Wake up the machine when match the address */ } usart_wakeup_t; /** @@ -235,8 +235,8 @@ typedef enum */ typedef enum { - USART_IrDA_MODE_NORMAL = 0x0, /**< Normal IrDA mode */ - USART_IrDA_MODE_LOW_POWER = 0x1, /**< Low-power IrDA mode */ + USART_IrDA_MODE_NORMAL = 0x0, /**< Normal IrDA mode */ + USART_IrDA_MODE_LOW_POWER = 0x1, /**< Low-power IrDA mode */ } usart_IrDA_mode_t; /** @@ -244,16 +244,16 @@ typedef enum */ typedef enum { - USART_IT_PE = ((1U << 8) | (1U << 16)), /**< Parity error */ - USART_IT_TXE = ((1U << 7) | (1U << 16)), /**< Tx empty */ - USART_IT_TC = ((1U << 6) | (1U << 16)), /**< Tx complete */ - USART_IT_RXNE = ((1U << 5) | (1U << 16)), /**< Rx not empty */ - USART_IT_IDLE = ((1U << 4) | (1U << 16)), /**< Idle */ - USART_IT_CTS = ((1U << 10) | (1U << 18)), /**< CTS */ - USART_IT_ERR = ((1U << 0) | (1U << 18)), /**< Error */ - USART_IT_ORE = (1U << 3), /**< Overrun error */ - USART_IT_NE = (1U << 2), /**< Noise error */ - USART_IT_FE = (1U << 0), /**< Frame error */ + USART_IT_PE = ((1U << 8) | (1U << 16)), /**< Parity error */ + USART_IT_TXE = ((1U << 7) | (1U << 16)), /**< Tx empty */ + USART_IT_TC = ((1U << 6) | (1U << 16)), /**< Tx complete */ + USART_IT_RXNE = ((1U << 5) | (1U << 16)), /**< Rx not empty */ + USART_IT_IDLE = ((1U << 4) | (1U << 16)), /**< Idle */ + USART_IT_CTS = ((1U << 10) | (1U << 18)), /**< CTS */ + USART_IT_ERR = ((1U << 0) | (1U << 18)), /**< Error */ + USART_IT_ORE = (1U << 3), /**< Overrun error */ + USART_IT_NE = (1U << 2), /**< Noise error */ + USART_IT_FE = (1U << 0), /**< Frame error */ } usart_it_t; /** @@ -261,15 +261,15 @@ typedef enum */ typedef enum { - USART_FLAG_CTS = (1U << 9), /**< CTS */ - USART_FLAG_TXE = (1U << 7), /**< Tx empty */ - USART_FLAG_TC = (1U << 6), /**< Tx complete */ - USART_FLAG_RXNE = (1U << 5), /**< Rx not empty */ - USART_FLAG_IDLE = (1U << 4), /**< Idle */ - USART_FLAG_ORE = (1U << 3), /**< Overrun error */ - USART_FLAG_NE = (1U << 2), /**< Noise error */ - USART_FLAG_FE = (1U << 1), /**< Frame error */ - USART_FLAG_PE = (1U << 0), /**< Parity error */ + USART_FLAG_CTS = (1U << 9), /**< CTS */ + USART_FLAG_TXE = (1U << 7), /**< Tx empty */ + USART_FLAG_TC = (1U << 6), /**< Tx complete */ + USART_FLAG_RXNE = (1U << 5), /**< Rx not empty */ + USART_FLAG_IDLE = (1U << 4), /**< Idle */ + USART_FLAG_ORE = (1U << 3), /**< Overrun error */ + USART_FLAG_NE = (1U << 2), /**< Noise error */ + USART_FLAG_FE = (1U << 1), /**< Frame error */ + USART_FLAG_PE = (1U << 0), /**< Parity error */ } usart_flag_t; /** @@ -292,13 +292,13 @@ typedef enum /** @defgroup USART_Public_Macros_2 USART clear PE flag * @{ */ -#define USART_CLEAR_PEFLAG(handle) \ -do { \ - __IO uint32_t tmpreg; \ - tmpreg = (handle)->perh->STAT; \ - tmpreg = (handle)->perh->DATA; \ - UNUSED(tmpreg); \ -} while (0) +#define USART_CLEAR_PEFLAG(handle) \ + do { \ + __IO uint32_t tmpreg; \ + tmpreg = (handle)->perh->STAT; \ + tmpreg = (handle)->perh->DATA; \ + UNUSED(tmpreg); \ + } while (0) /** * @} */ @@ -338,7 +338,7 @@ do { \ /** @defgroup USART_Public_Macros_7 USART enable CTS flow control * @{ */ -#define USART_HWCONTROL_CTS_ENABLE(handle) \ +#define USART_HWCONTROL_CTS_ENABLE(handle) \ (SET_BIT((handle)->perh->CON2, USART_CON2_CTSEN_MSK)) /** * @} @@ -347,7 +347,7 @@ do { \ /** @defgroup USART_Public_Macros_8 USART disable CTS flow control * @{ */ -#define USART_HWCONTROL_CTS_DISABLE(handle) \ +#define USART_HWCONTROL_CTS_DISABLE(handle) \ (CLEAR_BIT((handle)->perh->CON2, USART_CON2_CTSEN_MSK)) /** * @} @@ -356,7 +356,7 @@ do { \ /** @defgroup USART_Public_Macros_9 USART enable RTS flow control * @{ */ -#define USART_HWCONTROL_RTS_ENABLE(handle) \ +#define USART_HWCONTROL_RTS_ENABLE(handle) \ (SET_BIT((handle)->perh->CON2, USART_CON2_RTSEN_MSK)) /** * @} @@ -365,7 +365,7 @@ do { \ /** @defgroup USART_Public_Macros_10 USART disable RTS flow control * @{ */ -#define USART_HWCONTROL_RTS_DISABLE(handle) \ +#define USART_HWCONTROL_RTS_DISABLE(handle) \ (CLEAR_BIT((handle)->perh->CON2, USART_CON2_RTSEN_MSK)) /** * @} @@ -374,7 +374,7 @@ do { \ /** @defgroup USART_Public_Macros_11 USART enable * @{ */ -#define USART_ENABLE(handle) (SET_BIT((handle)->perh->CON0, USART_CON0_EN_MSK)) +#define USART_ENABLE(handle) (SET_BIT((handle)->perh->CON0, USART_CON0_EN_MSK)) /** * @} */ @@ -382,7 +382,7 @@ do { \ /** @defgroup USART_Public_Macros_12 USART disable * @{ */ -#define USART_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON0, USART_CON0_EN_MSK)) +#define USART_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON0, USART_CON0_EN_MSK)) /** * @} */ @@ -406,13 +406,13 @@ do { \ ((x) == USART_PARITY_EVEN) || \ ((x) == USART_PARITY_ODD)) #define IS_USART_MODE(x) (((x) == USART_MODE_RX) || \ - ((x) == USART_MODE_TX) || \ - ((x) == USART_MODE_TX_RX)) + ((x) == USART_MODE_TX) || \ + ((x) == USART_MODE_TX_RX)) #define IS_USART_HARDWARE_FLOW_CONTROL(x)\ - (((x) == USART_HW_FLOW_CTL_NONE) || \ - ((x) == USART_HW_FLOW_CTL_RTS) || \ - ((x) == USART_HW_FLOW_CTL_CTS) || \ - ((x) == USART_HW_FLOW_CTL_RTS_CTS)) + (((x) == USART_HW_FLOW_CTL_NONE) || \ + ((x) == USART_HW_FLOW_CTL_RTS) || \ + ((x) == USART_HW_FLOW_CTL_CTS) || \ + ((x) == USART_HW_FLOW_CTL_RTS_CTS)) #define IS_USART_CLOCK(x) (((x) == USART_CLOCK_DISABLE) || \ ((x) == USART_CLOCK_ENABLE)) #define IS_USART_CPOL(x) (((x) == USART_CPOL_LOW) || ((x) == USART_CPOL_HIGH)) @@ -436,7 +436,7 @@ do { \ ((x) == USART_IT_NE) || ((x) == USART_IT_FE) || \ ((x) == USART_IT_ERR)) #define IS_USART_CLEAR_IT(x) (((x) == USART_IT_TC) || ((x) == USART_IT_RXNE) || \ - ((x) == USART_IT_CTS)) + ((x) == USART_IT_CTS)) #define IS_USART_FLAG(x) (((x) == USART_FLAG_PE) || ((x) == USART_FLAG_TXE) || \ ((x) == USART_FLAG_TC) || ((x) == USART_FLAG_RXNE) || \ @@ -446,12 +446,12 @@ do { \ #define IS_USART_CLEAR_FLAG(x) (((x) == USART_FLAG_CTS) || \ ((x) == USART_FLAG_TC) || \ ((x) == USART_FLAG_RXNE)) -#define IS_USART_BAUDRATE(x) (((x) > 0) && ((x) < 0x0044AA21)) -#define IS_USART_ADDRESS(x) ((x) <= 0xF) -#define IS_USART_DATA(x) ((x) <= 0x1FF) -#define DUMMY_DATA 0xFFFF -#define USART_STATE_TX_MASK (1 << 4) -#define USART_STATE_RX_MASK (1 << 5) +#define IS_USART_BAUDRATE(x) (((x) > 0) && ((x) < 0x0044AA21)) +#define IS_USART_ADDRESS(x) ((x) <= 0xF) +#define IS_USART_DATA(x) ((x) <= 0x1FF) +#define DUMMY_DATA 0xFFFF +#define USART_STATE_TX_MASK (1 << 4) +#define USART_STATE_RX_MASK (1 << 5) /** * @} @@ -465,11 +465,11 @@ do { \ * @{ */ /* Initialization functions */ -void usart_reset(usart_handle_t *hperh); -ald_status_t usart_init(usart_handle_t *hperh); -ald_status_t usart_half_duplex_init(usart_handle_t *hperh); -ald_status_t usart_multi_processor_init(usart_handle_t *hperh, uint8_t addr, usart_wakeup_t wakeup); -ald_status_t usart_clock_init(usart_handle_t *hperh, usart_clock_init_t *init); +void ald_usart_reset(usart_handle_t *hperh); +ald_status_t ald_usart_init(usart_handle_t *hperh); +ald_status_t ald_usart_half_duplex_init(usart_handle_t *hperh); +ald_status_t ald_usart_multi_processor_init(usart_handle_t *hperh, uint8_t addr, usart_wakeup_t wakeup); +ald_status_t ald_usart_clock_init(usart_handle_t *hperh, usart_clock_init_t *init); /** * @} */ @@ -482,14 +482,14 @@ ald_status_t usart_clock_init(usart_handle_t *hperh, usart_clock_init_t *init); * @{ */ /* Asynchronization IO operation functions */ -ald_status_t usart_send(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t usart_recv(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t usart_send_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t usart_recv_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t usart_recv_frame_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_usart_send(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_usart_recv(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_usart_send_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_usart_recv_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_usart_recv_frame_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size); #ifdef ALD_DMA -ald_status_t usart_send_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_usart_send_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); #endif /** * @} @@ -499,16 +499,16 @@ ald_status_t usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t siz * @{ */ /* Synchronization IO operation functions */ -ald_status_t usart_send_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t usart_recv_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); -ald_status_t usart_send_recv_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout); -ald_status_t usart_send_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t usart_recv_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size); -ald_status_t usart_send_recv_by_it_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size); +ald_status_t ald_usart_send_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_usart_recv_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout); +ald_status_t ald_usart_send_recv_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout); +ald_status_t ald_usart_send_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_usart_recv_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size); +ald_status_t ald_usart_send_recv_by_it_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size); #ifdef ALD_DMA -ald_status_t usart_send_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); -ald_status_t usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel); -ald_status_t usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, +ald_status_t ald_usart_send_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel); +ald_status_t ald_usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel); +ald_status_t ald_usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel); #endif /** @@ -520,11 +520,11 @@ ald_status_t usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, */ /* Utilities functions */ #ifdef ALD_DMA -ald_status_t usart_dma_pause(usart_handle_t *hperh); -ald_status_t usart_dma_resume(usart_handle_t *hperh); -ald_status_t usart_dma_stop(usart_handle_t *hperh); +ald_status_t ald_usart_dma_pause(usart_handle_t *hperh); +ald_status_t ald_usart_dma_resume(usart_handle_t *hperh); +ald_status_t ald_usart_dma_stop(usart_handle_t *hperh); #endif -void usart_irq_handle(usart_handle_t *hperh); +void ald_usart_irq_handler(usart_handle_t *hperh); /** * @} */ @@ -537,15 +537,15 @@ void usart_irq_handle(usart_handle_t *hperh); * @{ */ /* Peripheral control functions */ -ald_status_t usart_multi_processor_enter_mute_mode(usart_handle_t *hperh); -ald_status_t usart_multi_processor_exit_mute_mode(usart_handle_t *hperh); -ald_status_t usart_half_duplex_enable_send(usart_handle_t *hperh); -ald_status_t usart_half_duplex_enable_recv(usart_handle_t *hperh); -void usart_dma_req_config(usart_handle_t *hperh, usart_dma_req_t req, type_func_t state); -void usart_interrupt_config(usart_handle_t *hperh, usart_it_t it, type_func_t state); -flag_status_t usart_get_flag_status(usart_handle_t *hperh, usart_flag_t flag); -void usart_clear_flag_status(usart_handle_t *hperh, usart_flag_t flag); -it_status_t usart_get_it_status(usart_handle_t *hperh, usart_it_t it); +ald_status_t ald_usart_multi_processor_enter_mute_mode(usart_handle_t *hperh); +ald_status_t ald_usart_multi_processor_exit_mute_mode(usart_handle_t *hperh); +ald_status_t ald_usart_half_duplex_enable_send(usart_handle_t *hperh); +ald_status_t ald_usart_half_duplex_enable_recv(usart_handle_t *hperh); +void ald_usart_dma_req_config(usart_handle_t *hperh, usart_dma_req_t req, type_func_t state); +void ald_usart_interrupt_config(usart_handle_t *hperh, usart_it_t it, type_func_t state); +flag_status_t ald_usart_get_flag_status(usart_handle_t *hperh, usart_flag_t flag); +void ald_usart_clear_flag_status(usart_handle_t *hperh, usart_flag_t flag); +it_status_t ald_usart_get_it_status(usart_handle_t *hperh, usart_it_t it); /** * @} */ @@ -555,8 +555,8 @@ it_status_t usart_get_it_status(usart_handle_t *hperh, usart_it_t it); */ /* Peripheral state and error functions */ -usart_state_t usart_get_state(usart_handle_t *hperh); -uint32_t usart_get_error(usart_handle_t *hperh); +usart_state_t ald_usart_get_state(usart_handle_t *hperh); +uint32_t ald_usart_get_error(usart_handle_t *hperh); /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_wdt.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_wdt.h similarity index 66% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_wdt.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_wdt.h index ee181e3da7..b2b0e2203a 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_wdt.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/ald_wdt.h @@ -40,10 +40,10 @@ extern "C" { */ typedef enum { - WWDT_WIN_25 = 0x0, /**< No dog window size: 25% */ - WWDT_WIN_50 = 0x1, /**< No dog window size: 50% */ - WWDT_WIN_75 = 0x2, /**< No dog window size: 75% */ - WWDT_WIN_00 = 0x3, /**< No dog window size: 0% */ + WWDT_WIN_25 = 0x0, /**< No dog window size: 25% */ + WWDT_WIN_50 = 0x1, /**< No dog window size: 50% */ + WWDT_WIN_75 = 0x2, /**< No dog window size: 75% */ + WWDT_WIN_00 = 0x3, /**< No dog window size: 0% */ } wwdt_win_t; /** @@ -71,8 +71,8 @@ typedef enum (x == WWDT_WIN_50) || \ (x == WWDT_WIN_75) || \ (x == WWDT_WIN_00)) -#define IS_FUNC_STATE(x) (((x) == DISABLE) || \ - ((x) == ENABLE)) +#define IS_FUNC_STATE(x) (((x) == DISABLE) || \ + ((x) == ENABLE)) /** * @} */ @@ -80,12 +80,12 @@ typedef enum /** @addtogroup WWDT_Public_Functions * @{ */ -void wwdt_init(uint32_t load, wwdt_win_t win, type_func_t interrupt); -void wwdt_start(void); -uint32_t wwdt_get_value(void); -it_status_t wwdt_get_flag_status(void); -void wwdt_clear_flag_status(void); -void wwdt_feed_dog(void); +void ald_wwdt_init(uint32_t load, wwdt_win_t win, type_func_t interrupt); +void ald_wwdt_start(void); +uint32_t ald_wwdt_get_value(void); +it_status_t ald_wwdt_get_flag_status(void); +void ald_wwdt_clear_flag_status(void); +void ald_wwdt_feed_dog(void); /** * @} */ @@ -93,12 +93,12 @@ void wwdt_feed_dog(void); /** @addtogroup IWDT_Public_Functions * @{ */ -void iwdt_init(uint32_t load, type_func_t interrupt); -void iwdt_start(void); -uint32_t iwdt_get_value(void); -it_status_t iwdt_get_flag_status(void); -void iwdt_clear_flag_status(void); -void iwdt_feed_dog(void); +void ald_iwdt_init(uint32_t load, type_func_t interrupt); +void ald_iwdt_start(void); +uint32_t ald_iwdt_get_value(void); +it_status_t ald_iwdt_get_flag_status(void); +void ald_iwdt_clear_flag_status(void); +void ald_iwdt_feed_dog(void); /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/type.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/type.h similarity index 55% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/type.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/type.h index 34303037d9..7bf1c1e543 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/type.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/type.h @@ -25,11 +25,11 @@ extern "C" { #if defined (__CC_ARM) -#define __INLINE__ __inline -#define __STATIC_INLINE__ static __inline +#define __INLINE__ __inline +#define __STATIC_INLINE__ static __inline #else -#define __INLINE__ inline -#define __STATIC_INLINE__ static inline +#define __INLINE__ inline +#define __STATIC_INLINE__ static inline #endif #define __isr__ @@ -51,7 +51,7 @@ typedef enum DISABLE = 0x0, ENABLE = 0x1, } type_func_t; -#define IS_FUNC_STATE(x) (((x) == DISABLE) || ((x) == ENABLE)) +#define IS_FUNC_STATE(x) (((x) == DISABLE) || ((x) == ENABLE)) typedef enum { @@ -64,40 +64,40 @@ typedef enum UNLOCK = 0x0, LOCK = 0x1, } lock_state_t; -#define IS_LOCK_STATE(x) (((x) == UNLOCK) || ((x) == LOCK)) - - -#define BIT(x) ((1U << (x))) -#define BITS(s, e) ((0xffffffff << (s)) & (0xffffffff >> (31 - (e)))) -#define SET_BIT(reg, bit) ((reg) |= (bit)) -#define CLEAR_BIT(reg, bit) ((reg) &= ~(bit)) -#define READ_BIT(reg, bit) ((reg) & (bit)) -#define READ_BITS(reg, msk, s) (((reg) & (msk)) >> (s)) -#define CLEAR_REG(reg) ((reg) = (0x0)) -#define WRITE_REG(reg, val) ((reg) = (val)) -#define READ_REG(reg) ((reg)) -#define MODIFY_REG(reg, clearmask, setmask) \ +#define IS_LOCK_STATE(x) (((x) == UNLOCK) || ((x) == LOCK)) + + +#define BIT(x) ((1U << (x))) +#define BITS(s, e) ((0xffffffff << (s)) & (0xffffffff >> (31 - (e)))) +#define SET_BIT(reg, bit) ((reg) |= (bit)) +#define CLEAR_BIT(reg, bit) ((reg) &= ~(bit)) +#define READ_BIT(reg, bit) ((reg) & (bit)) +#define READ_BITS(reg, msk, s) (((reg) & (msk)) >> (s)) +#define CLEAR_REG(reg) ((reg) = (0x0)) +#define WRITE_REG(reg, val) ((reg) = (val)) +#define READ_REG(reg) ((reg)) +#define MODIFY_REG(reg, clearmask, setmask) \ WRITE_REG((reg), (((READ_REG(reg)) & (~(clearmask))) | (setmask))) -#define UNUSED(x) ((void)(x)) +#define UNUSED(x) ((void)(x)) #ifdef USE_ASSERT -#define assert_param(x) \ -do { \ - if (!(x)) { \ - __disable_irq(); \ - while (1) \ - ; \ - } \ -} while (0) +#define assert_param(x) \ + do { \ + if (!(x)) { \ + __disable_irq(); \ + while (1) \ + ; \ + } \ + } while (0) #else #define assert_param(x) #endif -#define PER_MEM_BASE ((uint32_t) 0x40000000UL) /* PER base address */ -#define RAM_MEM_BASE ((uint32_t) 0x20000000UL) /* RAM base address */ -#define BITBAND_PER_BASE ((uint32_t) 0x42000000UL) /* Peripheral Address Space bit-band area */ -#define BITBAND_RAM_BASE ((uint32_t) 0x22000000UL) /* SRAM Address Space bit-band area */ +#define PER_MEM_BASE ((uint32_t) 0x40000000UL) /* PER base address */ +#define RAM_MEM_BASE ((uint32_t) 0x20000000UL) /* RAM base address */ +#define BITBAND_PER_BASE ((uint32_t) 0x42000000UL) /* Peripheral Address Space bit-band area */ +#define BITBAND_RAM_BASE ((uint32_t) 0x22000000UL) /* SRAM Address Space bit-band area */ __STATIC_INLINE__ void BITBAND_PER(volatile uint32_t *addr, uint32_t bit, uint32_t val) { @@ -114,10 +114,10 @@ __STATIC_INLINE__ void BITBAND_SRAM(uint32_t *addr, uint32_t bit, uint32_t val) #if defined ( __GNUC__ ) #ifndef __weak #define __weak __attribute__((weak)) -#endif /* __weak */ +#endif /* __weak */ #ifndef __packed #define __packed __attribute__((__packed__)) -#endif /* __packed */ +#endif /* __packed */ #endif /* __GNUC__ */ #ifdef __cplusplus diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/utils.h b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/utils.h similarity index 56% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/utils.h rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/utils.h index b80d155790..b9041cb62a 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/utils.h +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Include/utils.h @@ -59,10 +59,10 @@ typedef enum */ typedef enum { - SYSTICK_INTERVAL_1MS = 1000, /**< Interval is 1ms */ - SYSTICK_INTERVAL_10MS = 100, /**< Interval is 10ms */ - SYSTICK_INTERVAL_100MS = 10, /**< Interval is 100ms */ - SYSTICK_INTERVAL_1000MS = 1, /**< Interval is 1s */ + SYSTICK_INTERVAL_1MS = 1000, /**< Interval is 1ms */ + SYSTICK_INTERVAL_10MS = 100, /**< Interval is 10ms */ + SYSTICK_INTERVAL_100MS = 10, /**< Interval is 100ms */ + SYSTICK_INTERVAL_1000MS = 1, /**< Interval is 1s */ } systick_interval_t; /** * @} @@ -71,24 +71,24 @@ typedef enum /** @defgroup ALD_Public_Macros Public Macros * @{ */ -#define ALD_MAX_DELAY 0xFFFFFFFF - -#define IS_BIT_SET(reg, bit) (((reg) & (bit)) != RESET) -#define IS_BIT_CLR(reg, bit) (((reg) & (bit)) == RESET) -#define RESET_HANDLE_STATE(x) ((x)->state = 0) -#define __LOCK(x) \ - do { \ - if ((x)->lock == LOCK) { \ - return BUSY; \ - } \ - else { \ - (x)->lock = LOCK; \ - } \ +#define ALD_MAX_DELAY 0xFFFFFFFF + +#define IS_BIT_SET(reg, bit) (((reg) & (bit)) != RESET) +#define IS_BIT_CLR(reg, bit) (((reg) & (bit)) == RESET) +#define RESET_HANDLE_STATE(x) ((x)->state = 0) +#define __LOCK(x) \ + do { \ + if ((x)->lock == LOCK) { \ + return BUSY; \ + } \ + else { \ + (x)->lock = LOCK; \ + } \ } while (0) -#define __UNLOCK(x) \ - do { \ - (x)->lock = UNLOCK; \ +#define __UNLOCK(x) \ + do { \ + (x)->lock = UNLOCK; \ } while (0) /** @@ -98,8 +98,8 @@ typedef enum /** @defgroup ALD_Private_Macros Private Macros * @{ */ -#define IS_PRIO(x) ((x) < 4) -#define IS_SYSTICK_INTERVAL(x) (((x) == SYSTICK_INTERVAL_1MS) || \ +#define IS_PRIO(x) ((x) < 4) +#define IS_SYSTICK_INTERVAL(x) (((x) == SYSTICK_INTERVAL_1MS) || \ ((x) == SYSTICK_INTERVAL_10MS) || \ ((x) == SYSTICK_INTERVAL_100MS) || \ ((x) == SYSTICK_INTERVAL_1000MS)) @@ -116,9 +116,9 @@ typedef enum */ /* Initialization functions */ -void mcu_ald_init(void); -void __init_tick(uint32_t prio); -void systick_interval_select(systick_interval_t value); +void ald_cmu_init(void); +void ald_tick_init(uint32_t prio); +void ald_systick_interval_select(systick_interval_t value); /** * @} @@ -128,17 +128,18 @@ void systick_interval_select(systick_interval_t value); * @{ */ /* Peripheral Control functions */ -void __inc_tick(void); -void __delay_ms(__IO uint32_t delay); -uint32_t __get_tick(void); -void __suspend_tick(void); -void __resume_tick(void); -void systick_irq_cbk(void); -uint32_t get_ald_version(void); -ald_status_t __wait_flag(uint32_t *reg, uint32_t bit, flag_status_t status, uint32_t timeout); -void mcu_irq_config(IRQn_Type irq, uint8_t prio, type_func_t status); -uint32_t mcu_get_tick(void); -uint32_t mcu_get_cpu_id(void); +void ald_inc_tick_weak(void); +void ald_delay_ms(__IO uint32_t delay); +uint32_t ald_get_tick(void); +void ald_suspend_tick(void); +void ald_resume_tick(void); +void ald_systick_irq_cbk(void); +void ald_inc_tick(void); +uint32_t ald_get_ald_version(void); +ald_status_t ald_wait_flag(uint32_t *reg, uint32_t bit, flag_status_t status, uint32_t timeout); +void ald_mcu_irq_config(IRQn_Type irq, uint8_t prio, type_func_t status); +uint32_t ald_mcu_get_tick(void); +uint32_t ald_mcu_get_cpu_id(void); /** * @} diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_acmp.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_acmp.c similarity index 74% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_acmp.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_acmp.c index 0ea7a7c0eb..3057d7d246 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_acmp.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_acmp.c @@ -42,7 +42,7 @@ * the configuration information for the specified ACMP module. * @retval Status, see @ref ald_status_t. */ -ald_status_t acmp_init(acmp_handle_t *hperh) +ald_status_t ald_acmp_init(acmp_handle_t *hperh) { uint32_t tmp = 0; @@ -67,7 +67,7 @@ ald_status_t acmp_init(acmp_handle_t *hperh) tmp = hperh->perh->CON; tmp |= ((hperh->init.mode << ACMP_CON_MODSEL_POSS) | (hperh->init.warm_time << ACMP_CON_WARMUPT_POSS) | - (hperh->init.inactval << ACMP_CON_INACTV_POS)); + (hperh->init.inactval << ACMP_CON_INACTV_POS) | (hperh->init.hystsel << ACMP_CON_HYSTSEL_POSS)); hperh->perh->CON = tmp; @@ -85,33 +85,42 @@ ald_status_t acmp_init(acmp_handle_t *hperh) switch (hperh->init.edge) { - case ACMP_EDGE_NONE: - CLEAR_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK); - CLEAR_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK); - break; - - case ACMP_EDGE_FALL: - SET_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK); - CLEAR_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK); - break; - - case ACMP_EDGE_RISE: - CLEAR_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK); - SET_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK); - break; - - case ACMP_EDGE_ALL: - SET_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK); - SET_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK); - break; - - default: - break; + case ACMP_EDGE_NONE: + CLEAR_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK); + CLEAR_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK); + break; + + case ACMP_EDGE_FALL: + SET_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK); + CLEAR_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK); + break; + + case ACMP_EDGE_RISE: + CLEAR_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK); + SET_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK); + break; + + case ACMP_EDGE_ALL: + SET_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK); + SET_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK); + break; + + default: + break; } SET_BIT(hperh->perh->CON, ACMP_CON_EN_MSK); - while (READ_BIT(hperh->perh->STAT, ACMP_STAT_ACT_MSK) == 0); + tmp = 0; + + while (READ_BIT(hperh->perh->STAT, ACMP_STAT_ACT_MSK) == 0) + { + if (tmp++ >= 600000) + { + __UNLOCK(hperh); + return ERROR; + } + } __UNLOCK(hperh); return OK; @@ -136,7 +145,7 @@ ald_status_t acmp_init(acmp_handle_t *hperh) * - DISABLE * @retval Status, see @ref ald_status_t. */ -ald_status_t acmp_interrupt_config(acmp_handle_t *hperh, acmp_it_t it, type_func_t state) +ald_status_t ald_acmp_interrupt_config(acmp_handle_t *hperh, acmp_it_t it, type_func_t state) { assert_param(IS_ACMP_TYPE(hperh->perh)); assert_param(IS_ACMP_IT_TYPE(it)); @@ -154,6 +163,27 @@ ald_status_t acmp_interrupt_config(acmp_handle_t *hperh, acmp_it_t it, type_func return OK; } +/** + * @brief Checks whether the specified ACMP interrupt has set or not. + * @param hperh: Pointer to a acmp_handle_t structure that contains + * the configuration information for the specified ACMP module. + * @param it: Specifies the ACMP interrupt sources to be enabled or disabled. + * This parameter can be one of the @ref acmp_it_t. + * @retval it_status_t + * - SET + * - RESET + */ +it_status_t ald_acmp_get_it_status(acmp_handle_t *hperh, acmp_it_t it) +{ + assert_param(IS_ACMP_TYPE(hperh->perh)); + assert_param(IS_ACMP_IT_TYPE(it)); + + if (hperh->perh->IEV & it) + return SET; + else + return RESET; +} + /** * @brief Checks whether the specified ACMP interrupt has occurred or not. * @param hperh: Pointer to a acmp_handle_t structure that contains @@ -164,7 +194,7 @@ ald_status_t acmp_interrupt_config(acmp_handle_t *hperh, acmp_it_t it, type_func * - SET * - RESET */ -it_status_t acmp_get_flag_status(acmp_handle_t *hperh, acmp_flag_t flag) +it_status_t ald_acmp_get_flag_status(acmp_handle_t *hperh, acmp_flag_t flag) { assert_param(IS_ACMP_TYPE(hperh->perh)); assert_param(IS_ACMP_FLAG_TYPE(flag)); @@ -185,7 +215,7 @@ it_status_t acmp_get_flag_status(acmp_handle_t *hperh, acmp_flag_t flag) * This parameter can be one of the @ref acmp_it_t. * @retval Status, see @ref ald_status_t. */ -ald_status_t acmp_clear_flag_status(acmp_handle_t *hperh, acmp_flag_t flag) +ald_status_t ald_acmp_clear_flag_status(acmp_handle_t *hperh, acmp_flag_t flag) { assert_param(IS_ACMP_TYPE(hperh->perh)); assert_param(IS_ACMP_FLAG_TYPE(flag)); @@ -225,7 +255,7 @@ ald_status_t acmp_set_it_mask(acmp_handle_t *hperh, acmp_it_t it) * - SET * - RESET */ -flag_status_t acmp_get_status(acmp_handle_t *hperh, acmp_status_t status) +flag_status_t ald_acmp_get_status(acmp_handle_t *hperh, acmp_status_t status) { assert_param(IS_ACMP_TYPE(hperh->perh)); assert_param(IS_ACMP_STATUS_TYPE(status)); @@ -253,20 +283,22 @@ flag_status_t acmp_get_status(acmp_handle_t *hperh, acmp_status_t status) * the configuration information for the specified ACMP module. * @retval None */ -void acmp_irq_handle(acmp_handle_t *hperh) +void ald_acmp_irq_handler(acmp_handle_t *hperh) { - if (acmp_get_flag_status(hperh, ACMP_FLAG_WARMUP) == SET) + if ((ald_acmp_get_flag_status(hperh, ACMP_FLAG_WARMUP) == SET) && (ald_acmp_get_it_status(hperh, ACMP_IT_WARMUP) == SET)) { if (hperh->acmp_warmup_cplt_cbk) hperh->acmp_warmup_cplt_cbk(hperh); - acmp_clear_flag_status(hperh, ACMP_FLAG_WARMUP); + + ald_acmp_clear_flag_status(hperh, ACMP_FLAG_WARMUP); } - if (acmp_get_flag_status(hperh, ACMP_FLAG_EDGE) == SET) + if ((ald_acmp_get_flag_status(hperh, ACMP_FLAG_EDGE) == SET) && (ald_acmp_get_it_status(hperh, ACMP_IT_EDGE) == SET)) { if (hperh->acmp_edge_cplt_cbk) hperh->acmp_edge_cplt_cbk(hperh); - acmp_clear_flag_status(hperh, ACMP_FLAG_EDGE); + + ald_acmp_clear_flag_status(hperh, ACMP_FLAG_EDGE); } return; @@ -280,7 +312,7 @@ void acmp_irq_handle(acmp_handle_t *hperh) * the configutation information for acmp output. * @retval Status, see @ref ald_status_t. */ -ald_status_t acmp_out_config(acmp_handle_t *hperh, acmp_output_config_t *config) +ald_status_t ald_acmp_out_config(acmp_handle_t *hperh, acmp_output_config_t *config) { if (hperh == NULL) return ERROR; @@ -290,11 +322,9 @@ ald_status_t acmp_out_config(acmp_handle_t *hperh, acmp_output_config_t *config) assert_param(IS_ACMP_TYPE(hperh->perh)); assert_param(IS_ACMP_INVERT_TYPE(config->gpio_inv)); - assert_param(IS_ACMP_LOCATION_TYPE(config->location)); assert_param(IS_ACMP_OUT_FUNC_TYPE(config->out_func)); __LOCK(hperh); - hperh->perh->PORT = config->location; hperh->perh->CON |= (config->gpio_inv << ACMP_CON_OUTINV_POS); hperh->perh->PORT = config->out_func; __UNLOCK(hperh); @@ -308,7 +338,7 @@ ald_status_t acmp_out_config(acmp_handle_t *hperh, acmp_output_config_t *config) * the configuration information for the specified ACMP module. * @retval output value. */ -uint8_t acmp_out_result(acmp_handle_t *hperh) +uint8_t ald_acmp_out_result(acmp_handle_t *hperh) { assert_param(IS_ACMP_TYPE(hperh->perh)); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_adc.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_adc.c similarity index 69% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_adc.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_adc.c index 95d707dfda..2019e5a948 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_adc.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_adc.c @@ -71,7 +71,7 @@ * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_init(adc_handle_t *hperh) +ald_status_t ald_adc_init(adc_handle_t *hperh) { ald_status_t tmp_status = OK; @@ -85,20 +85,49 @@ ald_status_t adc_init(adc_handle_t *hperh) assert_param(IS_ADC_NEG_REF_VOLTAGE_TYPE(hperh->init.neg_ref)); assert_param(IS_POS_REF_VOLTAGE_TYPE(hperh->init.pos_ref)); assert_param(IS_ADC_CONV_RES_TYPE(hperh->init.conv_res)); - assert_param(IS_ADC_NBR_OF_NM_TYPE(hperh->init.conv_nbr)); + assert_param(IS_ADC_NCH_LEN_TYPE(hperh->init.nch_len)); + assert_param(IS_ADC_DISC_MODE_TYPE(hperh->init.disc_mode)); assert_param(IS_ADC_DISC_NBR_TYPE(hperh->init.disc_nbr)); assert_param(IS_FUNC_STATE(hperh->init.cont_mode)); - assert_param(IS_FUNC_STATE(hperh->init.disc_mode)); - assert_param(IS_ADC_NCHESEL_MODE_TYPE(hperh->init.nche_mode)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->nm_trig_mode)); + assert_param(IS_ADC_NCHESEL_MODE_TYPE(hperh->init.nche_sel)); if (hperh->state == ADC_STATE_RESET) { hperh->error_code = ADC_ERROR_NONE; - hperh->lock = UNLOCK; + hperh->lock = UNLOCK; + } + + if ((hperh->init.pos_ref == ADC_POS_REF_VDD) && (hperh->init.neg_ref == ADC_NEG_REF_VSS)) + { + ADC_ENABLE(hperh); + + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VRNSEL_MSK, hperh->init.neg_ref << ADC_CCR_VRNSEL_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VRPSEL_MSK, hperh->init.pos_ref << ADC_CCR_VRPSEL_POSS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VCMBUFEN_MSK, 1 << ADC_CCR_VCMBUFEN_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_IREFEN_MSK, 1 << ADC_CCR_IREFEN_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VREFEN_MSK, 1 << ADC_CCR_VREFEN_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_CKDIV_MSK, 6 << ADC_CCR_CKDIV_POSS); + MODIFY_REG(hperh->perh->CON1, ADC_CON1_ALIGN_MSK, ADC_DATAALIGN_RIGHT << ADC_CON1_ALIGN_POS); + MODIFY_REG(hperh->perh->CON0, ADC_CON0_RSEL_MSK, ADC_CONV_RES_12 << ADC_CON0_RSEL_POSS); + MODIFY_REG(hperh->perh->CON1, ADC_CON1_CM_MSK, DISABLE << ADC_CON1_CM_POS); + MODIFY_REG(hperh->perh->NCHS1, ADC_NCHS1_NS1_MSK, ADC_CHANNEL_18 << ADC_NCHS1_NS1_POSS); + + hperh->perh->SMPT2 = 0x30; + + /* Start adc normal convert */ + SET_BIT(hperh->perh->CON1, ADC_CON1_NCHTRG_MSK); + + /* Wait convert finish */ + while (!READ_BIT(hperh->perh->STAT, ADC_STAT_NCHE_MSK)); + + hperh->vdd_value = (hperh->perh->NCHDR & 0xfff); + + /* Get calibration VDD value */ + hperh->vdd_value = 2000 * 4096 / hperh->vdd_value; } ADC_DISABLE(hperh); + ald_adc_reset(hperh); hperh->state = ADC_STATE_BUSY_INTERNAL; MODIFY_REG(hperh->perh->CON1, ADC_CON1_ALIGN_MSK, hperh->init.data_align << ADC_CON1_ALIGN_POS); MODIFY_REG(hperh->perh->CON1, ADC_CON1_CM_MSK, hperh->init.cont_mode << ADC_CON1_CM_POS); @@ -106,32 +135,28 @@ ald_status_t adc_init(adc_handle_t *hperh) MODIFY_REG(hperh->perh->CON0, ADC_CON0_RSEL_MSK, hperh->init.conv_res << ADC_CON0_RSEL_POSS); /* Enable discontinuous mode only if continuous mode is enabled */ - if (hperh->init.disc_mode == ENABLE) + if (hperh->init.disc_mode == ADC_NCH_DISC_EN) { - if (hperh->init.cont_mode == ENABLE) - { - SET_BIT(hperh->perh->CON0, ADC_CON0_NCHDCEN_MSK); - MODIFY_REG(hperh->perh->CON0, ADC_CON0_ETRGN_MSK, hperh->init.disc_nbr << ADC_CON0_ETRGN_POSS); - MODIFY_REG(hperh->perh->CHSL, ADC_CHSL_NSL_MSK, hperh->init.conv_nbr << ADC_CHSL_NSL_POSS); - } - else - { - hperh->state |= ADC_STATE_ERROR; - hperh->error_code |= ADC_ERROR_INTERNAL; - tmp_status = ERROR; - } + hperh->init.scan_mode = ENABLE; + SET_BIT(hperh->perh->CON0, ADC_CON0_NCHDCEN_MSK); + MODIFY_REG(hperh->perh->CON0, ADC_CON0_ETRGN_MSK, hperh->init.disc_nbr << ADC_CON0_ETRGN_POSS); + } + else if (hperh->init.disc_mode == ADC_ICH_DISC_EN) + { + hperh->init.scan_mode = ENABLE; + SET_BIT(hperh->perh->CON0, ADC_CON0_ICHDCEN_MSK); + MODIFY_REG(hperh->perh->CON0, ADC_CON0_ETRGN_MSK, hperh->init.disc_nbr << ADC_CON0_ETRGN_POSS); } else { CLEAR_BIT(hperh->perh->CON0, ADC_CON0_NCHDCEN_MSK); + CLEAR_BIT(hperh->perh->CON0, ADC_CON0_ICHDCEN_MSK); } - if (hperh->init.scan_mode == ADC_SCAN_ENABLE) - MODIFY_REG(hperh->perh->CHSL, ADC_CHSL_NSL_MSK, hperh->init.conv_nbr << ADC_CHSL_NSL_POSS); - - if (hperh->init.cont_mode == ENABLE) - MODIFY_REG(hperh->perh->CHSL, ADC_CHSL_NSL_MSK, hperh->init.conv_nbr << ADC_CHSL_NSL_POSS); + if ((hperh->init.scan_mode == ENABLE) || (hperh->init.disc_mode == ADC_NCH_DISC_EN)) + MODIFY_REG(hperh->perh->CHSL, ADC_CHSL_NSL_MSK, hperh->init.nch_len << ADC_CHSL_NSL_POSS); + MODIFY_REG(hperh->perh->CON0, ADC_CON0_SCANEN_MSK, hperh->init.scan_mode << ADC_CON0_SCANEN_POS); MODIFY_REG(hperh->perh->CCR, ADC_CCR_GAINCALEN_MSK, DISABLE << ADC_CCR_GAINCALEN_POS); MODIFY_REG(hperh->perh->CCR, ADC_CCR_OFFCALEN_MSK, DISABLE << ADC_CCR_OFFCALEN_POS); MODIFY_REG(hperh->perh->CCR, ADC_CCR_DIFFEN_MSK, DISABLE << ADC_CCR_DIFFEN_POS); @@ -144,20 +169,17 @@ ald_status_t adc_init(adc_handle_t *hperh) MODIFY_REG(hperh->perh->CCR, ADC_CCR_CKDIV_MSK, hperh->init.clk_div << ADC_CCR_CKDIV_POSS); MODIFY_REG(hperh->perh->CCR, ADC_CCR_VRNSEL_MSK, hperh->init.neg_ref << ADC_CCR_VRNSEL_POS); MODIFY_REG(hperh->perh->CCR, ADC_CCR_VRPSEL_MSK, hperh->init.pos_ref << ADC_CCR_VRPSEL_POSS); - MODIFY_REG(hperh->perh->CON1, ADC_CON1_NCHESEL_MSK, hperh->init.nche_mode << ADC_CON1_NCHESEL_POS); - - if (hperh->nm_trig_mode != ADC_TRIG_SOFT) - pis_create(&hperh->reg_pis_handle); + MODIFY_REG(hperh->perh->CON1, ADC_CON1_NCHESEL_MSK, hperh->init.nche_sel << ADC_CON1_NCHESEL_POS); if (tmp_status == OK) { hperh->error_code = ADC_ERROR_NONE; - hperh->state |= ADC_STATE_READY; - hperh->state &= ~(ADC_STATE_ERROR | ADC_STATE_NM_BUSY + hperh->state |= ADC_STATE_READY; + hperh->state &= ~(ADC_STATE_ERROR | ADC_STATE_NM_BUSY | ADC_STATE_IST_BUSY | ADC_STATE_BUSY_INTERNAL); } - adc_interrupt_config(hperh, ADC_IT_OVR, ENABLE); + ald_adc_interrupt_config(hperh, ADC_IT_OVR, ENABLE); return tmp_status; } @@ -168,7 +190,7 @@ ald_status_t adc_init(adc_handle_t *hperh) * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_reset(adc_handle_t *hperh) +ald_status_t ald_adc_reset(adc_handle_t *hperh) { if (hperh == NULL) return ERROR; @@ -177,12 +199,12 @@ ald_status_t adc_reset(adc_handle_t *hperh) ADC_DISABLE(hperh); - adc_clear_flag_status(hperh, ADC_FLAG_AWD); - adc_clear_flag_status(hperh, ADC_FLAG_NH); - adc_clear_flag_status(hperh, ADC_FLAG_IH); - adc_clear_flag_status(hperh, ADC_FLAG_OVR); - adc_clear_flag_status(hperh, ADC_FLAG_NHS); - adc_clear_flag_status(hperh, ADC_FLAG_IHS); + ald_adc_clear_flag_status(hperh, ADC_FLAG_AWD); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_ICH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_OVR); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCHS); + ald_adc_clear_flag_status(hperh, ADC_FLAG_ICHS); WRITE_REG(hperh->perh->CON0, 0x0); WRITE_REG(hperh->perh->CON1, 0x0); @@ -202,12 +224,6 @@ ald_status_t adc_reset(adc_handle_t *hperh) WRITE_REG(hperh->perh->SMPT2, 0x0); WRITE_REG(hperh->perh->CHSL, 0x0); - if (hperh->nm_trig_mode != ADC_TRIG_SOFT) - pis_destroy(&hperh->reg_pis_handle); - - if (hperh->ist_trig_mode != ADC_TRIG_SOFT) - pis_destroy(&hperh->inj_pis_handle); - hperh->state = ADC_STATE_RESET; hperh->error_code = ADC_ERROR_NONE; return OK; @@ -227,12 +243,11 @@ ald_status_t adc_reset(adc_handle_t *hperh) * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_normal_start(adc_handle_t *hperh) +ald_status_t ald_adc_normal_start(adc_handle_t *hperh) { if (hperh == NULL) return ERROR; - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->nm_trig_mode)); assert_param(IS_ADC_TYPE(hperh->perh)); __LOCK(hperh); @@ -240,10 +255,9 @@ ald_status_t adc_normal_start(adc_handle_t *hperh) hperh->state &= ~(ADC_STATE_READY | ADC_STATE_NM_EOC); hperh->state |= ADC_STATE_NM_BUSY; __UNLOCK(hperh); - adc_clear_flag_status(hperh, ADC_FLAG_NH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCH); - if (hperh->nm_trig_mode == ADC_TRIG_SOFT) - SET_BIT(hperh->perh->CON1, ADC_CON1_NCHTRG_MSK); + SET_BIT(hperh->perh->CON1, ADC_CON1_NCHTRG_MSK); return OK; } @@ -253,14 +267,13 @@ ald_status_t adc_normal_start(adc_handle_t *hperh) * case of auto_injection mode), disable ADC peripheral. * @note: ADC peripheral disable is forcing stop of potential * conversion on insert group. If insert group is under use, it - * should be preliminarily stopped using adc_insert_stop function. + * should be preliminarily stopped using ald_adc_insert_stop function. * @param hperh: Pointer to a adc_handle_t structure that contains * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_normal_stop(adc_handle_t *hperh) +ald_status_t ald_adc_normal_stop(adc_handle_t *hperh) { - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->nm_trig_mode)); assert_param(IS_ADC_TYPE(hperh->perh)); __LOCK(hperh); @@ -285,18 +298,19 @@ ald_status_t adc_normal_stop(adc_handle_t *hperh) * @param timeout: Timeout value in millisecond. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_normal_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout) +ald_status_t ald_adc_normal_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout) { uint32_t tickstart = 0; assert_param(IS_ADC_TYPE(hperh->perh)); - tickstart = __get_tick(); + tickstart = ald_get_tick(); + while (!(READ_BIT(hperh->perh->STAT, ADC_STAT_NCHE_MSK))) { if (timeout != ALD_MAX_DELAY) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->state |= ADC_STATE_TIMEOUT; __UNLOCK(hperh); @@ -305,20 +319,19 @@ ald_status_t adc_normal_poll_for_conversion(adc_handle_t *hperh, uint32_t timeou } } - adc_clear_flag_status(hperh, ADC_FLAG_NHS); - adc_clear_flag_status(hperh, ADC_FLAG_NH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCHS); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCH); hperh->state |= ADC_STATE_NM_EOC; - if ((hperh->nm_trig_mode == ADC_TRIG_SOFT) - && (hperh->init.cont_mode == DISABLE) - && (hperh->init.scan_mode == ADC_SCAN_DISABLE)) + if ((hperh->init.cont_mode == DISABLE) && (hperh->init.scan_mode == DISABLE)) { hperh->state &= ~ADC_STATE_NM_BUSY; if ((hperh->state & ADC_STATE_IST_BUSY) == 0) hperh->state |= ADC_STATE_READY; } + return OK; } @@ -332,20 +345,20 @@ ald_status_t adc_normal_poll_for_conversion(adc_handle_t *hperh, uint32_t timeou * @param timeout: Timeout value in millisecond. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_poll_for_event(adc_handle_t *hperh, adc_event_type_t event_type, uint32_t timeout) +ald_status_t ald_adc_poll_for_event(adc_handle_t *hperh, adc_event_type_t event_type, uint32_t timeout) { uint32_t tickstart = 0; assert_param(IS_ADC_TYPE(hperh->perh)); assert_param(IS_ADC_EVENT_TYPE(event_type)); - tickstart = __get_tick(); + tickstart = ald_get_tick(); - while (adc_get_flag_status(hperh, (adc_flag_t)event_type) == RESET) + while (ald_adc_get_flag_status(hperh, (adc_flag_t)event_type) == RESET) { if (timeout != ALD_MAX_DELAY) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->state |= ADC_STATE_TIMEOUT; __UNLOCK(hperh); @@ -367,14 +380,14 @@ ald_status_t adc_poll_for_event(adc_handle_t *hperh, adc_event_type_t event_type * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_normal_start_by_it(adc_handle_t *hperh) +ald_status_t ald_adc_normal_start_by_it(adc_handle_t *hperh) { assert_param(IS_ADC_TYPE(hperh->perh)); __LOCK(hperh); ADC_ENABLE(hperh); - hperh->state &= ~(ADC_STATE_READY | ADC_STATE_NM_EOC); - hperh->state |= ADC_STATE_NM_BUSY; + hperh->state &= ~(ADC_STATE_READY | ADC_STATE_NM_EOC); + hperh->state |= ADC_STATE_NM_BUSY; hperh->error_code = ADC_ERROR_NONE; if (READ_BIT(hperh->perh->CON0, ADC_CON0_IAUTO_MSK)) @@ -384,11 +397,10 @@ ald_status_t adc_normal_start_by_it(adc_handle_t *hperh) } __UNLOCK(hperh); - adc_clear_flag_status(hperh, ADC_FLAG_NH); - adc_interrupt_config(hperh, ADC_IT_NH, ENABLE); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCH); + ald_adc_interrupt_config(hperh, ADC_IT_NCH, ENABLE); - if (hperh->nm_trig_mode == ADC_TRIG_SOFT) - SET_BIT(hperh->perh->CON1, ADC_CON1_NCHTRG_MSK); + SET_BIT(hperh->perh->CON1, ADC_CON1_NCHTRG_MSK); return OK; } @@ -401,13 +413,13 @@ ald_status_t adc_normal_start_by_it(adc_handle_t *hperh) * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_normal_stop_by_it(adc_handle_t *hperh) +ald_status_t ald_adc_normal_stop_by_it(adc_handle_t *hperh) { assert_param(IS_ADC_TYPE(hperh->perh)); __LOCK(hperh); ADC_DISABLE(hperh); - adc_interrupt_config(hperh, ADC_IT_NH, DISABLE); + ald_adc_interrupt_config(hperh, ADC_IT_NCH, DISABLE); hperh->state |= ADC_STATE_READY; hperh->state &= ~(ADC_STATE_NM_BUSY | ADC_STATE_IST_BUSY); @@ -426,7 +438,7 @@ ald_status_t adc_normal_stop_by_it(adc_handle_t *hperh) * @param channel: The DMA channel * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_start_by_dma(adc_handle_t *hperh, uint16_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_adc_start_by_dma(adc_handle_t *hperh, uint16_t *buf, uint16_t size, uint8_t channel) { if ((hperh == NULL) || (buf == NULL) || (size == 0) || (channel > 5)) return ERROR; @@ -454,6 +466,7 @@ ald_status_t adc_start_by_dma(adc_handle_t *hperh, uint16_t *buf, uint16_t size, hperh->state &= ~(ADC_STATE_ERROR); hperh->error_code = ADC_ERROR_NONE; } + __UNLOCK(hperh); if (hperh->hdma.perh == NULL) @@ -464,7 +477,7 @@ ald_status_t adc_start_by_dma(adc_handle_t *hperh, uint16_t *buf, uint16_t size, hperh->hdma.err_cbk = adc_dma_error; hperh->hdma.err_arg = hperh; - dma_config_struct(&hperh->hdma.config); + ald_dma_config_struct(&hperh->hdma.config); hperh->hdma.config.src = (void *)&hperh->perh->NCHDR; hperh->hdma.config.dst = (void *)buf; hperh->hdma.config.size = size; @@ -474,17 +487,9 @@ ald_status_t adc_start_by_dma(adc_handle_t *hperh, uint16_t *buf, uint16_t size, hperh->hdma.config.msel = DMA_MSEL_ADC0; hperh->hdma.config.msigsel = DMA_MSIGSEL_ADC; hperh->hdma.config.channel = channel; - dma_config_basic(&hperh->hdma); - - hperh->hpis.init.producer_src = PIS_ADC1_REGULAT; - hperh->hpis.init.producer_clk = PIS_CLK_PCLK2; - hperh->hpis.init.producer_edge = PIS_EDGE_NONE; - hperh->hpis.init.consumer_trig = PIS_CH7_DAC_CH0; - hperh->hpis.init.consumer_clk = PIS_CLK_PCLK1; - pis_create(&hperh->hpis); + ald_dma_config_basic(&hperh->hdma); - if (hperh->nm_trig_mode == ADC_TRIG_SOFT) - SET_BIT(hperh->perh->CON1, ADC_CON1_NCHTRG_MSK); + SET_BIT(hperh->perh->CON1, ADC_CON1_NCHTRG_MSK); return OK; } @@ -503,7 +508,7 @@ ald_status_t adc_stop_dma(adc_handle_t *hperh) __LOCK(hperh); ADC_DISABLE(hperh); - pis_destroy(&hperh->hpis); + ald_pis_destroy(&hperh->hpis); hperh->state &= ~(ADC_STATE_NM_BUSY | ADC_STATE_IST_BUSY); hperh->state |= ADC_STATE_READY; @@ -521,9 +526,10 @@ static void adc_dma_timer_trigger_cplt(void *arg) adc_timer_config_t *hperh = (adc_timer_config_t *)arg; ADC_DISABLE(&hperh->lh_adc); - timer_base_stop(&hperh->lh_timer); + ald_timer_base_stop(&hperh->lh_timer); __UNLOCK(hperh); + if (hperh->lh_adc.adc_reg_cplt_cbk != NULL) hperh->lh_adc.adc_reg_cplt_cbk(&hperh->lh_adc); @@ -536,22 +542,32 @@ static void adc_dma_timer_trigger_cplt(void *arg) * contains the configuration information for the specified function. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_timer_trigger_adc_by_dma(adc_timer_config_t *config) +ald_status_t ald_adc_timer_trigger_adc_by_dma(adc_timer_config_t *config) { __LOCK(config); config->lh_pis.perh = PIS; config->lh_pis.init.producer_clk = PIS_CLK_PCLK1; config->lh_pis.init.producer_edge = PIS_EDGE_NONE; - config->lh_pis.init.consumer_clk = PIS_CLK_PCLK1; + config->lh_pis.init.consumer_clk = PIS_CLK_PCLK2; + +#if defined (ES32F065x) - if (config->p_timer == TIMER0) + if (config->p_timer == AD16C4T0) config->lh_pis.init.producer_src = PIS_TIMER0_UPDATA; - else if (config->p_timer == TIMER1) + +#elif defined(ES32F033x) || defined (ES32F093x) + + if (config->p_timer == GP16C4T0) + config->lh_pis.init.producer_src = PIS_TIMER0_UPDATA; + +#endif + + else if (config->p_timer == BS16T0) config->lh_pis.init.producer_src = PIS_TIMER1_UPDATA; - else if (config->p_timer == TIMER2) + else if (config->p_timer == GP16C2T0) config->lh_pis.init.producer_src = PIS_TIMER2_UPDATA; - else if (config->p_timer == TIMER3) + else if (config->p_timer == GP16C2T1) config->lh_pis.init.producer_src = PIS_TIMER3_UPDATA; else return ERROR; @@ -563,27 +579,27 @@ ald_status_t adc_timer_trigger_adc_by_dma(adc_timer_config_t *config) else return ERROR; - pis_create(&config->lh_pis); + ald_pis_create(&config->lh_pis); /* Initialize TIMER0 */ config->lh_timer.perh = config->p_timer; config->lh_timer.init.prescaler = 0; config->lh_timer.init.mode = TIMER_CNT_MODE_UP; - config->lh_timer.init.period = ((cmu_get_pclk1_clock() / 1000000) * config->time); + config->lh_timer.init.period = ((ald_cmu_get_pclk1_clock() / 1000000) * config->time); config->lh_timer.init.clk_div = TIMER_CLOCK_DIV1; config->lh_timer.init.re_cnt = 0; - timer_base_init(&config->lh_timer); + ald_timer_base_init(&config->lh_timer); config->lh_adc.perh = config->p_adc; config->lh_adc.init.data_align = ADC_DATAALIGN_RIGHT; - config->lh_adc.init.scan_mode = ADC_SCAN_DISABLE; + config->lh_adc.init.scan_mode = DISABLE; config->lh_adc.init.cont_mode = DISABLE; - config->lh_adc.init.conv_nbr = ADC_NM_NBR_1; - config->lh_adc.init.disc_mode = DISABLE; + config->lh_adc.init.nch_len = ADC_NCH_LEN_1; + config->lh_adc.init.disc_mode = ADC_ALL_DISABLE; config->lh_adc.init.disc_nbr = ADC_DISC_NBR_1; config->lh_adc.init.conv_res = ADC_CONV_RES_12; config->lh_adc.init.clk_div = ADC_CKDIV_16; - config->lh_adc.init.nche_mode = ADC_NCHESEL_MODE_ONE; + config->lh_adc.init.nche_sel = ADC_NCHESEL_MODE_ONE; config->lh_adc.init.neg_ref = config->n_ref; config->lh_adc.init.pos_ref = config->p_ref; config->lh_adc.adc_reg_cplt_cbk = config->adc_cplt_cbk; @@ -591,19 +607,19 @@ ald_status_t adc_timer_trigger_adc_by_dma(adc_timer_config_t *config) config->lh_adc.adc_out_of_win_cbk = NULL; config->lh_adc.adc_error_cbk = NULL; config->lh_adc.adc_ovr_cbk = NULL; - adc_init(&config->lh_adc); + ald_adc_init(&config->lh_adc); config->lnm_config.channel = config->adc_ch; - config->lnm_config.rank = ADC_NC_RANK_1; - config->lnm_config.sampling_time = ADC_SAMPLETIME_1; - adc_normal_channel_config(&config->lh_adc, &config->lnm_config); + config->lnm_config.rank = ADC_NCH_RANK_1; + config->lnm_config.samp_time = ADC_SAMPLETIME_1; + ald_adc_normal_channel_config(&config->lh_adc, &config->lnm_config); config->lh_dma.cplt_cbk = adc_dma_timer_trigger_cplt; config->lh_dma.cplt_arg = config; config->lh_dma.err_cbk = adc_dma_error; config->lh_dma.err_arg = &config->lh_adc; - dma_config_struct(&config->lh_dma.config); + ald_dma_config_struct(&config->lh_dma.config); config->lh_dma.perh = DMA0; config->lh_dma.config.src = (void *)&config->lh_adc.perh->NCHDR; config->lh_dma.config.dst = (void *)config->buf; @@ -614,10 +630,10 @@ ald_status_t adc_timer_trigger_adc_by_dma(adc_timer_config_t *config) config->lh_dma.config.msel = config->p_adc == ADC0 ? DMA_MSEL_ADC0 : DMA_MSEL_ADC1; config->lh_dma.config.msigsel = DMA_MSIGSEL_ADC; config->lh_dma.config.channel = config->dma_ch; - dma_config_basic(&config->lh_dma); + ald_dma_config_basic(&config->lh_dma); ADC_ENABLE(&config->lh_adc); - timer_base_start(&config->lh_timer); + ald_timer_base_start(&config->lh_timer); return OK; } @@ -629,7 +645,7 @@ ald_status_t adc_timer_trigger_adc_by_dma(adc_timer_config_t *config) * the configuration information for the specified ADC module. * @retval ADC group normal conversion data */ -uint32_t adc_normal_get_value(adc_handle_t *hperh) +uint32_t ald_adc_normal_get_value(adc_handle_t *hperh) { assert_param(IS_ADC_TYPE(hperh->perh)); @@ -637,6 +653,54 @@ uint32_t adc_normal_get_value(adc_handle_t *hperh) return hperh->perh->NCHDR; } +/** + * @brief The pos reference is VDD and neg reference is VSS, + * get adc normal group result and convert voltage value. + * @param hperh: Pointer to a adc_handle_t structure that contains + * the configuration information for the specified ADC module. + * @retval ADC group normal voltage value,the unit is mV. + */ +uint32_t ald_adc_get_vdd_value(adc_handle_t *hperh) +{ + uint32_t value = 0; + + if ((hperh->init.pos_ref != ADC_POS_REF_VDD) || (hperh->init.neg_ref != ADC_NEG_REF_VSS)) + return 0; + + __LOCK(hperh); + ADC_ENABLE(hperh); + + /* Set adc and measure 2V */ + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VCMBUFEN_MSK, ENABLE << ADC_CCR_VCMBUFEN_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_IREFEN_MSK, ENABLE << ADC_CCR_IREFEN_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VREFEN_MSK, ENABLE << ADC_CCR_VREFEN_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VRBUFEN_MSK, DISABLE << ADC_CCR_VRBUFEN_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VREFOEN_MSK, DISABLE << ADC_CCR_VREFOEN_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_PWRMODSEL_MSK, ENABLE << ADC_CCR_PWRMODSEL_POS); + MODIFY_REG(hperh->perh->CCR, ADC_CCR_CKDIV_MSK, 6 << ADC_CCR_CKDIV_POSS); + MODIFY_REG(hperh->perh->CON0, ADC_CON1_ALIGN_MSK, ADC_DATAALIGN_RIGHT << ADC_CON1_ALIGN_POS); + MODIFY_REG(hperh->perh->CON0, ADC_CON0_RSEL_MSK, ADC_CONV_RES_12 << ADC_CON0_RSEL_POSS); + MODIFY_REG(hperh->perh->CON1, ADC_CON1_CM_MSK, DISABLE << ADC_CON1_CM_POS); + MODIFY_REG(hperh->perh->NCHS1, ADC_NCHS1_NS1_MSK, ADC_CHANNEL_18 << ADC_NCHS1_NS1_POSS); + + hperh->perh->SMPT2 = 0x30; + /* Start adc normal convert */ + SET_BIT(hperh->perh->CON1, ADC_CON1_NCHTRG_MSK); + + /* Wait convert finish */ + while (!READ_BIT(hperh->perh->STAT, ADC_STAT_NCHE_MSK)); + + value = (hperh->perh->NCHDR & 0xfff); + /* Get calibration VDD value */ + value = 2000 * 4096 / value; + hperh->vdd_value = value; + + MODIFY_REG(hperh->perh->CCR, ADC_CCR_VRBUFEN_MSK, ENABLE << ADC_CCR_VRBUFEN_POS); + __UNLOCK(hperh); + + return value; +} + /** * @brief Enables ADC, starts conversion of insert group. * Interruptions enabled in this function: None. @@ -644,10 +708,9 @@ uint32_t adc_normal_get_value(adc_handle_t *hperh) * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_insert_start(adc_handle_t *hperh) +ald_status_t ald_adc_insert_start(adc_handle_t *hperh) { assert_param(IS_ADC_TYPE(hperh->perh)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->ist_trig_mode)); __LOCK(hperh); ADC_ENABLE(hperh); @@ -658,12 +721,11 @@ ald_status_t adc_insert_start(adc_handle_t *hperh) hperh->error_code = ADC_ERROR_NONE; __UNLOCK(hperh); - adc_clear_flag_status(hperh, ADC_FLAG_IH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_ICH); if (!(READ_BIT(hperh->perh->CON0, ADC_CON0_IAUTO_MSK))) { - if (hperh->ist_trig_mode == ADC_TRIG_SOFT) - SET_BIT(hperh->perh->CON1, ADC_CON1_ICHTRG_MSK); + SET_BIT(hperh->perh->CON1, ADC_CON1_ICHTRG_MSK); } return OK; @@ -673,18 +735,17 @@ ald_status_t adc_insert_start(adc_handle_t *hperh) * @brief Stop conversion of insert channels. Disable ADC peripheral if * no normal conversion is on going. * @note If ADC must be disabled and if conversion is on going on - * normal group, function adc_normal_stop must be used to stop both + * normal group, function ald_adc_normal_stop must be used to stop both * insert and normal groups, and disable the ADC. * @note If insert group mode auto-injection is enabled, - * function adc_normal_stop must be used. + * function ald_adc_normal_stop must be used. * @param hperh: Pointer to a adc_handle_t structure that contains * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_insert_stop(adc_handle_t *hperh) +ald_status_t ald_adc_insert_stop(adc_handle_t *hperh) { assert_param(IS_ADC_TYPE(hperh->perh)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->ist_trig_mode)); __LOCK(hperh); @@ -713,20 +774,19 @@ ald_status_t adc_insert_stop(adc_handle_t *hperh) * @param timeout: Timeout value in millisecond. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_insert_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout) +ald_status_t ald_adc_insert_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout) { uint32_t tickstart; assert_param(IS_ADC_TYPE(hperh->perh)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->ist_trig_mode)); - tickstart = __get_tick(); + tickstart = ald_get_tick(); while (!(READ_BIT(hperh->perh->STAT, ADC_STAT_ICHE_MSK))) { if (timeout != ALD_MAX_DELAY) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->state |= ADC_STATE_TIMEOUT; __UNLOCK(hperh); @@ -735,18 +795,16 @@ ald_status_t adc_insert_poll_for_conversion(adc_handle_t *hperh, uint32_t timeou } } - adc_clear_flag_status(hperh, ADC_FLAG_IHS); - adc_clear_flag_status(hperh, ADC_FLAG_IH); - adc_clear_flag_status(hperh, ADC_FLAG_NH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_ICHS); + ald_adc_clear_flag_status(hperh, ADC_FLAG_ICH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCH); hperh->state |= ADC_STATE_IST_EOC; - if (hperh->ist_trig_mode == ADC_TRIG_SOFT) - { - hperh->state &= ~(ADC_STATE_IST_BUSY); - if ((hperh->state & ADC_STATE_NM_BUSY) == 0) - hperh->state |= ADC_STATE_READY; - } + hperh->state &= ~(ADC_STATE_IST_BUSY); + + if ((hperh->state & ADC_STATE_NM_BUSY) == 0) + hperh->state |= ADC_STATE_READY; hperh->state &= ~(ADC_STATE_TIMEOUT); __UNLOCK(hperh); @@ -761,10 +819,9 @@ ald_status_t adc_insert_poll_for_conversion(adc_handle_t *hperh, uint32_t timeou * the configuration information for the specified ADC module. * @retval Status, see @ref ald_status_t.. */ -ald_status_t adc_insert_start_by_it(adc_handle_t *hperh) +ald_status_t ald_adc_insert_start_by_it(adc_handle_t *hperh) { assert_param(IS_ADC_TYPE(hperh->perh)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->ist_trig_mode)); __LOCK(hperh); ADC_ENABLE(hperh); @@ -775,14 +832,12 @@ ald_status_t adc_insert_start_by_it(adc_handle_t *hperh) hperh->error_code = ADC_ERROR_NONE; __UNLOCK(hperh); - adc_clear_flag_status(hperh, ADC_FLAG_IH); - adc_interrupt_config(hperh, ADC_IT_IH, ENABLE); + ald_adc_clear_flag_status(hperh, ADC_FLAG_ICH); + ald_adc_interrupt_config(hperh, ADC_IT_ICH, ENABLE); if (!(READ_BIT(hperh->perh->CON0, ADC_CON0_IAUTO_MSK))) - { - if (hperh->ist_trig_mode == ADC_TRIG_SOFT) - SET_BIT(hperh->perh->CON1, ADC_CON1_ICHTRG_MSK); - } + SET_BIT(hperh->perh->CON1, ADC_CON1_ICHTRG_MSK); + return OK; } @@ -791,18 +846,17 @@ ald_status_t adc_insert_start_by_it(adc_handle_t *hperh) * end-of-conversion. Disable ADC peripheral if no normal conversion * is on going. * @note If ADC must be disabled and if conversion is on going on - * normal group, function adc_normal_stop must be used to stop both + * normal group, function ald_adc_normal_stop must be used to stop both * insert and normal groups, and disable the ADC. * @note If insert group mode auto-injection is enabled, - * function adc_normal_stop must be used. + * function ald_adc_normal_stop must be used. * @param hperh: Pointer to a adc_handle_t structure that contains * the configuration information for the specified ADC module. * @retval None */ -ald_status_t adc_insert_stop_by_it(adc_handle_t *hperh) +ald_status_t ald_adc_insert_stop_by_it(adc_handle_t *hperh) { assert_param(IS_ADC_TYPE(hperh->perh)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->ist_trig_mode)); __LOCK(hperh); @@ -810,13 +864,13 @@ ald_status_t adc_insert_stop_by_it(adc_handle_t *hperh) && (!(READ_BIT(hperh->perh->CON0, ADC_CON0_IAUTO_MSK)))) { ADC_DISABLE(hperh); - adc_interrupt_config(hperh, ADC_IT_IH, DISABLE); + ald_adc_interrupt_config(hperh, ADC_IT_ICH, DISABLE); hperh->state &= ~(ADC_STATE_NM_BUSY | ADC_STATE_IST_BUSY); hperh->state |= ADC_STATE_READY; } else { - adc_interrupt_config(hperh, ADC_IT_IH, DISABLE); + ald_adc_interrupt_config(hperh, ADC_IT_ICH, DISABLE); hperh->state |= ADC_STATE_ERROR; __UNLOCK(hperh); return ERROR; @@ -838,29 +892,33 @@ ald_status_t adc_insert_stop_by_it(adc_handle_t *hperh) * @arg ADC_INJ_RANK_4: insert Channel4 selected * @retval ADC group insert conversion data */ -uint32_t adc_insert_get_value(adc_handle_t *hperh, adc_ih_rank_t ih_rank) +uint32_t ald_adc_insert_get_value(adc_handle_t *hperh, adc_ich_rank_t ih_rank) { uint32_t tmp; assert_param(IS_ADC_TYPE(hperh->perh)); - assert_param(IS_ADC_IH_RANK_TYPE(ih_rank)); + assert_param(IS_ADC_ICH_RANK_TYPE(ih_rank)); switch (ih_rank) { - case ADC_IH_RANK_1: - tmp = hperh->perh->ICHDR[0]; - break; - case ADC_IH_RANK_2: - tmp = hperh->perh->ICHDR[1]; - break; - case ADC_IH_RANK_3: - tmp = hperh->perh->ICHDR[2]; - break; - case ADC_IH_RANK_4: - tmp = hperh->perh->ICHDR[3]; - break; - default: - break; + case ADC_ICH_RANK_1: + tmp = hperh->perh->ICHDR[0]; + break; + + case ADC_ICH_RANK_2: + tmp = hperh->perh->ICHDR[1]; + break; + + case ADC_ICH_RANK_3: + tmp = hperh->perh->ICHDR[2]; + break; + + case ADC_ICH_RANK_4: + tmp = hperh->perh->ICHDR[3]; + break; + + default: + break; } return tmp; @@ -872,21 +930,18 @@ uint32_t adc_insert_get_value(adc_handle_t *hperh, adc_ih_rank_t ih_rank) * the configuration information for the specified ADC module. * @retval None */ -void adc_irq_handler(adc_handle_t *hperh) +void ald_adc_irq_handler(adc_handle_t *hperh) { assert_param(IS_ADC_TYPE(hperh->perh)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->ist_trig_mode)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->nm_trig_mode)); - if (adc_get_it_status(hperh, ADC_IT_NH) && adc_get_flag_status(hperh, ADC_FLAG_NH)) + if (ald_adc_get_it_status(hperh, ADC_IT_NCH) && ald_adc_get_flag_status(hperh, ADC_FLAG_NCH)) { if ((hperh->state & ADC_STATE_ERROR) == 0) hperh->state |= ADC_STATE_NM_EOC; - if ((hperh->nm_trig_mode == ADC_TRIG_SOFT) - && (hperh->init.cont_mode == DISABLE)) + if (hperh->init.cont_mode == DISABLE) { - adc_interrupt_config(hperh, ADC_IT_NH, DISABLE); + ald_adc_interrupt_config(hperh, ADC_IT_NCH, DISABLE); hperh->state &= ~(ADC_STATE_NM_BUSY); if ((hperh->state & ADC_STATE_IST_BUSY) == 0) @@ -896,46 +951,45 @@ void adc_irq_handler(adc_handle_t *hperh) if (hperh->adc_reg_cplt_cbk != NULL) hperh->adc_reg_cplt_cbk(hperh); - adc_clear_flag_status(hperh, ADC_FLAG_NHS); - adc_clear_flag_status(hperh, ADC_FLAG_NH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCHS); + ald_adc_clear_flag_status(hperh, ADC_FLAG_NCH); } - if (adc_get_it_status(hperh, ADC_IT_IH) && adc_get_flag_status(hperh, ADC_FLAG_IH)) + if (ald_adc_get_it_status(hperh, ADC_IT_ICH) && ald_adc_get_flag_status(hperh, ADC_FLAG_ICH)) { if ((hperh->state & ADC_STATE_ERROR) == 0) hperh->state |= ADC_STATE_IST_EOC; - if ((hperh->ist_trig_mode == ADC_TRIG_SOFT) - || ((!(READ_BIT(hperh->perh->CON0, ADC_CON0_IAUTO_MSK))) - && (hperh->nm_trig_mode == ADC_TRIG_SOFT) - && (hperh->init.cont_mode == DISABLE))) + if ((!(READ_BIT(hperh->perh->CON0, ADC_CON0_IAUTO_MSK))) + && (hperh->init.cont_mode == DISABLE)) { - adc_interrupt_config(hperh, ADC_IT_IH, DISABLE); + ald_adc_interrupt_config(hperh, ADC_IT_ICH, DISABLE); hperh->state &= ~(ADC_STATE_IST_BUSY); if ((hperh->state & ADC_STATE_NM_BUSY) == 0) hperh->state |= ADC_STATE_READY; } + if (hperh->adc_inj_cplt_cbk != NULL) hperh->adc_inj_cplt_cbk(hperh); - adc_clear_flag_status(hperh, ADC_FLAG_IHS); - adc_clear_flag_status(hperh, ADC_FLAG_IH); + ald_adc_clear_flag_status(hperh, ADC_FLAG_ICHS); + ald_adc_clear_flag_status(hperh, ADC_FLAG_ICH); } - if (adc_get_it_status(hperh, ADC_IT_AWD) && adc_get_flag_status(hperh, ADC_FLAG_AWD)) + if (ald_adc_get_it_status(hperh, ADC_IT_AWD) && ald_adc_get_flag_status(hperh, ADC_FLAG_AWD)) { hperh->state |= ADC_STATE_AWD; if (hperh->adc_out_of_win_cbk != NULL) hperh->adc_out_of_win_cbk(hperh); - adc_clear_flag_status(hperh, ADC_FLAG_AWD); + ald_adc_clear_flag_status(hperh, ADC_FLAG_AWD); } - if (adc_get_it_status(hperh, ADC_IT_OVR) && adc_get_flag_status(hperh, ADC_FLAG_OVR)) + if (ald_adc_get_it_status(hperh, ADC_IT_OVR) && ald_adc_get_flag_status(hperh, ADC_FLAG_OVR)) { - adc_clear_flag_status(hperh, ADC_FLAG_OVR); + ald_adc_clear_flag_status(hperh, ADC_FLAG_OVR); hperh->error_code |= ADC_ERROR_OVR; hperh->state |= ADC_STATE_ERROR; @@ -961,26 +1015,26 @@ void adc_irq_handler(adc_handle_t *hperh) * @param config: Structure of ADC channel for normal group. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_normal_channel_config(adc_handle_t *hperh, adc_channel_conf_t *config) +ald_status_t ald_adc_normal_channel_config(adc_handle_t *hperh, adc_nch_conf_t *config) { assert_param(IS_ADC_TYPE(hperh->perh)); assert_param(IS_ADC_CHANNELS_TYPE(config->channel)); - assert_param(IS_ADC_NC_RANK_TYPE(config->rank)); - assert_param(IS_ADC_SAMPLING_TIMES_TYPE(config->sampling_time)); + assert_param(IS_ADC_NCH_RANK_TYPE(config->rank)); + assert_param(IS_ADC_SAMPLING_TIMES_TYPE(config->samp_time)); __LOCK(hperh); - if (config->rank <= ADC_NC_RANK_4) + if (config->rank <= ADC_NCH_RANK_4) { hperh->perh->NCHS1 &= ~(0x1f << ((config->rank - 1) << 3)); hperh->perh->NCHS1 |= (config->channel << ((config->rank - 1) << 3)); } - else if (config->rank <= ADC_NC_RANK_8) + else if (config->rank <= ADC_NCH_RANK_8) { hperh->perh->NCHS2 &= ~(0x1f << ((config->rank - 5) << 3)); hperh->perh->NCHS2 |= (config->channel << ((config->rank - 5) << 3)); } - else if (config->rank <= ADC_NC_RANK_12) + else if (config->rank <= ADC_NCH_RANK_12) { hperh->perh->NCHS3 &= ~(0x1f << ((config->rank - 9) << 3)); hperh->perh->NCHS3 |= (config->channel << ((config->rank - 9) << 3)); @@ -994,12 +1048,12 @@ ald_status_t adc_normal_channel_config(adc_handle_t *hperh, adc_channel_conf_t * if (config->channel <= 15) { hperh->perh->SMPT1 &= ~(0x03 << (config->channel << 1)); - hperh->perh->SMPT1 |= config->sampling_time << (config->channel << 1); + hperh->perh->SMPT1 |= config->samp_time << (config->channel << 1); } else { hperh->perh->SMPT2 &= ~(0x03 << ((config->channel - 16) << 1)); - hperh->perh->SMPT2 |= config->sampling_time << ((config->channel - 16) << 1); + hperh->perh->SMPT2 |= config->samp_time << ((config->channel - 16) << 1); } __UNLOCK(hperh); @@ -1014,51 +1068,53 @@ ald_status_t adc_normal_channel_config(adc_handle_t *hperh, adc_channel_conf_t * * @param config: Structure of ADC channel for insert group. * @retval Status, see @ref ald_status_t. */ -ald_status_t adc_insert_channel_config(adc_handle_t *hperh, adc_ih_conf_t *config) +ald_status_t ald_adc_insert_channel_config(adc_handle_t *hperh, adc_ich_conf_t *config) { uint8_t tmp1, tmp2; ald_status_t tmp_status = OK; assert_param(IS_ADC_TYPE(hperh->perh)); assert_param(IS_ADC_CHANNELS_TYPE(config->channel)); - assert_param(IS_ADC_IH_RANK_TYPE(config->rank)); + assert_param(IS_ADC_ICH_RANK_TYPE(config->rank)); assert_param(IS_ADC_SAMPLING_TIMES_TYPE(config->samp_time)); assert_param(IS_ADC_IST_OFFSET_TYPE(config->offset)); - assert_param(IS_ADC_NBR_OF_IST_TYPE(config->nbr)); - assert_param(IS_FUNC_STATE(config->disc_mode)); + assert_param(IS_ADC_NBR_OF_IST_TYPE(config->ich_len)); assert_param(IS_FUNC_STATE(config->auto_inj)); - assert_param(IS_ADC_TRIG_MODE_TYPE(hperh->ist_trig_mode)); __LOCK(hperh); - if (hperh->init.scan_mode == ADC_SCAN_DISABLE) + if (hperh->init.scan_mode == DISABLE) { switch (config->rank) { - case ADC_IH_RANK_1: - MODIFY_REG(hperh->perh->ICHS, ADC_ICHS_IS1_MSK, config->channel << ADC_ICHS_IS1_POSS); - break; - case ADC_IH_RANK_2: - MODIFY_REG(hperh->perh->ICHS, ADC_ICHS_IS2_MSK, config->channel << ADC_ICHS_IS1_POSS); - break; - case ADC_IH_RANK_3: - MODIFY_REG(hperh->perh->ICHS, ADC_ICHS_IS3_MSK, config->channel << ADC_ICHS_IS1_POSS); - break; - case ADC_IH_RANK_4: - MODIFY_REG(hperh->perh->ICHS, ADC_ICHS_IS4_MSK, config->channel << ADC_ICHS_IS1_POSS); - break; - default: - hperh->state |= ADC_STATE_ERROR; - hperh->error_code |= ADC_ERROR_INTERNAL; - tmp_status = ERROR; - break; + case ADC_ICH_RANK_1: + MODIFY_REG(hperh->perh->ICHS, ADC_ICHS_IS1_MSK, config->channel << ADC_ICHS_IS1_POSS); + break; + + case ADC_ICH_RANK_2: + MODIFY_REG(hperh->perh->ICHS, ADC_ICHS_IS2_MSK, config->channel << ADC_ICHS_IS2_POSS); + break; + + case ADC_ICH_RANK_3: + MODIFY_REG(hperh->perh->ICHS, ADC_ICHS_IS3_MSK, config->channel << ADC_ICHS_IS3_POSS); + break; + + case ADC_ICH_RANK_4: + MODIFY_REG(hperh->perh->ICHS, ADC_ICHS_IS4_MSK, config->channel << ADC_ICHS_IS4_POSS); + break; + + default: + hperh->state |= ADC_STATE_ERROR; + hperh->error_code |= ADC_ERROR_INTERNAL; + tmp_status = ERROR; + break; } } else { - MODIFY_REG(hperh->perh->CHSL, ADC_CHSL_ISL_MSK, config->nbr << ADC_CHSL_ISL_POSS); + MODIFY_REG(hperh->perh->CHSL, ADC_CHSL_ISL_MSK, config->ich_len << ADC_CHSL_ISL_POSS); tmp1 = config->rank ; - tmp2 = config->nbr; + tmp2 = config->ich_len; if (tmp1 <= tmp2) { @@ -1069,28 +1125,21 @@ ald_status_t adc_insert_channel_config(adc_handle_t *hperh, adc_ih_conf_t *confi else { hperh->perh->ICHS &= ~(0x1f << ((tmp1 - 1) << 3)); + hperh->perh->ICHS |= config->channel + << ((tmp1 - 1) << 3); } } if (config->auto_inj == ENABLE) { - if (hperh->ist_trig_mode == ADC_TRIG_SOFT) - { - SET_BIT(hperh->perh->CON0, ADC_CON0_IAUTO_MSK); - } - else - { - hperh->state |= ADC_STATE_ERROR; - hperh->error_code |= ADC_ERROR_INTERNAL; - tmp_status = ERROR; - } + SET_BIT(hperh->perh->CON0, ADC_CON0_IAUTO_MSK); } - if (config->disc_mode == ENABLE) + if (hperh->init.disc_mode == ADC_ICH_DISC_EN) { if (config->auto_inj == DISABLE) { - MODIFY_REG(hperh->perh->CHSL, ADC_CHSL_ISL_MSK, config->nbr << ADC_CHSL_ISL_POSS); + MODIFY_REG(hperh->perh->CHSL, ADC_CHSL_ISL_MSK, config->ich_len << ADC_CHSL_ISL_POSS); SET_BIT(hperh->perh->CON0, ADC_CON0_ICHDCEN_MSK); } else @@ -1114,24 +1163,25 @@ ald_status_t adc_insert_channel_config(adc_handle_t *hperh, adc_ih_conf_t *confi switch (config->rank) { - case ADC_IH_RANK_1: - hperh->perh->ICHOFF[0] = config->offset; - break; - case ADC_IH_RANK_2: - hperh->perh->ICHOFF[1] = config->offset; - break; - case ADC_IH_RANK_3: - hperh->perh->ICHOFF[2] = config->offset; - break; - case ADC_IH_RANK_4: - hperh->perh->ICHOFF[3] = config->offset; - break; - default: - break; - } + case ADC_ICH_RANK_1: + hperh->perh->ICHOFF[0] = config->offset; + break; - if (hperh->ist_trig_mode != ADC_TRIG_SOFT) - pis_create(&hperh->inj_pis_handle); + case ADC_ICH_RANK_2: + hperh->perh->ICHOFF[1] = config->offset; + break; + + case ADC_ICH_RANK_3: + hperh->perh->ICHOFF[2] = config->offset; + break; + + case ADC_ICH_RANK_4: + hperh->perh->ICHOFF[3] = config->offset; + break; + + default: + break; + } __UNLOCK(hperh); return tmp_status; @@ -1144,7 +1194,7 @@ ald_status_t adc_insert_channel_config(adc_handle_t *hperh, adc_ih_conf_t *confi * @param config: Structure of ADC analog watchdog configuration * @retval ALD status */ -ald_status_t adc_analog_wdg_config(adc_handle_t *hperh, adc_analog_wdg_conf_t *config) +ald_status_t ald_adc_analog_wdg_config(adc_handle_t *hperh, adc_analog_wdg_conf_t *config) { assert_param(IS_ADC_TYPE(hperh->perh)); @@ -1161,9 +1211,9 @@ ald_status_t adc_analog_wdg_config(adc_handle_t *hperh, adc_analog_wdg_conf_t *c assert_param(IS_ADC_CHANNELS_TYPE(config->channel)); if (config->it_mode == DISABLE) - adc_interrupt_config(hperh, ADC_IT_AWD, DISABLE); + ald_adc_interrupt_config(hperh, ADC_IT_AWD, DISABLE); else - adc_interrupt_config(hperh, ADC_IT_AWD, ENABLE); + ald_adc_interrupt_config(hperh, ADC_IT_AWD, ENABLE); CLEAR_BIT(hperh->perh->CON0, ADC_CON0_ICHWDTEN_MSK); CLEAR_BIT(hperh->perh->CON0, ADC_CON0_NCHWDEN_MSK); @@ -1190,7 +1240,7 @@ ald_status_t adc_analog_wdg_config(adc_handle_t *hperh, adc_analog_wdg_conf_t *c * - DISABLE * @retval None */ -void adc_interrupt_config(adc_handle_t *hperh, adc_it_t it, type_func_t state) +void ald_adc_interrupt_config(adc_handle_t *hperh, adc_it_t it, type_func_t state) { assert_param(IS_ADC_TYPE(hperh->perh)); assert_param(IS_ADC_IT_TYPE(it)); @@ -1213,7 +1263,7 @@ void adc_interrupt_config(adc_handle_t *hperh, adc_it_t it, type_func_t state) * - SET * - RESET */ -it_status_t adc_get_it_status(adc_handle_t *hperh, adc_it_t it) +it_status_t ald_adc_get_it_status(adc_handle_t *hperh, adc_it_t it) { assert_param(IS_ADC_TYPE(hperh->perh)); assert_param(IS_ADC_IT_TYPE(it)); @@ -1232,7 +1282,7 @@ it_status_t adc_get_it_status(adc_handle_t *hperh, adc_it_t it) * - SET * - RESET */ -flag_status_t adc_get_flag_status(adc_handle_t *hperh, adc_flag_t flag) +flag_status_t ald_adc_get_flag_status(adc_handle_t *hperh, adc_flag_t flag) { assert_param(IS_ADC_TYPE(hperh->perh)); assert_param(IS_ADC_FLAGS_TYPE(flag)); @@ -1249,7 +1299,7 @@ flag_status_t adc_get_flag_status(adc_handle_t *hperh, adc_flag_t flag) * This parameter can be one of the @ref adc_flag_t. * @retval None */ -void adc_clear_flag_status(adc_handle_t *hperh, adc_flag_t flag) +void ald_adc_clear_flag_status(adc_handle_t *hperh, adc_flag_t flag) { assert_param(IS_ADC_TYPE(hperh->perh)); assert_param(IS_ADC_FLAGS_TYPE(flag)); @@ -1272,7 +1322,7 @@ void adc_clear_flag_status(adc_handle_t *hperh, adc_flag_t flag) * the configuration information for the specified ADC module. * @retval state */ -uint32_t adc_get_state(adc_handle_t *hperh) +uint32_t ald_adc_get_state(adc_handle_t *hperh) { return hperh->state; } @@ -1283,7 +1333,7 @@ uint32_t adc_get_state(adc_handle_t *hperh) * the configuration information for the specified ADC module. * @retval ADC Error Code */ -uint32_t adc_get_error(adc_handle_t *hperh) +uint32_t ald_adc_get_error(adc_handle_t *hperh) { return hperh->error_code; } diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_bkpc.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_bkpc.c similarity index 85% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_bkpc.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_bkpc.c index 0a6e766b6a..7035bc5067 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_bkpc.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_bkpc.c @@ -40,8 +40,8 @@ ##### Peripheral Control functions ##### ============================================================================== [..] This section provides functions allowing to: - (+) bkpc_ldo_config() API can configure LDO in backup field. - (+) bkpc_bor_config() API can configure BOR in backup field. + (+) ald_bkpc_ldo_config() API can configure LDO in backup field. + (+) ald_bkpc_bor_config() API can configure BOR in backup field. @endverbatim * @{ @@ -53,7 +53,7 @@ * @param state: DISABLE/ENABLE. * @retval None */ -void bkpc_ldo_config(bkpc_ldo_output_t output, type_func_t state) +void ald_bkpc_ldo_config(bkpc_ldo_output_t output, type_func_t state) { assert_param(IS_BKPC_LDO_OUTPUT(output)); assert_param(IS_FUNC_STATE(state)); @@ -74,7 +74,7 @@ void bkpc_ldo_config(bkpc_ldo_output_t output, type_func_t state) * @param state: DISABLE/ENABLE. * @retval None */ -void bkpc_bor_config(bkpc_bor_vol_t vol, type_func_t state) +void ald_bkpc_bor_config(bkpc_bor_vol_t vol, type_func_t state) { assert_param(IS_BKPC_BOR_VOL(vol)); assert_param(IS_FUNC_STATE(state)); @@ -102,8 +102,8 @@ void bkpc_bor_config(bkpc_bor_vol_t vol, type_func_t state) ##### IO operation functions ##### ============================================================================== [..] This section provides functions allowing to: - (+) bkpc_write_ram() API can write data in backup ram. - (+) bkpc_read_ram() API can read data from backup ram. + (+) ald_bkpc_write_ram() API can write data in backup ram. + (+) ald_bkpc_read_ram() API can read data from backup ram. @endverbatim * @{ @@ -115,7 +115,7 @@ void bkpc_bor_config(bkpc_bor_vol_t vol, type_func_t state) * @param value: Value which will be written to backup ram. * @retval None */ -void bkpc_write_ram(uint8_t idx, uint32_t value) +void ald_bkpc_write_ram(uint8_t idx, uint32_t value) { assert_param(IS_BKPC_RAM_IDX(idx)); @@ -131,7 +131,7 @@ void bkpc_write_ram(uint8_t idx, uint32_t value) * @param idx: Index of backup word. * @retval The data. */ -uint32_t bkpc_read_ram(uint8_t idx) +uint32_t ald_bkpc_read_ram(uint8_t idx) { assert_param(IS_BKPC_RAM_IDX(idx)); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_calc.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_calc.c similarity index 91% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_calc.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_calc.c index 4ddc9901f9..26a67f2493 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_calc.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_calc.c @@ -48,9 +48,10 @@ * @param data: The data; * @retval The value of square root. */ -uint32_t calc_sqrt(uint32_t data) +uint32_t ald_calc_sqrt(uint32_t data) { WRITE_REG(CALC->RDCND, data); + while (READ_BIT(CALC->SQRTSR, CALC_SQRTSR_BUSY_MSK)); return READ_REG(CALC->SQRTRES); @@ -63,7 +64,7 @@ uint32_t calc_sqrt(uint32_t data) * @param remainder: The value of the remainder. * @retval The result of division. */ -uint32_t calc_div(uint32_t dividend, uint32_t divisor, uint32_t *remainder) +uint32_t ald_calc_div(uint32_t dividend, uint32_t divisor, uint32_t *remainder) { CLEAR_BIT(CALC->DIVCSR, CALC_DIVCSR_SIGN_MSK); SET_BIT(CALC->DIVCSR, CALC_DIVCSR_TRM_MSK); @@ -83,7 +84,7 @@ uint32_t calc_div(uint32_t dividend, uint32_t divisor, uint32_t *remainder) * @param remainder: The value of the remainder. * @retval The result of division. */ -int32_t calc_div_sign(int32_t dividend, int32_t divisor, int32_t *remainder) +int32_t ald_calc_div_sign(int32_t dividend, int32_t divisor, int32_t *remainder) { SET_BIT(CALC->DIVCSR, CALC_DIVCSR_SIGN_MSK); SET_BIT(CALC->DIVCSR, CALC_DIVCSR_TRM_MSK); @@ -100,7 +101,7 @@ int32_t calc_div_sign(int32_t dividend, int32_t divisor, int32_t *remainder) * @brief Get the flag of divisor is zero. * @retval The status, SET/RESET. */ -flag_status_t calc_get_dz_status(void) +flag_status_t ald_calc_get_dz_status(void) { if (READ_BIT(CALC->DIVCSR, CALC_DIVCSR_DZ_MSK)) return SET; diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_can.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_can.c similarity index 73% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_can.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_can.c index cb01604b87..cc55f867c5 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_can.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_can.c @@ -24,27 +24,27 @@ (#) CAN pins configuration (++) Enable the clock for the CAN GPIOs; (++) Connect and configure the involved CAN pins using the - following function gpio_init(); - (#) Initialise and configure the CAN using can_init() function. - (#) Transmit the CAN frame using can_send()/can_send_by_it() function. - (#) Receive a CAN frame using can_recv()/can_recv_by_it function. + following function ald_gpio_init(); + (#) Initialise and configure the CAN using ald_can_init() function. + (#) Transmit the CAN frame using ald_can_send()/ald_can_send_by_it() function. + (#) Receive a CAN frame using ald_can_recv()/ald_can_recv_by_it function. *** Polling mode IO operation *** ================================= [..] (+) Start the CAN peripheral transmission and wait the end of this operation - using can_send(), at this stage user can specify the value of timeout + using ald_can_send(), at this stage user can specify the value of timeout according to his end application. (+) Start the CAN peripheral reception and wait the end of this operation - using can_recv(), at this stage user can specify the value of timeout + using ald_can_recv(), at this stage user can specify the value of timeout according to his end application *** Interrupt mode IO operation *** =================================== [..] - (+) Start the CAN peripheral transmission using can_send_by_it() - (+) Start the CAN peripheral reception using can_recv_by_it() - (+) Use can_irq_handler() called under the used CAN Interrupt subroutine + (+) Start the CAN peripheral transmission using ald_can_send_by_it() + (+) Start the CAN peripheral reception using ald_can_recv_by_it() + (+) Use ald_can_irq_handler() called under the used CAN Interrupt subroutine (+) At CAN end of transmission pherh->tx_cplt_cbk() function is executed and user can add his own code by customization of function pointer pherh->tx_cplt_cbk() (+) In case of CAN Error, pherh->rx_cplt_cbk() function is executed and user can @@ -83,7 +83,7 @@ * @{ */ static void can_rx_fifo_release(can_handle_t *hperh, can_rx_fifo_t num); -static ald_status_t __can_send_by_it(can_handle_t *hperh); +static ald_status_t __can_send_by_it(can_handle_t *hperh, uint8_t err); static ald_status_t __can_recv_by_it(can_handle_t *hperh, uint8_t num); /** * @} @@ -116,7 +116,7 @@ static ald_status_t __can_recv_by_it(can_handle_t *hperh, uint8_t num); * the configuration information for the specified CAN. * @retval Status, see ald_status_t. */ -ald_status_t can_init(can_handle_t *hperh) +ald_status_t ald_can_init(can_handle_t *hperh) { uint32_t tickstart = 0; @@ -137,14 +137,14 @@ ald_status_t can_init(can_handle_t *hperh) hperh->lock = UNLOCK; hperh->state = CAN_STATE_BUSY; - tickstart = __get_tick(); + tickstart = ald_get_tick(); CLEAR_BIT(hperh->perh->CON, CAN_CON_SLPREQ_MSK); SET_BIT(hperh->perh->CON, CAN_CON_INIREQ_MSK); while (!READ_BIT(hperh->perh->STAT, CAN_STAT_INISTAT_MSK)) { - if ((__get_tick() - tickstart) > CAN_TIMEOUT_VALUE) + if ((ald_get_tick() - tickstart) > CAN_TIMEOUT_VALUE) { hperh->state = CAN_STATE_TIMEOUT; __UNLOCK(hperh); @@ -167,11 +167,11 @@ ald_status_t can_init(can_handle_t *hperh) MODIFY_REG(hperh->perh->BTIME, CAN_BTIME_BPSC_MSK, (hperh->init.psc - 1) << CAN_BTIME_BPSC_POSS); CLEAR_BIT(hperh->perh->CON, CAN_CON_INIREQ_MSK); - tickstart = __get_tick(); + tickstart = ald_get_tick(); while (READ_BIT(hperh->perh->STAT, CAN_STAT_INISTAT_MSK)) { - if ((__get_tick() - tickstart) > CAN_TIMEOUT_VALUE) + if ((ald_get_tick() - tickstart) > CAN_TIMEOUT_VALUE) { hperh->state = CAN_STATE_TIMEOUT; __UNLOCK(hperh); @@ -194,7 +194,7 @@ ald_status_t can_init(can_handle_t *hperh) * contains the filter configuration information. * @retval Status, see ald_status_t. */ -ald_status_t can_filter_config(can_handle_t *hperh, can_filter_t *config) +ald_status_t ald_can_filter_config(can_handle_t *hperh, can_filter_t *config) { uint32_t pos; @@ -247,7 +247,7 @@ ald_status_t can_filter_config(can_handle_t *hperh, can_filter_t *config) * @param hperh: pointer to a can_handle_t structure. * @retval None */ -void can_reset(can_handle_t *hperh) +void ald_can_reset(can_handle_t *hperh) { assert_param(IS_CAN_ALL(hperh->perh)); @@ -281,11 +281,11 @@ void can_reset(can_handle_t *hperh) /** * @brief Send a CAN frame message. * @param hperh: pointer to a can_handle_t structure. - * @param msg: message which will be snet. + * @param msg: message which will be sent. * @param timeout: specify Timeout value * @retval Status, see ald_status_t. */ -ald_status_t can_send(can_handle_t *hperh, can_tx_msg_t *msg, uint32_t timeout) +ald_status_t ald_can_send(can_handle_t *hperh, can_tx_msg_t *msg, uint32_t timeout) { uint32_t tick; can_tx_mailbox_t idx; @@ -330,15 +330,16 @@ ald_status_t can_send(can_handle_t *hperh, can_tx_msg_t *msg, uint32_t timeout) MODIFY_REG(hperh->perh->TxMailBox[idx].TXID, CAN_TXID0_STDID_MSK, ((msg->ext >> 18) & 0x7FF) << CAN_TXID0_STDID_POSS); MODIFY_REG(hperh->perh->TxMailBox[idx].TXID, CAN_TXID0_EXID_MSK, (msg->ext & 0x3FFFF) << CAN_TXID0_EXID_POSS); } + MODIFY_REG(hperh->perh->TxMailBox[idx].TXFCON, CAN_TXFCON0_DLEN_MSK, (msg->len & 0xF) << CAN_TXFCON0_DLEN_POSS); WRITE_REG(hperh->perh->TxMailBox[idx].TXDL, msg->data[0] | (msg->data[1] << 8) | (msg->data[2] << 16) | (msg->data[3] << 24)); WRITE_REG(hperh->perh->TxMailBox[idx].TXDH, msg->data[4] | (msg->data[5] << 8) | (msg->data[6] << 16) | (msg->data[7] << 24)); SET_BIT(hperh->perh->TxMailBox[idx].TXID, CAN_TXID0_TXMREQ_MSK); - tick = __get_tick(); + tick = ald_get_tick(); - while (!(can_get_tx_status(hperh, idx))) + while (!(ald_can_get_tx_status(hperh, idx))) { - if ((timeout == 0) || ((__get_tick() - tick) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tick) > timeout)) { hperh->state = CAN_STATE_TIMEOUT; __UNLOCK(hperh); @@ -354,10 +355,10 @@ ald_status_t can_send(can_handle_t *hperh, can_tx_msg_t *msg, uint32_t timeout) /** * @brief Send a CAN frame message using interrupt. * @param hperh: pointer to a can_handle_t structure. - * @param msg: message which will be snet. + * @param msg: message which will be sent. * @retval Status, see ald_status_t. */ -ald_status_t can_send_by_it(can_handle_t *hperh, can_tx_msg_t *msg) +ald_status_t ald_can_send_by_it(can_handle_t *hperh, can_tx_msg_t *msg) { uint8_t idx = CAN_TX_MAILBOX_NONE; @@ -404,12 +405,12 @@ ald_status_t can_send_by_it(can_handle_t *hperh, can_tx_msg_t *msg) SET_BIT(hperh->state, CAN_STATE_TX_MASK); - can_interrupt_config(hperh, CAN_IT_EWG, ENABLE); - can_interrupt_config(hperh, CAN_IT_EPV, ENABLE); - can_interrupt_config(hperh, CAN_IT_BOF, ENABLE); - can_interrupt_config(hperh, CAN_IT_LEC, ENABLE); - can_interrupt_config(hperh, CAN_IT_ERR, ENABLE); - can_interrupt_config(hperh, CAN_IT_TME, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_WARN, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_PERR, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_BOF, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_PRERR, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_ERR, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_TXM, ENABLE); SET_BIT(hperh->perh->TxMailBox[idx].TXID, CAN_TXID0_TXMREQ_MSK); return OK; @@ -423,7 +424,7 @@ ald_status_t can_send_by_it(can_handle_t *hperh, can_tx_msg_t *msg) * @param timeout: Specify timeout value * @retval Status, see ald_status_t. */ -ald_status_t can_recv(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg, uint32_t timeout) +ald_status_t ald_can_recv(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg, uint32_t timeout) { uint32_t tick, stid, exid; @@ -432,11 +433,11 @@ ald_status_t can_recv(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg, __LOCK(hperh); SET_BIT(hperh->state, CAN_STATE_RX_MASK); - tick = __get_tick(); + tick = ald_get_tick(); while (CAN_RX_MSG_PENDING(hperh, num) == 0) { - if ((timeout == 0) || ((__get_tick() - tick) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tick) > timeout)) { hperh->state = CAN_STATE_TIMEOUT; __UNLOCK(hperh); @@ -479,7 +480,7 @@ ald_status_t can_recv(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg, * @param msg: Storing message. * @retval Status, see ald_status_t. */ -ald_status_t can_recv_by_it(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg) +ald_status_t ald_can_recv_by_it(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg) { assert_param(IS_CAN_ALL(hperh->perh)); assert_param(IS_CAN_FIFO(num)); @@ -490,16 +491,16 @@ ald_status_t can_recv_by_it(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t SET_BIT(hperh->state, CAN_STATE_RX_MASK); hperh->rx_msg = msg; - can_interrupt_config(hperh, CAN_IT_EWG, ENABLE); - can_interrupt_config(hperh, CAN_IT_EPV, ENABLE); - can_interrupt_config(hperh, CAN_IT_BOF, ENABLE); - can_interrupt_config(hperh, CAN_IT_LEC, ENABLE); - can_interrupt_config(hperh, CAN_IT_ERR, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_WARN, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_PERR, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_BOF, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_PRERR, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_ERR, ENABLE); if (num == CAN_RX_FIFO0) - can_interrupt_config(hperh, CAN_IT_FMP0, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_FP0, ENABLE); else - can_interrupt_config(hperh, CAN_IT_FMP1, ENABLE); + ald_can_interrupt_config(hperh, CAN_IT_FP1, ENABLE); return OK; } @@ -535,7 +536,7 @@ ald_status_t can_recv_by_it(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t * @param hperh: pointer to a can_handle_t. * @retval Status, see ald_status_t. */ -ald_status_t can_sleep(can_handle_t *hperh) +ald_status_t ald_can_sleep(can_handle_t *hperh) { uint32_t tick; @@ -546,11 +547,11 @@ ald_status_t can_sleep(can_handle_t *hperh) CLEAR_BIT(hperh->perh->CON, CAN_CON_INIREQ_MSK); SET_BIT(hperh->perh->CON, CAN_CON_SLPREQ_MSK); - tick = __get_tick(); + tick = ald_get_tick(); while ((!(READ_BIT(hperh->perh->STAT, CAN_STAT_SLPSTAT_MSK))) || READ_BIT(hperh->perh->STAT, CAN_STAT_INISTAT_MSK)) { - if ((__get_tick() - tick) > CAN_TIMEOUT_VALUE) + if ((ald_get_tick() - tick) > CAN_TIMEOUT_VALUE) { hperh->state = CAN_STATE_TIMEOUT; __UNLOCK(hperh); @@ -570,7 +571,7 @@ ald_status_t can_sleep(can_handle_t *hperh) * @param hperh: pointer to a can_handle_t structure. * @retval Status, see ald_status_t. */ -ald_status_t can_wake_up(can_handle_t *hperh) +ald_status_t ald_can_wake_up(can_handle_t *hperh) { uint32_t tick; @@ -580,11 +581,11 @@ ald_status_t can_wake_up(can_handle_t *hperh) hperh->state = CAN_STATE_BUSY; CLEAR_BIT(hperh->perh->CON, CAN_CON_SLPREQ_MSK); - tick = __get_tick(); + tick = ald_get_tick(); while (READ_BIT(hperh->perh->STAT, CAN_STAT_SLPSTAT_MSK)) { - if ((__get_tick() - tick) > CAN_TIMEOUT_VALUE) + if ((ald_get_tick() - tick) > CAN_TIMEOUT_VALUE) { hperh->state = CAN_STATE_TIMEOUT; __UNLOCK(hperh); @@ -603,71 +604,107 @@ ald_status_t can_wake_up(can_handle_t *hperh) * @param hperh: pointer to a can_handle_t structure. * @retval None */ -void can_irq_handler(can_handle_t *hperh) +void ald_can_irq_handler(can_handle_t *hperh) { - if (can_get_it_status(hperh, CAN_IT_TME)) + if (ald_can_get_it_status(hperh, CAN_IT_TXM)) { - if ((can_get_tx_status(hperh, CAN_TX_MAILBOX_0)) - || (can_get_tx_status(hperh, CAN_TX_MAILBOX_1)) - || (can_get_tx_status(hperh, CAN_TX_MAILBOX_2))) - __can_send_by_it(hperh); + if ((ald_can_get_tx_status(hperh, CAN_TX_MAILBOX_0)) + || (ald_can_get_tx_status(hperh, CAN_TX_MAILBOX_1)) + || (ald_can_get_tx_status(hperh, CAN_TX_MAILBOX_2))) + __can_send_by_it(hperh, 0); + + if (hperh->perh->TXSTAT & CAN_TXSTAT_M0TXERR_MSK) + { + SET_BIT(hperh->perh->TXSTATC, CAN_TXSTATC_M0REQC_MSK); + __can_send_by_it(hperh, 1); + } + + if (hperh->perh->TXSTAT & CAN_TXSTAT_M1TXERR_MSK) + { + SET_BIT(hperh->perh->TXSTATC, CAN_TXSTATC_M1REQC_MSK); + __can_send_by_it(hperh, 1); + } + + if (hperh->perh->TXSTAT & CAN_TXSTAT_M2TXERR_MSK) + { + SET_BIT(hperh->perh->TXSTATC, CAN_TXSTATC_M2REQC_MSK); + __can_send_by_it(hperh, 1); + } } - if ((can_get_it_status(hperh, CAN_IT_FMP0)) + if ((ald_can_get_it_status(hperh, CAN_IT_FP0)) && (CAN_RX_MSG_PENDING(hperh, CAN_RX_FIFO0) != 0)) __can_recv_by_it(hperh, CAN_RX_FIFO0); - if ((can_get_it_status(hperh, CAN_IT_FMP1)) + if ((ald_can_get_it_status(hperh, CAN_IT_FP1)) && (CAN_RX_MSG_PENDING(hperh, CAN_RX_FIFO1) != 0)) __can_recv_by_it(hperh, CAN_RX_FIFO1); - if ((can_get_flag_status(hperh, CAN_FLAG_EWG)) - && (can_get_it_status(hperh, CAN_IT_EWG)) - && (can_get_it_status(hperh, CAN_IT_ERR))) + if ((ald_can_get_flag_status(hperh, CAN_FLAG_WARN)) + && (ald_can_get_it_status(hperh, CAN_IT_WARN)) + && (ald_can_get_it_status(hperh, CAN_IT_ERR))) hperh->err |= CAN_ERROR_EWG; - if ((can_get_flag_status(hperh, CAN_FLAG_EPV)) - && (can_get_it_status(hperh, CAN_IT_EPV)) - && (can_get_it_status(hperh, CAN_IT_ERR))) + if ((ald_can_get_flag_status(hperh, CAN_FLAG_PERR)) + && (ald_can_get_it_status(hperh, CAN_IT_PERR)) + && (ald_can_get_it_status(hperh, CAN_IT_ERR))) hperh->err |= CAN_ERROR_EPV; - if ((can_get_flag_status(hperh, CAN_FLAG_BOF)) - && (can_get_it_status(hperh, CAN_IT_BOF)) - && (can_get_it_status(hperh, CAN_IT_ERR))) + if ((ald_can_get_flag_status(hperh, CAN_FLAG_BOF)) + && (ald_can_get_it_status(hperh, CAN_IT_BOF)) + && (ald_can_get_it_status(hperh, CAN_IT_ERR))) hperh->err |= CAN_ERROR_BOF; if (READ_BIT(hperh->perh->ERRSTAT, CAN_ERRSTAT_PRERRF_MSK) - && (can_get_it_status(hperh, CAN_IT_LEC)) - && (can_get_it_status(hperh, CAN_IT_ERR))) + && (ald_can_get_it_status(hperh, CAN_IT_PRERR)) + && (ald_can_get_it_status(hperh, CAN_IT_ERR))) { switch (READ_BITS(hperh->perh->ERRSTAT, CAN_ERRSTAT_PRERRF_MSK, CAN_ERRSTAT_PRERRF_POSS)) { - case (1): - hperh->err |= CAN_ERROR_STF; - break; - case (2): - hperh->err |= CAN_ERROR_FOR; - break; - case (3): - hperh->err |= CAN_ERROR_ACK; - break; - case (4): - hperh->err |= CAN_ERROR_BR; - break; - case (5): - hperh->err |= CAN_ERROR_BD; - break; - case (6): - hperh->err |= CAN_ERROR_CRC; - break; - default: - break; + case (1): + hperh->err |= CAN_ERROR_STF; + break; + + case (2): + hperh->err |= CAN_ERROR_FOR; + break; + + case (3): + hperh->err |= CAN_ERROR_ACK; + break; + + case (4): + hperh->err |= CAN_ERROR_BR; + break; + + case (5): + hperh->err |= CAN_ERROR_BD; + break; + + case (6): + hperh->err |= CAN_ERROR_CRC; + break; + + default: + break; } CLEAR_BIT(hperh->perh->ERRSTAT, CAN_ERRSTAT_PRERRF_MSK); + + if (READ_BIT(hperh->perh->IE, CAN_IE_TXMEIE_MSK)) + ald_can_interrupt_config(hperh, CAN_IT_TXM, DISABLE); + + if (READ_BIT(hperh->perh->IE, CAN_IE_F0PIE_MSK)) + ald_can_interrupt_config(hperh, CAN_IT_FP0, DISABLE); + + if (READ_BIT(hperh->perh->IE, CAN_IE_F1PIE_MSK)) + ald_can_interrupt_config(hperh, CAN_IT_FP1, DISABLE); } + if ((ald_can_get_flag_status(hperh, CAN_FLAG_ERR)) && (hperh->err == CAN_ERROR_NONE)) + hperh->err = CAN_ERROR_UNK; + if (hperh->err != CAN_ERROR_NONE) { SET_BIT(hperh->perh->IFC, CAN_IFC_ERRIFC_MSK); @@ -684,45 +721,51 @@ void can_irq_handler(can_handle_t *hperh) * @param box: the index of the mailbox that is used for transmission. * @retval The new status of transmission(TRUE or FALSE). */ -type_bool_t can_get_tx_status(can_handle_t *hperh, can_tx_mailbox_t box) +type_bool_t ald_can_get_tx_status(can_handle_t *hperh, can_tx_mailbox_t box) { assert_param(IS_CAN_ALL(hperh->perh)); assert_param(IS_CAN_TX_MAILBOX(box)); switch (box) { - case CAN_TX_MAILBOX_0: - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M0REQC_MSK)) - return FALSE; - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M0TXC_MSK)) - return FALSE; - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_TXM0EF_MSK)) - return FALSE; - - return TRUE; - - case CAN_TX_MAILBOX_1: - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M1REQC_MSK)) - return FALSE; - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M1TXC_MSK)) - return FALSE; - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_TXM1EF_MSK)) - return FALSE; - - return TRUE; - - case CAN_TX_MAILBOX_2: - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M2REQC_MSK)) - return FALSE; - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M2TXC_MSK)) - return FALSE; - if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_TXM2EF_MSK)) - return FALSE; - - return TRUE; - - default: - break; + case CAN_TX_MAILBOX_0: + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M0REQC_MSK)) + return FALSE; + + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M0TXC_MSK)) + return FALSE; + + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_TXM0EF_MSK)) + return FALSE; + + return TRUE; + + case CAN_TX_MAILBOX_1: + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M1REQC_MSK)) + return FALSE; + + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M1TXC_MSK)) + return FALSE; + + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_TXM1EF_MSK)) + return FALSE; + + return TRUE; + + case CAN_TX_MAILBOX_2: + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M2REQC_MSK)) + return FALSE; + + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M2TXC_MSK)) + return FALSE; + + if (!READ_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_TXM2EF_MSK)) + return FALSE; + + return TRUE; + + default: + break; } return FALSE; @@ -734,24 +777,27 @@ type_bool_t can_get_tx_status(can_handle_t *hperh, can_tx_mailbox_t box) * @param box: the index of the mailbox that is used for transmission. * @retval None */ -void can_cancel_send(can_handle_t *hperh, can_tx_mailbox_t box) +void ald_can_cancel_send(can_handle_t *hperh, can_tx_mailbox_t box) { assert_param(IS_CAN_ALL(hperh->perh)); assert_param(IS_CAN_TX_MAILBOX(box)); switch (box) { - case CAN_TX_MAILBOX_0: - SET_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M0STPREQ_MSK); - break; - case CAN_TX_MAILBOX_1: - SET_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M1STPREQ_MSK); - break; - case CAN_TX_MAILBOX_2: - SET_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M2STPREQ_MSK); - break; - default: - break; + case CAN_TX_MAILBOX_0: + SET_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M0STPREQ_MSK); + break; + + case CAN_TX_MAILBOX_1: + SET_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M1STPREQ_MSK); + break; + + case CAN_TX_MAILBOX_2: + SET_BIT(hperh->perh->TXSTAT, CAN_TXSTAT_M2STPREQ_MSK); + break; + + default: + break; } return; @@ -768,7 +814,7 @@ void can_cancel_send(can_handle_t *hperh, can_tx_mailbox_t box) * @arg DISABLE * @retval None */ -void can_interrupt_config(can_handle_t *hperh, can_it_t it, type_func_t state) +void ald_can_interrupt_config(can_handle_t *hperh, can_it_t it, type_func_t state) { assert_param(IS_CAN_ALL(hperh->perh)); assert_param(IS_CAN_IT(it)); @@ -791,7 +837,7 @@ void can_interrupt_config(can_handle_t *hperh, can_it_t it, type_func_t state) * - 0: RESET * - 1: SET */ -it_status_t can_get_it_status(can_handle_t *hperh, can_it_t it) +it_status_t ald_can_get_it_status(can_handle_t *hperh, can_it_t it) { assert_param(IS_CAN_ALL(hperh->perh)); assert_param(IS_CAN_IT(it)); @@ -811,7 +857,7 @@ it_status_t can_get_it_status(can_handle_t *hperh, can_it_t it) * - 0: RESET * - 1: SET */ -flag_status_t can_get_flag_status(can_handle_t *hperh, can_flag_t flag) +flag_status_t ald_can_get_flag_status(can_handle_t *hperh, can_flag_t flag) { uint32_t idx = (flag >> 20) & 0x7; uint32_t _flag = flag & 0xFF8FFFFF; @@ -820,33 +866,38 @@ flag_status_t can_get_flag_status(can_handle_t *hperh, can_flag_t flag) switch (idx) { - case 0: - if (READ_BIT(hperh->perh->STAT, _flag)) - return SET; - - break; - case 1: - if (READ_BIT(hperh->perh->TXSTAT, _flag)) - return SET; - - break; - case 2: - if (READ_BIT(hperh->perh->RXF0, _flag)) - return SET; - - break; - case 3: - if (READ_BIT(hperh->perh->RXF1, _flag)) - return SET; - - break; - case 4: - if (READ_BIT(hperh->perh->ERRSTAT, _flag)) - return SET; - - break; - default: - break; + case 0: + if (READ_BIT(hperh->perh->STAT, _flag)) + return SET; + + break; + + case 1: + if (READ_BIT(hperh->perh->TXSTAT, _flag)) + return SET; + + break; + + case 2: + if (READ_BIT(hperh->perh->RXF0, _flag)) + return SET; + + break; + + case 3: + if (READ_BIT(hperh->perh->RXF1, _flag)) + return SET; + + break; + + case 4: + if (READ_BIT(hperh->perh->ERRSTAT, _flag)) + return SET; + + break; + + default: + break; } return RESET; @@ -857,7 +908,7 @@ flag_status_t can_get_flag_status(can_handle_t *hperh, can_flag_t flag) * @param flag: specifies the flag to check. * @retval None. */ -void can_clear_flag(can_handle_t *hperh, can_flag_t flag) +void ald_can_clear_flag_status(can_handle_t *hperh, can_flag_t flag) { uint32_t idx = (flag >> 20) & 0x7; uint32_t _flag = flag & 0xFF8FFFFF; @@ -866,20 +917,24 @@ void can_clear_flag(can_handle_t *hperh, can_flag_t flag) switch (idx) { - case 0: - WRITE_REG(hperh->perh->IFC, _flag); - break; - case 1: - WRITE_REG(hperh->perh->TXSTATC, _flag); - break; - case 2: - WRITE_REG(hperh->perh->RXF0C, _flag); - break; - case 3: - WRITE_REG(hperh->perh->RXF1C, _flag); - break; - default: - break; + case 0: + WRITE_REG(hperh->perh->IFC, _flag); + break; + + case 1: + WRITE_REG(hperh->perh->TXSTATC, _flag); + break; + + case 2: + WRITE_REG(hperh->perh->RXF0C, _flag); + break; + + case 3: + WRITE_REG(hperh->perh->RXF1C, _flag); + break; + + default: + break; } return; @@ -908,7 +963,7 @@ void can_clear_flag(can_handle_t *hperh, can_flag_t flag) * @param hperh: pointer to a can_handle_t structure. * @retval Status, see can_state_t. */ -can_state_t can_get_state(can_handle_t *hperh) +can_state_t ald_can_get_state(can_handle_t *hperh) { return hperh->state; } @@ -918,7 +973,7 @@ can_state_t can_get_state(can_handle_t *hperh) * @param hperh: pointer to a can_handle_t structure. * @retval CAN Error Code */ -can_error_t can_get_error(can_handle_t *hperh) +can_error_t ald_can_get_error(can_handle_t *hperh) { return hperh->err; } @@ -953,26 +1008,33 @@ static void can_rx_fifo_release(can_handle_t *hperh, can_rx_fifo_t num) /** * @brief transmits a CAN frame message using interrupt. * @param hperh: pointer to a can_handle_t structure. + * @param err: Error code, 0 - success, 1 - error. * @retval Status, see ald_status_t. */ -static ald_status_t __can_send_by_it(can_handle_t *hperh) +static ald_status_t __can_send_by_it(can_handle_t *hperh, uint8_t err) { - can_interrupt_config(hperh, CAN_IT_TME, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_TXM, DISABLE); if (hperh->state == CAN_STATE_BUSY_TX) { - can_interrupt_config(hperh, CAN_IT_EWG, DISABLE); - can_interrupt_config(hperh, CAN_IT_EPV, DISABLE); - can_interrupt_config(hperh, CAN_IT_BOF, DISABLE); - can_interrupt_config(hperh, CAN_IT_LEC, DISABLE); - can_interrupt_config(hperh, CAN_IT_ERR, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_WARN, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_PERR, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_BOF, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_PRERR, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_ERR, DISABLE); } CLEAR_BIT(hperh->state, CAN_STATE_TX_MASK); - if (hperh->tx_cplt_cbk) + if ((err == 0) && (hperh->tx_cplt_cbk)) hperh->tx_cplt_cbk(hperh); + if ((err) && (hperh->error_cbk != NULL)) + { + hperh->err = CAN_ERROR_UNK; + hperh->error_cbk(hperh); + } + return OK; } @@ -1010,21 +1072,21 @@ static ald_status_t __can_recv_by_it(can_handle_t *hperh, uint8_t num) if (num == CAN_RX_FIFO0) { can_rx_fifo_release(hperh, CAN_RX_FIFO0); - can_interrupt_config(hperh, CAN_IT_FMP0, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_FP0, DISABLE); } else { can_rx_fifo_release(hperh, CAN_RX_FIFO1); - can_interrupt_config(hperh, CAN_IT_FMP1, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_FP1, DISABLE); } if (hperh->state == CAN_STATE_BUSY_RX) { - can_interrupt_config(hperh, CAN_IT_EWG, DISABLE); - can_interrupt_config(hperh, CAN_IT_EPV, DISABLE); - can_interrupt_config(hperh, CAN_IT_BOF, DISABLE); - can_interrupt_config(hperh, CAN_IT_LEC, DISABLE); - can_interrupt_config(hperh, CAN_IT_ERR, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_WARN, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_PERR, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_BOF, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_PRERR, DISABLE); + ald_can_interrupt_config(hperh, CAN_IT_ERR, DISABLE); } CLEAR_BIT(hperh->state, CAN_STATE_RX_MASK); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_cmu.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_cmu.c similarity index 71% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_cmu.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_cmu.c index 88fc71952a..f5a6016d23 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_cmu.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_cmu.c @@ -20,9 +20,9 @@ *** System clock configure *** ================================= [..] - (+) If you don't change system clock, you can using cmu_clock_config_default() API. + (+) If you don't change system clock, you can using ald_cmu_clock_config_default() API. It will select HRC as system clock. The system clock is 24MHz. - (+) If you want to change system clock, you can using cmu_clock_config() API. + (+) If you want to change system clock, you can using ald_cmu_clock_config() API. You can select one of the following as system clock: @ref CMU_CLOCK_HRC 2MHz or 24MHz @ref CMU_CLOCK_LRC 32768Hz @@ -30,13 +30,13 @@ @ref CMU_CLOCK_PLL1 32MHz, 48MHz or (32768*1024)Hz @ref CMU_CLOCK_HOSC 1MHz -- 24MHz (+) If you select CMU_CLOCK_PLL1 as system clock, it must config the PLL1 - using cmu_pll1_config() API. The input of clock must be 4MHz or PLL2. - (+) If you get current clock, you can using cmu_get_clock() API. + using ald_cmu_pll1_config() API. The input of clock must be 4MHz or PLL2. + (+) If you get system clock, you can using ald_cmu_get_sys_clock() API. *** BUS division control *** =================================== - PLCK sys_clk hclk1 + MCLK sys_clk hclk1 -------DIV_SYS-----------+------DIV_AHB1------------Peripheral(GPIO, CRC, ... etc.) | | pclk1 @@ -46,41 +46,41 @@ +------DIV_APB2------------Peripheral(ADC, WWDT, ... etc.) [..] - (+) Configure the division using cmu_div_config() API. - (+) Get sys_clk using cmu_get_sys_clock() API. - (+) Get hclk1 using cmu_get_hclk1_clock() API. - (+) Get pclk1 using cmu_get_pclk1_clock() API. - (+) Get pclk2 using cmu_get_pclk2_clock() API. + (+) Configure the division using ald_cmu_div_config() API. + (+) Get sys_clk using ald_cmu_get_sys_clock() API. + (+) Get hclk1 using ald_cmu_get_hclk1_clock() API. + (+) Get pclk1 using ald_cmu_get_pclk1_clock() API. + (+) Get pclk2 using ald_cmu_get_pclk2_clock() API. *** Clock safe configure *** =================================== [..] (+) If you select CMU_CLOCK_HOSC as system clock, you need enable - clock safe using cmu_hosc_safe_config() API. It will change + clock safe using ald_cmu_hosc_safe_config() API. It will change CMU_CLOCK_HRC as system clock, when the outer crystal stoped. (+) If you select CMU_CLOCK_LOSC as system clock, you need enable - clock safe using cmu_losc_safe_config() API. It will change + clock safe using ald_cmu_losc_safe_config() API. It will change CMU_CLOCK_LRC as system clock, when the outer crystal stoped. (+) If you select CMU_CLOCK_PLL1 as system clock, you need enable - clock safe using cmu_pll_safe_config() API. It will change + clock safe using ald_cmu_pll_safe_config() API. It will change CMU_CLOCK_HRC as system clock, when the pll1 is lose. - (+) The cmu_irq_cbk() will be invoked, when CMU interrupt has + (+) The ald_cmu_irq_cbk() will be invoked, when CMU interrupt has been occurred. You can overwrite this function in application. *** Clock output configure *** =================================== [..] - (+) Output high-speed clock using cmu_output_high_clock_config() API. - (+) Output low-speed clock using cmu_output_low_clock_config() API. + (+) Output high-speed clock using ald_cmu_output_high_clock_config() API. + (+) Output low-speed clock using ald_cmu_output_low_clock_config() API. *** Peripheral clock configure *** =================================== [..] - (+) Configure buzz clock using cmu_buzz_config() API. - (+) Selected lptim0 clock using cmu_lptim0_clock_select() API. - (+) Selected lpuart clock using cmu_lpuart0_clock_select() API. - (+) Selected lcd clock using cmu_lcd_clock_select() API. - (+) Enable/Disable peripheral clock using cmu_perh_clock_config() API. + (+) Configure buzz clock using ald_cmu_buzz_config() API. + (+) Selected lptim0 clock using ald_cmu_lptim0_clock_select() API. + (+) Selected lpuart clock using ald_cmu_lpuart0_clock_select() API. + (+) Selected lcd clock using ald_cmu_lcd_clock_select() API. + (+) Enable/Disable peripheral clock using ald_cmu_perh_clock_config() API. *** CMU ALD driver macros list *** ============================================= @@ -146,7 +146,7 @@ static void cmu_clock_update(uint32_t clock) __system_clock = clock; if (clock > 1000000) - __init_tick(TICK_INT_PRIORITY); + ald_tick_init(TICK_INT_PRIORITY); return; } @@ -155,7 +155,7 @@ static void cmu_clock_update(uint32_t clock) * @brief CMU module interrupt handler * @retval None */ -void CMU_Handler(void) +void ald_cmu_irq_handler(void) { /* HOSC stop */ if (READ_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIF_MSK) && READ_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIE_MSK)) @@ -168,7 +168,8 @@ void CMU_Handler(void) && ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 1) || ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 5)))) cmu_clock_update(READ_BIT(CMU->CFGR, CMU_CFGR_HRCFST_MSK) ? 2000000 : 24000000); - cmu_irq_cbk(CMU_HOSC_STOP); + + ald_cmu_irq_cbk(CMU_HOSC_STOP); } /* HOSC start */ @@ -181,7 +182,8 @@ void CMU_Handler(void) if (!(READ_BIT(CMU->HOSMCR, CMU_HOSMCR_CLKS_MSK)) && ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 5))) cmu_clock_update((READ_BITS(CMU->HOSCCFG, CMU_HOSCCFG_FREQ_MSK, CMU_HOSCCFG_FREQ_POSS) + 1) * 1000000); - cmu_irq_cbk(CMU_HOSC_START); + + ald_cmu_irq_cbk(CMU_HOSC_START); } /* LOSC stop */ @@ -190,7 +192,7 @@ void CMU_Handler(void) SYSCFG_UNLOCK(); SET_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIF_MSK); SYSCFG_LOCK(); - cmu_irq_cbk(CMU_LOSC_STOP); + ald_cmu_irq_cbk(CMU_LOSC_STOP); } /* LOSC start */ @@ -199,7 +201,7 @@ void CMU_Handler(void) SYSCFG_UNLOCK(); SET_BIT(CMU->LOSMCR, CMU_LOSMCR_STRIF_MSK); SYSCFG_LOCK(); - cmu_irq_cbk(CMU_LOSC_START); + ald_cmu_irq_cbk(CMU_LOSC_START); } /* PLL1 lose */ @@ -213,7 +215,8 @@ void CMU_Handler(void) && ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 1) || ((READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) == 5)))) cmu_clock_update(READ_BIT(CMU->CFGR, CMU_CFGR_HRCFST_MSK) ? 2000000 : 24000000); - cmu_irq_cbk(CMU_PLL1_UNLOCK); + + ald_cmu_irq_cbk(CMU_PLL1_UNLOCK); } return; @@ -249,7 +252,7 @@ void CMU_Handler(void) * enable CMU_CLOCK_LRC(32768Hz). * @retval The status of ALD. */ -ald_status_t cmu_clock_config_default(void) +ald_status_t ald_cmu_clock_config_default(void) { uint32_t cnt = 4000, tmp; @@ -257,6 +260,7 @@ ald_status_t cmu_clock_config_default(void) /* Select HRC */ MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_HRC << CMU_CSR_SYS_CMD_POSS); + while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_HRC) @@ -265,7 +269,7 @@ ald_status_t cmu_clock_config_default(void) return ERROR; } - CLEAR_BIT(CMU->CFGR, CMU_CFGR_HRCFSW_MSK); /* Select 24Mhz */ + CLEAR_BIT(CMU->CFGR, CMU_CFGR_HRCFSW_MSK); /* Select 24Mhz */ tmp = READ_REG(CMU->CLKENR); /* Enable HRC/LRC/LOSC */ @@ -288,7 +292,7 @@ ald_status_t cmu_clock_config_default(void) * on the parameter of clk. * @retval The status of ALD. */ -ald_status_t cmu_clock_config(cmu_clock_t clk, uint32_t clock) +ald_status_t ald_cmu_clock_config(cmu_clock_t clk, uint32_t clock) { uint32_t cnt = 4000; @@ -297,127 +301,150 @@ ald_status_t cmu_clock_config(cmu_clock_t clk, uint32_t clock) switch (clk) { - case CMU_CLOCK_HRC: - assert_param(clock == 24000000 || clock == 2000000); + case CMU_CLOCK_HRC: + assert_param(clock == 24000000 || clock == 2000000); - MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_HRC << CMU_CSR_SYS_CMD_POSS); - while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); + MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_HRC << CMU_CSR_SYS_CMD_POSS); - if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_HRC) - { - SYSCFG_LOCK(); - return ERROR; - } + while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); - if (clock == 24000000) - CLEAR_BIT(CMU->CFGR, CMU_CFGR_HRCFSW_MSK); - else - SET_BIT(CMU->CFGR, CMU_CFGR_HRCFSW_MSK); + if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_HRC) + { + SYSCFG_LOCK(); + return ERROR; + } - SET_BIT(CMU->CLKENR, CMU_CLKENR_HRCEN_MSK); + if (clock == 24000000) + CLEAR_BIT(CMU->CFGR, CMU_CFGR_HRCFSW_MSK); + else + SET_BIT(CMU->CFGR, CMU_CFGR_HRCFSW_MSK); - for (cnt = 4000; cnt; --cnt); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HRCACT_MSK))) && (--cnt)); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HRCRDY_MSK))) && (--cnt)); + SET_BIT(CMU->CLKENR, CMU_CLKENR_HRCEN_MSK); - cmu_clock_update(clock); - break; + for (cnt = 4000; cnt; --cnt); - case CMU_CLOCK_LRC: - /* Close SysTick interrupt in lower clock */ - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + cnt = 4000; - MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_LRC << CMU_CSR_SYS_CMD_POSS); - while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HRCACT_MSK))) && (--cnt)); - if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_LRC) - { - SYSCFG_LOCK(); - return ERROR; - } + cnt = 4000; - SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK); + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HRCRDY_MSK))) && (--cnt)); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LRCACT_MSK))) && (--cnt)); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LRCRDY_MSK))) && (--cnt)); + cmu_clock_update(clock); + break; - cmu_clock_update(32768); - break; + case CMU_CLOCK_LRC: + /* Close SysTick interrupt in lower clock */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - case CMU_CLOCK_LOSC: - /* Close SysTick interrupt in lower clock */ - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_LRC << CMU_CSR_SYS_CMD_POSS); - MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_LOSC << CMU_CSR_SYS_CMD_POSS); - while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); + while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); - if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_LOSC) - { - SYSCFG_LOCK(); - return ERROR; - } + if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_LRC) + { + SYSCFG_LOCK(); + return ERROR; + } - SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK); + SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LOSCACT_MSK))) && (--cnt)); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LOSCRDY_MSK))) && (--cnt)); + cnt = 4000; - cmu_clock_update(32768); - break; + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LRCACT_MSK))) && (--cnt)); - case CMU_CLOCK_PLL1: - MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_PLL1 << CMU_CSR_SYS_CMD_POSS); - while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); + cnt = 4000; - if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_PLL1) - { - SYSCFG_LOCK(); - return ERROR; - } + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LRCRDY_MSK))) && (--cnt)); - SET_BIT(CMU->CLKENR, CMU_CLKENR_PLL1EN_MSK); + cmu_clock_update(32768); + break; - for (cnt = 4000; cnt; --cnt); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL1ACT_MSK))) && (--cnt)); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL1RDY_MSK))) && (--cnt)); + case CMU_CLOCK_LOSC: + /* Close SysTick interrupt in lower clock */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - cmu_clock_update(clock); - break; + MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_LOSC << CMU_CSR_SYS_CMD_POSS); - case CMU_CLOCK_HOSC: - assert_param(clock <= 24000000); + while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); - MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_HOSC << CMU_CSR_SYS_CMD_POSS); - while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); + if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_LOSC) + { + SYSCFG_LOCK(); + return ERROR; + } - if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_HOSC) - { - SYSCFG_LOCK(); - return ERROR; - } + SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK); - SET_BIT(CMU->CLKENR, CMU_CLKENR_HOSCEN_MSK); - MODIFY_REG(CMU->HOSCCFG, CMU_HOSCCFG_FREQ_MSK, clock / 1000000 - 1); + cnt = 4000; + + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LOSCACT_MSK))) && (--cnt)); + + cnt = 4000; + + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_LOSCRDY_MSK))) && (--cnt)); + + cmu_clock_update(32768); + break; + + case CMU_CLOCK_PLL1: + MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_PLL1 << CMU_CSR_SYS_CMD_POSS); + + while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); + + if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_PLL1) + { + SYSCFG_LOCK(); + return ERROR; + } + + SET_BIT(CMU->CLKENR, CMU_CLKENR_PLL1EN_MSK); + + for (cnt = 4000; cnt; --cnt); + + cnt = 4000; + + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL1ACT_MSK))) && (--cnt)); + + cnt = 4000; + + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL1RDY_MSK))) && (--cnt)); + + cmu_clock_update(clock); + break; - for (cnt = 4000; cnt; --cnt); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HOSCACT_MSK))) && (--cnt)); - cnt = 4000; - while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HOSCRDY_MSK))) && (--cnt)); + case CMU_CLOCK_HOSC: + assert_param(clock <= 24000000); - cmu_clock_update(clock); - break; + MODIFY_REG(CMU->CSR, CMU_CSR_SYS_CMD_MSK, CMU_CLOCK_HOSC << CMU_CSR_SYS_CMD_POSS); - default: - break; + while (READ_BIT(CMU->CSR, CMU_CSR_SYS_RDYN_MSK) && (--cnt)); + + if (READ_BITS(CMU->CSR, CMU_CSR_SYS_STU_MSK, CMU_CSR_SYS_STU_POSS) != CMU_CLOCK_HOSC) + { + SYSCFG_LOCK(); + return ERROR; + } + + SET_BIT(CMU->CLKENR, CMU_CLKENR_HOSCEN_MSK); + MODIFY_REG(CMU->HOSCCFG, CMU_HOSCCFG_FREQ_MSK, clock / 1000000 - 1); + + for (cnt = 4000; cnt; --cnt); + + cnt = 4000; + + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HOSCACT_MSK))) && (--cnt)); + + cnt = 4000; + + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_HOSCRDY_MSK))) && (--cnt)); + + cmu_clock_update(clock); + break; + + default: + break; } SYSCFG_LOCK(); @@ -434,7 +461,7 @@ ald_status_t cmu_clock_config(cmu_clock_t clk, uint32_t clock) * CMU_PLL1_OUTPUT_32M, and then the real clock is (32768x1024)Hz. * @retval None */ -void cmu_pll1_config(cmu_pll1_input_t input, cmu_pll1_output_t output) +void ald_cmu_pll1_config(cmu_pll1_input_t input, cmu_pll1_output_t output) { uint32_t cnt = 4000; @@ -463,7 +490,9 @@ void cmu_pll1_config(cmu_pll1_input_t input, cmu_pll1_output_t output) SET_BIT(CMU->CLKENR, CMU_CLKENR_PLL1EN_MSK); while ((READ_BIT(CMU->PLLCFG, CMU_PLLCFG_PLL1LCKN_MSK)) && (--cnt)); + cnt = 4000; + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL1RDY_MSK))) && (--cnt)); SYSCFG_LOCK(); @@ -471,10 +500,10 @@ void cmu_pll1_config(cmu_pll1_input_t input, cmu_pll1_output_t output) } /** - * @brief Gets current system clock. - * @retval The value of system clock. + * @brief Gets MCLK clock. + * @retval The value of MCLK clock. */ -uint32_t cmu_get_clock(void) +uint32_t ald_cmu_get_clock(void) { return __system_clock; } @@ -487,7 +516,7 @@ uint32_t cmu_get_clock(void) * - 0 Success * - -1 Failed */ -int32_t cmu_auto_calib_clock(cmu_auto_calib_input_t input, cmu_auto_calib_output_t freq) +int32_t ald_cmu_auto_calib_clock(cmu_auto_calib_input_t input, cmu_auto_calib_output_t freq) { uint32_t cnt = 5000, tmp; @@ -505,7 +534,9 @@ int32_t cmu_auto_calib_clock(cmu_auto_calib_input_t input, cmu_auto_calib_output WRITE_REG(CMU->HRCACR, tmp); while (cnt--); + cnt = 30000; + while ((READ_BIT(CMU->HRCACR, CMU_HRCACR_BUSY_MSK)) && (--cnt)); if (READ_BITS(CMU->HRCACR, CMU_HRCACR_STA_MSK, CMU_HRCACR_STA_POSS) != 1) @@ -534,10 +565,10 @@ int32_t cmu_auto_calib_clock(cmu_auto_calib_input_t input, cmu_auto_calib_output ============================================================================== [..] This section provides functions allowing to: (+) Configure the bus division. - (+) Get ahb1 clock. - (+) Get sys bus clock. - (+) Get apb1 clock. - (+) Get apb2 clock. + (+) Get AHB1 clock. + (+) Get system clock. + (+) Get APB1 clock. + (+) Get APB2 clock. @endverbatim * @{ @@ -553,7 +584,7 @@ int32_t cmu_auto_calib_clock(cmu_auto_calib_input_t input, cmu_auto_calib_output * @param div: The value of divider. * @retval None */ -void cmu_div_config(cmu_bus_t bus, cmu_div_t div) +void ald_cmu_div_config(cmu_bus_t bus, cmu_div_t div) { assert_param(IS_CMU_BUS(bus)); assert_param(IS_CMU_DIV(div)); @@ -562,24 +593,35 @@ void cmu_div_config(cmu_bus_t bus, cmu_div_t div) switch (bus) { - case CMU_HCLK_1: - MODIFY_REG(CMU->CFGR, CMU_CFGR_HCLK1DIV_MSK, div << CMU_CFGR_HCLK1DIV_POSS); - break; + case CMU_HCLK_1: + MODIFY_REG(CMU->CFGR, CMU_CFGR_HCLK1DIV_MSK, div << CMU_CFGR_HCLK1DIV_POSS); + break; - case CMU_SYS: - MODIFY_REG(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, div << CMU_CFGR_SYSDIV_POSS); - break; + case CMU_SYS: + MODIFY_REG(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, div << CMU_CFGR_SYSDIV_POSS); - case CMU_PCLK_1: - MODIFY_REG(CMU->CFGR, CMU_CFGR_PCLK1DIV_MSK, div << CMU_CFGR_PCLK1DIV_POSS); - break; + if ((__system_clock >> div) <= 1000000) + { + /* Close SysTick interrupt in lower clock */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + } + else + { + ald_tick_init(TICK_INT_PRIORITY); + } - case CMU_PCLK_2: - MODIFY_REG(CMU->CFGR, CMU_CFGR_PCLK2DIV_MSK, div << CMU_CFGR_PCLK2DIV_POSS); - break; + break; + + case CMU_PCLK_1: + MODIFY_REG(CMU->CFGR, CMU_CFGR_PCLK1DIV_MSK, div << CMU_CFGR_PCLK1DIV_POSS); + break; + + case CMU_PCLK_2: + MODIFY_REG(CMU->CFGR, CMU_CFGR_PCLK2DIV_MSK, div << CMU_CFGR_PCLK2DIV_POSS); + break; - default: - break; + default: + break; } SYSCFG_LOCK(); @@ -590,7 +632,7 @@ void cmu_div_config(cmu_bus_t bus, cmu_div_t div) * @brief Get AHB1 clock. * @retval The value of AHB1 clock. */ -uint32_t cmu_get_hclk1_clock(void) +uint32_t ald_cmu_get_hclk1_clock(void) { uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS); uint32_t ahb_div = READ_BITS(CMU->CFGR, CMU_CFGR_HCLK1DIV_MSK, CMU_CFGR_HCLK1DIV_POSS); @@ -599,10 +641,10 @@ uint32_t cmu_get_hclk1_clock(void) } /** - * @brief Get SYS clock - * @retval The value of SYS clock + * @brief Get system clock + * @retval The value of system clock */ -uint32_t cmu_get_sys_clock(void) +uint32_t ald_cmu_get_sys_clock(void) { uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS); @@ -613,7 +655,7 @@ uint32_t cmu_get_sys_clock(void) * @brief Get APB1 clock. * @retval The value of APB1 clock. */ -uint32_t cmu_get_pclk1_clock(void) +uint32_t ald_cmu_get_pclk1_clock(void) { uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS); uint32_t apb1_div = READ_BITS(CMU->CFGR, CMU_CFGR_PCLK1DIV_MSK, CMU_CFGR_PCLK1DIV_POSS); @@ -625,7 +667,7 @@ uint32_t cmu_get_pclk1_clock(void) * @brief Get APB2 clock. * @retval The value of APB2 clock. */ -uint32_t cmu_get_pclk2_clock(void) +uint32_t ald_cmu_get_pclk2_clock(void) { uint32_t sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS); uint32_t apb2_div = READ_BITS(CMU->CFGR, CMU_CFGR_PCLK2DIV_MSK, CMU_CFGR_PCLK2DIV_POSS); @@ -659,7 +701,7 @@ uint32_t cmu_get_pclk2_clock(void) * @param status: The new status. * @retval None */ -void cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status) +void ald_cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status) { assert_param(IS_CMU_HOSC_RANGE(clock)); assert_param(IS_FUNC_STATE(status)); @@ -673,7 +715,7 @@ void cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status) SET_BIT(CMU->HOSMCR, CMU_HOSMCR_EN_MSK); SET_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIE_MSK); - mcu_irq_config(CMU_IRQn, 3, ENABLE); + ald_mcu_irq_config(CMU_IRQn, 3, ENABLE); } else { @@ -681,7 +723,7 @@ void cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status) CLEAR_BIT(CMU->HOSMCR, CMU_HOSMCR_STPIE_MSK); if (READ_BIT(CMU->LOSMCR, CMU_LOSMCR_EN_MSK) == 0 && READ_BIT(CMU->PULMCR, CMU_PULMCR_EN_MSK) == 0) - mcu_irq_config(CMU_IRQn, 3, DISABLE); + ald_mcu_irq_config(CMU_IRQn, 3, DISABLE); } SYSCFG_LOCK(); @@ -693,7 +735,7 @@ void cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status) * @param status: The new status. * @retval None */ -void cmu_losc_safe_config(type_func_t status) +void ald_cmu_losc_safe_config(type_func_t status) { assert_param(IS_FUNC_STATE(status)); SYSCFG_UNLOCK(); @@ -704,7 +746,7 @@ void cmu_losc_safe_config(type_func_t status) SET_BIT(CMU->LOSMCR, CMU_LOSMCR_EN_MSK); SET_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIE_MSK); - mcu_irq_config(CMU_IRQn, 3, ENABLE); + ald_mcu_irq_config(CMU_IRQn, 3, ENABLE); } else { @@ -712,7 +754,7 @@ void cmu_losc_safe_config(type_func_t status) CLEAR_BIT(CMU->LOSMCR, CMU_LOSMCR_STPIE_MSK); if (READ_BIT(CMU->HOSMCR, CMU_HOSMCR_EN_MSK) == 0 && READ_BIT(CMU->PULMCR, CMU_PULMCR_EN_MSK) == 0) - mcu_irq_config(CMU_IRQn, 3, DISABLE); + ald_mcu_irq_config(CMU_IRQn, 3, DISABLE); } SYSCFG_LOCK(); @@ -724,7 +766,7 @@ void cmu_losc_safe_config(type_func_t status) * @param status: The new status. * @retval None */ -void cmu_pll_safe_config(type_func_t status) +void ald_cmu_pll_safe_config(type_func_t status) { assert_param(IS_FUNC_STATE(status)); SYSCFG_UNLOCK(); @@ -736,7 +778,7 @@ void cmu_pll_safe_config(type_func_t status) SET_BIT(CMU->PULMCR, CMU_PULMCR_EN_MSK); SET_BIT(CMU->PULMCR, CMU_PULMCR_ULKIE_MSK); - mcu_irq_config(CMU_IRQn, 3, ENABLE); + ald_mcu_irq_config(CMU_IRQn, 3, ENABLE); } else { @@ -744,7 +786,7 @@ void cmu_pll_safe_config(type_func_t status) CLEAR_BIT(CMU->PULMCR, CMU_PULMCR_ULKIE_MSK); if (READ_BIT(CMU->HOSMCR, CMU_HOSMCR_EN_MSK) == 0 && READ_BIT(CMU->LOSMCR, CMU_LOSMCR_EN_MSK) == 0) - mcu_irq_config(CMU_IRQn, 3, DISABLE); + ald_mcu_irq_config(CMU_IRQn, 3, DISABLE); } SYSCFG_LOCK(); @@ -756,7 +798,7 @@ void cmu_pll_safe_config(type_func_t status) * @param sr: The state type, see @ref cmu_clock_state_t. * @retval SET/RESET */ -flag_status_t cmu_get_clock_state(cmu_clock_state_t sr) +flag_status_t ald_cmu_get_clock_state(cmu_clock_state_t sr) { assert_param(IS_CMU_CLOCK_STATE(sr)); @@ -772,7 +814,7 @@ flag_status_t cmu_get_clock_state(cmu_clock_state_t sr) * implementations in user file. * @retval None */ -__weak void cmu_irq_cbk(cmu_security_t se) +__weak void ald_cmu_irq_cbk(cmu_security_t se) { return; } @@ -818,8 +860,8 @@ __weak void cmu_irq_cbk(cmu_security_t se) * @param status: The new status. * @retval None */ -void cmu_output_high_clock_config(cmu_output_high_sel_t sel, - cmu_output_high_div_t div, type_func_t status) +void ald_cmu_output_high_clock_config(cmu_output_high_sel_t sel, + cmu_output_high_div_t div, type_func_t status) { assert_param(IS_CMU_OUTPUT_HIGH_SEL(sel)); assert_param(IS_CMU_OUTPUT_HIGH_DIV(div)); @@ -853,7 +895,7 @@ void cmu_output_high_clock_config(cmu_output_high_sel_t sel, * @param status: The new status. * @retval None */ -void cmu_output_low_clock_config(cmu_output_low_sel_t sel, type_func_t status) +void ald_cmu_output_low_clock_config(cmu_output_low_sel_t sel, type_func_t status) { assert_param(IS_CMU_OUTPUT_LOW_SEL(sel)); assert_param(IS_FUNC_STATE(status)); @@ -903,7 +945,7 @@ void cmu_output_low_clock_config(cmu_output_low_sel_t sel, type_func_t status) * @param status: The new status. * @retval None */ -void cmu_buzz_config(cmu_buzz_div_t div, uint16_t dat, type_func_t status) +void ald_cmu_buzz_config(cmu_buzz_div_t div, uint16_t dat, type_func_t status) { assert_param(IS_CMU_BUZZ_DIV(div)); assert_param(IS_FUNC_STATE(status)); @@ -942,7 +984,7 @@ void cmu_buzz_config(cmu_buzz_div_t div, uint16_t dat, type_func_t status) * @arg CMU_LP_PERH_CLOCK_SEL_HOSM * @retval None */ -void cmu_lptim0_clock_select(cmu_lp_perh_clock_sel_t clock) +void ald_cmu_lptim0_clock_select(cmu_lp_perh_clock_sel_t clock) { assert_param(IS_CMU_LP_PERH_CLOCK_SEL(clock)); @@ -970,7 +1012,7 @@ void cmu_lptim0_clock_select(cmu_lp_perh_clock_sel_t clock) * @arg CMU_LP_PERH_CLOCK_SEL_HOSM * @retval None */ -void cmu_lpuart0_clock_select(cmu_lp_perh_clock_sel_t clock) +void ald_cmu_lpuart0_clock_select(cmu_lp_perh_clock_sel_t clock) { assert_param(IS_CMU_LP_PERH_CLOCK_SEL(clock)); @@ -992,7 +1034,7 @@ void cmu_lpuart0_clock_select(cmu_lp_perh_clock_sel_t clock) * @arg CMU_LCD_SEL_HOSC_1M * @retval None */ -void cmu_lcd_clock_select(cmu_lcd_clock_sel_t clock) +void ald_cmu_lcd_clock_select(cmu_lcd_clock_sel_t clock) { assert_param(IS_CMU_LCD_CLOCK_SEL(clock)); @@ -1009,7 +1051,7 @@ void cmu_lcd_clock_select(cmu_lcd_clock_sel_t clock) * @param status: The new status. * @retval None */ -void cmu_perh_clock_config(cmu_perh_t perh, type_func_t status) +void ald_cmu_perh_clock_config(cmu_perh_t perh, type_func_t status) { uint32_t idx, pos; @@ -1044,40 +1086,40 @@ void cmu_perh_clock_config(cmu_perh_t perh, type_func_t status) { switch (idx) { - case 0: - SET_BIT(CMU->AHB1ENR, pos); - break; + case 0: + SET_BIT(CMU->AHB1ENR, pos); + break; - case 1: - SET_BIT(CMU->APB1ENR, pos); - break; + case 1: + SET_BIT(CMU->APB1ENR, pos); + break; - case 2: - SET_BIT(CMU->APB2ENR, pos); - break; + case 2: + SET_BIT(CMU->APB2ENR, pos); + break; - default: - break; + default: + break; } } else { switch (idx) { - case 0: - CLEAR_BIT(CMU->AHB1ENR, pos); - break; + case 0: + CLEAR_BIT(CMU->AHB1ENR, pos); + break; - case 1: - CLEAR_BIT(CMU->APB1ENR, pos); - break; + case 1: + CLEAR_BIT(CMU->APB1ENR, pos); + break; - case 2: - CLEAR_BIT(CMU->APB2ENR, pos); - break; + case 2: + CLEAR_BIT(CMU->APB2ENR, pos); + break; - default: - break; + default: + break; } } diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crc.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crc.c similarity index 54% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crc.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crc.c index d03a935835..d49b39fe56 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crc.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crc.c @@ -29,7 +29,7 @@ /** @addtogroup CRC_Private_Functions CRC Private Functions * @{ */ -void crc_reset(crc_handle_t *hperh); +void ald_crc_reset(crc_handle_t *hperh); #ifdef ALD_DMA static void crc_dma_calculate_cplt(void *arg); static void crc_dma_error(void *arg); @@ -55,7 +55,7 @@ void crc_reset(crc_handle_t *hperh); * the configuration information for the specified CRC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t crc_init(crc_handle_t *hperh) +ald_status_t ald_crc_init(crc_handle_t *hperh) { uint32_t tmp = 0; @@ -69,7 +69,7 @@ ald_status_t crc_init(crc_handle_t *hperh) assert_param(IS_FUNC_STATE(hperh->init.data_rev)); assert_param(IS_FUNC_STATE(hperh->init.chs_inv)); - crc_reset(hperh); + ald_crc_reset(hperh); __LOCK(hperh); CRC_ENABLE(hperh); @@ -79,7 +79,7 @@ ald_status_t crc_init(crc_handle_t *hperh) tmp |= ((hperh->init.chs_rev << CRC_CR_CHSREV_POS) | (hperh->init.data_inv << CRC_CR_DATREV_POS) | (hperh->init.chs_inv << CRC_CR_CHSINV_POS) | (hperh->init.mode << CRC_CR_MODE_POSS) | (CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS) | (hperh->init.data_rev << CRC_CR_DATREV_POS) | - (1 << CRC_CR_BYTORD_POS)); + (0 << CRC_CR_BYTORD_POS)); hperh->perh->CR = tmp; hperh->perh->SEED = hperh->init.seed; @@ -101,14 +101,14 @@ ald_status_t crc_init(crc_handle_t *hperh) */ /** - * @brief Calculate the crc value of data. + * @brief Calculate the crc value of data by byte. * @param hperh: Pointer to a crc_handle_t structure that contains * the configuration information for the specified CRC module. * @param buf: Pointer to data buffer * @param size: The size of data to be calculate * @retval result, the result of a amount data */ -uint32_t crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size) +uint32_t ald_crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size) { uint32_t i; uint32_t ret; @@ -119,6 +119,71 @@ uint32_t crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size) return 0; __LOCK(hperh); + MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS); + hperh->state = CRC_STATE_BUSY; + + for (i = 0; i < size; i++) + *((volatile uint8_t *) & (hperh->perh->DATA)) = buf[i]; + + ret = CRC->CHECKSUM; + hperh->state = CRC_STATE_READY; + __UNLOCK(hperh); + + return ret; +} + +/** + * @brief Calculate the crc value of data by halfword. + * @param hperh: Pointer to a crc_handle_t structure that contains + * the configuration information for the specified CRC module. + * @param buf: Pointer to data buffer + * @param size: The size of data to be calculate,width is 2 bytes. + * @retval result, the result of a amount data + */ +uint32_t ald_crc_calculate_halfword(crc_handle_t *hperh, uint16_t *buf, uint32_t size) +{ + uint32_t i; + uint32_t ret; + + assert_param(IS_CRC(hperh->perh)); + + if (buf == NULL || size == 0) + return 0; + + __LOCK(hperh); + MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_16 << CRC_CR_DATLEN_POSS); + hperh->state = CRC_STATE_BUSY; + + for (i = 0; i < size; i++) + *((volatile uint16_t *) & (hperh->perh->DATA)) = buf[i]; + + ret = CRC->CHECKSUM; + hperh->state = CRC_STATE_READY; + __UNLOCK(hperh); + + return ret; +} + +/** + * @brief Calculate the crc value of data by word. + * @param hperh: Pointer to a crc_handle_t structure that contains + * the configuration information for the specified CRC module. + * @param buf: Pointer to data buffer + * @param size: The size of data to be calculate,width is 4 bytes + * @retval result, the result of a amount data + */ +uint32_t ald_crc_calculate_word(crc_handle_t *hperh, uint32_t *buf, uint32_t size) +{ + uint32_t i; + uint32_t ret; + + assert_param(IS_CRC(hperh->perh)); + + if (buf == NULL || size == 0) + return 0; + + __LOCK(hperh); + MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_32 << CRC_CR_DATLEN_POSS); hperh->state = CRC_STATE_BUSY; for (i = 0; i < size; i++) @@ -130,6 +195,7 @@ uint32_t crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size) return ret; } + /** * @} */ @@ -150,7 +216,7 @@ uint32_t crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size) * @param channel: DMA channel as CRC transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *res, uint16_t size, uint8_t channel) +ald_status_t ald_crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *res, uint16_t size, uint8_t channel) { if (hperh->state != CRC_STATE_READY) return BUSY; @@ -159,6 +225,7 @@ ald_status_t crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *r return ERROR; __LOCK(hperh); + MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_8 << CRC_CR_DATLEN_POSS); hperh->state = CRC_STATE_BUSY; @@ -173,7 +240,7 @@ ald_status_t crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *r hperh->hdma.err_arg = (void *)hperh; hperh->hdma.err_cbk = &crc_dma_error; - dma_config_struct(&(hperh->hdma.config)); + ald_dma_config_struct(&(hperh->hdma.config)); hperh->hdma.config.data_width = DMA_DATA_SIZE_BYTE; hperh->hdma.config.src = (void *)buf; hperh->hdma.config.dst = (void *)&hperh->perh->DATA; @@ -183,7 +250,59 @@ ald_status_t crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *r hperh->hdma.config.msel = DMA_MSEL_CRC; hperh->hdma.config.msigsel = DMA_MSIGSEL_NONE; hperh->hdma.config.channel = channel; - dma_config_basic(&(hperh->hdma)); + ald_dma_config_basic(&(hperh->hdma)); + + __UNLOCK(hperh); + CRC_DMA_ENABLE(hperh); + + return OK; +} + +/** + * @brief Calculate an amount of data used dma channel,data width is half-word. + * @param hperh: Pointer to a crc_handle_t structure that contains + * the configuration information for the specified CRC module. + * @param buf: Pointer to half_word data buffer + * @param res: Pointer to result + * @param size: Amount of half_word data to be Calculate + * @param channel: DMA channel as CRC transmit + * @retval Status, see @ref ald_status_t. + */ +ald_status_t ald_crc_calculate_halfword_by_dma(crc_handle_t *hperh, uint16_t *buf, uint32_t *res, uint16_t size, uint8_t channel) +{ + if (hperh->state != CRC_STATE_READY) + return BUSY; + + if (buf == NULL || size == 0) + return ERROR; + + __LOCK(hperh); + MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_16 << CRC_CR_DATLEN_POSS); + + hperh->state = CRC_STATE_BUSY; + + hperh->cal_buf = (uint8_t *)buf; + hperh->cal_res = res; + + if (hperh->hdma.perh == NULL) + hperh->hdma.perh = DMA0; + + hperh->hdma.cplt_arg = (void *)hperh; + hperh->hdma.cplt_cbk = &crc_dma_calculate_cplt; + hperh->hdma.err_arg = (void *)hperh; + hperh->hdma.err_cbk = &crc_dma_error; + + ald_dma_config_struct(&(hperh->hdma.config)); + hperh->hdma.config.data_width = DMA_DATA_SIZE_HALFWORD; + hperh->hdma.config.src = (void *)buf; + hperh->hdma.config.dst = (void *)&hperh->perh->DATA; + hperh->hdma.config.size = size; + hperh->hdma.config.src_inc = DMA_DATA_INC_HALFWORD; + hperh->hdma.config.dst_inc = DMA_DATA_INC_NONE; + hperh->hdma.config.msel = DMA_MSEL_CRC; + hperh->hdma.config.msigsel = DMA_MSIGSEL_NONE; + hperh->hdma.config.channel = channel; + ald_dma_config_basic(&(hperh->hdma)); __UNLOCK(hperh); CRC_DMA_ENABLE(hperh); @@ -191,13 +310,66 @@ ald_status_t crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *r return OK; } +/** + * @brief Calculate an amount of data used dma channel,data width is word. + * @param hperh: Pointer to a crc_handle_t structure that contains + * the configuration information for the specified CRC module. + * @param buf: Pointer to word data buffer + * @param res: Pointer to result + * @param size: Amount of word data to be Calculate + * @param channel: DMA channel as CRC transmit + * @retval Status, see @ref ald_status_t. + */ +ald_status_t ald_crc_calculate_word_by_dma(crc_handle_t *hperh, uint32_t *buf, uint32_t *res, uint16_t size, uint8_t channel) +{ + if (hperh->state != CRC_STATE_READY) + return BUSY; + + if (buf == NULL || size == 0) + return ERROR; + + __LOCK(hperh); + MODIFY_REG(hperh->perh->CR, CRC_CR_DATLEN_MSK, CRC_DATASIZE_32 << CRC_CR_DATLEN_POSS); + + hperh->state = CRC_STATE_BUSY; + + hperh->cal_buf = (uint8_t *)buf; + hperh->cal_res = res; + + if (hperh->hdma.perh == NULL) + hperh->hdma.perh = DMA0; + + hperh->hdma.cplt_arg = (void *)hperh; + hperh->hdma.cplt_cbk = &crc_dma_calculate_cplt; + hperh->hdma.err_arg = (void *)hperh; + hperh->hdma.err_cbk = &crc_dma_error; + + ald_dma_config_struct(&(hperh->hdma.config)); + hperh->hdma.config.data_width = DMA_DATA_SIZE_WORD; + hperh->hdma.config.src = (void *)buf; + hperh->hdma.config.dst = (void *)&hperh->perh->DATA; + hperh->hdma.config.size = size; + hperh->hdma.config.src_inc = DMA_DATA_INC_WORD; + hperh->hdma.config.dst_inc = DMA_DATA_INC_NONE; + hperh->hdma.config.msel = DMA_MSEL_CRC; + hperh->hdma.config.msigsel = DMA_MSIGSEL_NONE; + hperh->hdma.config.channel = channel; + ald_dma_config_basic(&(hperh->hdma)); + + __UNLOCK(hperh); + CRC_DMA_ENABLE(hperh); + + return OK; +} + + /** * @brief Pauses the DMA Transfer. * @param hperh: Pointer to a crc_handle_t structure that contains * the configuration information for the specified CRC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t crc_dma_pause(crc_handle_t *hperh) +ald_status_t ald_crc_dma_pause(crc_handle_t *hperh) { __LOCK(hperh); CRC_DMA_DISABLE(hperh); @@ -212,7 +384,7 @@ ald_status_t crc_dma_pause(crc_handle_t *hperh) * the configuration information for the specified CRC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t crc_dma_resume(crc_handle_t *hperh) +ald_status_t ald_crc_dma_resume(crc_handle_t *hperh) { __LOCK(hperh); CRC_DMA_ENABLE(hperh); @@ -227,7 +399,7 @@ ald_status_t crc_dma_resume(crc_handle_t *hperh) * the configuration information for the specified CRC module. * @retval Status, see @ref ald_status_t. */ -ald_status_t crc_dma_stop(crc_handle_t *hperh) +ald_status_t ald_crc_dma_stop(crc_handle_t *hperh) { __LOCK(hperh); CRC_DMA_DISABLE(hperh); @@ -253,7 +425,7 @@ ald_status_t crc_dma_stop(crc_handle_t *hperh) * the configuration information for the specified CRC module. * @retval CRC state */ -crc_state_t crc_get_state(crc_handle_t *hperh) +crc_state_t ald_crc_get_state(crc_handle_t *hperh) { assert_param(IS_CRC(hperh->perh)); @@ -278,7 +450,7 @@ crc_state_t crc_get_state(crc_handle_t *hperh) * the configuration information for the specified CRC module. * @retval None */ -void crc_reset(crc_handle_t *hperh) +void ald_crc_reset(crc_handle_t *hperh) { hperh->perh->DATA = 0x0; hperh->perh->CR = 0x2; @@ -331,11 +503,11 @@ static void crc_dma_error(void *arg) /** * @} */ +#endif /* ALD_CRC */ /** * @} */ -#endif /* ALD_CRC */ /** * @} diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crypt.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crypt.c similarity index 88% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crypt.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crypt.c index 4cf2f6e5a9..30d7f1e3ef 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crypt.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_crypt.c @@ -3,7 +3,7 @@ * * @file ald_crypt.c * @brief CRYPT module driver. - * This is the common part of the CRYPT initialization + * This is the common part of the CRYPT initialization * * @version V1.0 * @date 7 Dec 2017 @@ -58,7 +58,7 @@ void crypt_reset(crypt_handle_t *hperh); * the configuration information for the specified CRYPT module. * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_init(crypt_handle_t *hperh) +ald_status_t ald_crypt_init(crypt_handle_t *hperh) { uint32_t tmp = 0; @@ -92,7 +92,7 @@ ald_status_t crypt_init(crypt_handle_t *hperh) * @param key: Pointer to key data buffer * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_write_key(crypt_handle_t *hperh, uint32_t *key) +ald_status_t ald_crypt_write_key(crypt_handle_t *hperh, uint32_t *key) { uint32_t *temp = key; uint32_t i; @@ -123,7 +123,7 @@ ald_status_t crypt_write_key(crypt_handle_t *hperh, uint32_t *key) * @param key: The pointer to the key * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_read_key(crypt_handle_t *hperh, uint32_t *key) +ald_status_t ald_crypt_read_key(crypt_handle_t *hperh, uint32_t *key) { uint32_t *temp = key; @@ -150,10 +150,11 @@ ald_status_t crypt_read_key(crypt_handle_t *hperh, uint32_t *key) * @param iv: Pointer to iv data buffer * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_write_ivr(crypt_handle_t *hperh, uint32_t *iv) +ald_status_t ald_crypt_write_ivr(crypt_handle_t *hperh, uint32_t *iv) { uint32_t *temp = iv; uint32_t i; + if (hperh->state == CRYPT_STATE_BUSY) return BUSY; @@ -181,7 +182,7 @@ ald_status_t crypt_write_ivr(crypt_handle_t *hperh, uint32_t *iv) * @param iv: Pointer to iv data buffer * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_read_ivr(crypt_handle_t *hperh, uint32_t *iv) +ald_status_t ald_crypt_read_ivr(crypt_handle_t *hperh, uint32_t *iv) { uint32_t *temp = iv; @@ -220,7 +221,7 @@ ald_status_t crypt_read_ivr(crypt_handle_t *hperh, uint32_t *iv) * @retval Status, see @ref ald_status_t. * @note the size is multiple of 16(ase) */ -ald_status_t crypt_encrypt(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size) +ald_status_t ald_crypt_encrypt(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size) { uint32_t count = 0; uint32_t i; @@ -248,7 +249,7 @@ ald_status_t crypt_encrypt(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t * plain_buf++; } - while (crypt_get_flag_status(hperh, CRYPT_FLAG_DONE) == SET); + while (ald_crypt_get_flag_status(hperh, CRYPT_FLAG_DONE) == SET); for (i = 0; i < hperh->step; i++) { @@ -273,7 +274,7 @@ ald_status_t crypt_encrypt(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t * * @retval Status, see @ref ald_status_t. * @note the size is multiple of 16(ase) */ -ald_status_t crypt_decrypt(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size) +ald_status_t ald_crypt_decrypt(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size) { uint32_t count = 0; uint32_t i; @@ -282,7 +283,7 @@ ald_status_t crypt_decrypt(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t if (hperh->init.mode == CRYPT_MODE_CTR) { - return crypt_encrypt(hperh, cipher_text, plain_text, size); + return ald_crypt_encrypt(hperh, cipher_text, plain_text, size); } if (hperh->state != CRYPT_STATE_READY) @@ -306,7 +307,7 @@ ald_status_t crypt_decrypt(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t cipher_buf++; } - while (crypt_get_flag_status(hperh, CRYPT_FLAG_DONE) == SET); + while (ald_crypt_get_flag_status(hperh, CRYPT_FLAG_DONE) == SET); for (i = 0; i < hperh->step; i++) { @@ -357,7 +358,7 @@ void gcm_mul(uint32_t *res, uint32_t *data, uint32_t *iv) * @param tag: Pointer to authentication tag buffer * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint32_t size, uint8_t *aadata, uint32_t alen, uint8_t *tag) +ald_status_t ald_crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint32_t size, uint8_t *aadata, uint32_t alen, uint8_t *tag) { uint8_t GCM_HASH_in[0x60] = {0}; uint8_t ecb[16] = {0}; @@ -376,53 +377,65 @@ ald_status_t crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint3 { GCM_HASH_in [i] = * (aadata + i); } + len += alen; + for (i = 0; i < v / 8; i++) { GCM_HASH_in[i + len] = 0; } + len += v / 8; + for (i = 0; i < size; i++) { GCM_HASH_in[i + len] = * (cipher_text + i); } + len += size; + for (i = 0; i < u / 8; i++) { GCM_HASH_in[i + len] = 0; } + len += u / 8; for (i = 0; i < 4; i++) { GCM_HASH_in[i + len] = 0; } + len += 4; for (i = 0; i < 4; i++) { GCM_HASH_in[i + len] = ((alen * 8) >> (8 * i)) & 0xFF; } + len += 4; for (i = 0; i < 4; i++) { GCM_HASH_in[i + len] = 0; } + len += 4; for (i = 0; i < 4; i++) { GCM_HASH_in[i + len] = ((size * 8) >> (8 * i)) & 0xFF; } + len += 4; CRYPT->CON &= ~(3 << CRYPT_CON_MODE_POSS); CRYPT->CON |= (CRYPT_MODE_ECB << CRYPT_CON_MODE_POSS); - crypt_encrypt(hperh, ecb, ecb, 16); + ald_crypt_encrypt(hperh, ecb, ecb, 16); k = len / 16; + for (i = 0; i < 16; i++) { tag[i] = 0; @@ -430,6 +443,7 @@ ald_status_t crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint3 cipher_text_temp = (uint32_t *)GCM_HASH_in; tag_temp = (uint32_t *)tag; + for (i = 0; i < k; i++) { for (j = 0; j < 4; j++) @@ -445,13 +459,13 @@ ald_status_t crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint3 * T = CIPH_K(J0)^S,J0=IV||0^31||1,CIPH_K is the algorithm of AES in ECB mode */ tag_temp = (uint32_t *)tag; - crypt_init(hperh); + ald_crypt_init(hperh); CRYPT->CON &= ~(3 << CRYPT_CON_MODE_POSS); CRYPT->CON |= (CRYPT_MODE_CTR << CRYPT_CON_MODE_POSS); - crypt_write_key(hperh, hperh->key); + ald_crypt_write_key(hperh, hperh->key); hperh->iv[3] = 1; - crypt_write_ivr(hperh, hperh->iv); - crypt_encrypt(hperh, tag, tag, 16); + ald_crypt_write_ivr(hperh, hperh->iv); + ald_crypt_encrypt(hperh, tag, tag, 16); return OK; } @@ -466,7 +480,7 @@ ald_status_t crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint3 * @retval Status, see @ref ald_status_t. * @note the size is multiple of 16(ase) */ -ald_status_t crypt_encrypt_by_it(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size) +ald_status_t ald_crypt_encrypt_by_it(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size) { uint32_t i; uint32_t *plain_buf = (uint32_t *)plain_text; @@ -486,7 +500,7 @@ ald_status_t crypt_encrypt_by_it(crypt_handle_t *hperh, uint8_t *plain_text, uin hperh->plain_text = plain_text; hperh->cipher_text = cipher_text; hperh->size = size; - crypt_interrupt_config(hperh, CRYPT_IT_IT, ENABLE); + ald_crypt_interrupt_config(hperh, CRYPT_IT_IT, ENABLE); for (i = 0; i < hperh->step; i++) { @@ -508,14 +522,14 @@ ald_status_t crypt_encrypt_by_it(crypt_handle_t *hperh, uint8_t *plain_text, uin * @retval Status, see @ref ald_status_t. * @note the size is multiple of 16(ase) */ -ald_status_t crypt_decrypt_by_it(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size) +ald_status_t ald_crypt_decrypt_by_it(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size) { uint32_t i; uint32_t *cipher_buf = (uint32_t *)cipher_text; if (hperh->init.mode == CRYPT_MODE_CTR) { - return crypt_decrypt_by_it(hperh, cipher_text, plain_text, size); + return ald_crypt_decrypt_by_it(hperh, cipher_text, plain_text, size); } if (hperh->state != CRYPT_STATE_READY) @@ -533,7 +547,7 @@ ald_status_t crypt_decrypt_by_it(crypt_handle_t *hperh, uint8_t *cipher_text, ui hperh->plain_text = plain_text; hperh->cipher_text = cipher_text; hperh->size = size; - crypt_interrupt_config(hperh, CRYPT_IT_IT, ENABLE); + ald_crypt_interrupt_config(hperh, CRYPT_IT_IT, ENABLE); for (i = 0; i < hperh->step; i++) { @@ -558,8 +572,8 @@ ald_status_t crypt_decrypt_by_it(crypt_handle_t *hperh, uint8_t *cipher_text, ui * @retval Status, see @ref ald_status_t. * @note the size is multiple of 16(ase) */ -ald_status_t crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, - uint8_t *cipher_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m) +ald_status_t ald_crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, + uint8_t *cipher_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m) { if (hperh->state != CRYPT_STATE_READY) return ERROR; @@ -579,6 +593,7 @@ ald_status_t crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, if (hperh->hdma_m2p.perh == NULL) hperh->hdma_m2p.perh = DMA0; + if (hperh->hdma_p2m.perh == NULL) hperh->hdma_p2m.perh = DMA0; @@ -594,7 +609,7 @@ ald_status_t crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, CRYPT_SETDIR(hperh, CRYPT_ENCRYPT); - dma_config_struct(&hperh->hdma_m2p.config); + ald_dma_config_struct(&hperh->hdma_m2p.config); hperh->hdma_m2p.config.data_width = DMA_DATA_SIZE_WORD; hperh->hdma_m2p.config.src = (void *)hperh->plain_text; hperh->hdma_m2p.config.dst = (void *)&hperh->perh->FIFO; @@ -604,9 +619,9 @@ ald_status_t crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, hperh->hdma_m2p.config.msel = DMA_MSEL_CRYPT; hperh->hdma_m2p.config.msigsel = DMA_MSIGSEL_CRYPT_WRITE; hperh->hdma_m2p.config.channel = channel_m2p; - dma_config_basic(&(hperh->hdma_m2p)); + ald_dma_config_basic(&(hperh->hdma_m2p)); - dma_config_struct(&hperh->hdma_p2m.config); + ald_dma_config_struct(&hperh->hdma_p2m.config); hperh->hdma_p2m.config.data_width = DMA_DATA_SIZE_WORD; hperh->hdma_p2m.config.src = (void *)&hperh->perh->FIFO; hperh->hdma_p2m.config.dst = (void *)hperh->cipher_text; @@ -616,7 +631,7 @@ ald_status_t crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, hperh->hdma_p2m.config.msel = DMA_MSEL_CRYPT; hperh->hdma_p2m.config.msigsel = DMA_MSIGSEL_CRYPT_READ; hperh->hdma_p2m.config.channel = channel_p2m; - dma_config_basic(&(hperh->hdma_p2m)); + ald_dma_config_basic(&(hperh->hdma_p2m)); CRYPT_DMA_ENABLE(hperh); __UNLOCK(hperh); @@ -636,14 +651,15 @@ ald_status_t crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t *plain_text, * @retval Status, see @ref ald_status_t. * @note the size is multiple of 16(ase) */ -ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, - uint8_t *plain_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m) +ald_status_t ald_crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, + uint8_t *plain_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m) { if (hperh->init.mode == CRYPT_MODE_CTR) - return crypt_decrypt_by_dma(hperh, cipher_text, plain_text, size, channel_m2p, channel_p2m); + return ald_crypt_decrypt_by_dma(hperh, cipher_text, plain_text, size, channel_m2p, channel_p2m); if (hperh->state != CRYPT_STATE_READY) return ERROR; + if (plain_text == NULL || cipher_text == NULL || size == 0) return ERROR; @@ -657,6 +673,7 @@ ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, if (hperh->hdma_m2p.perh == NULL) hperh->hdma_m2p.perh = DMA0; + if (hperh->hdma_p2m.perh == NULL) hperh->hdma_p2m.perh = DMA0; @@ -673,7 +690,7 @@ ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, CRYPT_SETDIR(hperh, CRYPT_DECRYPT); - dma_config_struct(&hperh->hdma_m2p.config); + ald_dma_config_struct(&hperh->hdma_m2p.config); hperh->hdma_m2p.config.data_width = DMA_DATA_SIZE_WORD; hperh->hdma_m2p.config.src = (void *)hperh->cipher_text; hperh->hdma_m2p.config.dst = (void *)&hperh->perh->FIFO; @@ -683,9 +700,9 @@ ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, hperh->hdma_m2p.config.msel = DMA_MSEL_CRYPT; hperh->hdma_m2p.config.msigsel = DMA_MSIGSEL_CRYPT_WRITE; hperh->hdma_m2p.config.channel = channel_m2p; - dma_config_basic(&(hperh->hdma_m2p)); + ald_dma_config_basic(&(hperh->hdma_m2p)); - dma_config_struct(&hperh->hdma_p2m.config); + ald_dma_config_struct(&hperh->hdma_p2m.config); hperh->hdma_p2m.config.data_width = DMA_DATA_SIZE_WORD; hperh->hdma_p2m.config.src = (void *)&hperh->perh->FIFO; hperh->hdma_p2m.config.dst = (void *)hperh->plain_text; @@ -695,7 +712,7 @@ ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, hperh->hdma_p2m.config.msel = DMA_MSEL_CRYPT; hperh->hdma_p2m.config.msigsel = DMA_MSIGSEL_CRYPT_READ; hperh->hdma_p2m.config.channel = channel_p2m; - dma_config_basic(&(hperh->hdma_p2m)); + ald_dma_config_basic(&(hperh->hdma_p2m)); CRYPT_DMA_ENABLE(hperh); __UNLOCK(hperh); @@ -718,7 +735,7 @@ ald_status_t crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t *cipher_text, * the configuration information for the specified CRYPT module. * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_dma_pause(crypt_handle_t *hperh) +ald_status_t ald_crypt_dma_pause(crypt_handle_t *hperh) { __LOCK(hperh); CRYPT_DMA_DISABLE(hperh); @@ -734,7 +751,7 @@ ald_status_t crypt_dma_pause(crypt_handle_t *hperh) * the configuration information for the specified CRYPT module. * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_dma_resume(crypt_handle_t *hperh) +ald_status_t ald_crypt_dma_resume(crypt_handle_t *hperh) { __LOCK(hperh); CRYPT_DMA_ENABLE(hperh); @@ -749,7 +766,7 @@ ald_status_t crypt_dma_resume(crypt_handle_t *hperh) * the configuration information for the specified CRYPT module. * @retval Status, see @ref ald_status_t. */ -ald_status_t crypt_dma_stop(crypt_handle_t *hperh) +ald_status_t ald_crypt_dma_stop(crypt_handle_t *hperh) { __LOCK(hperh); CRYPT_DMA_DISABLE(hperh); @@ -766,7 +783,7 @@ ald_status_t crypt_dma_stop(crypt_handle_t *hperh) * the configuration information for the specified CRYPT module. * @retval None */ -void crypt_irq_handle(crypt_handle_t *hperh) +void ald_crypt_irq_handler(crypt_handle_t *hperh) { uint32_t i; uint32_t *in_buf; @@ -783,15 +800,16 @@ void crypt_irq_handle(crypt_handle_t *hperh) out_buf = (uint32_t *)hperh->plain_text + hperh->count - hperh->step; } - if (crypt_get_flag_status(hperh, CRYPT_FLAG_AESIF) == SET) + if (ald_crypt_get_flag_status(hperh, CRYPT_FLAG_AESIF) == SET) { - crypt_clear_flag_status(hperh, CRYPT_FLAG_AESIF); + ald_crypt_clear_flag_status(hperh, CRYPT_FLAG_AESIF); } for (i = 0; i < hperh->step; i++) *out_buf++ = CRYPT_READ_FIFO(hperh); hperh->count += hperh->step; + if (hperh->count > (hperh->size / 4)) { hperh->count = 0; @@ -829,7 +847,7 @@ void crypt_irq_handle(crypt_handle_t *hperh) * - DISABLE * @retval None */ -void crypt_interrupt_config(crypt_handle_t *hperh, crypt_it_t it, type_func_t state) +void ald_crypt_interrupt_config(crypt_handle_t *hperh, crypt_it_t it, type_func_t state) { assert_param(IS_CRYPT(hperh->perh)); @@ -851,7 +869,7 @@ void crypt_interrupt_config(crypt_handle_t *hperh, crypt_it_t it, type_func_t st * - SET * - RESET */ -flag_status_t crypt_get_flag_status(crypt_handle_t *hperh, crypt_flag_t flag) +flag_status_t ald_crypt_get_flag_status(crypt_handle_t *hperh, crypt_flag_t flag) { assert_param(IS_CRYPT(hperh->perh)); assert_param(IS_CRYPT_FLAG(flag)); @@ -871,7 +889,7 @@ flag_status_t crypt_get_flag_status(crypt_handle_t *hperh, crypt_flag_t flag) * @arg CRYPT_FLAG_DONE: encrypt or decrypt Complete flag. * @retval None */ -void crypt_clear_flag_status(crypt_handle_t *hperh, crypt_flag_t flag) +void ald_crypt_clear_flag_status(crypt_handle_t *hperh, crypt_flag_t flag) { assert_param(IS_CRYPT(hperh->perh)); assert_param(IS_CRYPT_FLAG(flag)); @@ -885,13 +903,13 @@ void crypt_clear_flag_status(crypt_handle_t *hperh, crypt_flag_t flag) * @param hperh: Pointer to a crypt_handle_t structure that contains * the configuration information for the specified CRYPT module. * @param it: Specifies the CRYPT interrupt source to check. - * This parameter can be one of the following values: - * @arg crypt_it_t: CRYPT interrupt + * This parameter can be one of the following values: + * @arg crypt_it_t: CRYPT interrupt * @retval Status * - SET * - RESET */ -it_status_t crypt_get_it_status(crypt_handle_t *hperh, crypt_it_t it) +it_status_t ald_crypt_get_it_status(crypt_handle_t *hperh, crypt_it_t it) { assert_param(IS_CRYPT_IT(it)); @@ -917,7 +935,7 @@ it_status_t crypt_get_it_status(crypt_handle_t *hperh, crypt_it_t it) * the configuration information for the specified CRYPT module. * @retval CRYPT state */ -crypt_state_t crypt_get_state(crypt_handle_t *hperh) +crypt_state_t ald_crypt_get_state(crypt_handle_t *hperh) { assert_param(IS_CRYPT(hperh->perh)); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_dma.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_dma.c similarity index 79% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_dma.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_dma.c index 9a7d04c392..5847fa627d 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_dma.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_dma.c @@ -19,38 +19,38 @@ [..] The DMA driver can be used as follows: - (#) System initialization invokes dma_init(), mcu_ald_init() --> dma_init(). + (#) System initialization invokes ald_dma_init(), ald_cmu_init() --> ald_dma_init(). (#) Declare a dma_handle_t handle structure. (#) Configure the dma_handle_t structure, you can configure the - dma_config_t structure with the help of dma_config_struct(). + dma_config_t structure with the help of ald_dma_config_struct(). (#) Enable the DMA Configure: - (##) Memory -- memory: call dma_config_auto(). - (##) Peripheral -- memory: call dma_config_basic(). - (##) If you want use the dma easily, you can do this: - (+++) Memory -- memory: call dma_config_auto_easy(). - (+++) Peripheral -- memory: call dma_config_basic_easy(). + (##) Memory -- memory: call ald_dma_config_auto(). + (##) Peripheral -- memory: call ald_dma_config_basic(). + (##) If you want use the dma easily, you can do this: + (+++) Memory -- memory: call ald_dma_config_auto_easy(). + (+++) Peripheral -- memory: call ald_dma_config_basic_easy(). (#) Enable the DMA request signal: (##) Memory -- memory: the DMA request signal is request automatic. - (##) Peripheral -- memory: you need enable peripheral request signal. + (##) Peripheral -- memory: you need enable peripheral request signal. (#) If you enable DMA interrupt, the callback will be invoked: (##) When DMA transfer is completed, the cplt_cbk() will be invoked. - (##) When DMA bus occurs error, the err_cbk() will be invoked. + (##) When DMA bus occurs error, the err_cbk() will be invoked. (#) If you don't enable the DMA interrupt, you need do this: - (##) Polling the dma_get_flag_status(), this function's parameter is channel - or DMA_ERR. - (+++) When the function's Parameter is channel, if retval is SET, it means - the DMA transfer is completed. at this moment, you can do something, - and then, you need invoke dma_clear_flag_status() to clear flag. + (##) Polling the ald_dma_get_flag_status(), this function's parameter is channel + or DMA_ERR. + (+++) When the function's Parameter is channel, if retval is SET, it means + the DMA transfer is completed. at this moment, you can do something, + and then, you need invoke ald_dma_clear_flag_status() to clear flag. - (+++) When the function's Parameter is DMA_ERR, if retval is SET, it means - the DMA bus occurs error. at this moment, you can do something, - and then, you need invoke dma_clear_flag_status() to clear flag. + (+++) When the function's Parameter is DMA_ERR, if retval is SET, it means + the DMA bus occurs error. at this moment, you can do something, + and then, you need invoke ald_dma_clear_flag_status() to clear flag. @endverbatim */ @@ -167,7 +167,7 @@ static void dma_config_base(DMA_TypeDef *DMAx, dma_cycle_ctrl_t mode, dma_config * @brief Handle DMA interrupt * @retval None */ -void DMA_Handler(void) +void ald_dma_irq_handler(void) { uint32_t i, reg = DMA0->IFLAG; @@ -178,13 +178,13 @@ void DMA_Handler(void) if (dma0_cbk[i].cplt_cbk != NULL) dma0_cbk[i].cplt_cbk(dma0_cbk[i].cplt_arg); - dma_clear_flag_status(DMA0, i); + ald_dma_clear_flag_status(DMA0, i); } } if (READ_BIT(reg, (1U << DMA_ERR))) { - dma_clear_flag_status(DMA0, DMA_ERR); + ald_dma_clear_flag_status(DMA0, DMA_ERR); for (i = 0; i < DMA_CH_COUNT; ++i) { @@ -193,7 +193,6 @@ void DMA_Handler(void) } } - dma0_irq_cbk(); return; } /** @@ -215,20 +214,20 @@ void DMA_Handler(void) =================================================================== [..] This subsection provides two functions to Initilizate DMA: - (+) dma_reset(): Reset the DMA register. - - (+) dma_init(): Initializate the DMA module. this function is - invoked by mcu_ald_init(). - this function do this: - (++) Initializte private variable dma_ctrl_base and dma_cbk. - (++) Reset DMA register. - (++) Set DMA interrupt priority: preempt_prio=1, sub_priority=1 - (++) Enable DMA interrupt. - (++) Enable DMA bus error interrupt. - (++) Configure CTRLBASE resigter. - (++) Enable DMA module. - - (+) dma_config_struct(): Configure dma_config_t + (+) ald_dma_reset(): Reset the DMA register. + + (+) ald_dma_init(): Initializate the DMA module. this function is + invoked by ald_cmu_init(). + this function do this: + (++) Initializte private variable dma_ctrl_base and dma_cbk. + (++) Reset DMA register. + (++) Set DMA interrupt priority: preempt_prio=1, sub_priority=1 + (++) Enable DMA interrupt. + (++) Enable DMA bus error interrupt. + (++) Configure CTRLBASE resigter. + (++) Enable DMA module. + + (+) ald_dma_config_struct(): Configure dma_config_t structure using default parameter. @endverbatim @@ -240,7 +239,7 @@ void DMA_Handler(void) * @param DMAx: Pointer to DMA peripheral * @retval None */ -void dma_reset(DMA_TypeDef *DMAx) +void ald_dma_reset(DMA_TypeDef *DMAx) { uint32_t i; @@ -264,18 +263,18 @@ void dma_reset(DMA_TypeDef *DMAx) /** * @brief DMA module initialization, this function - * is invoked by mcu_ald_init(). + * is invoked by ald_cmu_init(). * @param DMAx: Pointer to DMA peripheral * @retval None */ -void dma_init(DMA_TypeDef *DMAx) +void ald_dma_init(DMA_TypeDef *DMAx) { assert_param(IS_DMA(DMAx)); memset(dma0_ctrl_base, 0x0, sizeof(dma0_ctrl_base)); memset(dma0_cbk, 0x0, sizeof(dma0_cbk)); - dma_reset(DMAx); + ald_dma_reset(DMAx); NVIC_SetPriority(DMA_IRQn, 2); NVIC_EnableIRQ(DMA_IRQn); SET_BIT(DMAx->IER, DMA_IER_DMAERRIE_MSK); @@ -292,7 +291,7 @@ void dma_init(DMA_TypeDef *DMAx) * @param p: Pointer to dma_config_t structure, see @ref dma_config_t * @retval None */ -void dma_config_struct(dma_config_t *p) +void ald_dma_config_struct(dma_config_t *p) { p->data_width = DMA_DATA_SIZE_BYTE; p->src_inc = DMA_DATA_INC_BYTE; @@ -323,19 +322,19 @@ void dma_config_struct(dma_config_t *p) This subsection provides some functions allowing to configure DMA channel. Include two type DMA transfer: (+) Carry data from memory to memory, this mode APIs are: - (++) dma_config_auto(): Configure DMA channel according to - the specified parameter in the dma_handle_t structure. - (++) dma_restart_auto(): Restart DMA transmitted. - (++) dma_config_auto_easy(): Configure DMA channel according - to the specified parameter. If you want use the dma easily, + (++) ald_dma_config_auto(): Configure DMA channel according to + the specified parameter in the dma_handle_t structure. + (++) ald_dma_restart_auto(): Restart DMA transmitted. + (++) ald_dma_config_auto_easy(): Configure DMA channel according + to the specified parameter. If you want use the dma easily, you can invoke this function. (+) Carry data from peripheral to memory or from memory to peripheral, this mode APIs are: - (++) dma_config_basic(): Configure DMA channel according to - the specified parameter in the dma_handle_t structure. - (++) dma_restart_basic(): Restart DMA transmitted. - (++) dma_config_basic_easy(): Configure DMA channel according - to the specified parameter. If you want use the dma easily, + (++) ald_dma_config_basic(): Configure DMA channel according to + the specified parameter in the dma_handle_t structure. + (++) ald_dma_restart_basic(): Restart DMA transmitted. + (++) ald_dma_config_basic_easy(): Configure DMA channel according + to the specified parameter. If you want use the dma easily, you can invoke this function. @endverbatim @@ -350,7 +349,7 @@ void dma_config_struct(dma_config_t *p) * configuration information for specified DMA channel. * @retval None */ -void dma_config_auto(dma_handle_t *hperh) +void ald_dma_config_auto(dma_handle_t *hperh) { dma0_cbk[hperh->config.channel].cplt_cbk = hperh->cplt_cbk; dma0_cbk[hperh->config.channel].err_cbk = hperh->err_cbk; @@ -358,7 +357,7 @@ void dma_config_auto(dma_handle_t *hperh) dma0_cbk[hperh->config.channel].err_arg = hperh->err_arg; dma_config_base(hperh->perh, DMA_CYCLE_CTRL_AUTO, &hperh->config); - dma_clear_flag_status(hperh->perh, hperh->config.channel); + ald_dma_clear_flag_status(hperh->perh, hperh->config.channel); WRITE_REG(hperh->perh->CHENSET, (1 << hperh->config.channel)); SET_BIT(hperh->perh->CHSWREQ, (1 << hperh->config.channel)); @@ -375,7 +374,7 @@ void dma_config_auto(dma_handle_t *hperh) * @param size: Size. * @retval None */ -void dma_restart_auto(dma_handle_t *hperh, void *src, void *dst, uint16_t size) +void ald_dma_restart_auto(dma_handle_t *hperh, void *src, void *dst, uint16_t size) { dma_descriptor_t *descr; @@ -400,7 +399,7 @@ void dma_restart_auto(dma_handle_t *hperh, void *src, void *dst, uint16_t size) descr->dst = (void *)((uint32_t)dst + ((size - 1) << hperh->config.data_width)); } - dma_clear_flag_status(hperh->perh, hperh->config.channel); + ald_dma_clear_flag_status(hperh->perh, hperh->config.channel); descr->ctrl.cycle_ctrl = DMA_CYCLE_CTRL_AUTO; descr->ctrl.n_minus_1 = size - 1; WRITE_REG(hperh->perh->CHENSET, (1 << hperh->config.channel)); @@ -419,19 +418,19 @@ void dma_restart_auto(dma_handle_t *hperh, void *src, void *dst, uint16_t size) * @param src: Source data begin pointer * @param dst: Destination data begin pointer * @param size: The total number of DMA transfers that DMA cycle contains - * @param channel: Channel index which well be used. + * @param channel: Channel index which will be used. * @param cbk: DMA complete callback function * * @retval None */ -void dma_config_auto_easy(DMA_TypeDef *DMAx, void *src, void *dst, - uint16_t size, uint8_t channel, void (*cbk)(void *arg)) +void ald_dma_config_auto_easy(DMA_TypeDef *DMAx, void *src, void *dst, + uint16_t size, uint8_t channel, void (*cbk)(void *arg)) { dma_handle_t hperh; assert_param(IS_DMA(DMAx)); - dma_config_struct(&hperh.config); + ald_dma_config_struct(&hperh.config); hperh.config.src = src; hperh.config.dst = dst; hperh.config.size = size; @@ -444,8 +443,8 @@ void dma_config_auto_easy(DMA_TypeDef *DMAx, void *src, void *dst, hperh.cplt_arg = NULL; hperh.err_cbk = NULL; - dma_clear_flag_status(DMAx, channel); - dma_config_auto(&hperh); + ald_dma_clear_flag_status(DMAx, channel); + ald_dma_config_auto(&hperh); return; } @@ -459,14 +458,14 @@ void dma_config_auto_easy(DMA_TypeDef *DMAx, void *src, void *dst, * configuration information for specified DMA channel. * @retval None */ -void dma_config_basic(dma_handle_t *hperh) +void ald_dma_config_basic(dma_handle_t *hperh) { dma0_cbk[hperh->config.channel].cplt_cbk = hperh->cplt_cbk; dma0_cbk[hperh->config.channel].err_cbk = hperh->err_cbk; dma0_cbk[hperh->config.channel].cplt_arg = hperh->cplt_arg; dma0_cbk[hperh->config.channel].err_arg = hperh->err_arg; - dma_clear_flag_status(hperh->perh, hperh->config.channel); + ald_dma_clear_flag_status(hperh->perh, hperh->config.channel); dma_config_base(hperh->perh, DMA_CYCLE_CTRL_BASIC, &hperh->config); WRITE_REG(hperh->perh->CHENSET, (1 << hperh->config.channel)); @@ -483,7 +482,7 @@ void dma_config_basic(dma_handle_t *hperh) * @param size: Size. * @retval None */ -void dma_restart_basic(dma_handle_t *hperh, void *src, void *dst, uint16_t size) +void ald_dma_restart_basic(dma_handle_t *hperh, void *src, void *dst, uint16_t size) { dma_descriptor_t *descr; @@ -508,7 +507,7 @@ void dma_restart_basic(dma_handle_t *hperh, void *src, void *dst, uint16_t size) descr->dst = (void *)((uint32_t)dst + ((size - 1) << hperh->config.data_width)); } - dma_clear_flag_status(hperh->perh, hperh->config.channel); + ald_dma_clear_flag_status(hperh->perh, hperh->config.channel); descr->ctrl.cycle_ctrl = DMA_CYCLE_CTRL_BASIC; descr->ctrl.n_minus_1 = size - 1; WRITE_REG(hperh->perh->CHENSET, (1 << hperh->config.channel)); @@ -527,19 +526,19 @@ void dma_restart_basic(dma_handle_t *hperh, void *src, void *dst, uint16_t size) * @param size: The total number of DMA transfers that DMA cycle contains * @param msel: Input source to DMA channel @ref dma_msel_t * @param msigsel: Input signal to DMA channel @ref dma_msigsel_t - * @param channel: Channel index which well be used + * @param channel: Channel index which will be used * @param cbk: DMA complete callback function * * @retval None * */ -void dma_config_basic_easy(DMA_TypeDef *DMAx, void *src, void *dst, uint16_t size, dma_msel_t msel, - dma_msigsel_t msigsel, uint8_t channel, void (*cbk)(void *arg)) +void ald_dma_config_basic_easy(DMA_TypeDef *DMAx, void *src, void *dst, uint16_t size, dma_msel_t msel, + dma_msigsel_t msigsel, uint8_t channel, void (*cbk)(void *arg)) { dma_handle_t hperh; assert_param(IS_DMA(DMAx)); - dma_config_struct(&hperh.config); + ald_dma_config_struct(&hperh.config); if (((uint32_t)src) >= 0x40000000) hperh.config.src_inc = DMA_DATA_INC_NONE; @@ -559,8 +558,8 @@ void dma_config_basic_easy(DMA_TypeDef *DMAx, void *src, void *dst, uint16_t siz hperh.cplt_arg = NULL; hperh.err_cbk = NULL; - dma_clear_flag_status(DMAx, channel); - dma_config_basic(&hperh); + ald_dma_clear_flag_status(DMAx, channel); + ald_dma_config_basic(&hperh); return; } @@ -580,14 +579,14 @@ void dma_config_basic_easy(DMA_TypeDef *DMAx, void *src, void *dst, uint16_t siz =================================================================== [..] This subsection provides some functions allowing to control DMA: - (+) dma_channel_config(): Control DMA channel ENABLE/DISABLE. - (+) dma_interrupt_config(): Control DMA channel interrupt ENABLE or + (+) ald_dma_channel_config(): Control DMA channel ENABLE/DISABLE. + (+) ald_dma_interrupt_config(): Control DMA channel interrupt ENABLE or DISABLE. - (+) dma_get_it_status(): Check whether the specified channel + (+) ald_dma_get_it_status(): Check whether the specified channel interrupt is SET or RESET. - (+) dma_get_flag_status(): Check whether the specified channel + (+) ald_dma_get_flag_status(): Check whether the specified channel flag is SET or RESET. - (+) dma_clear_flag_status(): Clear the specified channel + (+) ald_dma_clear_flag_status(): Clear the specified channel pending flag @endverbatim @@ -604,7 +603,7 @@ void dma_config_basic_easy(DMA_TypeDef *DMAx, void *src, void *dst, uint16_t siz * @arg DISABLE: Disable the channel * @retval None */ -void dma_channel_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state) +void ald_dma_channel_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state) { dma_descriptor_t *descr, *alt_descr; @@ -642,7 +641,7 @@ void dma_channel_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state) * * @retval None */ -void dma_interrupt_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state) +void ald_dma_interrupt_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state) { assert_param(IS_DMA(DMAx)); assert_param(IS_DMA_IT_TYPE(channel)); @@ -667,7 +666,7 @@ void dma_interrupt_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state) * - SET: Channel interrupt is set * - RESET: Channel interrupt is reset */ -it_status_t dma_get_it_status(DMA_TypeDef *DMAx, uint8_t channel) +it_status_t ald_dma_get_it_status(DMA_TypeDef *DMAx, uint8_t channel) { assert_param(IS_DMA(DMAx)); assert_param(IS_DMA_IT_TYPE(channel)); @@ -689,7 +688,7 @@ it_status_t dma_get_it_status(DMA_TypeDef *DMAx, uint8_t channel) * - SET: Channel flag is set * - RESET: Channel flag is reset */ -flag_status_t dma_get_flag_status(DMA_TypeDef *DMAx, uint8_t channel) +flag_status_t ald_dma_get_flag_status(DMA_TypeDef *DMAx, uint8_t channel) { assert_param(IS_DMA(DMAx)); assert_param(IS_DMA_IT_TYPE(channel)); @@ -708,7 +707,7 @@ flag_status_t dma_get_flag_status(DMA_TypeDef *DMAx, uint8_t channel) * @arg DMA_ERR: DMA bus error * @retval None */ -void dma_clear_flag_status(DMA_TypeDef *DMAx, uint8_t channel) +void ald_dma_clear_flag_status(DMA_TypeDef *DMAx, uint8_t channel) { assert_param(IS_DMA(DMAx)); assert_param(IS_DMA_IT_TYPE(channel)); @@ -716,17 +715,6 @@ void dma_clear_flag_status(DMA_TypeDef *DMAx, uint8_t channel) WRITE_REG(DMAx->ICFR, (1 << channel)); return; } - -/** - * @brief Interrupt callback function. - * @note This function is declared as __weak to be overwritten in case of other - * implementations in user file. - * @retval None - */ -__weak void dma0_irq_cbk(void) -{ - return; -} /** * @} */ diff --git a/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash.c new file mode 100644 index 0000000000..b7a3e128c9 --- /dev/null +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash.c @@ -0,0 +1,222 @@ +/** + ********************************************************************************* + * + * @file ald_flash.c + * @brief FLASH module driver. + * + * @version V1.0 + * @date 20 Nov 2017 + * @author AE Team + * @note + * + * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. + */ + +#include "ald_flash.h" + + +/** @addtogroup ES32FXXX_ALD + * @{ + */ + +/** @defgroup FLASH FLASH + * @brief FLASH module driver + * @{ + */ + +#ifdef ALD_FLASH + +#if defined ( __ICCARM__ ) + #define __RAMFUNC __ramfunc +#else + #define __RAMFUNC +#endif + +/** @defgroup Flash_Private_Variables Flash Private Variables + * @{ + */ +/* global variable*/ +static op_cmd_type OP_CMD = OP_FLASH; +/** + * @} + */ + +/** @defgroup Flash_Private_Functions Flash Private Functions + * @brief Flash Private functions + * @{ + */ +/** + * @brief Unlock the flash. + * @retval Status, see @ref ald_status_t. + */ +__RAMFUNC static ald_status_t flash_unlock(void) +{ + uint16_t i; + uint16_t op_cmd = OP_CMD; + + if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK)) + return ERROR; + + FLASH_REG_UNLOCK(); + FLASH_IAP_ENABLE(); + FLASH_REQ(); + + for (i = 0; i < 0xFFFF; i++) + { + if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_FLASHACK_MSK)) + break; + } + + return i == 0xFFFF ? ERROR : OK; +} + +/** + * @brief Lock the flash. + * @retval Status, see @ref ald_status_t. + */ +__RAMFUNC static ald_status_t flash_lock(void) +{ + uint16_t i; + uint16_t op_cmd = OP_CMD; + + FLASH_REG_UNLOCK(); + WRITE_REG(MSC->FLASHCR, 0x0); + + for (i = 0; i < 0xFFFF; i++) + { + if (!(READ_BIT(MSC->FLASHSR, MSC_FLASHSR_FLASHACK_MSK))) + break; + } + + return i == 0xFFFF ? ERROR : OK; +} + +/** + * @brief Erase one page. + * @param addr: The erased page's address + * @retval Status, see @ref ald_status_t. + */ +__RAMFUNC ald_status_t flash_page_erase(uint32_t addr) +{ + uint32_t i; + uint16_t op_cmd = OP_CMD; + + if (flash_unlock() != OK) + goto end; + + if (op_cmd == OP_FLASH) + { + CLEAR_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK); + MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, FLASH_PAGE_ADDR(addr) << MSC_FLASHADDR_ADDR_POSS); + } + else + { + SET_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK); + MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, INFO_PAGE_ADDR(addr) << MSC_FLASHADDR_ADDR_POSS); + } + + WRITE_REG(MSC->FLASHCMD, FLASH_CMD_PE); + + for (i = 0; i < 0xFFFF; i++) + { + if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK)) + continue; + + if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_ADDR_OV_MSK)) + goto end; + + if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_WRP_FLAG_MSK)) + goto end; + + if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_SERA_MSK)) + break; + } + + if (i == 0xFFFF) + goto end; + + if (flash_lock() == ERROR) + goto end; + + return OK; +end: + flash_lock(); + return ERROR; +} + +/** + * @brief Programme a word. + * @param addr: The word's address, it is must word align. + * @param data: The 8 bytes data be write. + * @param len: The number of data be write. + * @param fifo: Choose if use fifo. + * @retval Status, see @ref ald_status_t. + */ +__RAMFUNC ald_status_t flash_word_program(uint32_t addr, uint32_t *data, uint32_t len, uint32_t fifo) +{ + uint16_t i; + uint16_t prog_len; + uint32_t *p_data = data; + uint16_t op_cmd = OP_CMD; + + if (flash_unlock() != OK) + goto end; + + if (op_cmd == OP_FLASH) + CLEAR_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK); + else + SET_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK); + + MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, addr << MSC_FLASHADDR_ADDR_POSS); + MODIFY_REG(MSC->FLASHCR, MSC_FLASHCR_FIFOEN_MSK, fifo << MSC_FLASHCR_FIFOEN_POS); + + for (prog_len = 0; prog_len < len; prog_len++) + { + if (fifo) + { + WRITE_REG(MSC->FLASHFIFO, p_data[0]); + WRITE_REG(MSC->FLASHFIFO, p_data[1]); + } + else + { + WRITE_REG(MSC->FLASHDL, p_data[0]); + WRITE_REG(MSC->FLASHDH, p_data[1]); + WRITE_REG(MSC->FLASHCMD, FLASH_CMD_WP); + } + + p_data += 2; + + for (i = 0; i < 0xFFFF; i++) + { + if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK)) + continue; + + if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_PROG_MSK)) + break; + } + } + + if (i == 0xFFFF) + goto end; + + if (flash_lock() == ERROR) + goto end; + + return OK; +end: + flash_lock(); + return ERROR; +} +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash_ext.c similarity index 60% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash_ext.c index 0b15ad7ca8..87595d3ce9 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_flash_ext.c @@ -1,11 +1,11 @@ /** ********************************************************************************* * - * @file ald_flash.c + * @file ald_flash_ext.c * @brief FLASH module driver. * * @version V1.0 - * @date 20 Nov 2017 + * @date 15 May 2019 * @author AE Team * @note * @@ -29,22 +29,23 @@ ##### How to use this driver ##### ============================================================================== [..] - (#) programme flash using flash_write(uint32_t addr, uint8_t *buf, uint16_t len) + (#) programme flash using ald_flash_write(uint32_t addr, uint8_t *buf, uint16_t len) (++) call the function and supply all the three paraments is needs, addr means the first address to write in this operation, buf is a pointer to the data which - need writing to flash. + need writing to flash. - (#) erase flash using flash_erase(uint32_t addr, uint16_t len) + (#) erase flash using ald_flash_erase(uint32_t addr, uint16_t len) (++) call the function and supply two paraments, addr is the first address to erase, len is the length to erase - (#) read flash using flash_read(uint32_t *ram_addr, uint32_t addr, uint16_t len) + (#) read flash using ald_flash_read(uint32_t *ram_addr, uint32_t addr, uint16_t len) (++) read the flash and save to a buffer, ram_addr is the buffer's first address, addr is the start reading address in flash, len is the length need read @endverbatim */ + #include "ald_flash.h" @@ -52,227 +53,25 @@ * @{ */ -/** @defgroup FLASH FLASH - * @brief FLASH module driver +/** @addtogroup FLASH * @{ */ #ifdef ALD_FLASH -/** @addtogroup FLASH_Private_Types +/** @addtogroup Flash_Private_Variables * @{ */ - -/* opration buffer, global variable*/ +/* opration buffer*/ static uint8_t write_buf[FLASH_PAGE_SIZE]; -static op_cmd_type OP_CMD = OP_FLASH; - -#if defined ( __ICCARM__ ) - #define __RAMFUNC __ramfunc -#else - #define __RAMFUNC -#endif - /** * @} */ -/** @defgroup Flash_Private_Functions Flash Private Functions - * @brief Flash Private functions +/** @addtogroup Flash_Private_Functions * @{ */ -/** - * @brief Unlock the flash. - * @retval Status, see @ref ald_status_t. - */ -__RAMFUNC static ald_status_t flash_unlock(void) -{ - uint16_t i; - uint16_t op_cmd = OP_CMD; - - if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK)) - return ERROR; - - FLASH_REG_UNLOCK(); - FLASH_IAP_ENABLE(); - FLASH_REQ(); - - for (i = 0; i < 0xFFFF; i++) - { - if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_FLASHACK_MSK)) - break; - } - - return i == 0xFFFF ? ERROR : OK; -} - -/** - * @brief Lock the flash. - * @retval Status, see @ref ald_status_t. - */ -__RAMFUNC static ald_status_t flash_lock(void) -{ - uint16_t i; - uint16_t op_cmd = OP_CMD; - - FLASH_REG_UNLOCK(); - WRITE_REG(MSC->FLASHCR, 0x0); - - for (i = 0; i < 0xFFFF; i++) - { - if (!(READ_BIT(MSC->FLASHSR, MSC_FLASHSR_FLASHACK_MSK))) - break; - } - - return i == 0xFFFF ? ERROR : OK; -} - -/** - * @brief Erase one page. - * @param addr: The erased page's address - * @retval Status, see @ref ald_status_t. - */ -__RAMFUNC static ald_status_t flash_page_erase(uint32_t addr) -{ - uint32_t i; - uint16_t op_cmd = OP_CMD; - - __disable_irq(); - if (flash_unlock() != OK) - goto end; - - if (op_cmd == OP_FLASH) - { - CLEAR_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK); - MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, FLASH_PAGE_ADDR(addr) << MSC_FLASHADDR_ADDR_POSS); - } - else - { - SET_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK); - MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, INFO_PAGE_ADDR(addr) << MSC_FLASHADDR_ADDR_POSS); - } - - WRITE_REG(MSC->FLASHCMD, FLASH_CMD_PE); - - for (i = 0; i < 0xFFFF; i++) - { - if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK)) - continue; - if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_ADDR_OV_MSK)) - goto end; - if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_WRP_FLAG_MSK)) - goto end; - if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_SERA_MSK)) - break; - } - - if (i == 0xFFFF) - goto end; - - if (flash_lock() == ERROR) - goto end; - - __enable_irq(); - return OK; -end: - - if (flash_lock() == ERROR) - while (1); - - __enable_irq(); - return ERROR; -} - -/** - * @brief Programme a word. - * @param addr: The word's address, it is must word align. - * @param data: The 8 bytes data be write. - * @param len: The number of data be write. - * @param fifo: Choose if use fifo. - * @retval Status, see @ref ald_status_t. - */ -__RAMFUNC static ald_status_t flash_word_program(uint32_t addr, uint32_t data[], uint32_t len, uint32_t fifo) -{ - uint16_t i; - uint16_t prog_len; - uint32_t *p_data = data; - uint16_t op_cmd = OP_CMD; - - __disable_irq(); - if (flash_unlock() != OK) - goto end; - - if (op_cmd == OP_FLASH) - CLEAR_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK); - else - SET_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK); - - MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, addr << MSC_FLASHADDR_ADDR_POSS); - MODIFY_REG(MSC->FLASHCR, MSC_FLASHCR_FIFOEN_MSK, fifo << MSC_FLASHCR_FIFOEN_POS); - - for (prog_len = 0; prog_len < len; prog_len++) - { - if (fifo) - { - WRITE_REG(MSC->FLASHFIFO, p_data[0]); - WRITE_REG(MSC->FLASHFIFO, p_data[1]); - } - else - { - WRITE_REG(MSC->FLASHDL, p_data[0]); - WRITE_REG(MSC->FLASHDH, p_data[1]); - WRITE_REG(MSC->FLASHCMD, FLASH_CMD_WP); - } - - p_data += 2; - - for (i = 0; i < 0xFFFF; i++) - { - if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK)) - continue; - if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_PROG_MSK)) - break; - } - } - if (i == 0xFFFF) - goto end; - - if (flash_lock() == ERROR) - goto end; - - __enable_irq(); - return OK; -end: - if (flash_lock() == ERROR) - while (1); - - __enable_irq(); - return ERROR; -} - -/** - * @brief Read data from flash, and store in buffer. - * @param ram_addr: The stored buffer's address. - * @param addr: The start address in flash to read. - * @param len: The length of byte to read. - * @retval Status, see @ref ald_status_t. - */ -__RAMFUNC static ald_status_t __flash_read(uint32_t ram_addr[], uint32_t addr, uint32_t len) -{ - uint32_t i; - - if (!len) - return ERROR; - - for (i = 0; i < len; i++) - { - ram_addr[i] = ((uint32_t *)addr)[i]; - } - - return OK; -} - /** * @brief Check whether the flash between the given address section * have been writen, if it have been writen, return TRUE, else @@ -283,7 +82,7 @@ __RAMFUNC static ald_status_t __flash_read(uint32_t ram_addr[], uint32_t addr, u * - TRUE * - FALSE */ -__RAMFUNC static type_bool_t page_have_writen(uint32_t begin_addr, uint32_t end_addr) +static type_bool_t page_have_writen(uint32_t begin_addr, uint32_t end_addr) { uint8_t *addr_to_read; uint8_t value; @@ -310,15 +109,14 @@ __RAMFUNC static type_bool_t page_have_writen(uint32_t begin_addr, uint32_t end_ return value == 0xFF ? FALSE : TRUE; } - /** * @} */ -/** @defgroup FLASH_Exported_Functions FLASH Exported Functions +/** @defgroup Flash_Public_Functions Flash Public Functions * @verbatim =============================================================================== - ##### Flash oprate functions ##### + ##### Flash operation functions ##### =============================================================================== [..] This section provides functions allowing to operate flash, such as read and write. @@ -327,6 +125,35 @@ __RAMFUNC static type_bool_t page_have_writen(uint32_t begin_addr, uint32_t end_ * @{ */ +/** + * @brief read the specified length bytes from flash, and store to the specified area. + * @param ram_addr: the specified area to store the reading bytes. + * @param addr: the start address. + * @param len: the length to read. + * @retval Status, see @ref ald_status_t. + */ +ald_status_t ald_flash_read(uint32_t *ram_addr, uint32_t addr, uint16_t len) +{ + uint32_t i; + uint32_t temp; + + assert_param(IS_4BYTES_ALIGN(ram_addr)); + assert_param(IS_FLASH_ADDRESS(addr)); + assert_param(IS_FLASH_ADDRESS(addr + len - 1)); + + temp = (uint32_t)ram_addr; + + if (((temp & 0x3) != 0) || (((addr) & 0x3) != 0)) + return ERROR; + + for (i = 0; i < len; i++) + { + ram_addr[i] = ((uint32_t *)addr)[i]; + } + + return OK; +} + /** * @brief Write the give bytes to the given address section. * @param addr: The start address to write. @@ -335,7 +162,7 @@ __RAMFUNC static type_bool_t page_have_writen(uint32_t begin_addr, uint32_t end_ * @retval Status, see @ref ald_status_t. */ -__RAMFUNC ald_status_t flash_write(uint32_t addr, uint8_t *buf, uint16_t len) +ald_status_t ald_flash_write(uint32_t addr, uint8_t *buf, uint16_t len) { uint32_t index = 0; uint32_t para = 0; @@ -353,6 +180,8 @@ __RAMFUNC ald_status_t flash_write(uint32_t addr, uint8_t *buf, uint16_t len) len_to_write = len; + __disable_irq(); + while (len_to_write > 0) { need_erase_page = FALSE; @@ -369,12 +198,18 @@ __RAMFUNC ald_status_t flash_write(uint32_t addr, uint8_t *buf, uint16_t len) if (need_erase_page) { - if (ERROR == __flash_read((uint32_t *)write_buf, FLASH_PAGE_ADDR(start_write_addr), - FLASH_PAGE_SIZE >> 2)) + if (ERROR == ald_flash_read((uint32_t *)write_buf, FLASH_PAGE_ADDR(start_write_addr), + FLASH_PAGE_SIZE >> 2)) + { + __enable_irq(); return ERROR; + } if (ERROR == flash_page_erase(FLASH_PAGE_ADDR(start_write_addr))) + { + __enable_irq(); return ERROR; + } para = end_write_addr & (FLASH_PAGE_SIZE - 1); index = start_write_addr & (FLASH_PAGE_SIZE - 1); @@ -405,11 +240,15 @@ __RAMFUNC ald_status_t flash_write(uint32_t addr, uint8_t *buf, uint16_t len) } if (ERROR == flash_word_program(index, (uint32_t *)(write_buf + index2), (len_index >> 3), FLASH_FIFO)) + { + __enable_irq(); return ERROR; + } len_to_write = len_to_write - (end_write_addr - start_write_addr + 1); } + __enable_irq(); return OK; } @@ -419,9 +258,9 @@ __RAMFUNC ald_status_t flash_write(uint32_t addr, uint8_t *buf, uint16_t len) * @param len: The length to erase. * @retval Status, see @ref ald_status_t. */ -__RAMFUNC ald_status_t flash_erase(uint32_t addr, uint16_t len) +ald_status_t ald_flash_erase(uint32_t addr, uint16_t len) { - int32_t index; + int32_t index; int32_t para; int32_t start_erase_addr; int32_t end_erase_addr; @@ -434,6 +273,8 @@ __RAMFUNC ald_status_t flash_erase(uint32_t addr, uint16_t len) len_not_erase = len; + __disable_irq(); + while (len_not_erase > 0) { page_need_save = FALSE; @@ -448,6 +289,7 @@ __RAMFUNC ald_status_t flash_erase(uint32_t addr, uint16_t len) if (page_have_writen(FLASH_PAGE_ADDR(start_erase_addr), (start_erase_addr - 1))) page_need_save = TRUE; } + if (end_erase_addr != FLASH_PAGEEND_ADDR(end_erase_addr)) { if (page_have_writen((end_erase_addr + 1), FLASH_PAGEEND_ADDR(end_erase_addr))) @@ -456,8 +298,8 @@ __RAMFUNC ald_status_t flash_erase(uint32_t addr, uint16_t len) if (page_need_save) { - if (ERROR == __flash_read((uint32_t *)write_buf, FLASH_PAGE_ADDR(start_erase_addr), - FLASH_PAGE_SIZE >> 2)) + if (ERROR == ald_flash_read((uint32_t *)write_buf, FLASH_PAGE_ADDR(start_erase_addr), + FLASH_PAGE_SIZE >> 2)) { __enable_irq(); return ERROR; @@ -480,45 +322,25 @@ __RAMFUNC ald_status_t flash_erase(uint32_t addr, uint16_t len) index = FLASH_PAGE_ADDR(start_erase_addr); len_index = FLASH_PAGE_SIZE; + if (ERROR == flash_word_program(index, (uint32_t *)write_buf, (len_index >> 3), FLASH_FIFO)) { __enable_irq(); return ERROR; } } + len_not_erase = len_not_erase - (end_erase_addr - start_erase_addr + 1); } + __enable_irq(); return OK; } - -/** - * @brief read the specified length bytes from flash, and store to the specified area. - * @param ram_addr: the specified area to store the reading bytes. - * @param addr: the start address. - * @param len: the length to read. - * @retval Status, see @ref ald_status_t. - */ -__RAMFUNC ald_status_t flash_read(uint32_t *ram_addr, uint32_t addr, uint16_t len) -{ - uint32_t temp; - - assert_param(IS_4BYTES_ALIGN(ram_addr)); - assert_param(IS_FLASH_ADDRESS(addr)); - assert_param(IS_FLASH_ADDRESS(addr + len - 1)); - - temp = (uint32_t)ram_addr; - - if (((temp & 0x3) != 0) || (((addr) & 0x3) != 0)) - return ERROR; - - return __flash_read(ram_addr, addr, len) == ERROR ? ERROR : OK; -} - /** * @} */ + #endif /** diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_gpio.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_gpio.c similarity index 91% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_gpio.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_gpio.c index e1d95dca31..17b4464ac1 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_gpio.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_gpio.c @@ -72,7 +72,7 @@ [..] (#) Enable the GPIO clock. - (#) Configure the GPIO pin(s) using gpio_init(). + (#) Configure the GPIO pin(s) using ald_gpio_init(). (++) Configure the IO mode using "mode" member from gpio_init_t structure (++) Activate Pull-up, Pull-down resistor using "pupd" member from gpio_init_t structure. @@ -87,7 +87,7 @@ (++) Analog mode is required when a pin is to be used as ADC channel or DAC output. - (#) Configure the GPIO pin(s) using gpio_init_default(). + (#) Configure the GPIO pin(s) using ald_gpio_init_default(). (++) Configure GPIO pin using default param: init.mode = GPIO_MODE_OUTPUT; init.odos = GPIO_PUSH_PULL; @@ -98,8 +98,8 @@ init.func = GPIO_FUNC_1; (#) In case of external interrupt/event mode selection, user need invoke - gpio_exti_init() to configure some param. And then invoke - gpio_exti_interrupt_config() to enable/disable external interrupt/event. + ald_gpio_exti_init() to configure some param. And then invoke + ald_gpio_exti_interrupt_config() to enable/disable external interrupt/event. (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority mapped to the EXTI line using NVIC_SetPriority() and enable it using @@ -108,17 +108,17 @@ (#) To get the level of a pin configured in input mode use GPIO_read_pin(). (#) To set/reset the level of a pin configured in output mode use - gpio_write_pin()/gpio_toggle_pin(). + ald_gpio_write_pin()/ald_gpio_toggle_pin(). - (#) To lock pin configuration until next reset use gpio_lock_pin(). + (#) To lock pin configuration until next reset use ald_gpio_lock_pin(). (#) Configure external interrupt mode and enable/disable using - gpio_exti_interrupt_config(). + ald_gpio_exti_interrupt_config(). - (#) Get external interrupt flag status using gpio_exti_get_flag_status(). + (#) Get external interrupt flag status using ald_gpio_exti_get_flag_status(). (#) Clear pending external interrupt flag status using - gpio_exti_clear_flag_status(). + ald_gpio_exti_clear_flag_status(). @endverbatim */ @@ -166,7 +166,7 @@ * the configuration information for the specified parameters. * @retval None */ -void gpio_init(GPIO_TypeDef *GPIOx, uint16_t pin, gpio_init_t *init) +void ald_gpio_init(GPIO_TypeDef *GPIOx, uint16_t pin, gpio_init_t *init) { uint32_t i, pos, mask, tmp; @@ -247,7 +247,7 @@ void gpio_init(GPIO_TypeDef *GPIOx, uint16_t pin, gpio_init_t *init) * @param pin: The pin which need to initialize. * @retval None */ -void gpio_init_default(GPIO_TypeDef *GPIOx, uint16_t pin) +void ald_gpio_init_default(GPIO_TypeDef *GPIOx, uint16_t pin) { gpio_init_t init; @@ -260,7 +260,7 @@ void gpio_init_default(GPIO_TypeDef *GPIOx, uint16_t pin) init.type = GPIO_TYPE_CMOS; init.func = GPIO_FUNC_1; - gpio_init(GPIOx, pin, &init); + ald_gpio_init(GPIOx, pin, &init); return; } @@ -269,7 +269,7 @@ void gpio_init_default(GPIO_TypeDef *GPIOx, uint16_t pin) * @param GPIOx: Where x can be (A--H) to select the GPIO peripheral. * @retval None */ -void gpio_func_default(GPIO_TypeDef *GPIOx) +void ald_gpio_func_default(GPIO_TypeDef *GPIOx) { WRITE_REG(GPIOx->FUNC0, 0x00); WRITE_REG(GPIOx->FUNC1, 0x00); @@ -286,7 +286,7 @@ void gpio_func_default(GPIO_TypeDef *GPIOx) * the configuration information for the specified parameters. * @retval None */ -void gpio_exti_init(GPIO_TypeDef *GPIOx, uint16_t pin, exti_init_t *init) +void ald_gpio_exti_init(GPIO_TypeDef *GPIOx, uint16_t pin, exti_init_t *init) { uint8_t i; uint8_t port; @@ -376,7 +376,7 @@ void gpio_exti_init(GPIO_TypeDef *GPIOx, uint16_t pin, exti_init_t *init) * - BIT_SET * - BIT_RESET */ -uint8_t gpio_read_pin(GPIO_TypeDef *GPIOx, uint16_t pin) +uint8_t ald_gpio_read_pin(GPIO_TypeDef *GPIOx, uint16_t pin) { assert_param(IS_GPIO_PORT(GPIOx)); assert_param(IS_GPIO_PIN(pin)); @@ -395,7 +395,7 @@ uint8_t gpio_read_pin(GPIO_TypeDef *GPIOx, uint16_t pin) * @param val: The specifies value to be written. * @retval None */ -void gpio_write_pin(GPIO_TypeDef *GPIOx, uint16_t pin, uint8_t val) +void ald_gpio_write_pin(GPIO_TypeDef *GPIOx, uint16_t pin, uint8_t val) { assert_param(IS_GPIO_PORT(GPIOx)); assert_param(IS_GPIO_PIN(pin)); @@ -414,7 +414,7 @@ void gpio_write_pin(GPIO_TypeDef *GPIOx, uint16_t pin, uint8_t val) * @param pin: Specifies the pin to turn over. * @retval None */ -void gpio_toggle_pin(GPIO_TypeDef *GPIOx, uint16_t pin) +void ald_gpio_toggle_pin(GPIO_TypeDef *GPIOx, uint16_t pin) { assert_param(IS_GPIO_PORT(GPIOx)); assert_param(IS_GPIO_PIN(pin)); @@ -429,7 +429,7 @@ void gpio_toggle_pin(GPIO_TypeDef *GPIOx, uint16_t pin) * @param pin: Specifies the pin to turn over. * @retval None */ -void gpio_toggle_dir(GPIO_TypeDef *GPIOx, uint16_t pin) +void ald_gpio_toggle_dir(GPIO_TypeDef *GPIOx, uint16_t pin) { uint32_t i, pos, mask, tmp, value; @@ -477,7 +477,7 @@ void gpio_toggle_dir(GPIO_TypeDef *GPIOx, uint16_t pin) * @param pin: The specified Pin to be written. * @retval None */ -void gpio_lock_pin(GPIO_TypeDef *GPIOx, uint16_t pin) +void ald_gpio_lock_pin(GPIO_TypeDef *GPIOx, uint16_t pin) { assert_param(IS_GPIO_PORT(GPIOx)); assert_param(IS_GPIO_PIN(pin)); @@ -493,7 +493,7 @@ void gpio_lock_pin(GPIO_TypeDef *GPIOx, uint16_t pin) * @param GPIOx: Where x can be (A--H) to select the GPIO peripheral. * @retval The value; */ -uint16_t gpio_read_port(GPIO_TypeDef *GPIOx) +uint16_t ald_gpio_read_port(GPIO_TypeDef *GPIOx) { assert_param(IS_GPIO_PORT(GPIOx)); @@ -506,7 +506,7 @@ uint16_t gpio_read_port(GPIO_TypeDef *GPIOx) * @param val: The specifies value to be written. * @retval None */ -void gpio_write_port(GPIO_TypeDef *GPIOx, uint16_t val) +void ald_gpio_write_port(GPIO_TypeDef *GPIOx, uint16_t val) { assert_param(IS_GPIO_PORT(GPIOx)); @@ -543,7 +543,7 @@ void gpio_write_port(GPIO_TypeDef *GPIOx, uint16_t val) * @arg DISABLE * @retval None */ -void gpio_exti_interrupt_config(uint16_t pin, exti_trigger_style_t style, type_func_t status) +void ald_gpio_exti_interrupt_config(uint16_t pin, exti_trigger_style_t style, type_func_t status) { assert_param(IS_GPIO_PIN(pin)); assert_param(IS_TRIGGER_STYLE(style)); @@ -605,7 +605,7 @@ void gpio_exti_interrupt_config(uint16_t pin, exti_trigger_style_t style, type_f * - SET * - RESET */ -flag_status_t gpio_exti_get_flag_status(uint16_t pin) +flag_status_t ald_gpio_exti_get_flag_status(uint16_t pin) { assert_param(IS_GPIO_PIN(pin)); @@ -620,7 +620,7 @@ flag_status_t gpio_exti_get_flag_status(uint16_t pin) * @param pin: The pin which belong to external interrupt. * @retval None */ -void gpio_exti_clear_flag_status(uint16_t pin) +void ald_gpio_exti_clear_flag_status(uint16_t pin) { assert_param(IS_GPIO_PIN(pin)); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_i2c.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_i2c.c similarity index 85% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_i2c.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_i2c.c index e285872cf2..1e5f32cde1 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_i2c.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_i2c.c @@ -24,24 +24,24 @@ (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1, Dual Addressing mode, Own Address2, General call and Nostretch mode in the hperh init structure. - (#) Initialize the I2C registers by calling the i2c_init(). - (#) To check if target device is ready for communication, use the function i2c_is_device_ready() + (#) Initialize the I2C registers by calling the ald_i2c_init(). + (#) To check if target device is ready for communication, use the function ald_i2c_is_device_ready() (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : *** Polling mode IO operation *** ================================= [..] - (+) Transmit in master mode an amount of data in blocking mode using i2c_master_send() - (+) Receive in master mode an amount of data in blocking mode using i2c_master_recv() - (+) Transmit in slave mode an amount of data in blocking mode using i2c_slave_send() - (+) Receive in slave mode an amount of data in blocking mode using i2c_slave_recv() + (+) Transmit in master mode an amount of data in blocking mode using ald_i2c_master_send() + (+) Receive in master mode an amount of data in blocking mode using ald_i2c_master_recv() + (+) Transmit in slave mode an amount of data in blocking mode using ald_i2c_slave_send() + (+) Receive in slave mode an amount of data in blocking mode using ald_i2c_slave_recv() *** Polling mode IO MEM operation *** ===================================== [..] - (+) Write an amount of data in blocking mode to a specific memory address using i2c_mem_write() - (+) Read an amount of data in blocking mode from a specific memory address using i2c_mem_read() + (+) Write an amount of data in blocking mode to a specific memory address using ald_i2c_mem_write() + (+) Read an amount of data in blocking mode from a specific memory address using ald_i2c_mem_read() *** Interrupt mode IO operation *** @@ -49,16 +49,16 @@ [..] (+) The I2C interrupts should have the highest priority in the application in order to make them uninterruptible. - (+) Transmit in master mode an amount of data in non-blocking mode using i2c_master_send_by_it() + (+) Transmit in master mode an amount of data in non-blocking mode using ald_i2c_master_send_by_it() (+) At transmission end of transfer, hperh->master_tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->master_tx_cplt_cbk() - (+) Receive in master mode an amount of data in non-blocking mode using i2c_master_recv_by_it() + (+) Receive in master mode an amount of data in non-blocking mode using ald_i2c_master_recv_by_it() (+) At reception end of transfer, hperh->master_rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->master_rx_cplt_cbk() - (+) Transmit in slave mode an amount of data in non-blocking mode using i2c_slave_send_by_it() + (+) Transmit in slave mode an amount of data in non-blocking mode using ald_i2c_slave_send_by_it() (+) At transmission end of transfer, hperh->slave_tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->slave_tx_cplt_cbk() - (+) Receive in slave mode an amount of data in non-blocking mode using i2c_slave_recv_by_it() + (+) Receive in slave mode an amount of data in non-blocking mode using ald_i2c_slave_recv_by_it() (+) At reception end of transfer, hperh->slave_rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->slave_rx_cplt_cbk() (+) In case of transfer Error, hperh->error_callback() function is executed and user can @@ -70,11 +70,11 @@ (+) The I2C interrupts should have the highest priority in the application in order to make them uninterruptible. (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using - i2c_mem_write_by_it() + ald_i2c_mem_write_by_it() (+) At Memory end of write transfer, hperh->mem_tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->mem_tx_cplt_cbk() (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using - i2c_mem_read_by_it() + ald_i2c_mem_read_by_it() (+) At Memory end of read transfer, hperh->mem_rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->mem_rx_cplt_cbk() (+) In case of transfer Error, hperh->error_callback() function is executed and user can @@ -84,19 +84,19 @@ ============================== [..] (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using - i2c_master_send_by_dma() + ald_i2c_master_send_by_dma() (+) At transmission end of transfer, hperh->master_tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->master_tx_cplt_cbk() (+) Receive in master mode an amount of data in non-blocking mode (DMA) using - i2c_master_recv_by_dma() + ald_i2c_master_recv_by_dma() (+) At reception end of transfer, hperh->master_rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->master_rx_cplt_cbk() (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using - i2c_slave_send_by_dma() + ald_i2c_slave_send_by_dma() (+) At transmission end of transfer, hperh->slave_tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->slave_tx_cplt_cbk() (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using - i2c_slave_recv_by_dma() + ald_i2c_slave_recv_by_dma() (+) At reception end of transfer, hperh->slave_rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->slave_rx_cplt_cbk() (+) In case of transfer Error, hperh->error_callback() function is executed and user can @@ -106,11 +106,11 @@ ================================= [..] (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using - i2c_mem_write_by_dma() + ald_i2c_mem_write_by_dma() (+) At Memory end of write transfer, hperh->mem_tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->mem_tx_cplt_cbk() (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using - i2c_mem_read_by_dma() + ald_i2c_mem_read_by_dma() (+) At Memory end of read transfer, hperh->mem_rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->mem_rx_cplt_cbk() (+) In case of transfer Error, hperh->error_callback() function is executed and user can @@ -144,7 +144,7 @@ supported by the slave. (##) Data valid time (tVD;DAT) violated without the OVR flag being set: Workaround: If the slave device allows it, use the clock stretching mechanism - by programming no_stretch = I2C_NOSTRETCH_DISABLE in i2c_init. + by programming no_stretch = I2C_NOSTRETCH_DISABLE in ald_i2c_init. @endverbatim ********************************************************************************* @@ -229,7 +229,7 @@ static uint32_t i2c_configure_speed(i2c_handle_t *hperh, uint32_t i2c_clk); [..] This subsection provides a set of functions allowing to initialize and de-initialiaze the I2Cx peripheral: - (+) Call the function i2c_init() to configure the selected device with + (+) Call the function ald_i2c_init() to configure the selected device with the selected configuration: (++) Communication Speed (++) Duty cycle @@ -240,7 +240,7 @@ static uint32_t i2c_configure_speed(i2c_handle_t *hperh, uint32_t i2c_clk); (++) General call mode (++) Nostretch mode - (+) Call the function i2c_reset() to restore the default configuration + (+) Call the function ald_i2c_reset() to restore the default configuration of the selected I2Cx periperal. @endverbatim @@ -254,7 +254,7 @@ static uint32_t i2c_configure_speed(i2c_handle_t *hperh, uint32_t i2c_clk); * the configuration information for the specified I2C. * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_init(i2c_handle_t *hperh) +ald_status_t ald_i2c_init(i2c_handle_t *hperh) { uint32_t freqrange = 0; uint32_t pclk1 = 0; @@ -278,7 +278,7 @@ ald_status_t i2c_init(i2c_handle_t *hperh) hperh->lock = UNLOCK; hperh->state = I2C_STATE_BUSY; - pclk1 = cmu_get_pclk1_clock(); + pclk1 = ald_cmu_get_pclk1_clock(); I2C_DISABLE(hperh); freqrange = I2C_FREQ_RANGE(pclk1); @@ -305,7 +305,7 @@ ald_status_t i2c_init(i2c_handle_t *hperh) * the configuration information for the specified I2C. * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_reset(i2c_handle_t *hperh) +ald_status_t ald_i2c_reset(i2c_handle_t *hperh) { if (hperh == NULL) return ERROR; @@ -349,29 +349,29 @@ ald_status_t i2c_reset(i2c_handle_t *hperh) using DMA mode. (#) Blocking mode functions are : - (++) i2c_master_send() - (++) i2c_master_recv() - (++) i2c_slave_send() - (++) i2c_slave_recv() - (++) i2c_mem_write() - (++) i2c_mem_read() - (++) i2c_is_device_ready() + (++) ald_i2c_master_send() + (++) ald_i2c_master_recv() + (++) ald_i2c_slave_send() + (++) ald_i2c_slave_recv() + (++) ald_i2c_mem_write() + (++) ald_i2c_mem_read() + (++) ald_i2c_is_device_ready() (#) No-Blocking mode functions with Interrupt are : - (++) i2c_master_send_by_it() - (++) i2c_master_recv_by_it() - (++) i2c_slave_send_by_it() - (++) i2c_slave_recv_by_it() - (++) i2c_mem_write_by_it() - (++) i2c_mem_read_by_it() + (++) ald_i2c_master_send_by_it() + (++) ald_i2c_master_recv_by_it() + (++) ald_i2c_slave_send_by_it() + (++) ald_i2c_slave_recv_by_it() + (++) ald_i2c_mem_write_by_it() + (++) ald_i2c_mem_read_by_it() (#) No-Blocking mode functions with DMA are : - (++) i2c_master_send_by_dma() - (++) i2c_master_recv_by_dma() - (++) i2c_slave_send_by_dma() - (++) i2c_slave_recv_by_dma() - (++) i2c_mem_write_by_dma() - (++) i2c_mem_read_by_dma() + (++) ald_i2c_master_send_by_dma() + (++) ald_i2c_master_recv_by_dma() + (++) ald_i2c_slave_send_by_dma() + (++) ald_i2c_slave_recv_by_dma() + (++) ald_i2c_mem_write_by_dma() + (++) ald_i2c_mem_read_by_dma() (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: (++) hperh->mem_tx_cplt_cbk() @@ -396,8 +396,8 @@ ald_status_t i2c_reset(i2c_handle_t *hperh) * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_master_send(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, - uint16_t size, uint32_t timeout) +ald_status_t ald_i2c_master_send(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, + uint16_t size, uint32_t timeout) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -453,7 +453,7 @@ ald_status_t i2c_master_send(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *bu hperh->perh->DATA = (*buf++); --size; - if ((i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) && (size != 0)) + if ((ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) && (size != 0)) { hperh->perh->DATA = (*buf++); --size; @@ -492,8 +492,8 @@ ald_status_t i2c_master_send(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *bu * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_master_recv(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, - uint16_t size, uint32_t timeout) +ald_status_t ald_i2c_master_recv(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, + uint16_t size, uint32_t timeout) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -568,7 +568,7 @@ ald_status_t i2c_master_recv(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *bu (*buf++) = hperh->perh->DATA; --size; - if (i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) + if (ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) { (*buf++) = hperh->perh->DATA; --size; @@ -577,64 +577,64 @@ ald_status_t i2c_master_recv(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *bu switch (size) { - case 1: - if (i2c_wait_rxne_to_timeout(hperh, timeout) != OK) - { - if (hperh->error_code == I2C_ERROR_TIMEOUT) + case 1: + if (i2c_wait_rxne_to_timeout(hperh, timeout) != OK) { - __UNLOCK(hperh); - return TIMEOUT; + if (hperh->error_code == I2C_ERROR_TIMEOUT) + { + __UNLOCK(hperh); + return TIMEOUT; + } + else + { + __UNLOCK(hperh); + return ERROR; + } } - else + + (*buf++) = hperh->perh->DATA; + break; + + case 2: + if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) { __UNLOCK(hperh); - return ERROR; + return TIMEOUT; } - } - - (*buf++) = hperh->perh->DATA; - break; - case 2: - if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) - { - __UNLOCK(hperh); - return TIMEOUT; - } + __disable_irq(); + SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); + (*buf++) = hperh->perh->DATA; + __enable_irq(); + (*buf++) = hperh->perh->DATA; + break; - __disable_irq(); - SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); - (*buf++) = hperh->perh->DATA; - __enable_irq(); - (*buf++) = hperh->perh->DATA; - break; + case 3: + if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) + { + __UNLOCK(hperh); + return TIMEOUT; + } - case 3: - if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) - { - __UNLOCK(hperh); - return TIMEOUT; - } + CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); + __disable_irq(); + (*buf++) = hperh->perh->DATA; - CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); - __disable_irq(); - (*buf++) = hperh->perh->DATA; + if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) + { + __UNLOCK(hperh); + __enable_irq(); + return TIMEOUT; + } - if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) - { - __UNLOCK(hperh); + SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); + (*buf++) = hperh->perh->DATA; __enable_irq(); - return TIMEOUT; - } - - SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); - (*buf++) = hperh->perh->DATA; - __enable_irq(); - (*buf++) = hperh->perh->DATA; - break; + (*buf++) = hperh->perh->DATA; + break; - default : - break; + default : + break; } hperh->state = I2C_STATE_READY; @@ -652,7 +652,7 @@ ald_status_t i2c_master_recv(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *bu * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_slave_send(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_i2c_slave_send(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -713,7 +713,7 @@ ald_status_t i2c_slave_send(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, ui hperh->perh->DATA = (*buf++); --size; - if ((i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) && (size != 0)) + if ((ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) && (size != 0)) { hperh->perh->DATA = (*buf++); --size; @@ -726,7 +726,7 @@ ald_status_t i2c_slave_send(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, ui return TIMEOUT; } - i2c_clear_flag_status(hperh, I2C_FLAG_AF); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_AF); CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); hperh->state = I2C_STATE_READY; @@ -744,7 +744,7 @@ ald_status_t i2c_slave_send(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, ui * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_slave_recv(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_i2c_slave_recv(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -794,7 +794,7 @@ ald_status_t i2c_slave_recv(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, ui (*buf++) = hperh->perh->DATA; --size; - if ((i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) && (size != 0)) + if ((ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) && (size != 0)) { (*buf++) = hperh->perh->DATA; --size; @@ -804,6 +804,7 @@ ald_status_t i2c_slave_recv(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, ui if (i2c_wait_stop_to_timeout(hperh, I2C_TIMEOUT_FLAG) != OK) { CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); + if (hperh->error_code == I2C_ERROR_AF) { __UNLOCK(hperh); @@ -833,7 +834,7 @@ ald_status_t i2c_slave_recv(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, ui * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_master_send_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint16_t size) +ald_status_t ald_i2c_master_send_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint16_t size) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -877,9 +878,9 @@ ald_status_t i2c_master_send_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8 /* Note : The I2C interrupts must be enabled after unlocking current process * to avoid the risk of I2C interrupt handle execution before current * process unlock */ - i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); return OK; } @@ -892,7 +893,7 @@ ald_status_t i2c_master_send_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8 * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_master_recv_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint16_t size) +ald_status_t ald_i2c_master_recv_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint16_t size) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -952,9 +953,9 @@ ald_status_t i2c_master_recv_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8 /* Note : The I2C interrupts must be enabled after unlocking current process * to avoid the risk of I2C interrupt handle execution before current * process unlock */ - i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); return OK; } @@ -966,7 +967,7 @@ ald_status_t i2c_master_recv_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8 * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_slave_send_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_i2c_slave_send_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t size) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -994,9 +995,9 @@ ald_status_t i2c_slave_send_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t si /* Note : The I2C interrupts must be enabled after unlocking current process * to avoid the risk of I2C interrupt handle execution before current * process unlock */ - i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); return OK; } @@ -1009,7 +1010,7 @@ ald_status_t i2c_slave_send_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t si * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_slave_recv_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_i2c_slave_recv_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t size) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1037,9 +1038,9 @@ ald_status_t i2c_slave_recv_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t si /* Note : The I2C interrupts must be enabled after unlocking current process * to avoid the risk of I2C interrupt handle execution before current * process unlock */ - i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); return OK; } @@ -1055,8 +1056,8 @@ ald_status_t i2c_slave_recv_by_it(i2c_handle_t *hperh, uint8_t *buf, uint16_t si * @param channel: DMA channel as I2C transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_master_send_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, - uint16_t size, uint8_t channel) +ald_status_t ald_i2c_master_send_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, + uint16_t size, uint8_t channel) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1087,7 +1088,7 @@ ald_status_t i2c_master_send_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint hperh->hdmatx.err_cbk = i2c_dma_error; hperh->hdmatx.err_arg = hperh; - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; hperh->hdmatx.config.size = size; @@ -1097,7 +1098,7 @@ ald_status_t i2c_master_send_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint hperh->hdmatx.config.msel = hperh->perh == I2C0 ? DMA_MSEL_I2C0 : DMA_MSEL_I2C1; hperh->hdmatx.config.msigsel = DMA_MSIGSEL_I2C_TXEMPTY; hperh->hdmatx.config.channel = channel; - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); if (i2c_master_req_write(hperh, dev_addr, I2C_TIMEOUT_FLAG) != OK) { @@ -1129,8 +1130,8 @@ ald_status_t i2c_master_send_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint * @param channel: DMA channel as I2C receive * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_master_recv_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, - uint16_t size, uint8_t channel) +ald_status_t ald_i2c_master_recv_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, + uint16_t size, uint8_t channel) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1161,7 +1162,7 @@ ald_status_t i2c_master_recv_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint hperh->hdmarx.err_cbk = i2c_dma_error; hperh->hdmarx.err_arg = (void *)hperh; - dma_config_struct(&hperh->hdmarx.config); + ald_dma_config_struct(&hperh->hdmarx.config); hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)buf; hperh->hdmarx.config.size = size; @@ -1171,7 +1172,7 @@ ald_status_t i2c_master_recv_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint hperh->hdmarx.config.msel = hperh->perh == I2C0 ? DMA_MSEL_I2C0 : DMA_MSEL_I2C1; hperh->hdmarx.config.msigsel = DMA_MSIGSEL_I2C_RNR; hperh->hdmarx.config.channel = channel; - dma_config_basic(&hperh->hdmarx); + ald_dma_config_basic(&hperh->hdmarx); if (i2c_master_req_read(hperh, dev_addr, I2C_TIMEOUT_FLAG) != OK) { @@ -1207,7 +1208,7 @@ ald_status_t i2c_master_recv_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint * @param channel: DMA channel as I2C Transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_slave_send_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_i2c_slave_send_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1238,7 +1239,7 @@ ald_status_t i2c_slave_send_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t s hperh->hdmatx.err_cbk = i2c_dma_error; hperh->hdmatx.err_arg = hperh; - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; hperh->hdmatx.config.size = size; @@ -1248,7 +1249,7 @@ ald_status_t i2c_slave_send_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t s hperh->hdmatx.config.msel = hperh->perh == I2C0 ? DMA_MSEL_I2C0 : DMA_MSEL_I2C1; hperh->hdmatx.config.msigsel = DMA_MSIGSEL_I2C_TXEMPTY; hperh->hdmatx.config.channel = channel; - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); SET_BIT(hperh->perh->CON2, I2C_CON2_DMAEN); SET_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); @@ -1290,7 +1291,7 @@ ald_status_t i2c_slave_send_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t s * @param channel: DMA channel as I2C receive * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_slave_recv_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_i2c_slave_recv_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1321,7 +1322,7 @@ ald_status_t i2c_slave_recv_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t s hperh->hdmarx.err_cbk = i2c_dma_error; hperh->hdmarx.err_arg = (void *)hperh; - dma_config_struct(&hperh->hdmarx.config); + ald_dma_config_struct(&hperh->hdmarx.config); hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)buf; hperh->hdmarx.config.size = size; @@ -1331,7 +1332,7 @@ ald_status_t i2c_slave_recv_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t s hperh->hdmarx.config.msel = hperh->perh == I2C0 ? DMA_MSEL_I2C0 : DMA_MSEL_I2C1; hperh->hdmarx.config.msigsel = DMA_MSIGSEL_I2C_RNR; hperh->hdmarx.config.channel = channel; - dma_config_basic(&hperh->hdmarx); + ald_dma_config_basic(&hperh->hdmarx); SET_BIT(hperh->perh->CON2, I2C_CON2_DMAEN); SET_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); @@ -1360,8 +1361,8 @@ ald_status_t i2c_slave_recv_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint16_t s * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, - i2c_addr_size_t add_size, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_i2c_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, + i2c_addr_size_t add_size, uint8_t *buf, uint16_t size, uint32_t timeout) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1416,7 +1417,7 @@ ald_status_t i2c_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_ hperh->perh->DATA = (*buf++); --size; - if ((i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) && (size != 0)) + if ((ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) && (size != 0)) { hperh->perh->DATA = (*buf++); --size; @@ -1441,7 +1442,7 @@ ald_status_t i2c_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_ SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); hperh->state = I2C_STATE_READY; hperh->mode = I2C_MODE_NONE; - __delay_ms(10); + ald_delay_ms(10); __UNLOCK(hperh); return OK; } @@ -1458,8 +1459,8 @@ ald_status_t i2c_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_ * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size, - uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_i2c_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size, + uint8_t *buf, uint16_t size, uint32_t timeout) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1535,7 +1536,7 @@ ald_status_t i2c_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_a (*buf++) = hperh->perh->DATA; --size; - if (i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) + if (ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF) == SET) { (*buf++) = hperh->perh->DATA; --size; @@ -1544,64 +1545,64 @@ ald_status_t i2c_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_a switch (size) { - case 1: - if (i2c_wait_rxne_to_timeout(hperh, timeout) != OK) - { - if (hperh->error_code == I2C_ERROR_TIMEOUT) + case 1: + if (i2c_wait_rxne_to_timeout(hperh, timeout) != OK) { - __UNLOCK(hperh); - return TIMEOUT; + if (hperh->error_code == I2C_ERROR_TIMEOUT) + { + __UNLOCK(hperh); + return TIMEOUT; + } + else + { + __UNLOCK(hperh); + return ERROR; + } } - else + + (*buf++) = hperh->perh->DATA; + break; + + case 2: + if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) { __UNLOCK(hperh); - return ERROR; + return TIMEOUT; } - } - - (*buf++) = hperh->perh->DATA; - break; - case 2: - if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) - { - __UNLOCK(hperh); - return TIMEOUT; - } + __disable_irq(); + SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); + (*buf++) = hperh->perh->DATA; + __enable_irq(); + (*buf++) = hperh->perh->DATA; + break; - __disable_irq(); - SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); - (*buf++) = hperh->perh->DATA; - __enable_irq(); - (*buf++) = hperh->perh->DATA; - break; + case 3: + if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) + { + __UNLOCK(hperh); + return TIMEOUT; + } - case 3: - if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) - { - __UNLOCK(hperh); - return TIMEOUT; - } + CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); + __disable_irq(); + (*buf++) = hperh->perh->DATA; - CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); - __disable_irq(); - (*buf++) = hperh->perh->DATA; + if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) + { + __UNLOCK(hperh); + __enable_irq(); + return TIMEOUT; + } - if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BTF, RESET, timeout) != OK) - { - __UNLOCK(hperh); + SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); + (*buf++) = hperh->perh->DATA; __enable_irq(); - return TIMEOUT; - } - - SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); - (*buf++) = hperh->perh->DATA; - __enable_irq(); - (*buf++) = hperh->perh->DATA; - break; + (*buf++) = hperh->perh->DATA; + break; - default: - break; + default: + break; } hperh->state = I2C_STATE_READY; @@ -1621,8 +1622,8 @@ ald_status_t i2c_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_a * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_mem_write_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, - i2c_addr_size_t add_size, uint8_t *buf, uint16_t size) +ald_status_t ald_i2c_mem_write_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, + i2c_addr_size_t add_size, uint8_t *buf, uint16_t size) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1665,9 +1666,9 @@ ald_status_t i2c_mem_write_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_ /* Note : The I2C interrupts must be enabled after unlocking current process * to avoid the risk of I2C interrupt handle execution before current * process unlock */ - i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); return OK; } @@ -1683,8 +1684,8 @@ ald_status_t i2c_mem_write_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_ * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_mem_read_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, - i2c_addr_size_t add_size, uint8_t *buf, uint16_t size) +ald_status_t ald_i2c_mem_read_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, + i2c_addr_size_t add_size, uint8_t *buf, uint16_t size) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1745,9 +1746,9 @@ ald_status_t i2c_mem_read_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t /* Note : The I2C interrupts must be enabled after unlocking current process * to avoid the risk of I2C interrupt handle execution before current * process unlock */ - i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, ENABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, ENABLE); return OK; } @@ -1765,8 +1766,8 @@ ald_status_t i2c_mem_read_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t * @param channel: DMA channel * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_mem_write_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size, - uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_i2c_mem_write_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size, + uint8_t *buf, uint16_t size, uint8_t channel) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1797,7 +1798,7 @@ ald_status_t i2c_mem_write_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16 hperh->hdmatx.cplt_arg = hperh; hperh->hdmatx.err_cbk = i2c_dma_error; hperh->hdmatx.err_arg = hperh; - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; @@ -1808,7 +1809,7 @@ ald_status_t i2c_mem_write_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16 hperh->hdmatx.config.msel = hperh->perh == I2C0 ? DMA_MSEL_I2C0 : DMA_MSEL_I2C1; hperh->hdmatx.config.msigsel = DMA_MSIGSEL_I2C_TXEMPTY; hperh->hdmatx.config.channel = channel; - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); if (i2c_req_mem_write(hperh, dev_addr, mem_addr, add_size, I2C_TIMEOUT_FLAG) != OK) { @@ -1841,8 +1842,8 @@ ald_status_t i2c_mem_write_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16 * @param channel: DMA channel * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_mem_read_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size, - uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_i2c_mem_read_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size, + uint8_t *buf, uint16_t size, uint8_t channel) { if (hperh->state != I2C_STATE_READY) return BUSY; @@ -1873,7 +1874,7 @@ ald_status_t i2c_mem_read_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_ hperh->hdmarx.cplt_arg = (void *)hperh; hperh->hdmarx.err_cbk = i2c_dma_error; hperh->hdmarx.err_arg = (void *)hperh; - dma_config_struct(&hperh->hdmarx.config); + ald_dma_config_struct(&hperh->hdmarx.config); hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)buf; @@ -1884,7 +1885,7 @@ ald_status_t i2c_mem_read_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_ hperh->hdmarx.config.msel = hperh->perh == I2C0 ? DMA_MSEL_I2C0 : DMA_MSEL_I2C1; hperh->hdmarx.config.msigsel = DMA_MSIGSEL_I2C_RNR; hperh->hdmarx.config.channel = channel; - dma_config_basic(&hperh->hdmarx); + ald_dma_config_basic(&hperh->hdmarx); if (i2c_req_mem_read(hperh, dev_addr, mem_addr, add_size, I2C_TIMEOUT_FLAG) != OK) { @@ -1922,7 +1923,7 @@ ald_status_t i2c_mem_read_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_ * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t i2c_is_device_ready(i2c_handle_t *hperh, uint16_t dev_addr, uint32_t trials, uint32_t timeout) +ald_status_t ald_i2c_is_device_ready(i2c_handle_t *hperh, uint16_t dev_addr, uint32_t trials, uint32_t timeout) { uint32_t tickstart = 0; uint32_t tmp1 = 0; @@ -1955,23 +1956,24 @@ ald_status_t i2c_is_device_ready(i2c_handle_t *hperh, uint16_t dev_addr, uint32_ } hperh->perh->DATA = I2C_7BIT_ADD_WRITE(dev_addr); - tickstart = __get_tick(); - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_ADDR); - tmp2 = i2c_get_flag_status(hperh, I2C_FLAG_AF); + tickstart = ald_get_tick(); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_ADDR); + tmp2 = ald_i2c_get_flag_status(hperh, I2C_FLAG_AF); tmp3 = hperh->state; while ((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != I2C_STATE_TIMEOUT)) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) hperh->state = I2C_STATE_TIMEOUT; - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_ADDR); - tmp2 = i2c_get_flag_status(hperh, I2C_FLAG_AF); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_ADDR); + tmp2 = ald_i2c_get_flag_status(hperh, I2C_FLAG_AF); tmp3 = hperh->state; } + hperh->state = I2C_STATE_READY; - if (i2c_get_flag_status(hperh, I2C_FLAG_ADDR) == SET) + if (ald_i2c_get_flag_status(hperh, I2C_FLAG_ADDR) == SET) { SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); I2C_CLEAR_ADDRFLAG(hperh); @@ -1990,7 +1992,7 @@ ald_status_t i2c_is_device_ready(i2c_handle_t *hperh, uint16_t dev_addr, uint32_ else { SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); - i2c_clear_flag_status(hperh, I2C_FLAG_AF); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_AF); if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != OK) @@ -2036,7 +2038,7 @@ ald_status_t i2c_is_device_ready(i2c_handle_t *hperh, uint16_t dev_addr, uint32_ * @arg DISABLE * @retval None */ -void i2c_interrupt_config(i2c_handle_t *hperh, i2c_interrupt_t it, type_func_t state) +void ald_i2c_interrupt_config(i2c_handle_t *hperh, i2c_interrupt_t it, type_func_t state) { assert_param(IS_I2C_TYPE(hperh->perh)); assert_param(IS_I2C_IT_TYPE(it)); @@ -2059,7 +2061,7 @@ void i2c_interrupt_config(i2c_handle_t *hperh, i2c_interrupt_t it, type_func_t s * - 0: RESET * - 1: SET */ -flag_status_t i2c_get_flag_status(i2c_handle_t *hperh, i2c_flag_t flag) +flag_status_t ald_i2c_get_flag_status(i2c_handle_t *hperh, i2c_flag_t flag) { flag_status_t state = RESET; @@ -2089,7 +2091,7 @@ flag_status_t i2c_get_flag_status(i2c_handle_t *hperh, i2c_flag_t flag) * - 0: RESET * - 1: SET */ -flag_status_t i2c_get_it_status(i2c_handle_t *hperh, i2c_interrupt_t it) +flag_status_t ald_i2c_get_it_status(i2c_handle_t *hperh, i2c_interrupt_t it) { assert_param(IS_I2C_TYPE(hperh->perh)); assert_param(IS_I2C_IT_TYPE(it)); @@ -2107,7 +2109,7 @@ flag_status_t i2c_get_it_status(i2c_handle_t *hperh, i2c_interrupt_t it) * This parameter can be one of the @ref uart_flag_t. * @retval None */ -void i2c_clear_flag_status(i2c_handle_t *hperh, i2c_flag_t flag) +void ald_i2c_clear_flag_status(i2c_handle_t *hperh, i2c_flag_t flag) { assert_param(IS_I2C_TYPE(hperh->perh)); assert_param(IS_I2C_FLAG(flag)); @@ -2127,7 +2129,7 @@ void i2c_clear_flag_status(i2c_handle_t *hperh, i2c_flag_t flag) * the configuration information for the specified I2C. * @retval ald_status_t state */ -i2c_state_t i2c_get_state(i2c_handle_t *hperh) +i2c_state_t ald_i2c_get_state(i2c_handle_t *hperh) { return hperh->state; } @@ -2138,7 +2140,7 @@ i2c_state_t i2c_get_state(i2c_handle_t *hperh) * the configuration information for the specified I2C. * @retval I2C Error Code */ -uint32_t i2c_get_error(i2c_handle_t *hperh) +uint32_t ald_i2c_get_error(i2c_handle_t *hperh) { return hperh->error_code; } @@ -2156,7 +2158,7 @@ uint32_t i2c_get_error(i2c_handle_t *hperh) * the configuration information for the specified I2C. * @retval None */ -void i2c_ev_irq_handler(i2c_handle_t *hperh) +void ald_i2c_ev_irq_handler(i2c_handle_t *hperh) { uint32_t tmp1 = 0; uint32_t tmp2 = 0; @@ -2165,12 +2167,12 @@ void i2c_ev_irq_handler(i2c_handle_t *hperh) if ((hperh->mode == I2C_MODE_MASTER) || (hperh->mode == I2C_MODE_MEM)) { - if (i2c_get_flag_status(hperh, I2C_FLAG_TRA) == SET) + if (ald_i2c_get_flag_status(hperh, I2C_FLAG_TRA) == SET) { - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_TXE); - tmp2 = i2c_get_it_status(hperh, I2C_IT_BUF); - tmp3 = i2c_get_flag_status(hperh, I2C_FLAG_BTF); - tmp4 = i2c_get_it_status(hperh, I2C_IT_EVT); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_TXE); + tmp2 = ald_i2c_get_it_status(hperh, I2C_IT_BUF); + tmp3 = ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF); + tmp4 = ald_i2c_get_it_status(hperh, I2C_IT_EVT); if ((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET)) i2c_master_send_txe(hperh); @@ -2181,10 +2183,10 @@ void i2c_ev_irq_handler(i2c_handle_t *hperh) /* I2C in mode Receiver */ else { - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_RXNE); - tmp2 = i2c_get_it_status(hperh, I2C_IT_BUF); - tmp3 = i2c_get_flag_status(hperh, I2C_FLAG_BTF); - tmp4 = i2c_get_it_status(hperh, I2C_IT_EVT); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_RXNE); + tmp2 = ald_i2c_get_it_status(hperh, I2C_IT_BUF); + tmp3 = ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF); + tmp4 = ald_i2c_get_it_status(hperh, I2C_IT_EVT); if ((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET)) i2c_master_recv_rxne(hperh); @@ -2196,10 +2198,10 @@ void i2c_ev_irq_handler(i2c_handle_t *hperh) /* Slave mode selected */ else { - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_ADDR); - tmp2 = i2c_get_it_status(hperh, (I2C_IT_EVT)); - tmp3 = i2c_get_flag_status(hperh, I2C_FLAG_STOPF); - tmp4 = i2c_get_flag_status(hperh, I2C_FLAG_TRA); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_ADDR); + tmp2 = ald_i2c_get_it_status(hperh, (I2C_IT_EVT)); + tmp3 = ald_i2c_get_flag_status(hperh, I2C_FLAG_STOPF); + tmp4 = ald_i2c_get_flag_status(hperh, I2C_FLAG_TRA); if ((tmp1 == SET) && (tmp2 == SET)) { @@ -2213,10 +2215,10 @@ void i2c_ev_irq_handler(i2c_handle_t *hperh) /* I2C in mode Transmitter */ else if (tmp4 == SET) { - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_TXE); - tmp2 = i2c_get_it_status(hperh, I2C_IT_BUF); - tmp3 = i2c_get_flag_status(hperh, I2C_FLAG_BTF); - tmp4 = i2c_get_it_status(hperh, I2C_IT_EVT); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_TXE); + tmp2 = ald_i2c_get_it_status(hperh, I2C_IT_BUF); + tmp3 = ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF); + tmp4 = ald_i2c_get_it_status(hperh, I2C_IT_EVT); if ((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET)) i2c_slave_send_txe(hperh); @@ -2227,10 +2229,10 @@ void i2c_ev_irq_handler(i2c_handle_t *hperh) /* I2C in mode Receiver */ else { - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_RXNE); - tmp2 = i2c_get_it_status(hperh, I2C_IT_BUF); - tmp3 = i2c_get_flag_status(hperh, I2C_FLAG_BTF); - tmp4 = i2c_get_it_status(hperh, I2C_IT_EVT); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_RXNE); + tmp2 = ald_i2c_get_it_status(hperh, I2C_IT_BUF); + tmp3 = ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF); + tmp4 = ald_i2c_get_it_status(hperh, I2C_IT_EVT); if ((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET)) i2c_slave_recv_rxne(hperh); @@ -2246,35 +2248,35 @@ void i2c_ev_irq_handler(i2c_handle_t *hperh) * the configuration information for I2C module * @retval NONE */ -void i2c_er_irq_handler(i2c_handle_t *hperh) +void ald_i2c_er_irq_handler(i2c_handle_t *hperh) { uint32_t tmp1 = 0; uint32_t tmp2 = 0; uint32_t tmp3 = 0; - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_BERR); - tmp2 = i2c_get_it_status(hperh, I2C_IT_ERR); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_BERR); + tmp2 = ald_i2c_get_it_status(hperh, I2C_IT_ERR); /* I2C Bus error interrupt occurred */ if ((tmp1 == SET) && (tmp2 == SET)) { hperh->error_code |= I2C_ERROR_BERR; - i2c_clear_flag_status(hperh, I2C_FLAG_BERR); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_BERR); SET_BIT(hperh->perh->CON1, I2C_CON1_SRST); } - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_ARLO); - tmp2 = i2c_get_it_status(hperh, I2C_IT_ERR); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_ARLO); + tmp2 = ald_i2c_get_it_status(hperh, I2C_IT_ERR); /* I2C Arbitration Loss error interrupt occurred */ if ((tmp1 == SET) && (tmp2 == SET)) { hperh->error_code |= I2C_ERROR_ARLO; - i2c_clear_flag_status(hperh, I2C_FLAG_ARLO); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_ARLO); } - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_AF); - tmp2 = i2c_get_it_status(hperh, I2C_IT_ERR); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_AF); + tmp2 = ald_i2c_get_it_status(hperh, I2C_IT_ERR); /* I2C Acknowledge failure error interrupt occurred */ if ((tmp1 == SET) && (tmp2 == SET)) @@ -2282,6 +2284,7 @@ void i2c_er_irq_handler(i2c_handle_t *hperh) tmp1 = hperh->mode; tmp2 = hperh->xfer_count; tmp3 = hperh->state; + if ((tmp1 == I2C_MODE_SLAVE) && (tmp2 == 0) && \ (tmp3 == I2C_STATE_BUSY_TX)) { @@ -2291,24 +2294,25 @@ void i2c_er_irq_handler(i2c_handle_t *hperh) { hperh->error_code |= I2C_ERROR_AF; SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); - i2c_clear_flag_status(hperh, I2C_FLAG_AF); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_AF); } } - tmp1 = i2c_get_flag_status(hperh, I2C_FLAG_OVR); - tmp2 = i2c_get_it_status(hperh, I2C_IT_ERR); + tmp1 = ald_i2c_get_flag_status(hperh, I2C_FLAG_OVR); + tmp2 = ald_i2c_get_it_status(hperh, I2C_IT_ERR); /* I2C Over-Run/Under-Run interrupt occurred */ if ((tmp1 == SET) && (tmp2 == SET)) { hperh->error_code |= I2C_ERROR_OVR; - i2c_clear_flag_status(hperh, I2C_FLAG_OVR); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_OVR); } if (hperh->error_code != I2C_ERROR_NONE) { hperh->state = I2C_STATE_READY; CLEAR_BIT(hperh->perh->CON1, I2C_CON1_POSAP); + if (hperh->error_callback) hperh->error_callback(hperh); } @@ -2335,7 +2339,7 @@ static ald_status_t i2c_master_send_txe(i2c_handle_t *hperh) { if (hperh->xfer_count == 0) { - i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); } else { @@ -2361,23 +2365,27 @@ static ald_status_t i2c_master_send_btf(i2c_handle_t *hperh) } else { - i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); + if (hperh->mode == I2C_MODE_MEM) { hperh->state = I2C_STATE_READY; + if (hperh->mem_tx_cplt_cbk) hperh->mem_tx_cplt_cbk(hperh); } else { hperh->state = I2C_STATE_READY; + if (hperh->master_tx_cplt_cbk) hperh->master_tx_cplt_cbk(hperh); } } + return OK; } @@ -2392,6 +2400,7 @@ static ald_status_t i2c_master_recv_rxne(i2c_handle_t *hperh) uint32_t tmp = 0; tmp = hperh->xfer_count; + if (tmp > 3) { (*hperh->p_buff++) = hperh->perh->DATA; @@ -2399,29 +2408,32 @@ static ald_status_t i2c_master_recv_rxne(i2c_handle_t *hperh) } else if ((tmp == 2) || (tmp == 3)) { - i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); } else { - i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); (*hperh->p_buff++) = hperh->perh->DATA; hperh->xfer_count--; if (hperh->mode == I2C_MODE_MEM) { hperh->state = I2C_STATE_READY; + if (hperh->mem_rx_cplt_cbk) hperh->mem_rx_cplt_cbk(hperh); } else { hperh->state = I2C_STATE_READY; + if (hperh->master_rx_cplt_cbk) hperh->master_rx_cplt_cbk(hperh); } } + return OK; } @@ -2441,8 +2453,8 @@ static ald_status_t i2c_master_recv_btf(i2c_handle_t *hperh) } else if (hperh->xfer_count == 2) { - i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); (*hperh->p_buff++) = hperh->perh->DATA; --hperh->xfer_count; @@ -2453,12 +2465,14 @@ static ald_status_t i2c_master_recv_btf(i2c_handle_t *hperh) if (hperh->mode == I2C_MODE_MEM) { hperh->state = I2C_STATE_READY; + if (hperh->mem_rx_cplt_cbk) hperh->mem_rx_cplt_cbk(hperh); } else { hperh->state = I2C_STATE_READY; + if (hperh->master_rx_cplt_cbk) hperh->master_rx_cplt_cbk(hperh); } @@ -2468,6 +2482,7 @@ static ald_status_t i2c_master_recv_btf(i2c_handle_t *hperh) (*hperh->p_buff++) = hperh->perh->DATA; --hperh->xfer_count; } + return OK; } @@ -2484,6 +2499,7 @@ static ald_status_t i2c_slave_send_txe(i2c_handle_t *hperh) hperh->perh->DATA = (*hperh->p_buff++); --hperh->xfer_count; } + return OK; } @@ -2500,6 +2516,7 @@ static ald_status_t i2c_slave_send_btf(i2c_handle_t *hperh) hperh->perh->DATA = (*hperh->p_buff++); --hperh->xfer_count; } + return OK; } @@ -2516,6 +2533,7 @@ static ald_status_t i2c_slave_recv_rxne(i2c_handle_t *hperh) (*hperh->p_buff++) = hperh->perh->DATA; --hperh->xfer_count; } + return OK; } @@ -2532,6 +2550,7 @@ static ald_status_t i2c_slave_recv_btf(i2c_handle_t *hperh) (*hperh->p_buff++) = hperh->perh->DATA; --hperh->xfer_count; } + return OK; } @@ -2562,9 +2581,9 @@ static ald_status_t i2c_slave_stopf(i2c_handle_t *hperh) --hperh->xfer_count; } - i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); __I2C_CLEAR_STOPFLAG(hperh); CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); @@ -2584,10 +2603,10 @@ static ald_status_t i2c_slave_stopf(i2c_handle_t *hperh) */ static ald_status_t i2c_slave_af(i2c_handle_t *hperh) { - i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); - i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); - i2c_clear_flag_status(hperh, I2C_FLAG_AF); + ald_i2c_interrupt_config(hperh, I2C_IT_EVT, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_BUF, DISABLE); + ald_i2c_interrupt_config(hperh, I2C_IT_ERR, DISABLE); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_AF); CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); hperh->state = I2C_STATE_READY; @@ -2643,6 +2662,7 @@ static ald_status_t i2c_master_req_write(i2c_handle_t *hperh, uint16_t dev_addr, else return TIMEOUT; } + return OK; } @@ -2669,6 +2689,7 @@ static ald_status_t i2c_master_req_read(i2c_handle_t *hperh, uint16_t dev_addr, else { hperh->perh->DATA = I2C_10BIT_HEADER_WRITE(dev_addr); + if (i2c_wait_master_addr_to_timeout(hperh, I2C_FLAG_ADD10, timeout) != OK) { if (hperh->error_code == I2C_ERROR_AF) @@ -2759,6 +2780,7 @@ static ald_status_t i2c_req_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, ui else { hperh->perh->DATA = I2C_MEM_ADD_MSB(mem_addr); + if (i2c_wait_txe_to_timeout(hperh, timeout) != OK) { if (hperh->error_code == I2C_ERROR_AF) @@ -2771,6 +2793,7 @@ static ald_status_t i2c_req_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, ui return TIMEOUT; } } + hperh->perh->DATA = I2C_MEM_ADD_LSB(mem_addr); } @@ -2840,6 +2863,7 @@ static ald_status_t i2c_req_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uin return TIMEOUT; } } + hperh->perh->DATA = I2C_MEM_ADD_LSB(mem_addr); } @@ -2918,7 +2942,7 @@ static void i2c_dma_slave_send_cplt(void *argv) if (i2c_wait_flag_to_timeout(hperh, I2C_FLAG_AF, RESET, I2C_TIMEOUT_FLAG) != OK) hperh->error_code |= I2C_ERROR_TIMEOUT; - i2c_clear_flag_status(hperh, I2C_FLAG_AF); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_AF); CLEAR_BIT(hperh->perh->CON1, I2C_CON1_ACKEN); CLEAR_BIT(hperh->perh->CON2, I2C_CON2_DMAEN); @@ -3083,6 +3107,7 @@ static uint32_t i2c_configure_speed(i2c_handle_t *hperh, uint32_t i2c_clk) if (hperh->init.clk_speed <= I2C_STANDARD_MODE_MAX_CLK) { tmp1 = (i2c_clk / (hperh->init.clk_speed << 1)); + if ((tmp1 & I2C_CKCFG_CLKSET) < 4) return 4; else @@ -3139,13 +3164,13 @@ static ald_status_t i2c_wait_flag_to_timeout(i2c_handle_t *hperh, i2c_flag_t fla { uint32_t tickstart = 0; - tickstart = __get_tick(); + tickstart = ald_get_tick(); if (status == RESET) { - while (i2c_get_flag_status(hperh, flag) == RESET) + while (ald_i2c_get_flag_status(hperh, flag) == RESET) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->state = I2C_STATE_READY; __UNLOCK(hperh); @@ -3155,9 +3180,9 @@ static ald_status_t i2c_wait_flag_to_timeout(i2c_handle_t *hperh, i2c_flag_t fla } else { - while (i2c_get_flag_status(hperh, flag) != RESET) + while (ald_i2c_get_flag_status(hperh, flag) != RESET) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->state = I2C_STATE_READY; __UNLOCK(hperh); @@ -3165,6 +3190,7 @@ static ald_status_t i2c_wait_flag_to_timeout(i2c_handle_t *hperh, i2c_flag_t fla } } } + return OK; } @@ -3180,13 +3206,14 @@ static ald_status_t i2c_wait_master_addr_to_timeout(i2c_handle_t *hperh, i2c_fla { uint32_t tickstart = 0; - tickstart = __get_tick(); - while (i2c_get_flag_status(hperh, flag) == RESET) + tickstart = ald_get_tick(); + + while (ald_i2c_get_flag_status(hperh, flag) == RESET) { - if (i2c_get_flag_status(hperh, I2C_FLAG_AF) == SET) + if (ald_i2c_get_flag_status(hperh, I2C_FLAG_AF) == SET) { SET_BIT(hperh->perh->CON1, I2C_CON1_STOP); - i2c_clear_flag_status(hperh, I2C_FLAG_AF); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_AF); hperh->error_code = I2C_ERROR_AF; hperh->state = I2C_STATE_READY; @@ -3196,7 +3223,7 @@ static ald_status_t i2c_wait_master_addr_to_timeout(i2c_handle_t *hperh, i2c_fla if (timeout != I2C_MAX_DELAY) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->state = I2C_STATE_READY; __UNLOCK(hperh); @@ -3204,6 +3231,7 @@ static ald_status_t i2c_wait_master_addr_to_timeout(i2c_handle_t *hperh, i2c_fla } } } + return OK; } @@ -3216,16 +3244,16 @@ static ald_status_t i2c_wait_master_addr_to_timeout(i2c_handle_t *hperh, i2c_fla */ static ald_status_t i2c_wait_txe_to_timeout(i2c_handle_t *hperh, uint32_t timeout) { - uint32_t tickstart = __get_tick(); + uint32_t tickstart = ald_get_tick(); - while (i2c_get_flag_status(hperh, I2C_FLAG_TXE) == RESET) + while (ald_i2c_get_flag_status(hperh, I2C_FLAG_TXE) == RESET) { if (i2c_is_ack_failed(hperh) != OK) return ERROR; if (timeout != I2C_MAX_DELAY) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->error_code |= I2C_ERROR_TIMEOUT; hperh->state = I2C_STATE_READY; @@ -3234,6 +3262,7 @@ static ald_status_t i2c_wait_txe_to_timeout(i2c_handle_t *hperh, uint32_t timeou } } } + return OK; } @@ -3246,9 +3275,9 @@ static ald_status_t i2c_wait_txe_to_timeout(i2c_handle_t *hperh, uint32_t timeou */ static ald_status_t i2c_wait_btf_to_timeout(i2c_handle_t *hperh, uint32_t timeout) { - uint32_t tickstart = __get_tick(); + uint32_t tickstart = ald_get_tick(); - while (i2c_get_flag_status(hperh, I2C_FLAG_BTF) == RESET) + while (ald_i2c_get_flag_status(hperh, I2C_FLAG_BTF) == RESET) { if (i2c_is_ack_failed(hperh) != OK) { @@ -3257,7 +3286,7 @@ static ald_status_t i2c_wait_btf_to_timeout(i2c_handle_t *hperh, uint32_t timeou if (timeout != I2C_MAX_DELAY) { - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->error_code |= I2C_ERROR_TIMEOUT; hperh->state = I2C_STATE_READY; @@ -3266,6 +3295,7 @@ static ald_status_t i2c_wait_btf_to_timeout(i2c_handle_t *hperh, uint32_t timeou } } } + return OK; } @@ -3279,14 +3309,14 @@ static ald_status_t i2c_wait_btf_to_timeout(i2c_handle_t *hperh, uint32_t timeou static ald_status_t i2c_wait_stop_to_timeout(i2c_handle_t *hperh, uint32_t timeout) { uint32_t tickstart = 0x00; - tickstart = __get_tick(); + tickstart = ald_get_tick(); - while (i2c_get_flag_status(hperh, I2C_FLAG_STOPF) == RESET) + while (ald_i2c_get_flag_status(hperh, I2C_FLAG_STOPF) == RESET) { if (i2c_is_ack_failed(hperh) != OK) return ERROR; - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->error_code |= I2C_ERROR_TIMEOUT; hperh->state = I2C_STATE_READY; @@ -3294,6 +3324,7 @@ static ald_status_t i2c_wait_stop_to_timeout(i2c_handle_t *hperh, uint32_t timeo return TIMEOUT; } } + return OK; } @@ -3307,20 +3338,20 @@ static ald_status_t i2c_wait_stop_to_timeout(i2c_handle_t *hperh, uint32_t timeo static ald_status_t i2c_wait_rxne_to_timeout(i2c_handle_t *hperh, uint32_t timeout) { uint32_t tickstart = 0x00; - tickstart = __get_tick(); + tickstart = ald_get_tick(); - while (i2c_get_flag_status(hperh, I2C_FLAG_RXNE) == RESET) + while (ald_i2c_get_flag_status(hperh, I2C_FLAG_RXNE) == RESET) { - if (i2c_get_flag_status(hperh, I2C_FLAG_STOPF) == SET) + if (ald_i2c_get_flag_status(hperh, I2C_FLAG_STOPF) == SET) { - i2c_clear_flag_status(hperh, I2C_FLAG_STOPF); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_STOPF); hperh->error_code = I2C_ERROR_NONE; hperh->state = I2C_STATE_READY; __UNLOCK(hperh); return ERROR; } - if ((timeout == 0) || ((__get_tick() - tickstart) > timeout)) + if ((timeout == 0) || ((ald_get_tick() - tickstart) > timeout)) { hperh->error_code |= I2C_ERROR_TIMEOUT; hperh->state = I2C_STATE_READY; @@ -3328,6 +3359,7 @@ static ald_status_t i2c_wait_rxne_to_timeout(i2c_handle_t *hperh, uint32_t timeo return TIMEOUT; } } + return OK; } @@ -3339,9 +3371,9 @@ static ald_status_t i2c_wait_rxne_to_timeout(i2c_handle_t *hperh, uint32_t timeo */ static ald_status_t i2c_is_ack_failed(i2c_handle_t *hperh) { - if (i2c_get_flag_status(hperh, I2C_FLAG_AF) == SET) + if (ald_i2c_get_flag_status(hperh, I2C_FLAG_AF) == SET) { - i2c_clear_flag_status(hperh, I2C_FLAG_AF); + ald_i2c_clear_flag_status(hperh, I2C_FLAG_AF); hperh->error_code = I2C_ERROR_AF; hperh->state = I2C_STATE_READY; __UNLOCK(hperh); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_iap.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_iap.c similarity index 92% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_iap.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_iap.c index 842e40938f..81b933d6c7 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_iap.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_iap.c @@ -49,7 +49,7 @@ * - 0: SUCCESS * - 1: ERROR */ -uint32_t iap_erase_page(uint32_t addr) +uint32_t ald_iap_erase_page(uint32_t addr) { uint32_t status; IAP_PE iap_pe = (IAP_PE)(*(uint32_t *)IAP_PE_ADDR); @@ -70,7 +70,7 @@ uint32_t iap_erase_page(uint32_t addr) * - 0: SUCCESS * - 1: ERROR */ -uint32_t iap_program_word(uint32_t addr, uint32_t data) +uint32_t ald_iap_program_word(uint32_t addr, uint32_t data) { uint32_t status; IAP_WP iap_wp = (IAP_WP)(*(uint32_t *)IAP_WP_ADDR); @@ -95,7 +95,7 @@ uint32_t iap_program_word(uint32_t addr, uint32_t data) * - 0: SUCCESS * - 1: ERROR */ -uint32_t iap_program_dword(uint32_t addr, uint32_t data_l, uint32_t data_h) +uint32_t ald_iap_program_dword(uint32_t addr, uint32_t data_l, uint32_t data_h) { uint32_t status; IAP_DWP iap_dwp = (IAP_DWP)(*(uint32_t *)IAP_DWP_ADDR); @@ -122,7 +122,7 @@ uint32_t iap_program_dword(uint32_t addr, uint32_t data_l, uint32_t data_h) * - 0: SUCCESS * - 1: ERROR */ -uint32_t iap_program_words(uint32_t addr, uint8_t *data, uint32_t len, uint32_t erase) +uint32_t ald_iap_program_words(uint32_t addr, uint8_t *data, uint32_t len, uint32_t erase) { uint32_t status; IAP_WSP iap_wsp = (IAP_WSP)(*(uint32_t *)IAP_WSP_ADDR); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pis.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pis.c similarity index 58% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pis.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pis.c index f15053cd6d..0966ea26a2 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pis.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pis.c @@ -42,7 +42,7 @@ * the configuration information for the specified PIS module. * @retval Status, see @ref ald_status_t. */ -ald_status_t pis_create(pis_handle_t *hperh) +ald_status_t ald_pis_create(pis_handle_t *hperh) { pis_divide_t temp; uint8_t clock_menu = 0; @@ -81,32 +81,39 @@ ald_status_t pis_create(pis_handle_t *hperh) /* configure sync clock, judging by producer clock with consumer clock */ switch (clock_menu) { - case 0x00: - case 0x11: - case 0x22: - case 0x33: - MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 0 << PIS_CH0_CON_SYNCSEL_POSS); - break; - case 0x01: - MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 5 << PIS_CH0_CON_SYNCSEL_POSS); - break; - case 0x02: - case 0x12: - MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 6 << PIS_CH0_CON_SYNCSEL_POSS); - break; - case 0x21: - MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 4 << PIS_CH0_CON_SYNCSEL_POSS); - break; - case 0x30: - MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 1 << PIS_CH0_CON_SYNCSEL_POSS); - break; - case 0x31: - MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 2 << PIS_CH0_CON_SYNCSEL_POSS); - break; - case 0x32: - MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 3 << PIS_CH0_CON_SYNCSEL_POSS); - default: - break; + case 0x00: + case 0x11: + case 0x22: + case 0x33: + MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 0 << PIS_CH0_CON_SYNCSEL_POSS); + break; + + case 0x01: + MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 5 << PIS_CH0_CON_SYNCSEL_POSS); + break; + + case 0x02: + case 0x12: + MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 6 << PIS_CH0_CON_SYNCSEL_POSS); + break; + + case 0x21: + MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 4 << PIS_CH0_CON_SYNCSEL_POSS); + break; + + case 0x30: + MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 1 << PIS_CH0_CON_SYNCSEL_POSS); + break; + + case 0x31: + MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 2 << PIS_CH0_CON_SYNCSEL_POSS); + break; + + case 0x32: + MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_SYNCSEL_MSK, 3 << PIS_CH0_CON_SYNCSEL_POSS); + + default: + break; } MODIFY_REG(hperh->perh->CH_CON[hperh->consumer_ch], PIS_CH0_CON_PULCK_MSK, hperh->init.consumer_clk << PIS_CH0_CON_PULCK_POSS); @@ -116,14 +123,16 @@ ald_status_t pis_create(pis_handle_t *hperh) /* enable consumer bit, switch pin of consumer */ switch (hperh->consumer_con) { - case PIS_CON_0: - PIS->TAR_CON0 |= hperh->consumer_pos; - break; - case PIS_CON_1: - PIS->TAR_CON1 |= hperh->consumer_pos; - break; - default: - break; + case PIS_CON_0: + PIS->TAR_CON0 |= hperh->consumer_pos; + break; + + case PIS_CON_1: + PIS->TAR_CON1 |= hperh->consumer_pos; + break; + + default: + break; } __UNLOCK(hperh); @@ -137,7 +146,7 @@ ald_status_t pis_create(pis_handle_t *hperh) * the configuration information for the specified PIS module. * @retval Status, see @ref ald_status_t. */ -ald_status_t pis_destroy(pis_handle_t *hperh) +ald_status_t ald_pis_destroy(pis_handle_t *hperh) { assert_param(IS_PIS(hperh->perh)); @@ -151,14 +160,16 @@ ald_status_t pis_destroy(pis_handle_t *hperh) switch (hperh->consumer_con) { - case PIS_CON_0: - PIS->TAR_CON0 &= ~(hperh->consumer_pos); - break; - case PIS_CON_1: - PIS->TAR_CON1 &= ~(hperh->consumer_pos); - break; - default: - break; + case PIS_CON_0: + PIS->TAR_CON0 &= ~(hperh->consumer_pos); + break; + + case PIS_CON_1: + PIS->TAR_CON1 &= ~(hperh->consumer_pos); + break; + + default: + break; } hperh->state = PIS_STATE_RESET; @@ -180,14 +191,14 @@ ald_status_t pis_destroy(pis_handle_t *hperh) * @param hperh: Pointer to a pis_handle_t structure that contains * the configuration information for the specified PIS module. * @param ch: The PIS channel enable output - * This parameter can be one of the following values: - * @arg PIS_OUT_CH_0 - * @arg PIS_OUT_CH_1 - * @arg PIS_OUT_CH_2 - * @arg PIS_OUT_CH_3 + * This parameter can be one of the following values: + * @arg PIS_OUT_CH_0 + * @arg PIS_OUT_CH_1 + * @arg PIS_OUT_CH_2 + * @arg PIS_OUT_CH_3 * @retval Status, see @ref ald_status_t. */ -ald_status_t pis_output_start(pis_handle_t *hperh, pis_out_ch_t ch) +ald_status_t ald_pis_output_start(pis_handle_t *hperh, pis_out_ch_t ch) { assert_param(IS_PIS(hperh->perh)); assert_param(IS_PIS_OUPUT_CH(ch)); @@ -203,14 +214,14 @@ ald_status_t pis_output_start(pis_handle_t *hperh, pis_out_ch_t ch) * @param hperh: Pointer to a pis_handle_t structure that contains * the configuration information for the specified PIS module. * @param ch: The PIS channel disable output - * This parameter can be one of the following values: - * @arg PIS_OUT_CH_0 - * @arg PIS_OUT_CH_1 - * @arg PIS_OUT_CH_2 - * @arg PIS_OUT_CH_3 + * This parameter can be one of the following values: + * @arg PIS_OUT_CH_0 + * @arg PIS_OUT_CH_1 + * @arg PIS_OUT_CH_2 + * @arg PIS_OUT_CH_3 * @retval Status, see @ref ald_status_t. */ -ald_status_t pis_output_stop(pis_handle_t *hperh, pis_out_ch_t ch) +ald_status_t ald_pis_output_stop(pis_handle_t *hperh, pis_out_ch_t ch) { assert_param(IS_PIS(hperh->perh)); assert_param(IS_PIS_OUPUT_CH(ch)); @@ -235,7 +246,7 @@ ald_status_t pis_output_stop(pis_handle_t *hperh, pis_out_ch_t ch) * the configuration information for the specified PIS module. * @retval ALD state */ -pis_state_t pis_get_state(pis_handle_t *hperh) +pis_state_t ald_pis_get_state(pis_handle_t *hperh) { assert_param(IS_PIS(hperh->perh)); return hperh->state; @@ -259,7 +270,7 @@ pis_state_t pis_get_state(pis_handle_t *hperh) * LPUART0) how to modulate the target output signal. * @retval Status, see @ref ald_status_t. */ -ald_status_t pis_modu_config(pis_handle_t *hperh, pis_modulate_config_t *config) +ald_status_t ald_pis_modu_config(pis_handle_t *hperh, pis_modulate_config_t *config) { assert_param(IS_PIS(hperh->perh)); assert_param(IS_PIS_MODU_TARGET(config->target)); @@ -270,38 +281,38 @@ ald_status_t pis_modu_config(pis_handle_t *hperh, pis_modulate_config_t *config) switch (config->target) { - case PIS_UART0_TX: - MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); - MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); - MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); - break; - - case PIS_UART1_TX: - MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); - MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); - MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); - break; - - case PIS_UART2_TX: - MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); - MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); - MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); - break; - - case PIS_UART3_TX: - MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); - MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); - MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); - break; - - case PIS_LPUART0_TX: - MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); - MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); - MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); - break; - - default: - break; + case PIS_UART0_TX: + MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); + MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); + MODIFY_REG(hperh->perh->UART0_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); + break; + + case PIS_UART1_TX: + MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); + MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); + MODIFY_REG(hperh->perh->UART1_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); + break; + + case PIS_UART2_TX: + MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); + MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); + MODIFY_REG(hperh->perh->UART2_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); + break; + + case PIS_UART3_TX: + MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); + MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); + MODIFY_REG(hperh->perh->UART3_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); + break; + + case PIS_LPUART0_TX: + MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_TXMCR_TXMLVLS_MSK, config->level << PIS_TXMCR_TXMLVLS_POS); + MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_TXMCR_TXMSS_MSK, config->src << PIS_TXMCR_TXMSS_POSS); + MODIFY_REG(hperh->perh->LPUART0_TXMCR, PIS_TXMCR_TXSIGS_MSK, config->channel << PIS_TXMCR_TXSIGS_POSS); + break; + + default: + break; } __UNLOCK(hperh); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pmu.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pmu.c similarity index 75% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pmu.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pmu.c index f959aa3001..0c488304a1 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pmu.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_pmu.c @@ -37,13 +37,12 @@ * @brief PMU module interrupt handler * @retval None */ -void LVD_Handler(void) +void ald_lvd_irq_handler(void) { SYSCFG_UNLOCK(); SET_BIT(PMU->LVDCR, PMU_LVDCR_LVDCIF_MSK); SYSCFG_LOCK(); - lvd_irq_cbk(); return; } /** @@ -64,7 +63,6 @@ void LVD_Handler(void) [..] This section provides functions allowing to: (+) Enter stop1 mode. (+) Enter stop2 mode. - (+) Enter standby mode. (+) Get wakeup status. (+) Clear wakeup status. @@ -76,7 +74,7 @@ void LVD_Handler(void) * @brief Enter stop1 mode * @retval None */ -void pmu_stop1_enter(void) +void ald_pmu_stop1_enter(void) { SYSCFG_UNLOCK(); MODIFY_REG(PMU->CR, PMU_CR_LPM_MSK, PMU_LP_STOP1 << PMU_CR_LPM_POSS); @@ -94,9 +92,10 @@ void pmu_stop1_enter(void) * @brief Enter stop2 mode * @retval None */ -void pmu_stop2_enter(void) +void ald_pmu_stop2_enter(void) { SYSCFG_UNLOCK(); + SET_BIT(PMU->CR, PMU_CR_LPSTOP_MSK); MODIFY_REG(PMU->CR, PMU_CR_LPM_MSK, PMU_LP_STOP2 << PMU_CR_LPM_POSS); SYSCFG_LOCK(); @@ -105,38 +104,6 @@ void pmu_stop2_enter(void) __WFI(); SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; - return; - -} - -/** - * @brief Enter standby mode - * @param port: The port whick wake up the standby mode. - * @retval None - */ -void pmu_standby_enter(pmu_standby_wakeup_sel_t port) -{ - assert_param(IS_PMU_STANDBY_PORT_SEL(port)); - - if (port != PMU_STANDBY_PORT_NONE) - { - BKPC_UNLOCK(); - MODIFY_REG(BKPC->CR, BKPC_CR_WKPS_MSK, port << BKPC_CR_WKPS_POSS); - SET_BIT(BKPC->CR, BKPC_CR_WKPEN_MSK); - BKPC_LOCK(); - - SYSCFG_UNLOCK(); - MODIFY_REG(PMU->CR, PMU_CR_WKPS_MSK, port << PMU_CR_WKPS_POSS); - SET_BIT(PMU->CR, PMU_CR_WKPEN_MSK); - MODIFY_REG(PMU->CR, PMU_CR_LPM_MSK, PMU_LP_STANDBY << PMU_CR_LPM_POSS); - SYSCFG_LOCK(); - } - - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - __WFI(); - SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; - return; } @@ -145,7 +112,7 @@ void pmu_standby_enter(pmu_standby_wakeup_sel_t port) * @param sr: Status bit. * @retval Status. */ -flag_status_t pmu_get_status(pmu_status_t sr) +flag_status_t ald_pmu_get_status(pmu_status_t sr) { assert_param(IS_PMU_STATUS(sr)); @@ -160,7 +127,7 @@ flag_status_t pmu_get_status(pmu_status_t sr) * @param sr: Status bit. * @retval None */ -void pmu_clear_status(pmu_status_t sr) +void ald_pmu_clear_status(pmu_status_t sr) { assert_param(IS_PMU_STATUS(sr)); SYSCFG_UNLOCK(); @@ -201,7 +168,7 @@ void pmu_clear_status(pmu_status_t sr) * @param state: New state, ENABLE/DISABLE; * @retval None */ -void pmu_lvd_config(pmu_lvd_voltage_sel_t sel, pmu_lvd_trigger_mode_t mode, type_func_t state) +void ald_pmu_lvd_config(pmu_lvd_voltage_sel_t sel, pmu_lvd_trigger_mode_t mode, type_func_t state) { assert_param(IS_FUNC_STATE(state)); SYSCFG_UNLOCK(); @@ -228,17 +195,6 @@ void pmu_lvd_config(pmu_lvd_voltage_sel_t sel, pmu_lvd_trigger_mode_t mode, type SYSCFG_LOCK(); return; } - -/** - * @brief Interrupt callback function. - * @note This function is declared as __weak to be overwritten in case of other - * implementations in user file. - * @retval None - */ -__weak void lvd_irq_cbk(void) -{ - return; -} /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rmu.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rmu.c similarity index 78% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rmu.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rmu.c index 5b8efcad02..b896bcf104 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rmu.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rmu.c @@ -38,7 +38,7 @@ * @param state: The new status: ENABLE/DISABLE. * @retval None */ -void rmu_bor_config(rmu_bor_filter_t flt, rmu_bor_vol_t vol, type_func_t state) +void ald_rmu_bor_config(rmu_bor_filter_t flt, rmu_bor_vol_t vol, type_func_t state) { assert_param(IS_FUNC_STATE(state)); @@ -67,7 +67,7 @@ void rmu_bor_config(rmu_bor_filter_t flt, rmu_bor_vol_t vol, type_func_t state) * @param state: Speicifies the type of the reset, * @retval The status: SET/RESET. */ -flag_status_t rmu_get_reset_status(rmu_state_t state) +flag_status_t ald_rmu_get_reset_status(rmu_state_t state) { assert_param(IS_RMU_STATE(state)); @@ -82,7 +82,7 @@ flag_status_t rmu_get_reset_status(rmu_state_t state) * @param state: Specifies the type of the reset, * @retval None */ -void rmu_clear_reset_status(rmu_state_t state) +void ald_rmu_clear_reset_status(rmu_state_t state) { assert_param(IS_RMU_STATE_CLEAR(state)); @@ -97,7 +97,7 @@ void rmu_clear_reset_status(rmu_state_t state) * @param perh: The peripheral device, * @retval None */ -void rmu_reset_periperal(rmu_peripheral_t perh) +void ald_rmu_reset_periperal(rmu_peripheral_t perh) { uint32_t idx, pos; @@ -109,24 +109,24 @@ void rmu_reset_periperal(rmu_peripheral_t perh) switch (idx) { - case 0: - WRITE_REG(RMU->AHB1RSTR, pos); - break; + case 0: + WRITE_REG(RMU->AHB1RSTR, pos); + break; - case 1: - WRITE_REG(RMU->AHB2RSTR, pos); - break; + case 1: + WRITE_REG(RMU->AHB2RSTR, pos); + break; - case 2: - WRITE_REG(RMU->APB1RSTR, pos); - break; + case 2: + WRITE_REG(RMU->APB1RSTR, pos); + break; - case 4: - WRITE_REG(RMU->APB2RSTR, pos); - break; + case 4: + WRITE_REG(RMU->APB2RSTR, pos); + break; - default: - break; + default: + break; } SYSCFG_LOCK(); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rtc.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rtc.c similarity index 84% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rtc.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rtc.c index 913a095bd2..c8294d3ab7 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rtc.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_rtc.c @@ -27,48 +27,48 @@ (+) Enable the RTC controller interface clock. (+) Select the RTC source clock(default LOSC). (+) Configure the RTC asynchronous prescaler, synchronous prescaler and hour - format using the rtc_init() function. + format using the ald_rtc_init() function. *** Time and date operation *** ================================= [..] - (+) To configure the time use the rtc_set_time() function. - (+) To configure the date use the rtc_set_date() function. - (+) To read the time use the rtc_get_time() function. - (+) To read the date use the rtc_get_date() function. + (+) To configure the time use the ald_rtc_set_time() function. + (+) To configure the date use the ald_rtc_set_date() function. + (+) To read the time use the ald_rtc_get_time() function. + (+) To read the date use the ald_rtc_get_date() function. *** Alarm operation *** =================================== [..] - (+) To configure the alarm use rtc_set_alarm() function - (+) To read the alarm use rtc_get_alarm() function - (+) To cancel the alarm use rtc_alarm_cmd() function + (+) To configure the alarm use ald_rtc_set_alarm() function + (+) To read the alarm use ald_rtc_get_alarm() function + (+) To cancel the alarm use ald_rtc_alarm_cmd() function *** Time stamp operation *** =================================== [..] - (+) To configure the time stamp use rtc_set_time_stamp() function - (+) To read the time stamp use rtc_get_time_stamp() function - (+) To cancel the time stamp use rtc_cancel_time_stamp() function + (+) To configure the time stamp use ald_rtc_set_time_stamp() function + (+) To read the time stamp use ald_rtc_get_time_stamp() function + (+) To cancel the time stamp use ald_rtc_cancel_time_stamp() function *** Tamper operation *** =================================== [..] - (+) To configure the tamper use rtc_set_tamper() function - (+) To cancel the tamper use rtc_alarm_cmd() function + (+) To configure the tamper use ald_rtc_set_tamper() function + (+) To cancel the tamper use ald_rtc_alarm_cmd() function *** Wake-up operation *** =================================== [..] - (+) To configure the wake-up parameters use rtc_set_wakeup() function - (+) To read the re-load register value use rtc_get_wakeup_timer_value() function - (+) To cancel the wake-up use rtc_cancel_wakeup() function + (+) To configure the wake-up parameters use ald_rtc_set_wakeup() function + (+) To read the re-load register value use ald_rtc_get_wakeup_timer_value() function + (+) To cancel the wake-up use ald_rtc_cancel_wakeup() function *** Output clock operation *** =================================== [..] - (+) To configure the clock output type use rtc_set_clock_output() function - (+) To cancel the clock output use rtc_cancel_clock_output() function + (+) To configure the clock output type use ald_rtc_set_clock_output() function + (+) To cancel the clock output use ald_rtc_cancel_clock_output() function *** Control functions *** =================================== @@ -118,7 +118,7 @@ #include "ald_rtc.h" #include "ald_bkpc.h" -#include "ald_temp.h" +#include "ald_tsense.h" #include "ald_syscfg.h" @@ -170,14 +170,19 @@ static int32_t rtc_consistency_check(rtc_time_t *t_last, { if (t_last->second != time->second) return 0; + if (t_last->minute != time->minute) return 0; + if (t_last->hour != time->hour) return 0; + if (d_last->day != date->day) return 0; + if (d_last->month != date->month) return 0; + if (d_last->year != date->year) return 0; @@ -217,7 +222,7 @@ static int32_t rtc_consistency_check(rtc_time_t *t_last, * @brief Reset RTC register. * @retval None */ -void rtc_reset(void) +void ald_rtc_reset(void) { RTC_UNLOCK(); @@ -237,13 +242,13 @@ void rtc_reset(void) * the configuration parameters. * @retval None */ -void rtc_init(rtc_init_t *init) +void ald_rtc_init(rtc_init_t *init) { assert_param(IS_RTC_HOUR_FORMAT(init->hour_format)); assert_param(IS_RTC_OUTPUT_SEL(init->output)); assert_param(IS_RTC_OUTPUT_POLARITY(init->output_polarity)); - rtc_reset(); + ald_rtc_reset(); RTC_UNLOCK(); MODIFY_REG(RTC->CON, RTC_CON_HFM_MSK, init->hour_format << RTC_CON_HFM_POS); @@ -262,7 +267,7 @@ void rtc_init(rtc_init_t *init) * @param sel: RTC source type. * @retval None */ -void rtc_source_selcet(rtc_source_sel_t sel) +void ald_rtc_source_select(rtc_source_sel_t sel) { assert_param(IS_RTC_SOURCE_SEL(sel)); @@ -299,10 +304,10 @@ void rtc_source_selcet(rtc_source_sel_t sel) [..] This section provides functions allowing: [#] - (+) To configure the time use the rtc_set_time() function. - (+) To configure the date use the rtc_set_date() function. - (+) To read the time use the rtc_get_time() function. - (+) To read the date use the rtc_get_date() function. + (+) To configure the time use the ald_rtc_set_time() function. + (+) To configure the date use the ald_rtc_set_date() function. + (+) To read the time use the ald_rtc_get_time() function. + (+) To read the date use the ald_rtc_get_date() function. @endverbatim * @{ @@ -314,7 +319,7 @@ void rtc_source_selcet(rtc_source_sel_t sel) * @param format: Data format. * @retval ALD status. */ -ald_status_t rtc_set_time(rtc_time_t *time, rtc_format_t format) +ald_status_t ald_rtc_set_time(rtc_time_t *time, rtc_format_t format) { uint32_t tmp; @@ -344,11 +349,11 @@ ald_status_t rtc_set_time(rtc_time_t *time, rtc_format_t format) WRITE_REG(RTC->SSEC, time->sub_sec); RTC_LOCK(); - tmp = __get_tick(); + tmp = ald_get_tick(); while (READ_BIT(RTC->CON, RTC_CON_BUSY_MSK)) { - if ((__get_tick() - tmp) > RTC_TIMEOUT_VALUE) + if ((ald_get_tick() - tmp) > RTC_TIMEOUT_VALUE) return TIMEOUT; } @@ -361,7 +366,7 @@ ald_status_t rtc_set_time(rtc_time_t *time, rtc_format_t format) * @param format: Data format. * @retval ALD status. */ -ald_status_t rtc_set_date(rtc_date_t *date, rtc_format_t format) +ald_status_t ald_rtc_set_date(rtc_date_t *date, rtc_format_t format) { uint32_t tmp; @@ -392,11 +397,11 @@ ald_status_t rtc_set_date(rtc_date_t *date, rtc_format_t format) WRITE_REG(RTC->DATE, tmp); RTC_LOCK(); - tmp = __get_tick(); + tmp = ald_get_tick(); while (READ_BIT(RTC->CON, RTC_CON_BUSY_MSK)) { - if ((__get_tick() - tmp) > RTC_TIMEOUT_VALUE) + if ((ald_get_tick() - tmp) > RTC_TIMEOUT_VALUE) return TIMEOUT; } @@ -409,7 +414,7 @@ ald_status_t rtc_set_date(rtc_date_t *date, rtc_format_t format) * @param format: Data format. * @retval None */ -void rtc_get_time(rtc_time_t *time, rtc_format_t format) +void ald_rtc_get_time(rtc_time_t *time, rtc_format_t format) { uint32_t tmp; @@ -441,7 +446,7 @@ void rtc_get_time(rtc_time_t *time, rtc_format_t format) * @param format: Data format. * @retval None */ -void rtc_get_date(rtc_date_t *date, rtc_format_t format) +void ald_rtc_get_date(rtc_date_t *date, rtc_format_t format) { uint32_t tmp = RTC->DATE; @@ -475,7 +480,7 @@ void rtc_get_date(rtc_date_t *date, rtc_format_t format) * 0 - Consistency * -1 - Not consistency */ -int32_t rtc_get_date_time(rtc_date_t *date, rtc_time_t *time, rtc_format_t format) +int32_t ald_rtc_get_date_time(rtc_date_t *date, rtc_time_t *time, rtc_format_t format) { int32_t nr = 3; rtc_date_t d_last; @@ -483,10 +488,10 @@ int32_t rtc_get_date_time(rtc_date_t *date, rtc_time_t *time, rtc_format_t forma while (nr--) { - rtc_get_time(&t_last, format); - rtc_get_date(&d_last, format); - rtc_get_time(time, format); - rtc_get_date(date, format); + ald_rtc_get_time(&t_last, format); + ald_rtc_get_date(&d_last, format); + ald_rtc_get_time(time, format); + ald_rtc_get_date(date, format); if (rtc_consistency_check(&t_last, &d_last, time, date)) return 0; @@ -508,8 +513,8 @@ int32_t rtc_get_date_time(rtc_date_t *date, rtc_time_t *time, rtc_format_t forma [..] This section provides functions allowing: [#] - (+) To configure the alarm use rtc_set_alarm() function - (+) To read the alarm use rtc_get_alarm() function + (+) To configure the alarm use ald_rtc_set_alarm() function + (+) To read the alarm use ald_rtc_get_alarm() function @endverbatim * @{ @@ -521,7 +526,7 @@ int32_t rtc_get_date_time(rtc_date_t *date, rtc_time_t *time, rtc_format_t forma * @param format: Data format. * @retval None */ -void rtc_set_alarm(rtc_alarm_t *alarm, rtc_format_t format) +void ald_rtc_set_alarm(rtc_alarm_t *alarm, rtc_format_t format) { unsigned int tmp, ss_tmp; @@ -607,7 +612,7 @@ void rtc_set_alarm(rtc_alarm_t *alarm, rtc_format_t format) * @param format: Data format. * @retval None */ -void rtc_get_alarm(rtc_alarm_t *alarm, rtc_format_t format) +void ald_rtc_get_alarm(rtc_alarm_t *alarm, rtc_format_t format) { uint8_t week; uint32_t tmp, ss_tmp; @@ -633,29 +638,36 @@ void rtc_get_alarm(rtc_alarm_t *alarm, rtc_format_t format) switch (week) { - case 1: - alarm->week = 0; - break; - case 2: - alarm->week = 1; - break; - case 4: - alarm->week = 2; - break; - case 8: - alarm->week = 3; - break; - case 16: - alarm->week = 4; - break; - case 32: - alarm->week = 5; - break; - case 64: - alarm->week = 6; - break; - default: - break; + case 1: + alarm->week = 0; + break; + + case 2: + alarm->week = 1; + break; + + case 4: + alarm->week = 2; + break; + + case 8: + alarm->week = 3; + break; + + case 16: + alarm->week = 4; + break; + + case 32: + alarm->week = 5; + break; + + case 64: + alarm->week = 6; + break; + + default: + break; } } else @@ -701,9 +713,9 @@ void rtc_get_alarm(rtc_alarm_t *alarm, rtc_format_t format) [..] This section provides functions allowing: [#] - (+) To configure the time stamp use rtc_set_time_stamp() function - (+) To read the time stamp use rtc_get_time_stamp() function - (+) To cancel the time stamp use rtc_cancel_time_stamp() function + (+) To configure the time stamp use ald_rtc_set_time_stamp() function + (+) To read the time stamp use ald_rtc_get_time_stamp() function + (+) To cancel the time stamp use ald_rtc_cancel_time_stamp() function @endverbatim * @{ @@ -719,7 +731,7 @@ void rtc_get_alarm(rtc_alarm_t *alarm, rtc_format_t format) * @arg RTC_TS_FALLING_EDGE * @retval None */ -void rtc_set_time_stamp(rtc_ts_signal_sel_t sel, rtc_ts_trigger_style_t style) +void ald_rtc_set_time_stamp(rtc_ts_signal_sel_t sel, rtc_ts_trigger_style_t style) { assert_param(IS_RTC_TS_SIGNAL(sel)); assert_param(IS_RTC_TS_STYLE(style)); @@ -739,7 +751,7 @@ void rtc_set_time_stamp(rtc_ts_signal_sel_t sel, rtc_ts_trigger_style_t style) * @brief Cancel time stamp. * @retval None */ -void rtc_cancel_time_stamp(void) +void ald_rtc_cancel_time_stamp(void) { RTC_UNLOCK(); CLEAR_BIT(RTC->CON, RTC_CON_TSEN_MSK); @@ -755,7 +767,7 @@ void rtc_cancel_time_stamp(void) * @param format: Data format. * @retval None */ -void rtc_get_time_stamp(rtc_time_t *ts_time, rtc_date_t *ts_date, rtc_format_t format) +void ald_rtc_get_time_stamp(rtc_time_t *ts_time, rtc_date_t *ts_date, rtc_format_t format) { uint32_t tmp0, tmp1; @@ -804,8 +816,8 @@ void rtc_get_time_stamp(rtc_time_t *ts_time, rtc_date_t *ts_date, rtc_format_t f [..] This section provides functions allowing: [#] - (+) To configure the tamper use rtc_set_tamper() function - (+) To cancel the tamper use rtc_alarm_cmd() function + (+) To configure the tamper use ald_rtc_set_tamper() function + (+) To cancel the tamper use ald_rtc_alarm_cmd() function @endverbatim * @{ @@ -815,7 +827,7 @@ void rtc_get_time_stamp(rtc_time_t *ts_time, rtc_date_t *ts_date, rtc_format_t f * @param tamper: pointer to rtc_tamper_t structure. * @retval None */ -void rtc_set_tamper(rtc_tamper_t *tamper) +void ald_rtc_set_tamper(rtc_tamper_t *tamper) { assert_param(IS_RTC_TAMPER(tamper->idx)); assert_param(IS_RTC_TAMPER_TRIGGER(tamper->trig)); @@ -850,7 +862,7 @@ void rtc_set_tamper(rtc_tamper_t *tamper) * @arg RTC_TAMPER_1 * @retval None */ -void rtc_cancel_tamper(rtc_tamper_idx_t idx) +void ald_rtc_cancel_tamper(rtc_tamper_idx_t idx) { assert_param(IS_RTC_TAMPER(idx)); @@ -878,9 +890,9 @@ void rtc_cancel_tamper(rtc_tamper_idx_t idx) [..] This section provides functions allowing: [#] - (+) To configure the wake-up parameters use rtc_set_wakeup() function - (+) To read the re-load register value use rtc_get_wakeup_timer_value() function - (+) To cancel the wake-up use rtc_cancel_wakeup() function + (+) To configure the wake-up parameters use ald_rtc_set_wakeup() function + (+) To read the re-load register value use ald_rtc_get_wakeup_timer_value() function + (+) To cancel the wake-up use ald_rtc_cancel_wakeup() function @endverbatim * @{ @@ -891,7 +903,7 @@ void rtc_cancel_tamper(rtc_tamper_idx_t idx) * @param value: re-load value. * @retval None */ -void rtc_set_wakeup(rtc_wakeup_clock_t clock, uint16_t value) +void ald_rtc_set_wakeup(rtc_wakeup_clock_t clock, uint16_t value) { assert_param(IS_RTC_WAKEUP_CLOCK(clock)); @@ -908,7 +920,7 @@ void rtc_set_wakeup(rtc_wakeup_clock_t clock, uint16_t value) * @brief Cancel wake-up. * @retval None */ -void rtc_cancel_wakeup(void) +void ald_rtc_cancel_wakeup(void) { RTC_UNLOCK(); CLEAR_BIT(RTC->CON, RTC_CON_WUTE_MSK); @@ -921,7 +933,7 @@ void rtc_cancel_wakeup(void) * @brief Get wake-up re-load register value. * @retval Value of re-load register. */ -uint16_t rtc_get_wakeup_timer_value(void) +uint16_t ald_rtc_get_wakeup_timer_value(void) { return RTC->WUMAT & 0xFFFF; } @@ -939,8 +951,8 @@ uint16_t rtc_get_wakeup_timer_value(void) [..] This section provides functions allowing: [#] - (+) To configure the clock output type use rtc_set_clock_output() function - (+) To cancel the clock output use rtc_cancel_clock_output() function + (+) To configure the clock output type use ald_rtc_set_clock_output() function + (+) To cancel the clock output use ald_rtc_cancel_clock_output() function @endverbatim * @{ @@ -950,7 +962,7 @@ uint16_t rtc_get_wakeup_timer_value(void) * @param clock: pointer to rtc_clock_output_t structure. * @retval ALD status. */ -ald_status_t rtc_set_clock_output(rtc_clock_output_t clock) +ald_status_t ald_rtc_set_clock_output(rtc_clock_output_t clock) { uint32_t cnt = 4000; assert_param(IS_RTC_CLOCK_OUTPUT(clock)); @@ -960,8 +972,11 @@ ald_status_t rtc_set_clock_output(rtc_clock_output_t clock) if (clock == RTC_CLOCK_OUTPUT_EXA_1) { SET_BIT(CMU->CLKENR, CMU_CLKENR_PLL2EN_MSK); + while ((READ_BIT(CMU->PLLCFG, CMU_PLLCFG_PLL2LCKN_MSK)) && (--cnt)); + cnt = 4000; + while ((!(READ_BIT(CMU->CLKSR, CMU_CLKSR_PLL2RDY_MSK))) && (--cnt)); } else @@ -982,7 +997,7 @@ ald_status_t rtc_set_clock_output(rtc_clock_output_t clock) * @brief Cancel clock output. * @retval None */ -void rtc_cancel_clock_output(void) +void ald_rtc_cancel_clock_output(void) { RTC_UNLOCK(); CLEAR_BIT(RTC->CON, RTC_CON_CKOE_MSK); @@ -1025,7 +1040,7 @@ void rtc_cancel_clock_output(void) * @arg DISABLE * @retval None */ -void rtc_interrupt_config(rtc_it_t it, type_func_t state) +void ald_rtc_interrupt_config(rtc_it_t it, type_func_t state) { assert_param(IS_RTC_IT(it)); assert_param(IS_FUNC_STATE(state)); @@ -1051,7 +1066,7 @@ void rtc_interrupt_config(rtc_it_t it, type_func_t state) * @arg DISABLE * @retval None */ -void rtc_alarm_cmd(rtc_alarm_idx_t idx, type_func_t state) +void ald_rtc_alarm_cmd(rtc_alarm_idx_t idx, type_func_t state) { assert_param(IS_RTC_ALARM(idx)); assert_param(IS_FUNC_STATE(state)); @@ -1073,7 +1088,7 @@ void rtc_alarm_cmd(rtc_alarm_idx_t idx, type_func_t state) * @param sub_ss: value of sub-sconde. * @retval ALD status. */ -ald_status_t rtc_set_shift(type_func_t add_1s, uint16_t sub_ss) +ald_status_t ald_rtc_set_shift(type_func_t add_1s, uint16_t sub_ss) { uint32_t tick; @@ -1085,11 +1100,11 @@ ald_status_t rtc_set_shift(type_func_t add_1s, uint16_t sub_ss) MODIFY_REG(RTC->SSECTR, RTC_SSECTR_INC_MSK, add_1s << RTC_SSECTR_INC_POS); RTC_LOCK(); - tick = __get_tick(); + tick = ald_get_tick(); while (READ_BIT(RTC->CON, RTC_CON_SSEC_MSK)) { - if ((__get_tick() - tick) > RTC_TIMEOUT_VALUE) + if ((ald_get_tick() - tick) > RTC_TIMEOUT_VALUE) return TIMEOUT; } @@ -1101,7 +1116,7 @@ ald_status_t rtc_set_shift(type_func_t add_1s, uint16_t sub_ss) * @param config: pointer to rtc_cali_t structure. * @retval None */ -void rtc_set_cali(rtc_cali_t *config) +void ald_rtc_set_cali(rtc_cali_t *config) { assert_param(IS_RTC_CALI_FREQ(config->cali_freq)); assert_param(IS_RTC_CALI_TC(config->tc)); @@ -1129,7 +1144,7 @@ void rtc_set_cali(rtc_cali_t *config) * @brief Cancel calibration * @retval None */ -void rtc_cancel_cali(void) +void ald_rtc_cancel_cali(void) { RTC_CALI_UNLOCK(); CLEAR_BIT(RTC->CALCON, RTC_CALCON_CALEN_MSK); @@ -1142,7 +1157,7 @@ void rtc_cancel_cali(void) * @brief Get calibration status. * @retval ALD status. */ -ald_status_t rtc_get_cali_status(void) +ald_status_t ald_rtc_get_cali_status(void) { if (READ_BIT(RTC->CALCON, RTC_CALCON_ERR_MSK)) return ERROR; @@ -1155,7 +1170,7 @@ ald_status_t rtc_get_cali_status(void) * @param temp: the value of temperature. * @retval None */ -void rtc_write_temp(uint16_t temp) +void ald_rtc_write_temp(uint16_t temp) { RTC_CALI_UNLOCK(); MODIFY_REG(RTC->TEMPR, RTC_TEMPR_VAL_MSK, temp << RTC_TEMPR_VAL_POSS); @@ -1172,7 +1187,7 @@ void rtc_write_temp(uint16_t temp) * - 0: RESET * - 1: SET */ -it_status_t rtc_get_it_status(rtc_it_t it) +it_status_t ald_rtc_get_it_status(rtc_it_t it) { assert_param(IS_RTC_IT(it)); @@ -1190,7 +1205,7 @@ it_status_t rtc_get_it_status(rtc_it_t it) * - 0: RESET * - 1: SET */ -flag_status_t rtc_get_flag_status(rtc_flag_t flag) +flag_status_t ald_rtc_get_flag_status(rtc_flag_t flag) { assert_param(IS_RTC_IF(flag)); @@ -1204,7 +1219,7 @@ flag_status_t rtc_get_flag_status(rtc_flag_t flag) * @param flag: specifies the flag to check. * @retval None. */ -void rtc_clear_flag_status(rtc_flag_t flag) +void ald_rtc_clear_flag_status(rtc_flag_t flag) { assert_param(IS_RTC_IF(flag)); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_smartcard.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_smartcard.c similarity index 83% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_smartcard.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_smartcard.c index 79f2af9ac7..e7d1f46622 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_smartcard.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_smartcard.c @@ -29,12 +29,12 @@ (##) SMARTCARD pins configuration: (+++) Enable the clock for the SMARTCARD GPIOs. (+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input). - (##) NVIC configuration if you need to use interrupt process (smartcard_send_by_it() - and smartcard_recv_by_it() APIs): + (##) NVIC configuration if you need to use interrupt process (ald_smartcard_send_by_it() + and ald_smartcard_recv_by_it() APIs): (+++) Configure the USARTx interrupt priority. (+++) Enable the NVIC USART IRQ handle. - (##) DMA Configuration if you need to use DMA process (smartcard_send_by_dma() - and smartcard_recv_by_dma() APIs): + (##) DMA Configuration if you need to use DMA process (ald_smartcard_send_by_dma() + and ald_smartcard_recv_by_dma() APIs): (+++) Declare a DMA handle structure for the Tx/Rx channel. (+++) Enable the DMAx interface clock. (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. @@ -47,23 +47,23 @@ (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware flow control and Mode(Receiver/Transmitter) in the SMARTCARD Init structure. - (#) Initialize the SMARTCARD registers by calling the smartcard_init() API. + (#) Initialize the SMARTCARD registers by calling the ald_smartcard_init() API. (#) Three operation modes are available within this driver : *** Polling mode IO operation *** ================================= [..] - (+) Send an amount of data in blocking mode using smartcard_send() - (+) Receive an amount of data in blocking mode using smartcard_recv() + (+) Send an amount of data in blocking mode using ald_smartcard_send() + (+) Receive an amount of data in blocking mode using ald_smartcard_recv() *** Interrupt mode IO operation *** =================================== [..] - (+) Send an amount of data in non blocking mode using smartcard_send_by_it() + (+) Send an amount of data in non blocking mode using ald_smartcard_send_by_it() (+) At transmission end of transfer hperh->tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->tx_cplt_cbk() - (+) Receive an amount of data in non blocking mode using smartcard_recv_by_it() + (+) Receive an amount of data in non blocking mode using ald_smartcard_recv_by_it() (+) At reception end of transfer hperh->rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->rx_cplt_cbk() (+) In case of transfer Error, hperh->error_cbk() function is executed and user can @@ -72,10 +72,10 @@ *** DMA mode IO operation *** ============================== [..] - (+) Send an amount of data in non blocking mode (DMA) using smartcard_send_by_dma() + (+) Send an amount of data in non blocking mode (DMA) using ald_smartcard_send_by_dma() (+) At transmission end of transfer hperh->tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->tx_cplt_cbk() - (+) Receive an amount of data in non blocking mode (DMA) using smartcard_recv_by_dma() + (+) Receive an amount of data in non blocking mode (DMA) using ald_smartcard_recv_by_dma() (+) At reception end of transfer hperh->rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->rx_cplt_cbk() (+) In case of transfer Error, hperh->error_cbk()() function is executed and user can @@ -180,7 +180,7 @@ static ald_status_t smartcard_wait_flag(smartcard_handle_t *hperh, usart_flag_t to use 1.5 stop bits for both transmitting and receiving to avoid switching between the two configurations. [..] - The smartcard_init() function follows the USART SmartCard configuration procedure. + The ald_smartcard_init() function follows the USART SmartCard configuration procedure. @endverbatim * @{ @@ -202,7 +202,7 @@ static ald_status_t smartcard_wait_flag(smartcard_handle_t *hperh, usart_flag_t * the configuration information for the specified SMARTCARD module. * @retval Status, see @ref ald_status_t. */ -ald_status_t smartcard_init(smartcard_handle_t *hperh) +ald_status_t ald_smartcard_init(smartcard_handle_t *hperh) { assert_param(IS_USART_WORD_LENGTH(hperh->init.word_length)); assert_param(IS_USART_STOPBITS(hperh->init.stop_bits)); @@ -239,7 +239,7 @@ ald_status_t smartcard_init(smartcard_handle_t *hperh) * the configuration information for the specified SMARTCARD module. * @retval Status, see @ref ald_status_t. */ -ald_status_t smartcard_reset(smartcard_handle_t *hperh) +ald_status_t ald_smartcard_reset(smartcard_handle_t *hperh) { assert_param(IS_USART(hperh->perh)); @@ -295,17 +295,17 @@ ald_status_t smartcard_reset(smartcard_handle_t *hperh) error is detected. (#) Blocking mode APIs are : - (++) smartcard_send() - (++) smartcard_recv() + (++) ald_smartcard_send() + (++) ald_smartcard_recv() (#) Non Blocking mode APIs with Interrupt are : - (++) smartcard_send_by_it() - (++) smartcard_recv_by_it() - (++) smartcard_irq_handle() + (++) ald_smartcard_send_by_it() + (++) ald_smartcard_recv_by_it() + (++) ald_smartcard_irq_handler() (#) Non Blocking mode functions with DMA are : - (++) smartcard_send_by_dma() - (++) smartcard_recv_by_dma() + (++) ald_smartcard_send_by_dma() + (++) ald_smartcard_recv_by_dma() * @endverbatim * @{ @@ -320,10 +320,11 @@ ald_status_t smartcard_reset(smartcard_handle_t *hperh) * @param timeout: Specify timeout value * @retval Status, see @ref ald_status_t. */ -ald_status_t smartcard_send(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_smartcard_send(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { if ((hperh->state != SMARTCARD_STATE_READY) && (hperh->state != SMARTCARD_STATE_BUSY_RX)) return BUSY; + if ((buf == NULL) || (size == 0)) return ERROR; @@ -368,10 +369,11 @@ ald_status_t smartcard_send(smartcard_handle_t *hperh, uint8_t *buf, uint16_t si * @param timeout: Specify timeout value * @retval Status, see @ref ald_status_t. */ -ald_status_t smartcard_recv(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_smartcard_recv(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { if ((hperh->state != SMARTCARD_STATE_READY) && (hperh->state != SMARTCARD_STATE_BUSY_TX)) return BUSY; + if ((buf == NULL) || (size == 0)) return ERROR; @@ -408,10 +410,11 @@ ald_status_t smartcard_recv(smartcard_handle_t *hperh, uint8_t *buf, uint16_t si * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t smartcard_send_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_smartcard_send_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size) { if ((hperh->state != SMARTCARD_STATE_READY) && (hperh->state != SMARTCARD_STATE_BUSY_RX)) return BUSY; + if ((buf == NULL) || (size == 0)) return ERROR; @@ -424,8 +427,8 @@ ald_status_t smartcard_send_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint1 hperh->err_code = SMARTCARD_ERROR_NONE; __UNLOCK(hperh); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, ENABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TXE, ENABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, ENABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TXE, ENABLE); return OK; } @@ -438,10 +441,11 @@ ald_status_t smartcard_send_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint1 * @param size: Amount of data to be received * @retval Status, see @ref ald_status_t. */ -ald_status_t smartcard_recv_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_smartcard_recv_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size) { if ((hperh->state != SMARTCARD_STATE_READY) && (hperh->state != SMARTCARD_STATE_BUSY_TX)) return BUSY; + if ((buf == NULL) || (size == 0)) return ERROR; @@ -454,9 +458,9 @@ ald_status_t smartcard_recv_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint1 hperh->err_code = SMARTCARD_ERROR_NONE; __UNLOCK(hperh); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_RXNE, ENABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_PE, ENABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, ENABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_RXNE, ENABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_PE, ENABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, ENABLE); return OK; } @@ -471,10 +475,11 @@ ald_status_t smartcard_recv_by_it(smartcard_handle_t *hperh, uint8_t *buf, uint1 * @param channel: DMA channel as USART transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t smartcard_send_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_smartcard_send_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { if ((hperh->state != SMARTCARD_STATE_READY) && (hperh->state != SMARTCARD_STATE_BUSY_RX)) return BUSY; + if ((buf == NULL) || (size == 0)) return ERROR; @@ -494,7 +499,7 @@ ald_status_t smartcard_send_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint hperh->hdmatx.err_cbk = smartcard_dma_error; hperh->hdmatx.err_arg = (void *)hperh; - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; hperh->hdmatx.config.size = size; @@ -503,11 +508,11 @@ ald_status_t smartcard_send_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint hperh->hdmatx.config.msel = hperh->perh == USART0 ? DMA_MSEL_USART0 : DMA_MSEL_USART1; hperh->hdmatx.config.msigsel = DMA_MSIGSEL_USART_TXEMPTY; hperh->hdmatx.config.channel = channel; - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); - usart_clear_flag_status((usart_handle_t *)hperh, USART_FLAG_TC); + ald_usart_clear_flag_status((usart_handle_t *)hperh, USART_FLAG_TC); __UNLOCK(hperh); - usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_TX, ENABLE); + ald_usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_TX, ENABLE); return OK; } @@ -522,10 +527,11 @@ ald_status_t smartcard_send_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint * @note When the SMARTCARD parity is enabled (PCE = 1) the data received contain the parity bit. * @retval Status, see @ref ald_status_t. */ -ald_status_t smartcard_recv_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_smartcard_recv_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { if ((hperh->state != SMARTCARD_STATE_READY) && (hperh->state != SMARTCARD_STATE_BUSY_TX)) return BUSY; + if ((buf == NULL) || (size == 0)) return ERROR; @@ -545,7 +551,7 @@ ald_status_t smartcard_recv_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint hperh->hdmarx.err_cbk = smartcard_dma_error; hperh->hdmarx.err_arg = (void *)hperh; - dma_config_struct(&hperh->hdmarx.config); + ald_dma_config_struct(&hperh->hdmarx.config); hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)buf; hperh->hdmarx.config.size = size; @@ -554,10 +560,10 @@ ald_status_t smartcard_recv_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint hperh->hdmarx.config.msel = hperh->perh == USART0 ? DMA_MSEL_USART0 : DMA_MSEL_USART1; hperh->hdmarx.config.msigsel = DMA_MSIGSEL_USART_RNR; hperh->hdmarx.config.channel = channel; - dma_config_basic(&hperh->hdmarx); + ald_dma_config_basic(&hperh->hdmarx); __UNLOCK(hperh); - usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_RX, ENABLE); + ald_usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_RX, ENABLE); return OK; } @@ -569,48 +575,55 @@ ald_status_t smartcard_recv_by_dma(smartcard_handle_t *hperh, uint8_t *buf, uint * the configuration information for the specified SMARTCARD module. * @retval None */ -void smartcard_irq_handle(smartcard_handle_t *hperh) +void ald_smartcard_irq_handler(smartcard_handle_t *hperh) { uint32_t flag; uint32_t source; /* Handle parity error */ - flag = usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_PE); - source = usart_get_it_status((usart_handle_t *)hperh, USART_IT_PE); + flag = ald_usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_PE); + source = ald_usart_get_it_status((usart_handle_t *)hperh, USART_IT_PE); + if ((flag != RESET) && (source != RESET)) hperh->err_code |= SMARTCARD_ERROR_PE; /* Handle frame error */ - flag = usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_FE); - source = usart_get_it_status((usart_handle_t *)hperh, USART_IT_ERR); + flag = ald_usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_FE); + source = ald_usart_get_it_status((usart_handle_t *)hperh, USART_IT_ERR); + if ((flag != RESET) && (source != RESET)) hperh->err_code |= SMARTCARD_ERROR_FE; /* Handle noise error */ - flag = usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_NE); + flag = ald_usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_NE); + if ((flag != RESET) && (source != RESET)) hperh->err_code |= SMARTCARD_ERROR_NE; /* Handle overrun error */ - flag = usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_ORE); + flag = ald_usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_ORE); + if ((flag != RESET) && (source != RESET)) hperh->err_code |= SMARTCARD_ERROR_ORE; /* Handle receive */ - flag = usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_RXNE); - source = usart_get_it_status((usart_handle_t *)hperh, USART_IT_RXNE); + flag = ald_usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_RXNE); + source = ald_usart_get_it_status((usart_handle_t *)hperh, USART_IT_RXNE); + if ((flag != RESET) && (source != RESET)) __smartcard_recv_by_it(hperh); /* Handle transmit */ - flag = usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_TXE); - source = usart_get_it_status((usart_handle_t *)hperh, USART_IT_TXE); + flag = ald_usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_TXE); + source = ald_usart_get_it_status((usart_handle_t *)hperh, USART_IT_TXE); + if ((flag != RESET) && (source != RESET)) __smartcard_send_by_it(hperh); /* Handle transmit complete */ - flag = usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_TC); - source = usart_get_it_status((usart_handle_t *)hperh, USART_IT_TC); + flag = ald_usart_get_flag_status((usart_handle_t *)hperh, USART_FLAG_TC); + source = ald_usart_get_it_status((usart_handle_t *)hperh, USART_IT_TC); + if ((flag != RESET) && (source != RESET)) __smartcard_end_send_by_it(hperh); @@ -638,9 +651,9 @@ void smartcard_irq_handle(smartcard_handle_t *hperh) [..] This subsection provides a set of functions allowing to return the State of SmartCard communication process and also return Peripheral Errors occurred during communication process - (+) smartcard_get_state() API can be helpful to check in run-time the state + (+) ald_smartcard_get_state() API can be helpful to check in run-time the state of the SMARTCARD peripheral. - (+) smartcard_get_error() check in run-time errors that could be occurred during + (+) ald_smartcard_get_error() check in run-time errors that could be occurred during communication. @endverbatim @@ -653,7 +666,7 @@ void smartcard_irq_handle(smartcard_handle_t *hperh) * the configuration information for the specified SMARTCARD module. * @retval ALD state */ -smartcard_state_t smartcard_get_state(smartcard_handle_t *hperh) +smartcard_state_t ald_smartcard_get_state(smartcard_handle_t *hperh) { return hperh->state; } @@ -664,7 +677,7 @@ smartcard_state_t smartcard_get_state(smartcard_handle_t *hperh) * the configuration information for the specified SMARTCARD module. * @retval SMARTCARD Error Code */ -uint32_t smartcard_get_error(smartcard_handle_t *hperh) +uint32_t ald_smartcard_get_error(smartcard_handle_t *hperh) { return hperh->err_code; } @@ -694,8 +707,8 @@ static void smartcard_dma_send_cplt(void *arg) smartcard_handle_t *hperh = (smartcard_handle_t *)arg; hperh->tx_count = 0; - usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_TX, DISABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TC, ENABLE); + ald_usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_TX, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TC, ENABLE); return; } @@ -711,7 +724,7 @@ static void smartcard_dma_recv_cplt(void *arg) smartcard_handle_t *hperh = (smartcard_handle_t *)arg; hperh->rx_count = 0; - usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_RX, DISABLE); + ald_usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_RX, DISABLE); CLEAR_BIT(hperh->state, USART_STATE_RX_MASK); if (hperh->rx_cplt_cbk) @@ -735,8 +748,8 @@ static void smartcard_dma_error(void *arg) hperh->err_code = SMARTCARD_ERROR_DMA; hperh->state = SMARTCARD_STATE_READY; - usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_TX, DISABLE); - usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_RX, DISABLE); + ald_usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_TX, DISABLE); + ald_usart_dma_req_config((usart_handle_t *)hperh, USART_DMA_REQ_RX, DISABLE); if (hperh->error_cbk) hperh->error_cbk(hperh); @@ -761,16 +774,16 @@ static ald_status_t smartcard_wait_flag(smartcard_handle_t *hperh, usart_flag_t if (timeout == 0) return OK; - tick = __get_tick(); + tick = ald_get_tick(); - while ((usart_get_flag_status((usart_handle_t *)hperh, flag)) != status) + while ((ald_usart_get_flag_status((usart_handle_t *)hperh, flag)) != status) { - if (((__get_tick()) - tick) > timeout) + if (((ald_get_tick()) - tick) > timeout) { - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TXE, DISABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_RXNE, DISABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_PE, DISABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TXE, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_RXNE, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_PE, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, DISABLE); return TIMEOUT; } @@ -784,7 +797,7 @@ static ald_status_t smartcard_wait_flag(smartcard_handle_t *hperh, usart_flag_t * @param hperh: Pointer to a smartcard_handle_t structure that contains * the configuration information for the specified SMARTCARD module. * Function called under interruption only, once - * interruptions have been enabled by smartcard_send_by_it() + * interruptions have been enabled by ald_smartcard_send_by_it() * @retval Status, see @ref ald_status_t. */ static ald_status_t __smartcard_send_by_it(smartcard_handle_t *hperh) @@ -796,8 +809,8 @@ static ald_status_t __smartcard_send_by_it(smartcard_handle_t *hperh) if (--hperh->tx_count == 0) { - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TXE, DISABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TC, ENABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TXE, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TC, ENABLE); } return OK; @@ -812,11 +825,11 @@ static ald_status_t __smartcard_send_by_it(smartcard_handle_t *hperh) */ static ald_status_t __smartcard_end_send_by_it(smartcard_handle_t *hperh) { - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TC, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_TC, DISABLE); CLEAR_BIT(hperh->state, USART_STATE_TX_MASK); if (hperh->state == SMARTCARD_STATE_READY) - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, DISABLE); if (hperh->tx_cplt_cbk) hperh->tx_cplt_cbk(hperh); @@ -840,9 +853,9 @@ static ald_status_t __smartcard_recv_by_it(smartcard_handle_t *hperh) if (--hperh->rx_count == 0) { - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_RXNE, DISABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_PE, DISABLE); - usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_RXNE, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_PE, DISABLE); + ald_usart_interrupt_config((usart_handle_t *)hperh, USART_IT_ERR, DISABLE); CLEAR_BIT(hperh->state, USART_STATE_RX_MASK); if (hperh->rx_cplt_cbk) @@ -901,13 +914,14 @@ static void smartcard_set_config(smartcard_handle_t *hperh) if (READ_BIT(hperh->perh->CON0, (1 << 15))) { /* Integer part computing in case Oversampling mode is 8 Samples */ - integer = ((25 * cmu_get_pclk1_clock()) / (2 * (hperh->init.baud))); + integer = ((25 * ald_cmu_get_pclk1_clock()) / (2 * (hperh->init.baud))); } else { /* Integer part computing in case Oversampling mode is 16 Samples */ - integer = ((25 * cmu_get_pclk1_clock()) / (4 * (hperh->init.baud))); + integer = ((25 * ald_cmu_get_pclk1_clock()) / (4 * (hperh->init.baud))); } + tmp = (integer / 100) << 4; /* Determine the fractional part */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_spi.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_spi.c similarity index 83% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_spi.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_spi.c index 45e24960f8..9ab99c71a5 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_spi.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_spi.c @@ -34,16 +34,16 @@ (+++) Enable the clock for the SPI GPIOs (+++) Configure these SPI pins as push-pull (##) NVIC configuration if you need to use interrupt process - by implementing the mcu_irq_config() API. - Invoked spi_irq_handle() function in SPI-IRQ function + by implementing the ald_mcu_irq_config() API. + Invoked ald_spi_irq_handler() function in SPI-IRQ function (##) DMA Configuration if you need to use DMA process (+++) Define ALD_DMA in ald_conf.h - (+++) Enable the DMAx clock + (+++) Enable the DMAx clock (#) Program the Mode, Direction , Data size, Baudrate Prescaler, NSS management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure. - (#) Initialize the SPI module by invoking the spi_init() API. + (#) Initialize the SPI module by invoking the ald_spi_init() API. [..] Circular mode restriction: @@ -51,7 +51,7 @@ (##) Master 2Lines RxOnly (##) Master 1Line Rx (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs - the spi_dma_pause()/ spi_dma_stop(). + the ald_spi_dma_pause()/ ald_spi_dma_stop(). * @endverbatim */ @@ -104,7 +104,7 @@ static void __spi_send_recv_by_it(spi_handle_t *hperh, spi_sr_status_t status); (+) User must configure all related peripherals resources (CLOCK, GPIO, DMA, NVIC). - (+) Call the function spi_init() to configure the selected device with + (+) Call the function ald_spi_init() to configure the selected device with the selected configuration: (++) Mode (++) Direction @@ -117,7 +117,7 @@ static void __spi_send_recv_by_it(spi_handle_t *hperh, spi_sr_status_t status); (++) CRC Calculation (++) CRC Polynomial if CRC enabled - (+) Call the function spi_reset() to reset the selected SPIx periperal. + (+) Call the function ald_spi_reset() to reset the selected SPIx periperal. @endverbatim * @{ @@ -129,7 +129,7 @@ static void __spi_send_recv_by_it(spi_handle_t *hperh, spi_sr_status_t status); * the configuration information for the specified SPI module. * @retval None */ -void spi_reset(spi_handle_t *hperh) +void ald_spi_reset(spi_handle_t *hperh) { hperh->perh->CON1 = 0x0; hperh->perh->CON2 = 0x0; @@ -148,7 +148,7 @@ void spi_reset(spi_handle_t *hperh) * the configuration information for the specified SPI module. * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_init(spi_handle_t *hperh) +ald_status_t ald_spi_init(spi_handle_t *hperh) { uint32_t tmp = 0; @@ -166,7 +166,7 @@ ald_status_t spi_init(spi_handle_t *hperh) if (hperh == NULL) return ERROR; - spi_reset(hperh); + ald_spi_reset(hperh); tmp = hperh->perh->CON1; @@ -251,37 +251,63 @@ ald_status_t spi_init(spi_handle_t *hperh) * - 0 Success * - -1 Failed */ -int32_t spi_send_byte_fast(spi_handle_t *hperh, uint8_t data) +int32_t ald_spi_send_byte_fast(spi_handle_t *hperh, uint8_t data) { uint16_t cnt = 2000, temp; hperh->perh->DATA = data; + while (((hperh->perh->STAT & (1 << SPI_STAT_TXBE_POS)) == 0) && (--cnt)); - while ((hperh->perh->STAT & (1 << SPI_STAT_RXBNE_POS)) == 0); + cnt = 2000; + + while ((hperh->perh->STAT & (1 << SPI_STAT_RXBNE_POS)) == 0 && (--cnt)); + temp = hperh->perh->DATA; UNUSED(temp); return cnt == 0 ? -1 : 0; } +/** + * @brief transmit one byte fast in blocking mode(1line). + * @param hperh: Pointer to a spi_handle_t structure. + * @param data: Data to be sent + * @retval status: + * - 0 Success + * - -1 Failed + */ +int32_t ald_spi_send_byte_fast_1line(spi_handle_t *hperh, uint8_t data) +{ + uint16_t cnt = 2000; + + hperh->perh->DATA = data; + + while (((hperh->perh->STAT & (1 << SPI_STAT_TXBE_POS)) == 0) && (--cnt)); + + return cnt == 0 ? -1 : 0; +} + /** * @brief Receive one byte fast in blocking mode. * @param hperh: Pointer to a spi_handle_t structure. * @retval Data. */ -uint8_t spi_recv_byte_fast(spi_handle_t *hperh) +uint8_t ald_spi_recv_byte_fast(spi_handle_t *hperh) { uint16_t cnt = 2000; if (hperh->init.mode == SPI_MODE_MASTER) { hperh->perh->DATA = 0xFF; + while (((hperh->perh->STAT & (1 << SPI_STAT_TXBE_POS)) == 0) && (--cnt)); } cnt = 2000; + while (((hperh->perh->STAT & (1 << SPI_STAT_RXBNE_POS)) == 0) && (--cnt)); + return (uint8_t)hperh->perh->DATA; } @@ -293,12 +319,13 @@ uint8_t spi_recv_byte_fast(spi_handle_t *hperh) * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_send(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_spi_send(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { assert_param(IS_SPI(hperh->perh)); if (hperh->state != SPI_STATE_READY) return BUSY; + if (buf == NULL || size == 0) return ERROR; @@ -316,8 +343,10 @@ ald_status_t spi_send(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t if (hperh->init.crc_calc) SPI_CRC_RESET(hperh); + if (hperh->init.dir == SPI_DIRECTION_1LINE) SPI_1LINE_TX(hperh); + if (READ_BIT(hperh->perh->CON1, SPI_CON1_SPIEN_MSK) == 0) SPI_ENABLE(hperh); @@ -378,7 +407,7 @@ ald_status_t spi_send(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t } if (hperh->init.dir == SPI_DIRECTION_2LINES) - spi_clear_flag_status(hperh, SPI_IF_OVE); + ald_spi_clear_flag_status(hperh, SPI_IF_OVE); hperh->state = SPI_STATE_READY; __UNLOCK(hperh); @@ -394,13 +423,14 @@ ald_status_t spi_send(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { uint16_t temp; assert_param(IS_SPI(hperh->perh)); if (hperh->state != SPI_STATE_READY) return BUSY; + if (buf == NULL || size == 0) return ERROR; @@ -417,6 +447,7 @@ ald_status_t spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t if (hperh->init.crc_calc) SPI_CRC_RESET(hperh); + if (hperh->init.dir == SPI_DIRECTION_1LINE_RX) SPI_1LINE_RX(hperh); @@ -424,7 +455,7 @@ ald_status_t spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t { __UNLOCK(hperh); hperh->state = SPI_STATE_READY; - return spi_send_recv(hperh, buf, buf, size, timeout); + return ald_spi_send_recv(hperh, buf, buf, size, timeout); } if ((hperh->init.dir == SPI_DIRECTION_2LINES_RXONLY) || (hperh->init.dir == SPI_DIRECTION_1LINE_RX)) @@ -498,11 +529,11 @@ ald_status_t spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t UNUSED(temp); } - if ((hperh->init.crc_calc) && (spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET)) + if ((hperh->init.crc_calc) && (ald_spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET)) { hperh->err_code |= SPI_ERROR_CRC; SPI_CRC_RESET(hperh); - spi_clear_flag_status(hperh, SPI_IF_CRCERR); + ald_spi_clear_flag_status(hperh, SPI_IF_CRCERR); hperh->state = SPI_STATE_READY; __UNLOCK(hperh); return ERROR; @@ -523,7 +554,7 @@ ald_status_t spi_recv(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_send_recv(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout) +ald_status_t ald_spi_send_recv(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout) { uint16_t temp; @@ -531,8 +562,10 @@ ald_status_t spi_send_recv(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf if (hperh->state != SPI_STATE_READY) return BUSY; + if (hperh->init.dir != SPI_DIRECTION_2LINES) return ERROR; + if (tx_buf == NULL || rx_buf == NULL || size == 0) return ERROR; @@ -701,11 +734,11 @@ ald_status_t spi_send_recv(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf return TIMEOUT; } - if ((hperh->init.crc_calc) && (spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET)) + if ((hperh->init.crc_calc) && (ald_spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET)) { hperh->err_code |= SPI_ERROR_CRC; SPI_CRC_RESET(hperh); - spi_clear_flag_status(hperh, SPI_IF_CRCERR); + ald_spi_clear_flag_status(hperh, SPI_IF_CRCERR); hperh->state = SPI_STATE_READY; __UNLOCK(hperh); @@ -725,12 +758,13 @@ ald_status_t spi_send_recv(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_send_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_spi_send_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size) { assert_param(IS_SPI(hperh->perh)); if (hperh->state != SPI_STATE_READY) return BUSY; + if (buf == NULL || size == 0) return ERROR; @@ -754,12 +788,12 @@ ald_status_t spi_send_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size) if (hperh->init.dir == SPI_DIRECTION_2LINES) { - spi_interrupt_config(hperh, SPI_IT_TXBE, ENABLE); + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, ENABLE); } else { - spi_interrupt_config(hperh, SPI_IT_TXBE, ENABLE); - spi_interrupt_config(hperh, SPI_IT_ERR, ENABLE); + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, ENABLE); + ald_spi_interrupt_config(hperh, SPI_IT_ERR, ENABLE); } if (READ_BIT(hperh->perh->CON1, SPI_CON1_SPIEN_MSK) == 0) @@ -775,16 +809,18 @@ ald_status_t spi_send_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size) * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_recv_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_spi_recv_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size) { assert_param(IS_SPI(hperh->perh)); if (hperh->state != SPI_STATE_READY) return BUSY; + if (buf == NULL || size == 0) return ERROR; + if ((hperh->init.dir == SPI_DIRECTION_2LINES) && (hperh->init.mode == SPI_MODE_MASTER)) - return ERROR; /* Please call spi_send_recv_by_it() */ + return ERROR; /* Please call ald_spi_send_recv_by_it() */ __LOCK(hperh); hperh->state = SPI_STATE_BUSY_RX; @@ -804,8 +840,8 @@ ald_status_t spi_recv_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size) if (hperh->init.crc_calc == ENABLE) SPI_CRC_RESET(hperh); - spi_interrupt_config(hperh, SPI_IT_RXBNE, ENABLE); - spi_interrupt_config(hperh, SPI_IT_ERR, ENABLE); + ald_spi_interrupt_config(hperh, SPI_IT_RXBNE, ENABLE); + ald_spi_interrupt_config(hperh, SPI_IT_ERR, ENABLE); if ((hperh->init.dir == SPI_DIRECTION_2LINES_RXONLY) || (hperh->init.dir == SPI_DIRECTION_1LINE_RX)) SPI_ENABLE(hperh); @@ -822,12 +858,13 @@ ald_status_t spi_recv_by_it(spi_handle_t *hperh, uint8_t *buf, uint16_t size) * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_send_recv_by_it(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size) +ald_status_t ald_spi_send_recv_by_it(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size) { assert_param(IS_SPI(hperh->perh)); if (hperh->state != SPI_STATE_READY) return BUSY; + if (tx_buf == NULL || rx_buf == NULL || size == 0) return ERROR; @@ -846,9 +883,9 @@ ald_status_t spi_send_recv_by_it(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t * if (hperh->init.crc_calc) SPI_CRC_RESET(hperh); - spi_interrupt_config(hperh, SPI_IT_RXBNE, ENABLE); - spi_interrupt_config(hperh, SPI_IT_TXBE, ENABLE); - spi_interrupt_config(hperh, SPI_IT_ERR, ENABLE); + ald_spi_interrupt_config(hperh, SPI_IT_RXBNE, ENABLE); + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, ENABLE); + ald_spi_interrupt_config(hperh, SPI_IT_ERR, ENABLE); return OK; } @@ -862,12 +899,13 @@ ald_status_t spi_send_recv_by_it(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t * * @param channel: DMA channel as SPI transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { assert_param(IS_SPI(hperh->perh)); if (hperh->state != SPI_STATE_READY) return BUSY; + if (buf == NULL || size == 0) return ERROR; @@ -884,6 +922,7 @@ ald_status_t spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, u if (hperh->init.dir == SPI_DIRECTION_1LINE) SPI_1LINE_TX(hperh); + if (hperh->init.crc_calc) SPI_CRC_RESET(hperh); @@ -896,7 +935,7 @@ ald_status_t spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, u hperh->hdmatx.err_cbk = spi_dma_error; /* Configure SPI DMA transmit */ - dma_config_struct(&(hperh->hdmatx.config)); + ald_dma_config_struct(&(hperh->hdmatx.config)); hperh->hdmatx.config.data_width = hperh->init.data_size == SPI_DATA_SIZE_8 ? DMA_DATA_SIZE_BYTE : DMA_DATA_SIZE_HALFWORD; hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; @@ -906,10 +945,10 @@ ald_status_t spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, u hperh->hdmatx.config.msel = hperh->perh == SPI0 ? DMA_MSEL_SPI0 : (hperh->perh == SPI1 ? DMA_MSEL_SPI1 : DMA_MSEL_SPI2); hperh->hdmatx.config.msigsel = DMA_MSIGSEL_SPI_TXEMPTY; hperh->hdmatx.config.channel = channel; - dma_config_basic(&(hperh->hdmatx)); + ald_dma_config_basic(&(hperh->hdmatx)); __UNLOCK(hperh); - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, ENABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, ENABLE); if (READ_BIT(hperh->perh->CON1, SPI_CON1_SPIEN_MSK) == 0) SPI_ENABLE(hperh); @@ -925,12 +964,13 @@ ald_status_t spi_send_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, u * @param channel: DMA channel as SPI transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { assert_param(IS_SPI(hperh->perh)); if (hperh->state != SPI_STATE_READY) return BUSY; + if (buf == NULL || size == 0) return ERROR; @@ -947,11 +987,13 @@ ald_status_t spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, u if (hperh->init.dir == SPI_DIRECTION_1LINE_RX) SPI_1LINE_RX(hperh); + if ((hperh->init.dir == SPI_DIRECTION_2LINES) && (hperh->init.mode == SPI_MODE_MASTER)) { __UNLOCK(hperh); - return ERROR; /* Please use spi_send_recv_by_dma() */ + return ERROR; /* Please use ald_spi_send_recv_by_dma() */ } + if (hperh->init.crc_calc) SPI_CRC_RESET(hperh); @@ -964,7 +1006,7 @@ ald_status_t spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, u hperh->hdmarx.err_cbk = spi_dma_error; /* Configure DMA Receive */ - dma_config_struct(&(hperh->hdmarx.config)); + ald_dma_config_struct(&(hperh->hdmarx.config)); hperh->hdmarx.config.data_width = hperh->init.data_size == SPI_DATA_SIZE_8 ? DMA_DATA_SIZE_BYTE : DMA_DATA_SIZE_HALFWORD; hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)buf; @@ -974,10 +1016,10 @@ ald_status_t spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, u hperh->hdmarx.config.msel = hperh->perh == SPI0 ? DMA_MSEL_SPI0 : (hperh->perh == SPI1 ? DMA_MSEL_SPI1 : DMA_MSEL_SPI2); hperh->hdmarx.config.msigsel = DMA_MSIGSEL_SPI_RNR; hperh->hdmarx.config.channel = channel; - dma_config_basic(&(hperh->hdmarx)); + ald_dma_config_basic(&(hperh->hdmarx)); __UNLOCK(hperh); - spi_dma_req_config(hperh, SPI_DMA_REQ_RX, ENABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_RX, ENABLE); if ((hperh->init.dir == SPI_DIRECTION_2LINES_RXONLY) || (hperh->init.dir == SPI_DIRECTION_1LINE_RX)) SPI_ENABLE(hperh); @@ -995,12 +1037,13 @@ ald_status_t spi_recv_by_dma(spi_handle_t *hperh, uint8_t *buf, uint16_t size, u * @param rx_channel: DMA channel as SPI receive * @retval Status, see @ref ald_status_t. */ -ald_status_t spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel) +ald_status_t ald_spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel) { assert_param(IS_SPI(hperh->perh)); if (hperh->state != SPI_STATE_READY && hperh->state != SPI_STATE_BUSY_RX) return BUSY; + if (tx_buf == NULL || rx_buf == NULL || size == 0) return ERROR; @@ -1017,6 +1060,7 @@ ald_status_t spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t if (hperh->hdmatx.perh == NULL) hperh->hdmatx.perh = DMA0; + if (hperh->hdmarx.perh == NULL) hperh->hdmarx.perh = DMA0; @@ -1033,7 +1077,7 @@ ald_status_t spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t SPI_CRC_RESET(hperh); /* Configure SPI DMA transmit */ - dma_config_struct(&(hperh->hdmatx.config)); + ald_dma_config_struct(&(hperh->hdmatx.config)); hperh->hdmatx.config.data_width = hperh->init.data_size == SPI_DATA_SIZE_8 ? DMA_DATA_SIZE_BYTE : DMA_DATA_SIZE_HALFWORD; hperh->hdmatx.config.src = (void *)tx_buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; @@ -1043,10 +1087,10 @@ ald_status_t spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t hperh->hdmatx.config.msel = hperh->perh == SPI0 ? DMA_MSEL_SPI0 : (hperh->perh == SPI1 ? DMA_MSEL_SPI1 : DMA_MSEL_SPI2); hperh->hdmatx.config.msigsel = DMA_MSIGSEL_SPI_TXEMPTY; hperh->hdmatx.config.channel = tx_channel; - dma_config_basic(&(hperh->hdmatx)); + ald_dma_config_basic(&(hperh->hdmatx)); /* Configure DMA Receive */ - dma_config_struct(&(hperh->hdmarx.config)); + ald_dma_config_struct(&(hperh->hdmarx.config)); hperh->hdmarx.config.data_width = hperh->init.data_size == SPI_DATA_SIZE_8 ? DMA_DATA_SIZE_BYTE : DMA_DATA_SIZE_HALFWORD; hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)rx_buf; @@ -1056,11 +1100,11 @@ ald_status_t spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t hperh->hdmarx.config.msel = hperh->perh == SPI0 ? DMA_MSEL_SPI0 : (hperh->perh == SPI1 ? DMA_MSEL_SPI1 : DMA_MSEL_SPI2); hperh->hdmarx.config.msigsel = DMA_MSIGSEL_SPI_RNR; hperh->hdmarx.config.channel = rx_channel; - dma_config_basic(&(hperh->hdmarx)); + ald_dma_config_basic(&(hperh->hdmarx)); __UNLOCK(hperh); - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, ENABLE); - spi_dma_req_config(hperh, SPI_DMA_REQ_RX, ENABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, ENABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_RX, ENABLE); return OK; } @@ -1070,13 +1114,13 @@ ald_status_t spi_send_recv_by_dma(spi_handle_t *hperh, uint8_t *tx_buf, uint8_t * @param hperh: Pointer to a spi_handle_t structure. * @retval Status */ -ald_status_t spi_dma_pause(spi_handle_t *hperh) +ald_status_t ald_spi_dma_pause(spi_handle_t *hperh) { assert_param(IS_SPI(hperh->perh)); __LOCK(hperh); - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); - spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); __UNLOCK(hperh); return OK; @@ -1087,13 +1131,13 @@ ald_status_t spi_dma_pause(spi_handle_t *hperh) * @param hperh: Pointer to a spi_handle_t structure. * @retval Status */ -ald_status_t spi_dma_resume(spi_handle_t *hperh) +ald_status_t ald_spi_dma_resume(spi_handle_t *hperh) { assert_param(IS_SPI(hperh->perh)); __LOCK(hperh); - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, ENABLE); - spi_dma_req_config(hperh, SPI_DMA_REQ_RX, ENABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, ENABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_RX, ENABLE); __UNLOCK(hperh); return OK; @@ -1104,13 +1148,13 @@ ald_status_t spi_dma_resume(spi_handle_t *hperh) * @param hperh: Pointer to a spi_handle_t structure. * @retval Status */ -ald_status_t spi_dma_stop(spi_handle_t *hperh) +ald_status_t ald_spi_dma_stop(spi_handle_t *hperh) { assert_param(IS_SPI(hperh->perh)); __LOCK(hperh); - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); - spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); __UNLOCK(hperh); hperh->state = SPI_STATE_READY; @@ -1130,7 +1174,7 @@ ald_status_t spi_dma_stop(spi_handle_t *hperh) =============================================================================== [..] This subsection provides a set of functions allowing to control the SPI. - (+) Handle interrupt about SPI module. The spi_irq_handle() function must + (+) Handle interrupt about SPI module. The ald_spi_irq_handler() function must be invoked by SPI-IRQ function. (+) Configure the interrupt DISABLE/ENABLE. (+) Configure the DMA request. @@ -1147,14 +1191,14 @@ ald_status_t spi_dma_stop(spi_handle_t *hperh) * @param hperh: Pointer to a spi_handle_t structure. * @retval None */ -void spi_irq_handle(spi_handle_t *hperh) +void ald_spi_irq_handler(spi_handle_t *hperh) { if ((hperh->state == SPI_STATE_BUSY_RX) || (hperh->state == SPI_STATE_BUSY_TX)) { - if ((spi_get_it_status(hperh, SPI_IT_RXBNE) != RESET) && (spi_get_flag_status(hperh, SPI_IF_RXBNE) != RESET)) + if ((ald_spi_get_it_status(hperh, SPI_IT_RXBNE) != RESET) && (ald_spi_get_flag_status(hperh, SPI_IF_RXBNE) != RESET)) __spi_recv_by_it(hperh); - if ((spi_get_it_status(hperh, SPI_IT_TXBE) != RESET) && (spi_get_flag_status(hperh, SPI_IF_TXBE) != RESET)) + if ((ald_spi_get_it_status(hperh, SPI_IT_TXBE) != RESET) && (ald_spi_get_flag_status(hperh, SPI_IF_TXBE) != RESET)) __spi_send_by_it(hperh); } @@ -1162,43 +1206,45 @@ void spi_irq_handle(spi_handle_t *hperh) { if (hperh->tx_size == hperh->tx_count) { - if ((spi_get_it_status(hperh, SPI_IT_TXBE) != RESET) && (spi_get_flag_status(hperh, SPI_IF_TXBE) != RESET)) + if ((ald_spi_get_it_status(hperh, SPI_IT_TXBE) != RESET) && (ald_spi_get_flag_status(hperh, SPI_IF_TXBE) != RESET)) __spi_send_recv_by_it(hperh, SPI_SR_TXBE); } else { - if ((spi_get_it_status(hperh, SPI_IT_TXBE) != RESET) && (spi_get_flag_status(hperh, SPI_IF_TXBE) != RESET) - && (spi_get_it_status(hperh, SPI_IT_RXBNE) != RESET) && (spi_get_flag_status(hperh, SPI_IF_RXBNE) != RESET)) + if ((ald_spi_get_it_status(hperh, SPI_IT_TXBE) != RESET) && (ald_spi_get_flag_status(hperh, SPI_IF_TXBE) != RESET) + && (ald_spi_get_it_status(hperh, SPI_IT_RXBNE) != RESET) && (ald_spi_get_flag_status(hperh, SPI_IF_RXBNE) != RESET)) __spi_send_recv_by_it(hperh, SPI_SR_TXBE_RXBNE); } } - if ((spi_get_it_status(hperh, SPI_IT_ERR) != RESET)) + if ((ald_spi_get_it_status(hperh, SPI_IT_ERR) != RESET)) { - if (spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET) + if (ald_spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET) { hperh->err_code |= SPI_ERROR_CRC; - spi_clear_flag_status(hperh, SPI_IF_CRCERR); + ald_spi_clear_flag_status(hperh, SPI_IF_CRCERR); } - if (spi_get_flag_status(hperh, SPI_IF_MODF) != RESET) + + if (ald_spi_get_flag_status(hperh, SPI_IF_MODF) != RESET) { hperh->err_code |= SPI_ERROR_MODF; - spi_clear_flag_status(hperh, SPI_IF_MODF); + ald_spi_clear_flag_status(hperh, SPI_IF_MODF); } - if (spi_get_flag_status(hperh, SPI_IF_OVE) != RESET) + + if (ald_spi_get_flag_status(hperh, SPI_IF_OVE) != RESET) { if (hperh->state != SPI_STATE_BUSY_TX) { hperh->err_code |= SPI_ERROR_OVE; - spi_clear_flag_status(hperh, SPI_IF_OVE); + ald_spi_clear_flag_status(hperh, SPI_IF_OVE); } } if (hperh->err_code != SPI_ERROR_NONE) { - spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); - spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); - spi_interrupt_config(hperh, SPI_IT_ERR, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_ERR, DISABLE); hperh->state = SPI_STATE_READY; if (hperh->err_cbk) @@ -1219,7 +1265,7 @@ void spi_irq_handle(spi_handle_t *hperh) * - DISABLE * @retval None */ -void spi_interrupt_config(spi_handle_t *hperh, spi_it_t it, type_func_t state) +void ald_spi_interrupt_config(spi_handle_t *hperh, spi_it_t it, type_func_t state) { assert_param(IS_SPI(hperh->perh)); assert_param(IS_SPI_IT(it)); @@ -1240,7 +1286,7 @@ void spi_interrupt_config(spi_handle_t *hperh, spi_it_t it, type_func_t state) * This parameter can be one of the @ref spi_baud_t. * @retval None */ -void spi_speed_config(spi_handle_t *hperh, spi_baud_t speed) +void ald_spi_speed_config(spi_handle_t *hperh, spi_baud_t speed) { uint32_t tmp = 0; assert_param(IS_SPI(hperh->perh)); @@ -1263,7 +1309,7 @@ void spi_speed_config(spi_handle_t *hperh, spi_baud_t speed) * - DISABLE * @retval None */ -void spi_dma_req_config(spi_handle_t *hperh, spi_dma_req_t req, type_func_t state) +void ald_spi_dma_req_config(spi_handle_t *hperh, spi_dma_req_t req, type_func_t state) { assert_param(IS_SPI(hperh->perh)); assert_param(IS_SPI_DMA_REQ(req)); @@ -1287,6 +1333,25 @@ void spi_dma_req_config(spi_handle_t *hperh, spi_dma_req_t req, type_func_t stat return; } +/** @brief Check whether the specified SPI state flag is set or not. + * @param hperh: Pointer to a spi_handle_t structure. + * @param status: specifies the flag to check. + * This parameter can be one of the @ref spi_status_t. + * @retval Status + * - SET + * - RESET + */ +flag_status_t spi_get_status(spi_handle_t *hperh, spi_status_t status) +{ + assert_param(IS_SPI(hperh->perh)); + assert_param(IS_SPI_STATUS(status)); + + if (hperh->perh->STAT & status) + return SET; + + return RESET; +} + /** * @brief Checks whether the specified SPI interrupt has occurred or not. * @param hperh: Pointer to a spi_handle_t structure. @@ -1296,7 +1361,7 @@ void spi_dma_req_config(spi_handle_t *hperh, spi_dma_req_t req, type_func_t stat * - SET * - RESET */ -it_status_t spi_get_it_status(spi_handle_t *hperh, spi_it_t it) +it_status_t ald_spi_get_it_status(spi_handle_t *hperh, spi_it_t it) { assert_param(IS_SPI(hperh->perh)); assert_param(IS_SPI_IT(it)); @@ -1315,7 +1380,7 @@ it_status_t spi_get_it_status(spi_handle_t *hperh, spi_it_t it) * - SET * - RESET */ -flag_status_t spi_get_flag_status(spi_handle_t *hperh, spi_flag_t flag) +flag_status_t ald_spi_get_flag_status(spi_handle_t *hperh, spi_flag_t flag) { assert_param(IS_SPI(hperh->perh)); assert_param(IS_SPI_IF(flag)); @@ -1332,7 +1397,7 @@ flag_status_t spi_get_flag_status(spi_handle_t *hperh, spi_flag_t flag) * This parameter can be one of the @ref spi_flag_t. * @retval None */ -void spi_clear_flag_status(spi_handle_t *hperh, spi_flag_t flag) +void ald_spi_clear_flag_status(spi_handle_t *hperh, spi_flag_t flag) { uint32_t temp; @@ -1344,6 +1409,7 @@ void spi_clear_flag_status(spi_handle_t *hperh, spi_flag_t flag) SET_BIT(hperh->perh->STAT, SPI_STAT_CRCERR_MSK); return; } + if (flag == SPI_IF_OVE) { temp = hperh->perh->DATA; @@ -1351,6 +1417,7 @@ void spi_clear_flag_status(spi_handle_t *hperh, spi_flag_t flag) UNUSED(temp); return; } + if (flag == SPI_IF_MODF) { temp = hperh->perh->STAT; @@ -1372,17 +1439,17 @@ void spi_clear_flag_status(spi_handle_t *hperh, spi_flag_t flag) */ static ald_status_t spi_wait_flag(spi_handle_t *hperh, spi_flag_t flag, flag_status_t status, uint32_t timeout) { - uint32_t tick = __get_tick(); + uint32_t tick = ald_get_tick(); assert_param(timeout > 0); - while ((spi_get_flag_status(hperh, flag)) != status) + while ((ald_spi_get_flag_status(hperh, flag)) != status) { - if (((__get_tick()) - tick) > timeout) + if (((ald_get_tick()) - tick) > timeout) { - spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); - spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); - spi_interrupt_config(hperh, SPI_IT_ERR, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_ERR, DISABLE); return TIMEOUT; } } @@ -1402,14 +1469,14 @@ static ald_status_t spi_wait_flag_irq(spi_handle_t *hperh, spi_flag_t flag, flag { assert_param(timeout > 0); - while (((spi_get_flag_status(hperh, flag)) != status) && (--timeout)); + while (((ald_spi_get_flag_status(hperh, flag)) != status) && (--timeout)); if (timeout) return OK; - spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); - spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); - spi_interrupt_config(hperh, SPI_IT_ERR, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_ERR, DISABLE); return TIMEOUT; } @@ -1427,8 +1494,8 @@ static ald_status_t spi_wait_flag_irq(spi_handle_t *hperh, spi_flag_t flag, flag =============================================================================== [..] This subsection provides a set of functions allowing to control the SPI. - (+) spi_get_state() API can check in run-time the state of the SPI peripheral - (+) spi_get_error() check in run-time Errors occurring during communication + (+) ald_spi_get_state() API can check in run-time the state of the SPI peripheral + (+) ald_spi_get_error() check in run-time Errors occurring during communication @endverbatim * @{ @@ -1439,7 +1506,7 @@ static ald_status_t spi_wait_flag_irq(spi_handle_t *hperh, spi_flag_t flag, flag * @param hperh: Pointer to a spi_handle_t structure. * @retval ALD state */ -spi_state_t spi_get_state(spi_handle_t *hperh) +spi_state_t ald_spi_get_state(spi_handle_t *hperh) { assert_param(IS_SPI(hperh->perh)); return hperh->state; @@ -1450,7 +1517,7 @@ spi_state_t spi_get_state(spi_handle_t *hperh) * @param hperh: Pointer to a spi_handle_t structure. * @retval SPI Error Code */ -uint32_t spi_get_error(spi_handle_t *hperh) +uint32_t ald_spi_get_error(spi_handle_t *hperh) { assert_param(IS_SPI(hperh->perh)); return hperh->err_code; @@ -1477,11 +1544,11 @@ static void __spi_send_by_it(spi_handle_t *hperh) { if (hperh->tx_count == 0) { - spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); hperh->state = SPI_STATE_READY; if (hperh->init.dir == SPI_DIRECTION_2LINES) - spi_clear_flag_status(hperh, SPI_IF_OVE); + ald_spi_clear_flag_status(hperh, SPI_IF_OVE); if ((spi_wait_flag_irq(hperh, SPI_IF_BUSY, RESET, 5000)) != OK) { @@ -1507,6 +1574,7 @@ static void __spi_send_by_it(spi_handle_t *hperh) hperh->perh->DATA = *(uint16_t *)hperh->tx_buf; hperh->tx_buf += 2; } + --hperh->tx_count; if (hperh->tx_count == 0) @@ -1526,6 +1594,7 @@ static void __spi_send_by_it(spi_handle_t *hperh) static void __spi_recv_by_it(spi_handle_t *hperh) { uint16_t temp; + if (hperh->init.data_size == SPI_DATA_SIZE_8) { *hperh->rx_buf = hperh->perh->DATA; @@ -1536,6 +1605,7 @@ static void __spi_recv_by_it(spi_handle_t *hperh) *(uint16_t *)hperh->rx_buf = hperh->perh->DATA; hperh->rx_buf += 2; } + --hperh->rx_count; if ((hperh->rx_count == 1) && (hperh->init.crc_calc)) @@ -1543,13 +1613,13 @@ static void __spi_recv_by_it(spi_handle_t *hperh) if (hperh->rx_count == 0) { - spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); hperh->state = SPI_STATE_READY; - if ((hperh->init.crc_calc) && (spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET)) + if ((hperh->init.crc_calc) && (ald_spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET)) { hperh->err_code |= SPI_ERROR_CRC; - spi_clear_flag_status(hperh, SPI_IF_CRCERR); + ald_spi_clear_flag_status(hperh, SPI_IF_CRCERR); if (hperh->err_cbk) hperh->err_cbk(hperh); @@ -1638,7 +1708,8 @@ static void __spi_send_recv_by_it(spi_handle_t *hperh, spi_sr_status_t status) { if (hperh->init.crc_calc) SPI_CRCNEXT_ENABLE(hperh); - spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); + + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); } } } @@ -1646,15 +1717,15 @@ static void __spi_send_recv_by_it(spi_handle_t *hperh, spi_sr_status_t status) if (hperh->rx_count == 0) { - spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); - spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); - spi_interrupt_config(hperh, SPI_IT_ERR, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_TXBE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_RXBNE, DISABLE); + ald_spi_interrupt_config(hperh, SPI_IT_ERR, DISABLE); hperh->state = SPI_STATE_READY; - if ((hperh->init.crc_calc) && (spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET)) + if ((hperh->init.crc_calc) && (ald_spi_get_flag_status(hperh, SPI_IF_CRCERR) != RESET)) { hperh->err_code |= SPI_ERROR_CRC; - spi_clear_flag_status(hperh, SPI_IF_CRCERR); + ald_spi_clear_flag_status(hperh, SPI_IF_CRCERR); if (hperh->err_cbk) hperh->err_cbk(hperh); @@ -1682,11 +1753,11 @@ static void spi_dma_send_cplt(void *arg) spi_handle_t *hperh = (spi_handle_t *)arg; hperh->tx_count = 0; - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); hperh->state = SPI_STATE_READY; if (hperh->init.dir == SPI_DIRECTION_2LINES) - spi_clear_flag_status(hperh, SPI_IF_OVE); + ald_spi_clear_flag_status(hperh, SPI_IF_OVE); if ((spi_wait_flag_irq(hperh, SPI_IF_BUSY, RESET, 5000)) != OK) hperh->err_code |= SPI_ERROR_FLAG; @@ -1718,8 +1789,8 @@ static void spi_dma_recv_cplt(void *arg) spi_handle_t *hperh = (spi_handle_t *)arg; hperh->rx_count = 0; - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); - spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); hperh->state = SPI_STATE_READY; if (hperh->init.crc_calc) @@ -1730,11 +1801,11 @@ static void spi_dma_recv_cplt(void *arg) tmp = hperh->perh->DATA; UNUSED(tmp); - if (spi_get_flag_status(hperh, SPI_IF_CRCERR) == SET) + if (ald_spi_get_flag_status(hperh, SPI_IF_CRCERR) == SET) { SET_BIT(hperh->err_code, SPI_ERROR_CRC); SPI_CRC_RESET(hperh); - spi_clear_flag_status(hperh, SPI_IF_CRCERR); + ald_spi_clear_flag_status(hperh, SPI_IF_CRCERR); } } @@ -1771,10 +1842,10 @@ static void spi_dma_send_recv_cplt(void *arg) tmp = hperh->perh->DATA; UNUSED(tmp); - if (spi_get_flag_status(hperh, SPI_IF_CRCERR) == SET) + if (ald_spi_get_flag_status(hperh, SPI_IF_CRCERR) == SET) { SET_BIT(hperh->err_code, SPI_ERROR_CRC); - spi_clear_flag_status(hperh, SPI_IF_CRCERR); + ald_spi_clear_flag_status(hperh, SPI_IF_CRCERR); } } @@ -1783,8 +1854,8 @@ static void spi_dma_send_recv_cplt(void *arg) for (delay = 0; delay < 3000; delay++); - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); - spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); hperh->tx_count = 0; hperh->rx_count = 0; hperh->state = SPI_STATE_READY; @@ -1813,8 +1884,8 @@ static void spi_dma_error(void *arg) { spi_handle_t *hperh = (spi_handle_t *)arg; - spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); - spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_TX, DISABLE); + ald_spi_dma_req_config(hperh, SPI_DMA_REQ_RX, DISABLE); SET_BIT(hperh->err_code, SPI_ERROR_DMA); hperh->tx_count = 0; diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_timer.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_timer.c similarity index 66% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_timer.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_timer.c index d4419ebdec..677bbdcf86 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_timer.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_timer.c @@ -3,7 +3,7 @@ * * @file ald_timer.c * @brief TIMER module driver. - * This is the common part of the TIMER initialization + * This is the common part of the TIMER initialization * * @version V1.0 * @date 06 Nov 2017 @@ -57,6 +57,7 @@ static void timer_slave_set_config(timer_handle_t *hperh, timer_slave_config_t * static void timer_dma_capture_cplt(void *arg); static void timer_dma_period_elapse_cplt(void *arg); static void timer_dma_error(void *arg); + static void timer_dma_msel(TIMER_TypeDef *hperh, dma_config_t *config); #endif /** * @} @@ -93,7 +94,7 @@ static void timer_slave_set_config(timer_handle_t *hperh, timer_slave_config_t * * @param hperh: TIMER base handle * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_base_init(timer_handle_t *hperh) +ald_status_t ald_timer_base_init(timer_handle_t *hperh) { if (hperh == NULL) return ERROR; @@ -117,7 +118,7 @@ ald_status_t timer_base_init(timer_handle_t *hperh) * @param hperh: TIMER base handle * @retval Status, see @ref ald_status_t. */ -void timer_base_reset(timer_handle_t *hperh) +void ald_timer_base_reset(timer_handle_t *hperh) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); @@ -134,7 +135,7 @@ void timer_base_reset(timer_handle_t *hperh) * @param hperh: TIMER handle * @retval None */ -void timer_base_start(timer_handle_t *hperh) +void ald_timer_base_start(timer_handle_t *hperh) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); @@ -150,7 +151,7 @@ void timer_base_start(timer_handle_t *hperh) * @param hperh: TIMER handle * @retval None */ -void timer_base_stop(timer_handle_t *hperh) +void ald_timer_base_stop(timer_handle_t *hperh) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); @@ -166,11 +167,11 @@ void timer_base_stop(timer_handle_t *hperh) * @param hperh: TIMER handle * @retval None */ -void timer_base_start_by_it(timer_handle_t *hperh) +void ald_timer_base_start_by_it(timer_handle_t *hperh) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); - timer_interrupt_config(hperh, TIMER_IT_UPDATE, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_UPDATE, ENABLE); TIMER_ENABLE(hperh); return; @@ -181,11 +182,11 @@ void timer_base_start_by_it(timer_handle_t *hperh) * @param hperh: TIMER handle * @retval None */ -void timer_base_stop_by_it(timer_handle_t *hperh) +void ald_timer_base_stop_by_it(timer_handle_t *hperh) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); - timer_interrupt_config(hperh, TIMER_IT_UPDATE, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_UPDATE, DISABLE); TIMER_DISABLE(hperh); return; @@ -201,13 +202,14 @@ void timer_base_stop_by_it(timer_handle_t *hperh) * @param dma_ch: Channel of DMA. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_base_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, - uint16_t *buf, uint32_t len, uint8_t dma_ch) +ald_status_t ald_timer_base_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, + uint16_t *buf, uint32_t len, uint8_t dma_ch) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); if ((hperh->state == TIMER_STATE_BUSY)) return BUSY; + if ((hperh->state == TIMER_STATE_READY)) { if (((uint32_t)buf == 0) || (len == 0)) @@ -224,7 +226,7 @@ ald_status_t timer_base_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, hdma->err_cbk = timer_dma_error; hdma->err_arg = (void *)hperh; - dma_config_struct(&hdma->config); + ald_dma_config_struct(&hdma->config); hdma->config.src = (void *)buf; hdma->config.dst = (void *)&hperh->perh->AR; hdma->config.size = len; @@ -234,27 +236,9 @@ ald_status_t timer_base_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, hdma->config.msigsel = DMA_MSIGSEL_TIMER_UPDATE; hdma->config.channel = dma_ch; - if (hperh->perh == TIMER0) - hdma->config.msel = DMA_MSEL_TIMER0; - else if (hperh->perh == TIMER1) - hdma->config.msel = DMA_MSEL_TIMER1; - else if (hperh->perh == TIMER2) - hdma->config.msel = DMA_MSEL_TIMER2; - else if (hperh->perh == TIMER3) - hdma->config.msel = DMA_MSEL_TIMER3; - else if (hperh->perh == TIMER4) - hdma->config.msel = DMA_MSEL_TIMER4; - else if (hperh->perh == TIMER5) - hdma->config.msel = DMA_MSEL_TIMER5; - else if (hperh->perh == TIMER6) - hdma->config.msel = DMA_MSEL_TIMER6; - else if (hperh->perh == TIMER7) - hdma->config.msel = DMA_MSEL_TIMER7; - else - ; - - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_UPDATE, ENABLE); + timer_dma_msel(hperh->perh, &hdma->config); + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_UPDATE, ENABLE); TIMER_ENABLE(hperh); return OK; @@ -265,11 +249,11 @@ ald_status_t timer_base_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, * @param hperh: TIMER handle * @retval None */ -void timer_base_stop_by_dma(timer_handle_t *hperh) +void ald_timer_base_stop_by_dma(timer_handle_t *hperh) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); - timer_dma_req_config(hperh, TIMER_DMA_UPDATE, DISABLE); + ald_timer_dma_req_config(hperh, TIMER_DMA_UPDATE, DISABLE); TIMER_DISABLE(hperh); hperh->state = TIMER_STATE_READY; @@ -306,9 +290,9 @@ void timer_base_stop_by_dma(timer_handle_t *hperh) * @param hperh: TIMER handle * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_oc_init(timer_handle_t *hperh) +ald_status_t ald_timer_oc_init(timer_handle_t *hperh) { - return timer_base_init(hperh); + return ald_timer_base_init(hperh); } /** @@ -322,7 +306,7 @@ ald_status_t timer_oc_init(timer_handle_t *hperh) * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_oc_start(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_oc_start(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); @@ -346,7 +330,7 @@ void timer_oc_start(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_oc_stop(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_oc_stop(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); @@ -371,30 +355,30 @@ void timer_oc_stop(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_oc_start_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_oc_start_by_it(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); - break; + case TIMER_CHANNEL_1: + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); + break; - case TIMER_CHANNEL_2: - timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); - break; + case TIMER_CHANNEL_2: + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); + break; - case TIMER_CHANNEL_3: - timer_interrupt_config(hperh, TIMER_IT_CC3, ENABLE); - break; + case TIMER_CHANNEL_3: + ald_timer_interrupt_config(hperh, TIMER_IT_CC3, ENABLE); + break; - case TIMER_CHANNEL_4: - timer_interrupt_config(hperh, TIMER_IT_CC4, ENABLE); - break; + case TIMER_CHANNEL_4: + ald_timer_interrupt_config(hperh, TIMER_IT_CC4, ENABLE); + break; - default: - break; + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, ENABLE); @@ -417,30 +401,30 @@ void timer_oc_start_by_it(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_oc_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_oc_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); - break; + case TIMER_CHANNEL_1: + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); + break; - case TIMER_CHANNEL_2: - timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); - break; + case TIMER_CHANNEL_2: + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); + break; - case TIMER_CHANNEL_3: - timer_interrupt_config(hperh, TIMER_IT_CC3, DISABLE); - break; + case TIMER_CHANNEL_3: + ald_timer_interrupt_config(hperh, TIMER_IT_CC3, DISABLE); + break; - case TIMER_CHANNEL_4: - timer_interrupt_config(hperh, TIMER_IT_CC4, DISABLE); - break; + case TIMER_CHANNEL_4: + ald_timer_interrupt_config(hperh, TIMER_IT_CC4, DISABLE); + break; - default: - break; + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, DISABLE); @@ -453,29 +437,34 @@ void timer_oc_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) return; } + + + + #ifdef ALD_DMA /** * @brief Starts the TIMER Output Compare signal generation in DMA mode. * @param hperh: TIMER handle * @param ch: TIMER Channels to be enabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @param hdma: Pointer to dma_handle_t. * @param buf: The source Buffer address. * @param len: The length of buffer to be transferred from memory to TIMER peripheral * @param dma_ch: Channel of DMA. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_oc_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, - dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch) +ald_status_t ald_timer_oc_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, + dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); if ((hperh->state == TIMER_STATE_BUSY)) return BUSY; + if ((hperh->state == TIMER_STATE_READY)) { if (((uint32_t)buf == 0) || (len == 0)) @@ -492,7 +481,7 @@ ald_status_t timer_oc_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, hdma->err_cbk = timer_dma_error; hdma->err_arg = (void *)hperh; - dma_config_struct(&hdma->config); + ald_dma_config_struct(&hdma->config); hdma->config.src = (void *)buf; hdma->config.size = len; hdma->config.data_width = DMA_DATA_SIZE_HALFWORD; @@ -500,61 +489,45 @@ ald_status_t timer_oc_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, hdma->config.dst_inc = DMA_DATA_INC_NONE; hdma->config.channel = dma_ch; - if (hperh->perh == TIMER0) - hdma->config.msel = DMA_MSEL_TIMER0; - else if (hperh->perh == TIMER1) - hdma->config.msel = DMA_MSEL_TIMER1; - else if (hperh->perh == TIMER2) - hdma->config.msel = DMA_MSEL_TIMER2; - else if (hperh->perh == TIMER3) - hdma->config.msel = DMA_MSEL_TIMER3; - else if (hperh->perh == TIMER4) - hdma->config.msel = DMA_MSEL_TIMER4; - else if (hperh->perh == TIMER5) - hdma->config.msel = DMA_MSEL_TIMER5; - else if (hperh->perh == TIMER6) - hdma->config.msel = DMA_MSEL_TIMER6; - else if (hperh->perh == TIMER7) - hdma->config.msel = DMA_MSEL_TIMER7; - else - ;//do nothing + + timer_dma_msel(hperh->perh, &hdma->config); switch (ch) { - case TIMER_CHANNEL_1: - hdma->config.dst = (void *)&hperh->perh->CCVAL1; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH1; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_1; - break; - - case TIMER_CHANNEL_2: - hdma->config.dst = (void *)&hperh->perh->CCVAL2; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH2; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_2; - break; - - case TIMER_CHANNEL_3: - hdma->config.dst = (void *)&hperh->perh->CCVAL3; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH3; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC3, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_3; - break; - - case TIMER_CHANNEL_4: - hdma->config.dst = (void *)&hperh->perh->CCVAL4; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH4; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC4, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_4; - break; - - default: - break; + case TIMER_CHANNEL_1: + hdma->config.dst = (void *)&hperh->perh->CCVAL1; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH1; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_1; + break; + + case TIMER_CHANNEL_2: + hdma->config.dst = (void *)&hperh->perh->CCVAL2; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH2; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_2; + break; + + case TIMER_CHANNEL_3: + hdma->config.dst = (void *)&hperh->perh->CCVAL3; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH3; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC3, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_3; + break; + + case TIMER_CHANNEL_4: + hdma->config.dst = (void *)&hperh->perh->CCVAL4; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH4; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC4, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_4; + break; + + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, ENABLE); @@ -570,37 +543,37 @@ ald_status_t timer_oc_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, * @brief Stops the TIMER Output Compare signal generation in DMA mode. * @param hperh: TIMER handle * @param ch: TIMER Channels to be disabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_oc_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_oc_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); - break; + case TIMER_CHANNEL_1: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); + break; - case TIMER_CHANNEL_2: - timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); - break; + case TIMER_CHANNEL_2: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); + break; - case TIMER_CHANNEL_3: - timer_dma_req_config(hperh, TIMER_DMA_CC3, DISABLE); - break; + case TIMER_CHANNEL_3: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC3, DISABLE); + break; - case TIMER_CHANNEL_4: - timer_dma_req_config(hperh, TIMER_DMA_CC4, DISABLE); - break; + case TIMER_CHANNEL_4: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC4, DISABLE); + break; - default: - break; + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, DISABLE); @@ -621,18 +594,18 @@ void timer_oc_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @brief TIMER PWM functions * * @verbatim - ============================================================================== - ##### Time PWM functions ##### - ============================================================================== - [..] - This section provides functions allowing to: - (+) Initialize and configure the TIMER PWM. - (+) Start the Time PWM. - (+) Stop the Time PWM. - (+) Start the Time PWM and enable interrupt. - (+) Stop the Time PWM and disable interrupt. - (+) Start the Time PWM and enable DMA transfer. - (+) Stop the Time PWM and disable DMA transfer. + ============================================================================== + ##### Time PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIMER PWM. + (+) Start the Time PWM. + (+) Stop the Time PWM. + (+) Start the Time PWM and enable interrupt. + (+) Stop the Time PWM and disable interrupt. + (+) Start the Time PWM and enable DMA transfer. + (+) Stop the Time PWM and disable DMA transfer. @endverbatim * @{ @@ -643,25 +616,25 @@ void timer_oc_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @param hperh: TIMER handle * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_pwm_init(timer_handle_t *hperh) +ald_status_t ald_timer_pwm_init(timer_handle_t *hperh) { - return timer_base_init(hperh); + return ald_timer_base_init(hperh); } /** * @brief Starts the PWM signal generation. * @param hperh: TIMER handle * @param ch: TIMER Channels to be enabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_pwm_start(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwm_start(timer_handle_t *hperh, timer_channel_t ch) { - timer_oc_start(hperh, ch); + ald_timer_oc_start(hperh, ch); return; } @@ -669,16 +642,16 @@ void timer_pwm_start(timer_handle_t *hperh, timer_channel_t ch) * @brief Stops the PWM signal generation. * @param hperh: TIMER handle * @param ch: TIMER Channels to be disabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_pwm_stop(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwm_stop(timer_handle_t *hperh, timer_channel_t ch) { - timer_oc_stop(hperh, ch); + ald_timer_oc_stop(hperh, ch); return; } @@ -686,16 +659,16 @@ void timer_pwm_stop(timer_handle_t *hperh, timer_channel_t ch) * @brief Starts the PWM signal generation in interrupt mode. * @param hperh: TIMER handle * @param ch: TIMER Channel to be disabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_pwm_start_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwm_start_by_it(timer_handle_t *hperh, timer_channel_t ch) { - timer_oc_start_by_it(hperh, ch); + ald_timer_oc_start_by_it(hperh, ch); return; } @@ -703,16 +676,16 @@ void timer_pwm_start_by_it(timer_handle_t *hperh, timer_channel_t ch) * @brief Stops the PWM signal generation in interrupt mode. * @param hperh: TIMER handle * @param ch: TIMER Channels to be disabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_pwm_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwm_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) { - timer_oc_stop_by_it(hperh, ch); + ald_timer_oc_stop_by_it(hperh, ch); return; } @@ -721,37 +694,37 @@ void timer_pwm_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) * @brief Starts the TIMER PWM signal generation in DMA mode. * @param hperh: TIMER handle * @param ch: TIMER Channels to be enabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @param hdma: Pointer to dma_handle_t. * @param buf: The source Buffer address. * @param len: The length of buffer to be transferred from memory to TIMER peripheral * @param dma_ch: Channel of DMA. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_pwm_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, - dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch) +ald_status_t ald_timer_pwm_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, + dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch) { - return timer_oc_start_by_dma(hperh, ch, hdma, buf, len, dma_ch); + return ald_timer_oc_start_by_dma(hperh, ch, hdma, buf, len, dma_ch); } /** * @brief Stops the TIMER PWM signal generation in DMA mode. * @param hperh: TIMER handle * @param ch: TIMER Channels to be disabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_pwm_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwm_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) { - timer_oc_stop_by_dma(hperh, ch); + ald_timer_oc_stop_by_dma(hperh, ch); return; } #endif @@ -761,9 +734,9 @@ void timer_pwm_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @param freq: PWM freq to set * @retval None */ -void timer_pwm_set_freq(timer_handle_t *hperh, uint16_t freq) +void ald_timer_pwm_set_freq(timer_handle_t *hperh, uint16_t freq) { - uint32_t _arr = cmu_get_pclk1_clock() / (hperh->init.prescaler + 1) / freq - 1; + uint32_t _arr = ald_cmu_get_pclk1_clock() / (hperh->init.prescaler + 1) / freq - 1; WRITE_REG(hperh->perh->AR, _arr); hperh->init.period = _arr; @@ -773,15 +746,15 @@ void timer_pwm_set_freq(timer_handle_t *hperh, uint16_t freq) * @brief Set the PWM duty. * @param hperh: TIMER handle * @param ch: TIMER Channels to be enabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @param duty: PWM duty to set * @retval None */ -void timer_pwm_set_duty(timer_handle_t *hperh, timer_channel_t ch, uint16_t duty) +void ald_timer_pwm_set_duty(timer_handle_t *hperh, timer_channel_t ch, uint16_t duty) { uint32_t tmp = (hperh->init.period + 1) * duty / 100 - 1; @@ -803,40 +776,43 @@ void timer_pwm_set_duty(timer_handle_t *hperh, timer_channel_t ch, uint16_t duty * @brief Set capture the PWM. * @param hperh: TIMER handle * @param ch: TIMER Channels to be captured the PWM - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_pwm_set_input(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwm_set_input(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_PWM_INPUT_INSTANCE(hperh->perh, ch)); CLEAR_BIT(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK); + switch (ch) { - case TIMER_CHANNEL_1: - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CC1SSEL_MSK, TIMER_IC_SEL_DIRECT << TIMER_CHMR1_CC1SSEL_POSS); - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CC2SSEL_MSK, TIMER_IC_SEL_INDIRECT << TIMER_CHMR1_CC2SSEL_POSS); - MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC1POL_MSK, TIMER_IC_POLARITY_RISE << TIMER_CCEP_CC1POL_POS); - MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC1NPOL_MSK, TIMER_IC_POLARITY_RISE << TIMER_CCEP_CC1NPOL_POS); - MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC2POL_MSK, TIMER_IC_POLARITY_FALL << TIMER_CCEP_CC2POL_POS); - MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC2NPOL_MSK, TIMER_IC_POLARITY_FALL << TIMER_CCEP_CC2NPOL_POS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI1FP1 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_RESET << TIMER_SMCON_SMODS_POSS); - break; - case TIMER_CHANNEL_2: - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CC1SSEL_MSK, TIMER_IC_SEL_INDIRECT << TIMER_CHMR1_CC1SSEL_POSS); - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CC2SSEL_MSK, TIMER_IC_SEL_DIRECT << TIMER_CHMR1_CC2SSEL_POSS); - MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC1POL_MSK, TIMER_IC_POLARITY_RISE << TIMER_CCEP_CC1POL_POS); - MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC1NPOL_MSK, TIMER_IC_POLARITY_FALL << TIMER_CCEP_CC1NPOL_POS); - MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC2POL_MSK, TIMER_IC_POLARITY_FALL << TIMER_CCEP_CC2POL_POS); - MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC2NPOL_MSK, TIMER_IC_POLARITY_RISE << TIMER_CCEP_CC2NPOL_POS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI2FP2 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_RESET << TIMER_SMCON_SMODS_POSS); - break; - default: - break; + case TIMER_CHANNEL_1: + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CC1SSEL_MSK, TIMER_IC_SEL_DIRECT << TIMER_CHMR1_CC1SSEL_POSS); + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CC2SSEL_MSK, TIMER_IC_SEL_INDIRECT << TIMER_CHMR1_CC2SSEL_POSS); + MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC1POL_MSK, TIMER_IC_POLARITY_RISE << TIMER_CCEP_CC1POL_POS); + MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC1NPOL_MSK, TIMER_IC_POLARITY_RISE << TIMER_CCEP_CC1NPOL_POS); + MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC2POL_MSK, TIMER_IC_POLARITY_FALL << TIMER_CCEP_CC2POL_POS); + MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC2NPOL_MSK, TIMER_IC_POLARITY_FALL << TIMER_CCEP_CC2NPOL_POS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI1FP1 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_RESET << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_CHANNEL_2: + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CC1SSEL_MSK, TIMER_IC_SEL_INDIRECT << TIMER_CHMR1_CC1SSEL_POSS); + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CC2SSEL_MSK, TIMER_IC_SEL_DIRECT << TIMER_CHMR1_CC2SSEL_POSS); + MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC1POL_MSK, TIMER_IC_POLARITY_RISE << TIMER_CCEP_CC1POL_POS); + MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC1NPOL_MSK, TIMER_IC_POLARITY_FALL << TIMER_CCEP_CC1NPOL_POS); + MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC2POL_MSK, TIMER_IC_POLARITY_FALL << TIMER_CCEP_CC2POL_POS); + MODIFY_REG(hperh->perh->CCEP, TIMER_CCEP_CC2NPOL_MSK, TIMER_IC_POLARITY_RISE << TIMER_CCEP_CC2NPOL_POS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI2FP2 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_RESET << TIMER_SMCON_SMODS_POSS); + break; + + default: + break; } SET_BIT(hperh->perh->CCEP, TIMER_CCEP_CC1EN_MSK); @@ -874,9 +850,9 @@ void timer_pwm_set_input(timer_handle_t *hperh, timer_channel_t ch) * @param hperh: TIMER handle * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_ic_init(timer_handle_t *hperh) +ald_status_t ald_timer_ic_init(timer_handle_t *hperh) { - return timer_base_init(hperh); + return ald_timer_base_init(hperh); } /** @@ -890,7 +866,7 @@ ald_status_t timer_ic_init(timer_handle_t *hperh) * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_ic_start(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ic_start(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); @@ -910,7 +886,7 @@ void timer_ic_start(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_ic_stop(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ic_stop(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); @@ -930,26 +906,30 @@ void timer_ic_stop(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_ic_start_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ic_start_by_it(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); - break; - case TIMER_CHANNEL_2: - timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); - break; - case TIMER_CHANNEL_3: - timer_interrupt_config(hperh, TIMER_IT_CC3, ENABLE); - break; - case TIMER_CHANNEL_4: - timer_interrupt_config(hperh, TIMER_IT_CC4, ENABLE); - break; - default: - break; + case TIMER_CHANNEL_1: + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); + break; + + case TIMER_CHANNEL_2: + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); + break; + + case TIMER_CHANNEL_3: + ald_timer_interrupt_config(hperh, TIMER_IT_CC3, ENABLE); + break; + + case TIMER_CHANNEL_4: + ald_timer_interrupt_config(hperh, TIMER_IT_CC4, ENABLE); + break; + + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, ENABLE); @@ -968,26 +948,30 @@ void timer_ic_start_by_it(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_ic_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ic_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); - break; - case TIMER_CHANNEL_2: - timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); - break; - case TIMER_CHANNEL_3: - timer_interrupt_config(hperh, TIMER_IT_CC3, DISABLE); - break; - case TIMER_CHANNEL_4: - timer_interrupt_config(hperh, TIMER_IT_CC4, DISABLE); - break; - default: - break; + case TIMER_CHANNEL_1: + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); + break; + + case TIMER_CHANNEL_2: + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); + break; + + case TIMER_CHANNEL_3: + ald_timer_interrupt_config(hperh, TIMER_IT_CC3, DISABLE); + break; + + case TIMER_CHANNEL_4: + ald_timer_interrupt_config(hperh, TIMER_IT_CC4, DISABLE); + break; + + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, DISABLE); @@ -1000,24 +984,25 @@ void timer_ic_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) * @brief Starts the TIMER Input Capture measurement in DMA mode. * @param hperh: TIMER handle * @param ch: TIMER Channels to be enabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @param hdma: Pointer to dma_handle_t. * @param buf: The destination Buffer address. * @param len: The length of buffer to be transferred TIMER peripheral to memory * @param dma_ch: Channel of DMA. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_ic_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, - dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch) +ald_status_t ald_timer_ic_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, + dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); if ((hperh->state == TIMER_STATE_BUSY)) return BUSY; + if ((hperh->state == TIMER_STATE_READY)) { if (((uint32_t)buf == 0) || (len == 0)) @@ -1034,7 +1019,7 @@ ald_status_t timer_ic_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, hdma->err_cbk = timer_dma_error; hdma->err_arg = (void *)hperh; - dma_config_struct(&hdma->config); + ald_dma_config_struct(&hdma->config); hdma->config.dst = (void *)buf; hdma->config.size = len; hdma->config.data_width = DMA_DATA_SIZE_HALFWORD; @@ -1042,61 +1027,44 @@ ald_status_t timer_ic_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, hdma->config.dst_inc = DMA_DATA_INC_HALFWORD; hdma->config.channel = dma_ch; - if (hperh->perh == TIMER0) - hdma->config.msel = DMA_MSEL_TIMER0; - else if (hperh->perh == TIMER1) - hdma->config.msel = DMA_MSEL_TIMER1; - else if (hperh->perh == TIMER2) - hdma->config.msel = DMA_MSEL_TIMER2; - else if (hperh->perh == TIMER3) - hdma->config.msel = DMA_MSEL_TIMER3; - else if (hperh->perh == TIMER4) - hdma->config.msel = DMA_MSEL_TIMER4; - else if (hperh->perh == TIMER5) - hdma->config.msel = DMA_MSEL_TIMER5; - else if (hperh->perh == TIMER6) - hdma->config.msel = DMA_MSEL_TIMER6; - else if (hperh->perh == TIMER7) - hdma->config.msel = DMA_MSEL_TIMER7; - else - ;/* do nothing */ + timer_dma_msel(hperh->perh, &hdma->config); switch (ch) { - case TIMER_CHANNEL_1: - hdma->config.src = (void *)&hperh->perh->CCVAL1; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH1; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_1; - break; - - case TIMER_CHANNEL_2: - hdma->config.src = (void *)&hperh->perh->CCVAL2; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH2; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_2; - break; - - case TIMER_CHANNEL_3: - hdma->config.src = (void *)&hperh->perh->CCVAL3; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH3; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC3, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_3; - break; - - case TIMER_CHANNEL_4: - hdma->config.src = (void *)&hperh->perh->CCVAL4; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH4; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC4, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_4; - break; - - default: - break; + case TIMER_CHANNEL_1: + hdma->config.src = (void *)&hperh->perh->CCVAL1; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH1; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_1; + break; + + case TIMER_CHANNEL_2: + hdma->config.src = (void *)&hperh->perh->CCVAL2; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH2; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_2; + break; + + case TIMER_CHANNEL_3: + hdma->config.src = (void *)&hperh->perh->CCVAL3; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH3; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC3, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_3; + break; + + case TIMER_CHANNEL_4: + hdma->config.src = (void *)&hperh->perh->CCVAL4; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH4; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC4, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_4; + break; + + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, ENABLE); @@ -1108,33 +1076,37 @@ ald_status_t timer_ic_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, * @brief Stops the TIMER Input Capture measurement in DMA mode. * @param hperh: TIMER handle * @param ch: TIMER Channels to be disabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval None */ -void timer_ic_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ic_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); - break; - case TIMER_CHANNEL_2: - timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); - break; - case TIMER_CHANNEL_3: - timer_dma_req_config(hperh, TIMER_DMA_CC3, DISABLE); - break; - case TIMER_CHANNEL_4: - timer_dma_req_config(hperh, TIMER_DMA_CC4, DISABLE); - break; - default: - break; + case TIMER_CHANNEL_1: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); + break; + + case TIMER_CHANNEL_2: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); + break; + + case TIMER_CHANNEL_3: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC3, DISABLE); + break; + + case TIMER_CHANNEL_4: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC4, DISABLE); + break; + + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, DISABLE); @@ -1177,7 +1149,7 @@ void timer_ic_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_OP_MODE_REPEAT: Repetitive pulses wil be generated. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_one_pulse_init(timer_handle_t *hperh, timer_op_mode_t mode) +ald_status_t ald_timer_one_pulse_init(timer_handle_t *hperh, timer_op_mode_t mode) { if (hperh == NULL) return ERROR; @@ -1207,7 +1179,7 @@ ald_status_t timer_one_pulse_init(timer_handle_t *hperh, timer_op_mode_t mode) * @arg TIMER_OP_OUTPUT_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_one_pulse_start(timer_handle_t *hperh, timer_op_output_channel_t ch) +void ald_timer_one_pulse_start(timer_handle_t *hperh, timer_op_output_channel_t ch) { /* Enable the Capture compare and the Input Capture channels * (in the OPM Mode the two possible channels that can be used are TIMER_CHANNEL_1 and TIMER_CHANNEL_2) @@ -1233,7 +1205,7 @@ void timer_one_pulse_start(timer_handle_t *hperh, timer_op_output_channel_t ch) * @arg TIMER_OP_OUTPUT_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_one_pulse_stop(timer_handle_t *hperh, timer_op_output_channel_t ch) +void ald_timer_one_pulse_stop(timer_handle_t *hperh, timer_op_output_channel_t ch) { timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); @@ -1254,7 +1226,7 @@ void timer_one_pulse_stop(timer_handle_t *hperh, timer_op_output_channel_t ch) * @arg TIMER_OP_OUTPUT_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_one_pulse_start_by_it(timer_handle_t *hperh, timer_op_output_channel_t ch) +void ald_timer_one_pulse_start_by_it(timer_handle_t *hperh, timer_op_output_channel_t ch) { /* Enable the Capture compare and the Input Capture channels * (in the OPM Mode the two possible channels that can be used are TIMER_CHANNEL_1 and TIMER_CHANNEL_2) @@ -1262,8 +1234,8 @@ void timer_one_pulse_start_by_it(timer_handle_t *hperh, timer_op_output_channel_ * if TIMER_CHANNEL_1 is used as input, the TIMER_CHANNEL_2 will be used as output * in all combinations, the TIMER_CHANNEL_1 and TIMER_CHANNEL_2 should be enabled together */ - timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); - timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); @@ -1282,10 +1254,10 @@ void timer_one_pulse_start_by_it(timer_handle_t *hperh, timer_op_output_channel_ * @arg TIMER_OP_OUTPUT_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_one_pulse_stop_by_it(timer_handle_t *hperh, timer_op_output_channel_t ch) +void ald_timer_one_pulse_stop_by_it(timer_handle_t *hperh, timer_op_output_channel_t ch) { - timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); - timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); @@ -1303,18 +1275,18 @@ void timer_one_pulse_stop_by_it(timer_handle_t *hperh, timer_op_output_channel_t * @brief TIMER Encoder functions * * @verbatim - ============================================================================== - ##### Time Encoder functions ##### - ============================================================================== - [..] - This section provides functions allowing to: - (+) Initialize and configure the TIMER Encoder. - (+) Start the Time Encoder. - (+) Stop the Time Encoder. - (+) Start the Time Encoder and enable interrupt. - (+) Stop the Time Encoder and disable interrupt. - (+) Start the Time Encoder and enable DMA transfer. - (+) Stop the Time Encoder and disable DMA transfer. + ============================================================================== + ##### Time Encoder functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIMER Encoder. + (+) Start the Time Encoder. + (+) Stop the Time Encoder. + (+) Start the Time Encoder and enable interrupt. + (+) Stop the Time Encoder and disable interrupt. + (+) Start the Time Encoder and enable DMA transfer. + (+) Stop the Time Encoder and disable DMA transfer. * @endverbatim * @{ @@ -1325,7 +1297,7 @@ void timer_one_pulse_stop_by_it(timer_handle_t *hperh, timer_op_output_channel_t * @param config: TIMER Encoder Interface configuration structure * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_encoder_init(timer_handle_t *hperh, timer_encoder_init_t *config) +ald_status_t ald_timer_encoder_init(timer_handle_t *hperh, timer_encoder_init_t *config) { if (hperh == NULL) return ERROR; @@ -1374,22 +1346,24 @@ ald_status_t timer_encoder_init(timer_handle_t *hperh, timer_encoder_init_t *co * @arg TIMER_CHANNEL_ALL: TIMER Channel 1 and TIMER Channel 2 are selected * @retval None */ -void timer_encoder_start(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_encoder_start(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); switch (ch) { - case TIMER_CHANNEL_1: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); - break; - case TIMER_CHANNEL_2: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); - break; - default: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); - break; + case TIMER_CHANNEL_1: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); + break; + + case TIMER_CHANNEL_2: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); + break; + + default: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); + break; } TIMER_ENABLE(hperh); @@ -1406,22 +1380,24 @@ void timer_encoder_start(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_ALL: TIMER Channel 1 and TIMER Channel 2 are selected * @retval None */ -void timer_encoder_stop(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_encoder_stop(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); switch (ch) { - case TIMER_CHANNEL_1: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); - break; - case TIMER_CHANNEL_2: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); - break; - default: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); - break; + case TIMER_CHANNEL_1: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); + break; + + case TIMER_CHANNEL_2: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); + break; + + default: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); + break; } TIMER_DISABLE(hperh); @@ -1438,26 +1414,28 @@ void timer_encoder_stop(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_ALL: TIMER Channel 1 and TIMER Channel 2 are selected * @retval None */ -void timer_encoder_start_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_encoder_start_by_it(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); switch (ch) { - case TIMER_CHANNEL_1: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); - timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); - break; - case TIMER_CHANNEL_2: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); - timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); - break; - default: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); - timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); - timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); - break; + case TIMER_CHANNEL_1: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); + break; + + case TIMER_CHANNEL_2: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); + break; + + default: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); + break; } TIMER_ENABLE(hperh); @@ -1474,26 +1452,28 @@ void timer_encoder_start_by_it(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_ALL: TIMER Channel 1 and TIMER Channel 2 are selected * @retval None */ -void timer_encoder_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_encoder_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); switch (ch) { - case TIMER_CHANNEL_1: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); - timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); - break; - case TIMER_CHANNEL_2: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); - timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); - break; - default: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); - timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); - timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); - break; + case TIMER_CHANNEL_1: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); + break; + + case TIMER_CHANNEL_2: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); + break; + + default: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); + break; } TIMER_DISABLE(hperh); @@ -1519,14 +1499,15 @@ void timer_encoder_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) * @param dma_ch2: Channel of DMA. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_encoder_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, - dma_handle_t *hdma1, dma_handle_t *hdma2, uint16_t *buf1, - uint16_t *buf2, uint32_t len, uint8_t dma_ch1, uint8_t dma_ch2) +ald_status_t ald_timer_encoder_start_by_dma(timer_handle_t *hperh, timer_channel_t ch, + dma_handle_t *hdma1, dma_handle_t *hdma2, uint16_t *buf1, + uint16_t *buf2, uint32_t len, uint8_t dma_ch1, uint8_t dma_ch2) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); if ((hperh->state == TIMER_STATE_BUSY)) return BUSY; + if ((hperh->state == TIMER_STATE_READY)) { if (((uint32_t)buf1 == 0) || ((uint32_t)buf2 == 0) || (len == 0)) @@ -1535,6 +1516,7 @@ ald_status_t timer_encoder_start_by_dma(timer_handle_t *hperh, timer_channel_t c if (hdma1->perh == NULL) hdma1->perh = DMA0; + if (hdma2->perh == NULL) hdma2->perh = DMA0; @@ -1544,80 +1526,63 @@ ald_status_t timer_encoder_start_by_dma(timer_handle_t *hperh, timer_channel_t c hdma1->err_cbk = timer_dma_error; hdma1->err_arg = (void *)hperh; - dma_config_struct(&hdma1->config); + ald_dma_config_struct(&hdma1->config); hdma1->config.size = len; hdma1->config.data_width = DMA_DATA_SIZE_HALFWORD; hdma1->config.src_inc = DMA_DATA_INC_NONE; hdma1->config.dst_inc = DMA_DATA_INC_HALFWORD; - if (hperh->perh == TIMER0) - hdma1->config.msel = DMA_MSEL_TIMER0; - else if (hperh->perh == TIMER1) - hdma1->config.msel = DMA_MSEL_TIMER1; - else if (hperh->perh == TIMER2) - hdma1->config.msel = DMA_MSEL_TIMER2; - else if (hperh->perh == TIMER3) - hdma1->config.msel = DMA_MSEL_TIMER3; - else if (hperh->perh == TIMER4) - hdma1->config.msel = DMA_MSEL_TIMER4; - else if (hperh->perh == TIMER5) - hdma1->config.msel = DMA_MSEL_TIMER5; - else if (hperh->perh == TIMER6) - hdma1->config.msel = DMA_MSEL_TIMER6; - else if (hperh->perh == TIMER7) - hdma1->config.msel = DMA_MSEL_TIMER7; - else - ;/* do nothing */ + timer_dma_msel(hperh->perh, &hdma1->config); switch (ch) { - case TIMER_CHANNEL_1: - hdma1->config.src = (void *)&hperh->perh->CCVAL1; - hdma1->config.dst = (void *)buf1; - hdma1->config.msigsel = DMA_MSIGSEL_TIMER_CH1; - hdma1->config.channel = dma_ch1; - dma_config_basic(hdma1); - timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); - TIMER_ENABLE(hperh); - break; - - case TIMER_CHANNEL_2: - hdma1->config.src = (void *)&hperh->perh->CCVAL2; - hdma1->config.dst = (void *)buf2; - hdma1->config.msigsel = DMA_MSIGSEL_TIMER_CH2; - hdma1->config.channel = dma_ch2; - dma_config_basic(hdma1); - timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); - TIMER_ENABLE(hperh); - break; - - default: - hdma2->cplt_cbk = timer_dma_capture_cplt; - hdma2->cplt_arg = (void *)hperh; - hdma2->err_cbk = timer_dma_error; - hdma2->err_arg = (void *)hperh; - memcpy(&hdma2->config, &hdma1->config, sizeof(dma_config_t)); - - hdma1->config.src = (void *)&hperh->perh->CCVAL1; - hdma1->config.dst = (void *)buf1; - hdma1->config.msigsel = DMA_MSIGSEL_TIMER_CH1; - hdma1->config.channel = dma_ch1; - dma_config_basic(hdma1); - timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); - - hdma2->config.src = (void *)&hperh->perh->CCVAL2; - hdma2->config.dst = (void *)buf2; - hdma2->config.msigsel = DMA_MSIGSEL_TIMER_CH2; - hdma2->config.channel = dma_ch2; - dma_config_basic(hdma2); - timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); - - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); - TIMER_ENABLE(hperh); - break; + case TIMER_CHANNEL_1: + hdma1->config.src = (void *)&hperh->perh->CCVAL1; + hdma1->config.dst = (void *)buf1; + hdma1->config.msigsel = DMA_MSIGSEL_TIMER_CH1; + hdma1->config.channel = dma_ch1; + ald_dma_config_basic(hdma1); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); + TIMER_ENABLE(hperh); + break; + + case TIMER_CHANNEL_2: + hdma1->config.src = (void *)&hperh->perh->CCVAL2; + hdma1->config.dst = (void *)buf2; + hdma1->config.msigsel = DMA_MSIGSEL_TIMER_CH2; + hdma1->config.channel = dma_ch2; + ald_dma_config_basic(hdma1); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); + TIMER_ENABLE(hperh); + break; + + default: + hdma2->cplt_cbk = timer_dma_capture_cplt; + hdma2->cplt_arg = (void *)hperh; + hdma2->err_cbk = timer_dma_error; + hdma2->err_arg = (void *)hperh; + memcpy(&hdma2->config, &hdma1->config, sizeof(dma_config_t)); + + hdma1->config.src = (void *)&hperh->perh->CCVAL1; + hdma1->config.dst = (void *)buf1; + hdma1->config.msigsel = DMA_MSIGSEL_TIMER_CH1; + hdma1->config.channel = dma_ch1; + ald_dma_config_basic(hdma1); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); + + hdma2->config.src = (void *)&hperh->perh->CCVAL2; + hdma2->config.dst = (void *)buf2; + hdma2->config.msigsel = DMA_MSIGSEL_TIMER_CH2; + hdma2->config.channel = dma_ch2; + ald_dma_config_basic(hdma2); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); + + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, ENABLE); + TIMER_ENABLE(hperh); + break; } return OK; @@ -1633,26 +1598,28 @@ ald_status_t timer_encoder_start_by_dma(timer_handle_t *hperh, timer_channel_t c * @arg TIMER_CHANNEL_ALL: TIMER Channel 1 and TIMER Channel 2 are selected * @retval None */ -void timer_encoder_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_encoder_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); switch (ch) { - case TIMER_CHANNEL_1: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); - timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); - break; - case TIMER_CHANNEL_2: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); - timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); - break; - default: - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); - timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); - timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); - timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); - break; + case TIMER_CHANNEL_1: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); + break; + + case TIMER_CHANNEL_2: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); + break; + + default: + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); + timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_2, DISABLE); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); + break; } TIMER_DISABLE(hperh); @@ -1668,18 +1635,18 @@ void timer_encoder_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @brief TIMER Hall Sensor functions * * @verbatim - ============================================================================== - ##### Time Hall Sensor functions ##### - ============================================================================== - [..] - This section provides functions allowing to: - (+) Initialize and configure the TIMER hall sensor. - (+) Start the hall sensor. - (+) Stop the hall sensor. - (+) Start the hall sensor and enable interrupt. - (+) Stop the hall sensor and disable interrupt. - (+) Start the hall sensor and enable DMA transfer. - (+) Stop the hal sensor and disable DMA transfer. + ============================================================================== + ##### Time Hall Sensor functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIMER hall sensor. + (+) Start the hall sensor. + (+) Stop the hall sensor. + (+) Start the hall sensor and enable interrupt. + (+) Stop the hall sensor and disable interrupt. + (+) Start the hall sensor and enable DMA transfer. + (+) Stop the hal sensor and disable DMA transfer. * @endverbatim * @{ @@ -1690,7 +1657,7 @@ void timer_encoder_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @param config: TIMER Encoder Interface configuration structure * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_hall_sensor_init(timer_handle_t *hperh, timer_hall_sensor_init_t *config) +ald_status_t ald_timer_hall_sensor_init(timer_handle_t *hperh, timer_hall_sensor_init_t *config) { timer_oc_init_t oc; @@ -1730,7 +1697,7 @@ ald_status_t timer_hall_sensor_init(timer_handle_t *hperh, timer_hall_sensor_in * @param hperh: TIMER handle * @retval None */ -void timer_hall_sensor_start(timer_handle_t *hperh) +void ald_timer_hall_sensor_start(timer_handle_t *hperh) { assert_param(IS_TIMER_XOR_INSTANCE(hperh->perh)); @@ -1745,7 +1712,7 @@ void timer_hall_sensor_start(timer_handle_t *hperh) * @param hperh: TIMER handle * @retval None */ -void timer_hall_sensor_stop(timer_handle_t *hperh) +void ald_timer_hall_sensor_stop(timer_handle_t *hperh) { assert_param(IS_TIMER_XOR_INSTANCE(hperh->perh)); @@ -1760,11 +1727,11 @@ void timer_hall_sensor_stop(timer_handle_t *hperh) * @param hperh: TIMER handle * @retval None */ -void timer_hall_sensor_start_by_it(timer_handle_t *hperh) +void ald_timer_hall_sensor_start_by_it(timer_handle_t *hperh) { assert_param(IS_TIMER_XOR_INSTANCE(hperh->perh)); - timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); TIMER_ENABLE(hperh); @@ -1776,12 +1743,12 @@ void timer_hall_sensor_start_by_it(timer_handle_t *hperh) * @param hperh: TIMER handle * @retval None */ -void timer_hall_sensor_stop_by_it(timer_handle_t *hperh) +void ald_timer_hall_sensor_stop_by_it(timer_handle_t *hperh) { assert_param(IS_TIMER_XOR_INSTANCE(hperh->perh)); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); - timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); TIMER_DISABLE(hperh); return; @@ -1797,13 +1764,14 @@ void timer_hall_sensor_stop_by_it(timer_handle_t *hperh) * @param dma_ch: Channel of DMA. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_hall_sensor_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, +ald_status_t ald_timer_hall_sensor_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, uint16_t *buf, uint32_t len, uint8_t dma_ch) { assert_param(IS_TIMER_XOR_INSTANCE(hperh->perh)); if ((hperh->state == TIMER_STATE_BUSY)) return BUSY; + if ((hperh->state == TIMER_STATE_READY)) { if (((uint32_t)buf == 0) || (len == 0)) @@ -1819,25 +1787,20 @@ ald_status_t timer_hall_sensor_start_by_dma(timer_handle_t *hperh, dma_handle_t hdma->err_cbk = timer_dma_error; hdma->err_arg = (void *)hperh; - dma_config_struct(&hdma->config); + ald_dma_config_struct(&hdma->config); hdma->config.size = len; hdma->config.data_width = DMA_DATA_SIZE_HALFWORD; hdma->config.src_inc = DMA_DATA_INC_NONE; hdma->config.dst_inc = DMA_DATA_INC_HALFWORD; - if (hperh->perh == TIMER0) - hdma->config.msel = DMA_MSEL_TIMER0; - else if (hperh->perh == TIMER6) - hdma->config.msel = DMA_MSEL_TIMER6; - else - ;/* do nothing */ + timer_dma_msel(hperh->perh, &hdma->config); hdma->config.src = (void *)&hperh->perh->CCVAL1; hdma->config.dst = (void *)buf; hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH1; hdma->config.channel = dma_ch; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, ENABLE); TIMER_ENABLE(hperh); @@ -1848,11 +1811,11 @@ ald_status_t timer_hall_sensor_start_by_dma(timer_handle_t *hperh, dma_handle_t * @param hperh: TIMER handle * @retval None */ -void timer_hall_sensor_stop_by_dma(timer_handle_t *hperh) +void ald_timer_hall_sensor_stop_by_dma(timer_handle_t *hperh) { assert_param(IS_TIMER_XOR_INSTANCE(hperh->perh)); - timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); timer_ccx_channel_cmd(hperh->perh, TIMER_CHANNEL_1, DISABLE); TIMER_DISABLE(hperh); @@ -1867,17 +1830,17 @@ void timer_hall_sensor_stop_by_dma(timer_handle_t *hperh) * @brief TIMER complementary output compare functions * * @verbatim - ============================================================================== - ##### Time complementary output compare functions ##### - ============================================================================== - [..] - This section provides functions allowing to: - (+) Start the Time complementary output compare. - (+) Stop the Time complementary output compare. - (+) Start the Time complementary output compare and enable interrupt. - (+) Stop the Time complementary output compare and disable interrupt. - (+) Start the Time complementary output compare and enable DMA transfer. - (+) Stop the Time complementary output compare and disable DMA transfer. + ============================================================================== + ##### Time complementary output compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Time complementary output compare. + (+) Stop the Time complementary output compare. + (+) Start the Time complementary output compare and enable interrupt. + (+) Stop the Time complementary output compare and disable interrupt. + (+) Start the Time complementary output compare and enable DMA transfer. + (+) Stop the Time complementary output compare and disable DMA transfer. * @endverbatim * @{ @@ -1893,7 +1856,7 @@ void timer_hall_sensor_stop_by_dma(timer_handle_t *hperh) * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_ocn_start(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ocn_start(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCXN_INSTANCE(hperh->perh, ch)); @@ -1914,7 +1877,7 @@ void timer_ocn_start(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_ocn_stop(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ocn_stop(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCXN_INSTANCE(hperh->perh, ch)); @@ -1936,28 +1899,29 @@ void timer_ocn_stop(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_ocn_start_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ocn_start_by_it(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCXN_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); - break; - - case TIMER_CHANNEL_2: - timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); - break; - - case TIMER_CHANNEL_3: - timer_interrupt_config(hperh, TIMER_IT_CC3, ENABLE); - break; - default: - break; + case TIMER_CHANNEL_1: + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, ENABLE); + break; + + case TIMER_CHANNEL_2: + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, ENABLE); + break; + + case TIMER_CHANNEL_3: + ald_timer_interrupt_config(hperh, TIMER_IT_CC3, ENABLE); + break; + + default: + break; } - timer_interrupt_config(hperh, TIMER_IT_BREAK, ENABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_BREAK, ENABLE); timer_ccxn_channel_cmd(hperh->perh, ch, ENABLE); TIMER_MOE_ENABLE(hperh); TIMER_ENABLE(hperh); @@ -1976,32 +1940,33 @@ void timer_ocn_start_by_it(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_ocn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ocn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCXN_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); - break; - - case TIMER_CHANNEL_2: - timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); - break; - - case TIMER_CHANNEL_3: - timer_interrupt_config(hperh, TIMER_IT_CC3, DISABLE); - break; - default: - break; + case TIMER_CHANNEL_1: + ald_timer_interrupt_config(hperh, TIMER_IT_CC1, DISABLE); + break; + + case TIMER_CHANNEL_2: + ald_timer_interrupt_config(hperh, TIMER_IT_CC2, DISABLE); + break; + + case TIMER_CHANNEL_3: + ald_timer_interrupt_config(hperh, TIMER_IT_CC3, DISABLE); + break; + + default: + break; } if ((!(READ_BIT(hperh->perh->CCEP, TIMER_CCEP_CC1NEN_MSK))) && (!(READ_BIT(hperh->perh->CCEP, TIMER_CCEP_CC2NEN_MSK))) && (!(READ_BIT(hperh->perh->CCEP, TIMER_CCEP_CC3NEN_MSK)))) { - timer_interrupt_config(hperh, TIMER_IT_BREAK, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_BREAK, DISABLE); } timer_ccxn_channel_cmd(hperh->perh, ch, DISABLE); @@ -2027,13 +1992,14 @@ void timer_ocn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) * @param dma_ch: Channel of DMA. * @retval None */ -ald_status_t timer_ocn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, - timer_channel_t ch, uint16_t *buf, uint32_t len, uint8_t dma_ch) +ald_status_t ald_timer_ocn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, + timer_channel_t ch, uint16_t *buf, uint32_t len, uint8_t dma_ch) { assert_param(IS_TIMER_CCXN_INSTANCE(hperh->perh, ch)); if ((hperh->state == TIMER_STATE_BUSY)) return BUSY; + if ((hperh->state == TIMER_STATE_READY)) { if (((uint32_t)buf == 0) || (len == 0)) @@ -2050,7 +2016,7 @@ ald_status_t timer_ocn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, hdma->err_cbk = timer_dma_error; hdma->err_arg = (void *)hperh; - dma_config_struct(&hdma->config); + ald_dma_config_struct(&hdma->config); hdma->config.src = (void *)buf; hdma->config.size = len; hdma->config.data_width = DMA_DATA_SIZE_HALFWORD; @@ -2061,32 +2027,32 @@ ald_status_t timer_ocn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, switch (ch) { - case TIMER_CHANNEL_1: - hdma->config.dst = (void *)&hperh->perh->CCVAL1; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH1; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_1; - break; - - case TIMER_CHANNEL_2: - hdma->config.dst = (void *)&hperh->perh->CCVAL2; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH2; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_2; - break; - - case TIMER_CHANNEL_3: - hdma->config.dst = (void *)&hperh->perh->CCVAL3; - hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH3; - dma_config_basic(hdma); - timer_dma_req_config(hperh, TIMER_DMA_CC3, ENABLE); - hperh->ch = TIMER_ACTIVE_CHANNEL_3; - break; - - default: - break; + case TIMER_CHANNEL_1: + hdma->config.dst = (void *)&hperh->perh->CCVAL1; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH1; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_1; + break; + + case TIMER_CHANNEL_2: + hdma->config.dst = (void *)&hperh->perh->CCVAL2; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH2; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_2; + break; + + case TIMER_CHANNEL_3: + hdma->config.dst = (void *)&hperh->perh->CCVAL3; + hdma->config.msigsel = DMA_MSIGSEL_TIMER_CH3; + ald_dma_config_basic(hdma); + ald_timer_dma_req_config(hperh, TIMER_DMA_CC3, ENABLE); + hperh->ch = TIMER_ACTIVE_CHANNEL_3; + break; + + default: + break; } timer_ccx_channel_cmd(hperh->perh, ch, ENABLE); @@ -2107,25 +2073,26 @@ ald_status_t timer_ocn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_ocn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_ocn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) { assert_param(IS_TIMER_CCXN_INSTANCE(hperh->perh, ch)); switch (ch) { - case TIMER_CHANNEL_1: - timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); - break; - - case TIMER_CHANNEL_2: - timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); - break; - - case TIMER_CHANNEL_3: - timer_dma_req_config(hperh, TIMER_DMA_CC3, DISABLE); - break; - default: - break; + case TIMER_CHANNEL_1: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC1, DISABLE); + break; + + case TIMER_CHANNEL_2: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC2, DISABLE); + break; + + case TIMER_CHANNEL_3: + ald_timer_dma_req_config(hperh, TIMER_DMA_CC3, DISABLE); + break; + + default: + break; } timer_ccxn_channel_cmd(hperh->perh, ch, DISABLE); @@ -2143,17 +2110,17 @@ void timer_ocn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @brief TIMER complementary PWM functions * * @verbatim - ============================================================================== - ##### Time complementary PWM functions ##### - ============================================================================== - [..] - This section provides functions allowing to: - (+) Start the Time complementary PWM. - (+) Stop the Time complementary PWM. - (+) Start the Time complementary PWM and enable interrupt. - (+) Stop the Time complementary PWM and disable interrupt. - (+) Start the Time complementary PWM and enable DMA transfer. - (+) Stop the Time complementary PWM and disable DMA transfer. + ============================================================================== + ##### Time complementary PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Time complementary PWM. + (+) Stop the Time complementary PWM. + (+) Start the Time complementary PWM and enable interrupt. + (+) Stop the Time complementary PWM and disable interrupt. + (+) Start the Time complementary PWM and enable DMA transfer. + (+) Stop the Time complementary PWM and disable DMA transfer. * @endverbatim * @{ @@ -2169,9 +2136,9 @@ void timer_ocn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_pwmn_start(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwmn_start(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_start(hperh, ch); + ald_timer_ocn_start(hperh, ch); } /** @@ -2184,9 +2151,9 @@ void timer_pwmn_start(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_pwmn_stop(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwmn_stop(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_stop(hperh, ch); + ald_timer_ocn_stop(hperh, ch); } /** @@ -2200,9 +2167,9 @@ void timer_pwmn_stop(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_pwmn_start_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwmn_start_by_it(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_start_by_it(hperh, ch); + ald_timer_ocn_start_by_it(hperh, ch); } /** @@ -2216,9 +2183,9 @@ void timer_pwmn_start_by_it(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_pwmn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwmn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_stop_by_it(hperh, ch); + ald_timer_ocn_stop_by_it(hperh, ch); } #ifdef ALD_DMA @@ -2237,10 +2204,10 @@ void timer_pwmn_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) * @param dma_ch: Channel of DMA. * @retval None */ -ald_status_t timer_pwmn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, - timer_channel_t ch, uint16_t *buf, uint32_t len, uint8_t dma_ch) +ald_status_t ald_timer_pwmn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, + timer_channel_t ch, uint16_t *buf, uint32_t len, uint8_t dma_ch) { - return timer_ocn_start_by_dma(hperh, hdma, ch, buf, len, dma_ch); + return ald_timer_ocn_start_by_dma(hperh, hdma, ch, buf, len, dma_ch); } /** @@ -2254,9 +2221,9 @@ ald_status_t timer_pwmn_start_by_dma(timer_handle_t *hperh, dma_handle_t *hdma, * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected * @retval None */ -void timer_pwmn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_pwmn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_stop_by_dma(hperh, ch); + ald_timer_ocn_stop_by_dma(hperh, ch); } #endif /** @@ -2267,15 +2234,15 @@ void timer_pwmn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @brief TIMER complementary one pulse functions * * @verbatim - ============================================================================== - ##### Time complementary one pulse functions ##### - ============================================================================== - [..] - This section provides functions allowing to: - (+) Start the Time complementary one pulse. - (+) Stop the Time complementary one pulse. - (+) Start the Time complementary one pulse and enable interrupt. - (+) Stop the Time complementary one pulse and disable interrupt. + ============================================================================== + ##### Time complementary one pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Time complementary one pulse. + (+) Stop the Time complementary one pulse. + (+) Start the Time complementary one pulse and enable interrupt. + (+) Stop the Time complementary one pulse and disable interrupt. * @endverbatim * @{ @@ -2290,9 +2257,9 @@ void timer_pwmn_stop_by_dma(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_one_pulse_n_start(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_one_pulse_n_start(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_start(hperh, ch); + ald_timer_ocn_start(hperh, ch); } /** @@ -2304,9 +2271,9 @@ void timer_one_pulse_n_start(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_one_pulse_n_stop(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_one_pulse_n_stop(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_stop(hperh, ch); + ald_timer_ocn_stop(hperh, ch); } /** @@ -2319,9 +2286,9 @@ void timer_one_pulse_n_stop(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_one_pulse_n_start_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_one_pulse_n_start_by_it(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_start_by_it(hperh, ch); + ald_timer_ocn_start_by_it(hperh, ch); } /** @@ -2334,9 +2301,9 @@ void timer_one_pulse_n_start_by_it(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected * @retval None */ -void timer_one_pulse_n_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) +void ald_timer_one_pulse_n_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) { - timer_ocn_stop_by_it(hperh, ch); + ald_timer_ocn_stop_by_it(hperh, ch); } /** * @} @@ -2371,14 +2338,14 @@ void timer_one_pulse_n_stop_by_it(timer_handle_t *hperh, timer_channel_t ch) * @param hperh: TIMER handle * @param config: TIMER Output Compare configuration structure * @param ch: TIMER Channels to be enabled - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected - * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected - * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected - * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 selected + * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected + * @arg TIMER_CHANNEL_3: TIMER Channel 3 selected + * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_oc_config_channel(timer_handle_t *hperh, timer_oc_init_t *config, timer_channel_t ch) +ald_status_t ald_timer_oc_config_channel(timer_handle_t *hperh, timer_oc_init_t *config, timer_channel_t ch) { assert_param(IS_TIMER_CCX_INSTANCE(hperh->perh, ch)); assert_param(IS_TIMER_OC_MODE(config->oc_mode)); @@ -2389,24 +2356,24 @@ ald_status_t timer_oc_config_channel(timer_handle_t *hperh, timer_oc_init_t *con switch (ch) { - case TIMER_CHANNEL_1: - timer_oc1_set_config(hperh->perh, config); - break; + case TIMER_CHANNEL_1: + timer_oc1_set_config(hperh->perh, config); + break; - case TIMER_CHANNEL_2: - timer_oc2_set_config(hperh->perh, config); - break; + case TIMER_CHANNEL_2: + timer_oc2_set_config(hperh->perh, config); + break; - case TIMER_CHANNEL_3: - timer_oc3_set_config(hperh->perh, config); - break; + case TIMER_CHANNEL_3: + timer_oc3_set_config(hperh->perh, config); + break; - case TIMER_CHANNEL_4: - timer_oc4_set_config(hperh->perh, config); - break; + case TIMER_CHANNEL_4: + timer_oc4_set_config(hperh->perh, config); + break; - default: - break; + default: + break; } hperh->state = TIMER_STATE_READY; @@ -2427,7 +2394,7 @@ ald_status_t timer_oc_config_channel(timer_handle_t *hperh, timer_oc_init_t *con * @arg TIMER_CHANNEL_4: TIMER Channel 4 selected * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_ic_config_channel(timer_handle_t *hperh, timer_ic_init_t *config, timer_channel_t ch) +ald_status_t ald_timer_ic_config_channel(timer_handle_t *hperh, timer_ic_init_t *config, timer_channel_t ch) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); assert_param(IS_TIMER_IC_POLARITY(config->polarity)); @@ -2440,28 +2407,28 @@ ald_status_t timer_ic_config_channel(timer_handle_t *hperh, timer_ic_init_t *con switch (ch) { - case TIMER_CHANNEL_1: - timer_ti1_set_config(hperh->perh, config->polarity, config->sel, config->filter); - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_IC1PRES_MSK, config->psc << TIMER_CHMR1_IC1PRES_POSS); - break; - - case TIMER_CHANNEL_2: - timer_ti2_set_config(hperh->perh, config->polarity, config->sel, config->filter); - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_IC2PRES_MSK, config->psc << TIMER_CHMR1_IC2PRES_POSS); - break; - - case TIMER_CHANNEL_3: - timer_ti3_set_config(hperh->perh, config->polarity, config->sel, config->filter); - MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_IC3PRES_MSK, config->psc << TIMER_CHMR2_IC3PRES_POSS); - break; - - case TIMER_CHANNEL_4: - timer_ti4_set_config(hperh->perh, config->polarity, config->sel, config->filter); - MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_IC4PRES_MSK, config->psc << TIMER_CHMR2_IC4PRES_POSS); - break; - - default: - break; + case TIMER_CHANNEL_1: + timer_ti1_set_config(hperh->perh, config->polarity, config->sel, config->filter); + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_IC1PRES_MSK, config->psc << TIMER_CHMR1_IC1PRES_POSS); + break; + + case TIMER_CHANNEL_2: + timer_ti2_set_config(hperh->perh, config->polarity, config->sel, config->filter); + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_IC2PRES_MSK, config->psc << TIMER_CHMR1_IC2PRES_POSS); + break; + + case TIMER_CHANNEL_3: + timer_ti3_set_config(hperh->perh, config->polarity, config->sel, config->filter); + MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_IC3PRES_MSK, config->psc << TIMER_CHMR2_IC3PRES_POSS); + break; + + case TIMER_CHANNEL_4: + timer_ti4_set_config(hperh->perh, config->polarity, config->sel, config->filter); + MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_IC4PRES_MSK, config->psc << TIMER_CHMR2_IC4PRES_POSS); + break; + + default: + break; } hperh->state = TIMER_STATE_READY; @@ -2484,7 +2451,7 @@ ald_status_t timer_ic_config_channel(timer_handle_t *hperh, timer_ic_init_t *con * @arg TIMER_CHANNEL_2: TIMER Channel 2 selected * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_one_pulse_config_channel(timer_handle_t *hperh, timer_one_pulse_init_t *config, +ald_status_t ald_timer_one_pulse_config_channel(timer_handle_t *hperh, timer_one_pulse_init_t *config, timer_channel_t ch_out, timer_channel_t ch_in) { timer_oc_init_t tmp; @@ -2514,33 +2481,36 @@ ald_status_t timer_one_pulse_config_channel(timer_handle_t *hperh, timer_one_pul switch (ch_out) { - case TIMER_CHANNEL_1: - timer_oc1_set_config(hperh->perh, &tmp); - break; - case TIMER_CHANNEL_2: - timer_oc2_set_config(hperh->perh, &tmp); - break; - default: - break; + case TIMER_CHANNEL_1: + timer_oc1_set_config(hperh->perh, &tmp); + break; + + case TIMER_CHANNEL_2: + timer_oc2_set_config(hperh->perh, &tmp); + break; + + default: + break; } switch (ch_in) { - case TIMER_CHANNEL_1: - timer_ti1_set_config(hperh->perh, config->polarity, config->sel, config->filter); - CLEAR_BIT(hperh->perh->CHMR1, TIMER_CHMR1_IC1PRES_MSK); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI1FP1 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_TRIG << TIMER_SMCON_SMODS_POSS); - break; - - case TIMER_CHANNEL_2: - timer_ti2_set_config(hperh->perh, config->polarity, config->sel, config->filter); - CLEAR_BIT(hperh->perh->CHMR1, TIMER_CHMR1_IC2PRES_MSK); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI2FP2 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_TRIG << TIMER_SMCON_SMODS_POSS); - break; - default: - break; + case TIMER_CHANNEL_1: + timer_ti1_set_config(hperh->perh, config->polarity, config->sel, config->filter); + CLEAR_BIT(hperh->perh->CHMR1, TIMER_CHMR1_IC1PRES_MSK); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI1FP1 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_TRIG << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_CHANNEL_2: + timer_ti2_set_config(hperh->perh, config->polarity, config->sel, config->filter); + CLEAR_BIT(hperh->perh->CHMR1, TIMER_CHMR1_IC2PRES_MSK); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI2FP2 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_TRIG << TIMER_SMCON_SMODS_POSS); + break; + + default: + break; } hperh->state = TIMER_STATE_READY; @@ -2561,7 +2531,7 @@ ald_status_t timer_one_pulse_config_channel(timer_handle_t *hperh, timer_one_pul * @arg TIMER_CHANNEL_4: TIMER Channel 4 * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_config_oc_ref_clear(timer_handle_t *hperh, timer_clear_input_config_t *config, timer_channel_t ch) +ald_status_t ald_timer_config_oc_ref_clear(timer_handle_t *hperh, timer_clear_input_config_t *config, timer_channel_t ch) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); assert_param(IS_FUNC_STATE(config->state)); @@ -2582,26 +2552,26 @@ ald_status_t timer_config_oc_ref_clear(timer_handle_t *hperh, timer_clear_input_ switch (ch) { - case TIMER_CHANNEL_1: - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CH1OCLREN_MSK, config->state << TIMER_CHMR1_CH1OCLREN_POS); - break; - - case TIMER_CHANNEL_2: - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CH2OCLREN_MSK, config->state << TIMER_CHMR1_CH2OCLREN_POS); - break; - - case TIMER_CHANNEL_3: - assert_param(IS_TIMER_CC4_INSTANCE(hperh->perh)); - MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_CH3OCLREN_MSK, config->state << TIMER_CHMR2_CH3OCLREN_POS); - break; - - case TIMER_CHANNEL_4: - assert_param(IS_TIMER_CC4_INSTANCE(hperh->perh)); - MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_CH4OCLREN_MSK, config->state << TIMER_CHMR2_CH4OCLREN_POS); - break; - - default: - break; + case TIMER_CHANNEL_1: + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CH1OCLREN_MSK, config->state << TIMER_CHMR1_CH1OCLREN_POS); + break; + + case TIMER_CHANNEL_2: + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CH2OCLREN_MSK, config->state << TIMER_CHMR1_CH2OCLREN_POS); + break; + + case TIMER_CHANNEL_3: + assert_param(IS_TIMER_CC4_INSTANCE(hperh->perh)); + MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_CH3OCLREN_MSK, config->state << TIMER_CHMR2_CH3OCLREN_POS); + break; + + case TIMER_CHANNEL_4: + assert_param(IS_TIMER_CC4_INSTANCE(hperh->perh)); + MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_CH4OCLREN_MSK, config->state << TIMER_CHMR2_CH4OCLREN_POS); + break; + + default: + break; } return OK; @@ -2614,7 +2584,7 @@ ald_status_t timer_config_oc_ref_clear(timer_handle_t *hperh, timer_clear_input_ * contains the clock source information for the TIMER peripheral. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_config_clock_source(timer_handle_t *hperh, timer_clock_config_t *config) +ald_status_t ald_timer_config_clock_source(timer_handle_t *hperh, timer_clock_config_t *config) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_CLOCK_SOURCE(config->source)); @@ -2628,60 +2598,61 @@ ald_status_t timer_config_clock_source(timer_handle_t *hperh, timer_clock_config switch (config->source) { - case TIMER_SRC_INTER: - CLEAR_BIT(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK); - break; - - case TIMER_SRC_ETRMODE1: - timer_etr_set_config(hperh->perh, config->psc, config->polarity, config->filter); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ETRF << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); - break; - - case TIMER_SRC_ETRMODE2: - timer_etr_set_config(hperh->perh, config->psc, config->polarity, config->filter); - SET_BIT(hperh->perh->SMCON, TIMER_SMCON_ECM2EN_MSK); - break; - - case TIMER_SRC_TI1: - timer_ti1_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI1FP1 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); - break; - - case TIMER_SRC_TI2: - timer_ti2_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI2FP2 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); - break; - - case TIMER_SRC_TI1ED: - timer_ti1_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI1F_ED << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); - break; - - case TIMER_SRC_ITR0: - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ITR0 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); - break; - - case TIMER_SRC_ITR1: - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ITR1 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); - break; - - case TIMER_SRC_ITR2: - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ITR2 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); - break; - - case TIMER_SRC_ITR3: - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ITR3 << TIMER_SMCON_TSSEL_POSS); - MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); - break; - default: - break; + case TIMER_SRC_INTER: + CLEAR_BIT(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK); + break; + + case TIMER_SRC_ETRMODE1: + timer_etr_set_config(hperh->perh, config->psc, config->polarity, config->filter); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ETRF << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_SRC_ETRMODE2: + timer_etr_set_config(hperh->perh, config->psc, config->polarity, config->filter); + SET_BIT(hperh->perh->SMCON, TIMER_SMCON_ECM2EN_MSK); + break; + + case TIMER_SRC_TI1: + timer_ti1_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI1FP1 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_SRC_TI2: + timer_ti2_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI2FP2 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_SRC_TI1ED: + timer_ti1_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_TI1F_ED << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_SRC_ITR0: + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ITR0 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_SRC_ITR1: + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ITR1 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_SRC_ITR2: + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ITR2 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); + break; + + case TIMER_SRC_ITR3: + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_TSSEL_MSK, TIMER_TS_ITR3 << TIMER_SMCON_TSSEL_POSS); + MODIFY_REG(hperh->perh->SMCON, TIMER_SMCON_SMODS_MSK, TIMER_MODE_EXTERNAL1 << TIMER_SMCON_SMODS_POSS); + break; + + default: + break; } hperh->state = TIMER_STATE_READY; @@ -2701,7 +2672,7 @@ ald_status_t timer_config_clock_source(timer_handle_t *hperh, timer_clock_config * pins are connected to the TI1 input (XOR combination) * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_config_ti1_input(timer_handle_t *hperh, uint32_t ti1_select) +ald_status_t ald_timer_config_ti1_input(timer_handle_t *hperh, uint32_t ti1_select) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); @@ -2718,7 +2689,7 @@ ald_status_t timer_config_ti1_input(timer_handle_t *hperh, uint32_t ti1_select) * mode (Disable, Reset, Gated, Trigger, External clock mode 1). * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_slave_config_sync(timer_handle_t *hperh, timer_slave_config_t *config) +ald_status_t ald_timer_slave_config_sync(timer_handle_t *hperh, timer_slave_config_t *config) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_SLAVE_MODE(config->mode)); @@ -2731,8 +2702,8 @@ ald_status_t timer_slave_config_sync(timer_handle_t *hperh, timer_slave_config_t hperh->state = TIMER_STATE_BUSY; timer_slave_set_config(hperh, config); - timer_interrupt_config(hperh, TIMER_IT_TRIGGER, DISABLE); - timer_dma_req_config(hperh, TIMER_DMA_TRIGGER, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_TRIGGER, DISABLE); + ald_timer_dma_req_config(hperh, TIMER_DMA_TRIGGER, DISABLE); hperh->state = TIMER_STATE_READY; __UNLOCK(hperh); @@ -2748,7 +2719,7 @@ ald_status_t timer_slave_config_sync(timer_handle_t *hperh, timer_slave_config_t * mode (Disable, Reset, Gated, Trigger, External clock mode 1). * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_slave_config_sync_by_it(timer_handle_t *hperh, timer_slave_config_t *config) +ald_status_t ald_timer_slave_config_sync_by_it(timer_handle_t *hperh, timer_slave_config_t *config) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_SLAVE_MODE(config->mode)); @@ -2761,8 +2732,8 @@ ald_status_t timer_slave_config_sync_by_it(timer_handle_t *hperh, timer_slave_co hperh->state = TIMER_STATE_BUSY; timer_slave_set_config(hperh, config); - timer_interrupt_config(hperh, TIMER_IT_TRIGGER, ENABLE); - timer_dma_req_config(hperh, TIMER_DMA_TRIGGER, DISABLE); + ald_timer_interrupt_config(hperh, TIMER_IT_TRIGGER, ENABLE); + ald_timer_dma_req_config(hperh, TIMER_DMA_TRIGGER, DISABLE); hperh->state = TIMER_STATE_READY; __UNLOCK(hperh); @@ -2775,7 +2746,7 @@ ald_status_t timer_slave_config_sync_by_it(timer_handle_t *hperh, timer_slave_co * @param event: specifies the event source. * @retval Status, see @ref ald_status_t. */ -ald_status_t timer_generate_event(timer_handle_t *hperh, timer_event_source_t event) +ald_status_t ald_timer_generate_event(timer_handle_t *hperh, timer_event_source_t event) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_EVENT_SOURCE(event)); @@ -2800,7 +2771,7 @@ ald_status_t timer_generate_event(timer_handle_t *hperh, timer_event_source_t ev * @arg TIMER_CHANNEL_4 : TIMER Channel 4 selected * @retval Captured value */ -uint32_t timer_read_capture_value(timer_handle_t *hperh, timer_channel_t ch) +uint32_t ald_timer_read_capture_value(timer_handle_t *hperh, timer_channel_t ch) { uint32_t tmp; @@ -2809,20 +2780,24 @@ uint32_t timer_read_capture_value(timer_handle_t *hperh, timer_channel_t ch) switch (ch) { - case TIMER_CHANNEL_1: - tmp = hperh->perh->CCVAL1; - break; - case TIMER_CHANNEL_2: - tmp = hperh->perh->CCVAL2; - break; - case TIMER_CHANNEL_3: - tmp = hperh->perh->CCVAL3; - break; - case TIMER_CHANNEL_4: - tmp = hperh->perh->CCVAL4; - break; - default: - break; + case TIMER_CHANNEL_1: + tmp = hperh->perh->CCVAL1; + break; + + case TIMER_CHANNEL_2: + tmp = hperh->perh->CCVAL2; + break; + + case TIMER_CHANNEL_3: + tmp = hperh->perh->CCVAL3; + break; + + case TIMER_CHANNEL_4: + tmp = hperh->perh->CCVAL4; + break; + + default: + break; } hperh->state = TIMER_STATE_READY; @@ -2842,7 +2817,7 @@ uint32_t timer_read_capture_value(timer_handle_t *hperh, timer_channel_t ch) * @arg TIMER_CHANNEL_4 : TIMER Channel 4 selected * @retval None */ -void timer_set_output_mode(timer_handle_t *hperh, timer_oc_mode_t mode, timer_channel_t ch) +void ald_timer_set_output_mode(timer_handle_t *hperh, timer_oc_mode_t mode, timer_channel_t ch) { assert_param(IS_TIMER_CC2_INSTANCE(hperh->perh)); assert_param(IS_TIMER_OC_MODE(mode)); @@ -2850,20 +2825,24 @@ void timer_set_output_mode(timer_handle_t *hperh, timer_oc_mode_t mode, timer_ch switch (ch) { - case TIMER_CHANNEL_1: - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CH1OMOD_MSK, mode << TIMER_CHMR1_CH1OMOD_POSS); - break; - case TIMER_CHANNEL_2: - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CH2OMOD_MSK, mode << TIMER_CHMR1_CH2OMOD_POSS); - break; - case TIMER_CHANNEL_3: - MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_CH3OMOD_MSK, mode << TIMER_CHMR2_CH3OMOD_POSS); - break; - case TIMER_CHANNEL_4: - MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_CH4OMOD_MSK, mode << TIMER_CHMR2_CH4OMOD_POSS); - break; - default: - break; + case TIMER_CHANNEL_1: + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CH1OMOD_MSK, mode << TIMER_CHMR1_CH1OMOD_POSS); + break; + + case TIMER_CHANNEL_2: + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_CH2OMOD_MSK, mode << TIMER_CHMR1_CH2OMOD_POSS); + break; + + case TIMER_CHANNEL_3: + MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_CH3OMOD_MSK, mode << TIMER_CHMR2_CH3OMOD_POSS); + break; + + case TIMER_CHANNEL_4: + MODIFY_REG(hperh->perh->CHMR2, TIMER_CHMR2_CH4OMOD_MSK, mode << TIMER_CHMR2_CH4OMOD_POSS); + break; + + default: + break; } return; @@ -2875,7 +2854,7 @@ void timer_set_output_mode(timer_handle_t *hperh, timer_oc_mode_t mode, timer_ch * @param config: Parameters of the channel. * @retval None */ -void timer_com_change_config(timer_handle_t *hperh, timer_com_channel_config_t *config) +void ald_timer_com_change_config(timer_handle_t *hperh, timer_com_channel_config_t *config) { uint32_t cm1, cm2, cce; @@ -2932,7 +2911,7 @@ void timer_com_change_config(timer_handle_t *hperh, timer_com_channel_config_t * * @arg DISABLE: Commutation event source is set by software using the COMG bit * @retval None */ -void timer_com_event_config(timer_handle_t *hperh, timer_ts_t ts, type_func_t trgi) +void ald_timer_com_event_config(timer_handle_t *hperh, timer_ts_t ts, type_func_t trgi) { assert_param(IS_TIMER_COM_EVENT_INSTANCE(hperh->perh)); assert_param(IS_TIMER_TS(ts)); @@ -2961,10 +2940,10 @@ void timer_com_event_config(timer_handle_t *hperh, timer_ts_t ts, type_func_t tr * @arg DISABLE: Commutation event source is set by software using the COMG bit * @retval None */ -void timer_com_event_config_it(timer_handle_t *hperh, timer_ts_t ts, type_func_t trgi) +void ald_timer_com_event_config_it(timer_handle_t *hperh, timer_ts_t ts, type_func_t trgi) { - timer_com_event_config(hperh, ts, trgi); - timer_interrupt_config(hperh, TIMER_IT_COM, ENABLE); + ald_timer_com_event_config(hperh, ts, trgi); + ald_timer_interrupt_config(hperh, TIMER_IT_COM, ENABLE); } /** @@ -2973,7 +2952,7 @@ void timer_com_event_config_it(timer_handle_t *hperh, timer_ts_t ts, type_func_t * @param config: Pointer to the timer_break_dead_timere_t structure. * @retval None */ -void timer_break_dead_time_config(timer_handle_t *hperh, timer_break_dead_time_t *config) +void ald_timer_break_dead_time_config(timer_handle_t *hperh, timer_break_dead_time_t *config) { uint32_t tmp; @@ -3006,7 +2985,7 @@ void timer_break_dead_time_config(timer_handle_t *hperh, timer_break_dead_time_t * @param config: Pointer to the timer_master_config_t structure. * @retval None */ -void timer_master_sync_config(timer_handle_t *hperh, timer_master_config_t *config) +void ald_timer_master_sync_config(timer_handle_t *hperh, timer_master_config_t *config) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_MASTER_MODE_SEL(config->sel)); @@ -3025,14 +3004,14 @@ void timer_master_sync_config(timer_handle_t *hperh, timer_master_config_t *conf * @param hperh: TIMER handle * @retval None */ -void timer_irq_handle(timer_handle_t *hperh) +void ald_timer_irq_handler(timer_handle_t *hperh) { uint32_t reg = hperh->perh->IFM; /* Capture or compare 1 event */ if (READ_BIT(reg, TIMER_FLAG_CC1)) { - timer_clear_flag_status(hperh, TIMER_FLAG_CC1); + ald_timer_clear_flag_status(hperh, TIMER_FLAG_CC1); hperh->ch = TIMER_ACTIVE_CHANNEL_1; /* Input capture event */ @@ -3041,20 +3020,22 @@ void timer_irq_handle(timer_handle_t *hperh) if (hperh->capture_cbk) hperh->capture_cbk(hperh); } - else /* Output compare event */ + else /* Output compare event */ { if (hperh->delay_elapse_cbk) hperh->delay_elapse_cbk(hperh); + if (hperh->pwm_pulse_finish_cbk) hperh->pwm_pulse_finish_cbk(hperh); } hperh->ch = TIMER_ACTIVE_CHANNEL_CLEARED; } + /* Capture or compare 2 event */ if (READ_BIT(reg, TIMER_FLAG_CC2)) { - timer_clear_flag_status(hperh, TIMER_FLAG_CC2); + ald_timer_clear_flag_status(hperh, TIMER_FLAG_CC2); hperh->ch = TIMER_ACTIVE_CHANNEL_2; /* Input capture event */ @@ -3063,20 +3044,22 @@ void timer_irq_handle(timer_handle_t *hperh) if (hperh->capture_cbk) hperh->capture_cbk(hperh); } - else /* Output compare event */ + else /* Output compare event */ { if (hperh->delay_elapse_cbk) hperh->delay_elapse_cbk(hperh); + if (hperh->pwm_pulse_finish_cbk) hperh->pwm_pulse_finish_cbk(hperh); } hperh->ch = TIMER_ACTIVE_CHANNEL_CLEARED; } + /* Capture or compare 3 event */ if (READ_BIT(reg, TIMER_FLAG_CC3)) { - timer_clear_flag_status(hperh, TIMER_FLAG_CC3); + ald_timer_clear_flag_status(hperh, TIMER_FLAG_CC3); hperh->ch = TIMER_ACTIVE_CHANNEL_3; /* Input capture event */ @@ -3085,20 +3068,22 @@ void timer_irq_handle(timer_handle_t *hperh) if (hperh->capture_cbk) hperh->capture_cbk(hperh); } - else /* Output compare event */ + else /* Output compare event */ { if (hperh->delay_elapse_cbk) hperh->delay_elapse_cbk(hperh); + if (hperh->pwm_pulse_finish_cbk) hperh->pwm_pulse_finish_cbk(hperh); } hperh->ch = TIMER_ACTIVE_CHANNEL_CLEARED; } + /* Capture or compare 4 event */ if (READ_BIT(reg, TIMER_FLAG_CC4)) { - timer_clear_flag_status(hperh, TIMER_FLAG_CC4); + ald_timer_clear_flag_status(hperh, TIMER_FLAG_CC4); hperh->ch = TIMER_ACTIVE_CHANNEL_4; /* Input capture event */ @@ -3107,10 +3092,11 @@ void timer_irq_handle(timer_handle_t *hperh) if (hperh->capture_cbk) hperh->capture_cbk(hperh); } - else /* Output compare event */ + else /* Output compare event */ { if (hperh->delay_elapse_cbk) hperh->delay_elapse_cbk(hperh); + if (hperh->pwm_pulse_finish_cbk) hperh->pwm_pulse_finish_cbk(hperh); } @@ -3121,7 +3107,7 @@ void timer_irq_handle(timer_handle_t *hperh) /* TIMER Update event */ if (READ_BIT(reg, TIMER_FLAG_UPDATE)) { - timer_clear_flag_status(hperh, TIMER_FLAG_UPDATE); + ald_timer_clear_flag_status(hperh, TIMER_FLAG_UPDATE); if (hperh->period_elapse_cbk) hperh->period_elapse_cbk(hperh); @@ -3130,7 +3116,7 @@ void timer_irq_handle(timer_handle_t *hperh) /* TIMER Break input event */ if (READ_BIT(reg, TIMER_FLAG_BREAK)) { - timer_clear_flag_status(hperh, TIMER_FLAG_BREAK); + ald_timer_clear_flag_status(hperh, TIMER_FLAG_BREAK); if (hperh->break_cbk) hperh->break_cbk(hperh); @@ -3139,7 +3125,7 @@ void timer_irq_handle(timer_handle_t *hperh) /* TIMER Trigger detection event */ if (READ_BIT(reg, TIMER_FLAG_TRIGGER)) { - timer_clear_flag_status(hperh, TIMER_FLAG_TRIGGER); + ald_timer_clear_flag_status(hperh, TIMER_FLAG_TRIGGER); if (hperh->trigger_cbk) hperh->trigger_cbk(hperh); @@ -3148,7 +3134,7 @@ void timer_irq_handle(timer_handle_t *hperh) /* TIMER commutation event */ if (READ_BIT(reg, TIMER_FLAG_COM)) { - timer_clear_flag_status(hperh, TIMER_FLAG_COM); + ald_timer_clear_flag_status(hperh, TIMER_FLAG_COM); if (hperh->com_cbk) hperh->com_cbk(hperh); @@ -3164,7 +3150,7 @@ void timer_irq_handle(timer_handle_t *hperh) * @param state: New state of the specified DMA request. * @retval None */ -void timer_dma_req_config(timer_handle_t *hperh, timer_dma_req_t req, type_func_t state) +void ald_timer_dma_req_config(timer_handle_t *hperh, timer_dma_req_t req, type_func_t state) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_DMA_REQ(req)); @@ -3189,7 +3175,7 @@ void timer_dma_req_config(timer_handle_t *hperh, timer_dma_req_t req, type_func_ * @arg DISABLE * @retval None */ -void timer_interrupt_config(timer_handle_t *hperh, timer_it_t it, type_func_t state) +void ald_timer_interrupt_config(timer_handle_t *hperh, timer_it_t it, type_func_t state) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_IT(it)); @@ -3212,7 +3198,7 @@ void timer_interrupt_config(timer_handle_t *hperh, timer_it_t it, type_func_t st * - 0: RESET * - 1: SET */ -it_status_t timer_get_it_status(timer_handle_t *hperh, timer_it_t it) +it_status_t ald_timer_get_it_status(timer_handle_t *hperh, timer_it_t it) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_IT(it)); @@ -3232,7 +3218,7 @@ it_status_t timer_get_it_status(timer_handle_t *hperh, timer_it_t it) * - 0: RESET * - 1: SET */ -flag_status_t timer_get_flag_status(timer_handle_t *hperh, timer_flag_t flag) +flag_status_t ald_timer_get_flag_status(timer_handle_t *hperh, timer_flag_t flag) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_FLAG(flag)); @@ -3250,7 +3236,7 @@ flag_status_t timer_get_flag_status(timer_handle_t *hperh, timer_flag_t flag) * This parameter can be one of the @ref timer_flag_t. * @retval None */ -void timer_clear_flag_status(timer_handle_t *hperh, timer_flag_t flag) +void ald_timer_clear_flag_status(timer_handle_t *hperh, timer_flag_t flag) { assert_param(IS_TIMER_INSTANCE(hperh->perh)); assert_param(IS_TIMER_FLAG(flag)); @@ -3282,7 +3268,7 @@ void timer_clear_flag_status(timer_handle_t *hperh, timer_flag_t flag) * @param hperh: TIMER handle * @retval TIMER peripheral state */ -timer_state_t timer_get_state(timer_handle_t *hperh) +timer_state_t ald_timer_get_state(timer_handle_t *hperh) { return hperh->state; } @@ -3359,6 +3345,7 @@ void timer_dma_error(void *arg) timer_handle_t *hperh = (timer_handle_t *)arg; hperh->state = TIMER_STATE_READY; + if (hperh->error_cbk) hperh->error_cbk(hperh); @@ -3525,11 +3512,11 @@ static void timer_oc4_set_config(TIMER_TypeDef *TIMERx, timer_oc_init_t *oc_conf * @brief Enables or disables the TIMER Capture Compare Channel x. * @param TIMERx: Select the TIMER peripheral * @param ch: specifies the TIMER Channel - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 - * @arg TIMER_CHANNEL_2: TIMER Channel 2 - * @arg TIMER_CHANNEL_3: TIMER Channel 3 - * @arg TIMER_CHANNEL_4: TIMER Channel 4 + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 + * @arg TIMER_CHANNEL_2: TIMER Channel 2 + * @arg TIMER_CHANNEL_3: TIMER Channel 3 + * @arg TIMER_CHANNEL_4: TIMER Channel 4 * @param state: specifies the TIMER Channel CCxE bit new state. * @retval None */ @@ -3540,34 +3527,34 @@ static void timer_ccx_channel_cmd(TIMER_TypeDef *TIMERx, timer_channel_t ch, typ switch (ch) { - case TIMER_CHANNEL_1: - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1EN_MSK, state << TIMER_CCEP_CC1EN_POS); - break; + case TIMER_CHANNEL_1: + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1EN_MSK, state << TIMER_CCEP_CC1EN_POS); + break; - case TIMER_CHANNEL_2: - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2EN_MSK, state << TIMER_CCEP_CC2EN_POS); - break; + case TIMER_CHANNEL_2: + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2EN_MSK, state << TIMER_CCEP_CC2EN_POS); + break; - case TIMER_CHANNEL_3: - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC3EN_MSK, state << TIMER_CCEP_CC3EN_POS); - break; + case TIMER_CHANNEL_3: + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC3EN_MSK, state << TIMER_CCEP_CC3EN_POS); + break; - case TIMER_CHANNEL_4: - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC4EN_MSK, state << TIMER_CCEP_CC4EN_POS); - break; + case TIMER_CHANNEL_4: + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC4EN_MSK, state << TIMER_CCEP_CC4EN_POS); + break; - default: - break; + default: + break; } } /** * @brief Enables or disables the TIMER Capture Compare Channel xN. * @param TIMERx: Select the TIMER peripheral * @param ch: specifies the TIMER Channel - * This parameter can be one of the following values: - * @arg TIMER_CHANNEL_1: TIMER Channel 1 - * @arg TIMER_CHANNEL_2: TIMER Channel 2 - * @arg TIMER_CHANNEL_3: TIMER Channel 3 + * This parameter can be one of the following values: + * @arg TIMER_CHANNEL_1: TIMER Channel 1 + * @arg TIMER_CHANNEL_2: TIMER Channel 2 + * @arg TIMER_CHANNEL_3: TIMER Channel 3 * @param state: specifies the TIMER Channel CCxNE bit new state. * @retval None */ @@ -3575,20 +3562,20 @@ static void timer_ccxn_channel_cmd(TIMER_TypeDef *TIMERx, timer_channel_t ch, ty { switch (ch) { - case TIMER_CHANNEL_1: - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1NEN_MSK, state << TIMER_CCEP_CC1NEN_POS); - break; + case TIMER_CHANNEL_1: + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1NEN_MSK, state << TIMER_CCEP_CC1NEN_POS); + break; - case TIMER_CHANNEL_2: - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2NEN_MSK, state << TIMER_CCEP_CC2NEN_POS); - break; + case TIMER_CHANNEL_2: + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2NEN_MSK, state << TIMER_CCEP_CC2NEN_POS); + break; - case TIMER_CHANNEL_3: - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC3NEN_MSK, state << TIMER_CCEP_CC3NEN_POS); - break; + case TIMER_CHANNEL_3: + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC3NEN_MSK, state << TIMER_CCEP_CC3NEN_POS); + break; - default: - break; + default: + break; } } @@ -3608,8 +3595,7 @@ static void timer_ti1_set_config(TIMER_TypeDef *TIMERx, timer_ic_polarity_t pola CLEAR_BIT(TIMERx->CCEP, TIMER_CCEP_CC1EN_MSK); MODIFY_REG(TIMERx->CHMR1, TIMER_CHMR1_CC1SSEL_MSK, sel << TIMER_CHMR1_CC1SSEL_POSS); MODIFY_REG(TIMERx->CHMR1, TIMER_CHMR1_I1FLT_MSK, filter << TIMER_CHMR1_I1FLT_POSS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1POL_MSK, (polarity & 0x1) << TIMER_CCEP_CC1POL_POS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1NPOL_MSK, ((polarity >> 1) & 0x1) << TIMER_CCEP_CC1NPOL_POS); + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1POL_MSK, polarity << TIMER_CCEP_CC1POL_POS); return; } @@ -3625,8 +3611,8 @@ static void timer_ti1_set_config(TIMER_TypeDef *TIMERx, timer_ic_polarity_t pola static void timer_ti1_set_config_stage(TIMER_TypeDef *TIMERx, timer_ic_polarity_t polarity, uint32_t filter) { MODIFY_REG(TIMERx->CHMR1, TIMER_CHMR1_I1FLT_MSK, filter << TIMER_CHMR1_I1FLT_POSS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1POL_MSK, (polarity & 0x1) << TIMER_CCEP_CC1POL_POS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1NPOL_MSK, ((polarity >> 1) & 0x1) << TIMER_CCEP_CC1NPOL_POS); + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC1POL_MSK, polarity << TIMER_CCEP_CC1POL_POS); + return; } @@ -3646,8 +3632,8 @@ static void timer_ti2_set_config(TIMER_TypeDef *TIMERx, timer_ic_polarity_t pola CLEAR_BIT(TIMERx->CCEP, TIMER_CCEP_CC2EN_MSK); MODIFY_REG(TIMERx->CHMR1, TIMER_CHMR1_CC2SSEL_MSK, sel << TIMER_CHMR1_CC2SSEL_POSS); MODIFY_REG(TIMERx->CHMR1, TIMER_CHMR1_I2FLT_MSK, filter << TIMER_CHMR1_I2FLT_POSS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2POL_MSK, (polarity & 0x1) << TIMER_CCEP_CC2POL_POS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2NPOL_MSK, ((polarity >> 1) & 0x1) << TIMER_CCEP_CC2NPOL_POS); + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2POL_MSK, polarity << TIMER_CCEP_CC2POL_POS); + return; } @@ -3663,8 +3649,7 @@ static void timer_ti2_set_config(TIMER_TypeDef *TIMERx, timer_ic_polarity_t pola static void timer_ti2_set_config_stage(TIMER_TypeDef *TIMERx, timer_ic_polarity_t polarity, uint32_t filter) { MODIFY_REG(TIMERx->CHMR1, TIMER_CHMR1_I2FLT_MSK, filter << TIMER_CHMR1_I2FLT_POSS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2POL_MSK, (polarity & 0x1) << TIMER_CCEP_CC2POL_POS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2NPOL_MSK, ((polarity >> 1) & 0x1) << TIMER_CCEP_CC2NPOL_POS); + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC2POL_MSK, polarity << TIMER_CCEP_CC2POL_POS); return; } @@ -3683,8 +3668,7 @@ static void timer_ti3_set_config(TIMER_TypeDef *TIMERx, timer_ic_polarity_t pola CLEAR_BIT(TIMERx->CCEP, TIMER_CCEP_CC3EN_MSK); MODIFY_REG(TIMERx->CHMR2, TIMER_CHMR2_CC3SSEL_MSK, sel << TIMER_CHMR2_CC3SSEL_POSS); MODIFY_REG(TIMERx->CHMR2, TIMER_CHMR2_I3FLT_MSK, filter << TIMER_CHMR2_I3FLT_POSS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC3POL_MSK, (polarity & 0x1) << TIMER_CCEP_CC3POL_POS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC3NPOL_MSK, ((polarity >> 1) & 0x1) << TIMER_CCEP_CC3NPOL_POS); + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC3POL_MSK, polarity << TIMER_CCEP_CC3POL_POS); return; } @@ -3704,8 +3688,7 @@ static void timer_ti4_set_config(TIMER_TypeDef *TIMERx, timer_ic_polarity_t pola CLEAR_BIT(TIMERx->CCEP, TIMER_CCEP_CC4EN_MSK); MODIFY_REG(TIMERx->CHMR2, TIMER_CHMR2_CC4SSEL_MSK, sel << TIMER_CHMR2_CC4SSEL_POSS); MODIFY_REG(TIMERx->CHMR2, TIMER_CHMR2_I4FLT_MSK, filter << TIMER_CHMR2_I4FLT_POSS); - MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC4POL_MSK, (polarity & 0x1) << TIMER_CCEP_CC4POL_POS); - + MODIFY_REG(TIMERx->CCEP, TIMER_CCEP_CC4POL_MSK, polarity << TIMER_CCEP_CC4POL_POS); return; } @@ -3741,27 +3724,78 @@ static void timer_slave_set_config(timer_handle_t *hperh, timer_slave_config_t * switch (config->input) { - case TIMER_TS_ETRF: - timer_etr_set_config(hperh->perh, config->psc, config->polarity, config->filter); - break; + case TIMER_TS_ETRF: + timer_etr_set_config(hperh->perh, config->psc, config->polarity, config->filter); + break; - case TIMER_TS_TI1F_ED: - CLEAR_BIT(hperh->perh->CCEP, TIMER_CCEP_CC1EN_MSK); - MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_I1FLT_MSK, config->filter << TIMER_CHMR1_I1FLT_POSS); - break; + case TIMER_TS_TI1F_ED: + CLEAR_BIT(hperh->perh->CCEP, TIMER_CCEP_CC1EN_MSK); + MODIFY_REG(hperh->perh->CHMR1, TIMER_CHMR1_I1FLT_MSK, config->filter << TIMER_CHMR1_I1FLT_POSS); + break; - case TIMER_TS_TI1FP1: - timer_ti1_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); - break; + case TIMER_TS_TI1FP1: + timer_ti1_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); + break; - case TIMER_TS_TI2FP2: - timer_ti2_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); - break; + case TIMER_TS_TI2FP2: + timer_ti2_set_config_stage(hperh->perh, (timer_ic_polarity_t)config->polarity, config->filter); + break; - default: - break; + default: + break; } } + +#ifdef ALD_DMA + +/** + * @brief Timer DMA msel signal configuration + * @param hperh: pointer to a timer_handle_t structure that contains + * the configuration information for TIMER module. + * @param config: DMA configuration structure + * @retval None + */ +static void timer_dma_msel(TIMER_TypeDef *hperh, dma_config_t *config) +{ +#if defined (ES32F065x) + + if (hperh == AD16C4T0) + config->msel = DMA_MSEL_TIMER0; + + if (hperh == GP16C4T0) + config->msel = DMA_MSEL_TIMER6; + +#elif defined (ES32F033x) || defined (ES32F093x) + + if (hperh == GP16C4T0) + config->msel = DMA_MSEL_TIMER0; + + if (hperh == GP16C4T1) + config->msel = DMA_MSEL_TIMER6; + +#endif + + if (hperh == GP16C2T0) + config->msel = DMA_MSEL_TIMER2; + + if (hperh == GP16C2T1) + config->msel = DMA_MSEL_TIMER3; + + if (hperh == BS16T0) + config->msel = DMA_MSEL_TIMER1; + + if (hperh == BS16T1) + config->msel = DMA_MSEL_TIMER4; + + if (hperh == BS16T2) + config->msel = DMA_MSEL_TIMER5; + + if (hperh == BS16T3) + config->msel = DMA_MSEL_TIMER7; +} + +#endif + /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_trng.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_trng.c similarity index 43% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_trng.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_trng.c index 5a682f9195..85539e815a 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_trng.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_trng.c @@ -27,6 +27,14 @@ */ #ifdef ALD_TRNG +/** @addtogroup CRYPT_Private_Functions CRYPT Private Functions + * @{ + */ +void trng_reset(trng_handle_t *hperh); +/** + * @} + */ + /** @defgroup TRNG_Public_Functions TRNG Public Functions * @{ */ @@ -54,35 +62,46 @@ /** * @brief Initializes the TRNG according to the specified * parameters in the trng_init_t. - * @param init: Pointer to a trng_init_t structure that contains - * the configuration information. - * @retval None + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. + * @retval Status, see @ref ald_status_t. */ -void trng_init(trng_init_t *init) +ald_status_t ald_trng_init(trng_handle_t *hperh) { - assert_param(IS_TRNG_DATA_WIDTH(init->data_width)); - assert_param(IS_TRNG_SEED_TYPE(init->seed_type)); - assert_param(IS_TRNG_ADJC(init->adjc)); + uint32_t tmp = 0; - SET_BIT(TRNG->CR, TRNG_CR_TRNGSEL_MSK); - MODIFY_REG(TRNG->CR, TRNG_CR_DSEL_MSK, (init->data_width) << TRNG_CR_DSEL_POSS); - MODIFY_REG(TRNG->CR, TRNG_CR_SDSEL_MSK, (init->seed_type) << TRNG_CR_SDSEL_POSS); - MODIFY_REG(TRNG->CR, TRNG_CR_ADJC_MSK, (init->adjc) << TRNG_CR_ADJC_POSS); + if (hperh == NULL) + return ERROR; - if (init->adjc == 0) - { - MODIFY_REG(TRNG->CR, TRNG_CR_ADJC_MSK, (0) << TRNG_CR_ADJC_POSS); - } + assert_param(IS_TRNG_DATA_WIDTH(hperh->init.data_width)); + assert_param(IS_TRNG_SEED_TYPE(hperh->init.seed_type)); + assert_param(IS_TRNG_ADJC(hperh->init.adjc)); + + __LOCK(hperh); + trng_reset(hperh); + + if (hperh->state == TRNG_STATE_RESET) + __UNLOCK(hperh); + + tmp = TRNG->CR; + + if (hperh->init.adjc == 0) + tmp = (0 << TRNG_CR_ADJM_POS); else - { - MODIFY_REG(TRNG->CR, TRNG_CR_ADJC_MSK, (1) << TRNG_CR_ADJC_POSS); - } + tmp = (1 << TRNG_CR_ADJM_POS); - WRITE_REG(TRNG->SEED, init->seed); - MODIFY_REG(TRNG->CFGR, TRNG_CFGR_TSTART_MSK, (init->t_start) << TRNG_CFGR_TSTART_POSS); - MODIFY_REG(TRNG->CR, TRNG_CR_POSTEN_MSK, (init->posten) << TRNG_CR_POSTEN_MSK); + tmp |= ((1 << TRNG_CR_TRNGSEL_POS) | (hperh->init.data_width << TRNG_CR_DSEL_POSS) | + (hperh->init.seed_type << TRNG_CR_SDSEL_POSS) | (hperh->init.adjc << TRNG_CR_ADJC_POSS) | + (hperh->init.posten << TRNG_CR_POSTEN_MSK)); - return; + TRNG->CR = tmp; + + WRITE_REG(TRNG->SEED, hperh->init.seed); + MODIFY_REG(TRNG->CFGR, TRNG_CFGR_TSTART_MSK, (hperh->init.t_start) << TRNG_CFGR_TSTART_POSS); + + hperh->state = TRNG_STATE_READY; + __UNLOCK(hperh); + return OK; } /** * @} @@ -96,12 +115,12 @@ void trng_init(trng_init_t *init) ##### Peripheral Control functions ##### ============================================================================== [..] This section provides functions allowing to: - (+) trng_get_result() API can Get the result. - (+) trng_interrupt_config() API can be helpful to configure TRNG interrupt source. - (+) trng_get_it_status() API can get the status of interrupt source. - (+) trng_get_status() API can get the status of SR register. - (+) trng_get_flag_status() API can get the status of interrupt flag. - (+) trng_clear_flag_status() API can clear interrupt flag. + (+) ald_trng_get_result() API can Get the result. + (+) ald_trng_interrupt_config() API can be helpful to configure TRNG interrupt source. + (+) ald_trng_get_it_status() API can get the status of interrupt source. + (+) ald_trng_get_status() API can get the status of SR register. + (+) ald_trng_get_flag_status() API can get the status of interrupt flag. + (+) ald_trng_clear_flag_status() API can clear interrupt flag. @endverbatim * @{ @@ -109,15 +128,21 @@ void trng_init(trng_init_t *init) /** * @brief Get the result. + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. * @retval The resultl */ -uint32_t trng_get_result(void) +uint32_t ald_trng_get_result(trng_handle_t *hperh) { - return (uint32_t)TRNG->DR; + hperh->state = TRNG_STATE_READY; + hperh->data = hperh->perh->DR; + return (uint32_t)hperh->perh->DR; } /** * @brief Enable/disable the specified interrupts. + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. * @param it: Specifies the interrupt sources to be enabled or disabled. * This parameter can be one of the @ref trng_it_t. * @param state: New state of the specified interrupts. @@ -126,32 +151,34 @@ uint32_t trng_get_result(void) * @arg DISABLE * @retval None */ -void trng_interrupt_config(trng_it_t it, type_func_t state) +void ald_trng_interrupt_config(trng_handle_t *hperh, trng_it_t it, type_func_t state) { assert_param(IS_TRNG_IT(it)); assert_param(IS_FUNC_STATE(state)); if (state) - SET_BIT(TRNG->IER, it); + SET_BIT(hperh->perh->IER, it); else - CLEAR_BIT(TRNG->IER, it); + CLEAR_BIT(hperh->perh->IER, it); return; } /** * @brief Get the status of SR register. + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. * @param status: Specifies the TRNG status type. * This parameter can be one of the @ref trng_status_t. * @retval Status: * - 0: RESET * - 1: SET */ -flag_status_t trng_get_status(trng_status_t status) +flag_status_t ald_trng_get_status(trng_handle_t *hperh, trng_status_t status) { assert_param(IS_TRNG_STATUS(status)); - if (READ_BIT(TRNG->SR, status)) + if (READ_BIT(hperh->perh->SR, status)) return SET; return RESET; @@ -159,17 +186,19 @@ flag_status_t trng_get_status(trng_status_t status) /** * @brief Get the status of interrupt source. + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. * @param it: Specifies the interrupt source. * This parameter can be one of the @ref trng_it_t. * @retval Status: * - 0: RESET * - 1: SET */ -it_status_t trng_get_it_status(trng_it_t it) +it_status_t ald_trng_get_it_status(trng_handle_t *hperh, trng_it_t it) { assert_param(IS_TRNG_IT(it)); - if (READ_BIT(TRNG->IER, it)) + if (READ_BIT(hperh->perh->IER, it)) return SET; return RESET; @@ -177,17 +206,19 @@ it_status_t trng_get_it_status(trng_it_t it) /** * @brief Get the status of interrupt flag. + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. * @param flag: Specifies the interrupt flag. * This parameter can be one of the @ref trng_flag_t. * @retval Status: * - 0: RESET * - 1: SET */ -flag_status_t trng_get_flag_status(trng_flag_t flag) +flag_status_t ald_trng_get_flag_status(trng_handle_t *hperh, trng_flag_t flag) { assert_param(IS_TRNG_FLAG(flag)); - if (READ_BIT(TRNG->IFR, flag)) + if (READ_BIT(hperh->perh->IFR, flag)) return SET; return RESET; @@ -195,17 +226,78 @@ flag_status_t trng_get_flag_status(trng_flag_t flag) /** * @brief Clear the interrupt flag. + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. * @param flag: Specifies the interrupt flag. * This parameter can be one of the @ref trng_flag_t. * @retval None */ -void trng_clear_flag_status(trng_flag_t flag) +void ald_trng_clear_flag_status(trng_handle_t *hperh, trng_flag_t flag) { assert_param(IS_TRNG_FLAG(flag)); - WRITE_REG(TRNG->IFCR, flag); + WRITE_REG(hperh->perh->IFCR, flag); return; } + +/** + * @brief Reset the TRNG peripheral. + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. + * @retval None + */ +void trng_reset(trng_handle_t *hperh) +{ + TRNG->CR = 0; + TRNG->SEED = 0; + TRNG->CFGR = 0x1FF0707; + TRNG->IER = 0; + TRNG->IFCR = 0xFFFFFFFF; + + hperh->state = TRNG_STATE_READY; + __UNLOCK(hperh); + return; +} + +/** + * @brief This function handles TRNG interrupt request. + * @param hperh: Pointer to a trng_handle_t structure that contains + * the configuration information for the specified TRNG module. + * @retval None + */ +void ald_trng_irq_handler(trng_handle_t *hperh) +{ + if (ald_trng_get_flag_status(hperh, TRNG_IF_SERR) == SET) + { + hperh->state = TRNG_STATE_ERROR; + ald_trng_clear_flag_status(hperh, TRNG_IF_SERR); + + if (hperh->err_cplt_cbk) + hperh->err_cplt_cbk(hperh); + + return; + } + + if (ald_trng_get_flag_status(hperh, TRNG_IF_DAVLD) == SET) + { + hperh->data = hperh->perh->DR; + hperh->state = TRNG_STATE_READY; + ald_trng_clear_flag_status(hperh, TRNG_IF_DAVLD); + + if (hperh->trng_cplt_cbk) + hperh->trng_cplt_cbk(hperh); + } + + if (ald_trng_get_flag_status(hperh, TRNG_IF_START) == SET) + { + hperh->state = TRNG_STATE_BUSY; + ald_trng_clear_flag_status(hperh, TRNG_IF_START); + + if (hperh->init_cplt_cbk) + hperh->init_cplt_cbk(hperh); + } +} + /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_temp.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_tsense.c similarity index 40% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_temp.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_tsense.c index 4f311d1285..b31d5084cb 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_temp.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_tsense.c @@ -1,8 +1,8 @@ /** ********************************************************************************* * - * @file ald_temp.c - * @brief TEMP module driver. + * @file ald_tsense.c + * @brief TSENSE module driver. * * @version V1.0 * @date 15 Dec 2017 @@ -14,7 +14,7 @@ ********************************************************************************* */ -#include "ald_temp.h" +#include "ald_tsense.h" #include "ald_bkpc.h" @@ -22,82 +22,84 @@ * @{ */ -/** @defgroup TEMP TEMP - * @brief TEMP module driver +/** @defgroup TSENSE TSENSE + * @brief TSENSE module driver * @{ */ -#ifdef ALD_TEMP +#ifdef ALD_TSENSE -/** @defgroup TEMP_Private_Variables TEMP Private Variables +/** @defgroup TSENSE_Private_Variables TSENSE Private Variables * @{ */ -temp_cbk __temp_cbk; +tsense_cbk __tsense_cbk; /** * @} */ -/** @defgroup TEMP_Public_Functions TEMP Public Functions +/** @defgroup TSENSE_Public_Functions TSENSE Public Functions * @{ */ -/** @addtogroup TEMP_Public_Functions_Group1 Initialization functions +/** @addtogroup TSENSE_Public_Functions_Group1 Initialization functions * @brief Initialization functions * * @verbatim ============================================================================== ##### Initialization functions ##### ============================================================================== - [..] This section provides functions allowing to initialize the TEMP: + [..] This section provides functions allowing to initialize the TSENSE: (+) This parameters can be configured: (++) Update Cycle (++) Output Mode (++) Perscaler - (+) Select TEMP source clock(default LOSC) + (+) Select TSENSE source clock(default LOSC) @endverbatim * @{ */ /** - * @brief Initializes the TEMP according to the specified - * parameters in the temp_init_t. - * @param init: Pointer to a temp_init_t structure that contains + * @brief Initializes the TSENSE according to the specified + * parameters in the tsense_init_t. + * @param init: Pointer to a tsense_init_t structure that contains * the configuration information. * @retval None */ -void temp_init(temp_init_t *init) +void ald_tsense_init(tsense_init_t *init) { - assert_param(IS_TEMP_UPDATE_CYCLE(init->cycle)); - assert_param(IS_TEMP_OUTPUT_MODE(init->mode)); + assert_param(IS_TSENSE_UPDATE_CYCLE(init->cycle)); + assert_param(IS_TSENSE_OUTPUT_MODE(init->mode)); - TEMP_UNLOCK(); - MODIFY_REG(TEMP->CR, TEMP_CR_TSU_MSK, init->cycle << TEMP_CR_TSU_POSS); - MODIFY_REG(TEMP->CR, TEMP_CR_TOM_MSK, init->mode << TEMP_CR_TOM_POSS); - MODIFY_REG(TEMP->CR, TEMP_CR_CTN_MSK, init->ctn << TEMP_CR_CTN_POS); - MODIFY_REG(TEMP->PSR, TEMP_PSR_PRS_MSK, init->psc << TEMP_PSR_PRS_POSS); - TEMP_LOCK(); + TSENSE_UNLOCK(); + TSENSE->CR = 0; + + MODIFY_REG(TSENSE->CR, TSENSE_CR_TSU_MSK, init->cycle << TSENSE_CR_TSU_POSS); + MODIFY_REG(TSENSE->CR, TSENSE_CR_TOM_MSK, init->mode << TSENSE_CR_TOM_POSS); + MODIFY_REG(TSENSE->CR, TSENSE_CR_CTN_MSK, init->ctn << TSENSE_CR_CTN_POS); + MODIFY_REG(TSENSE->PSR, TSENSE_PSR_PRS_MSK, init->psc << TSENSE_PSR_PRS_POSS); + TSENSE_LOCK(); return; } /** - * @brief Configure the TEMP source. - * @param sel: TEMP source type. + * @brief Configure the TSENSE source. + * @param sel: TSENSE source type. * @retval None */ -void temp_source_selcet(temp_source_sel_t sel) +void ald_tsense_source_select(tsense_source_sel_t sel) { - assert_param(IS_TEMP_SOURCE_SEL(sel)); + assert_param(IS_TSENSE_SOURCE_SEL(sel)); BKPC_UNLOCK(); - MODIFY_REG(BKPC->PCCR, BKPC_PCCR_TEMPCS_MSK, sel << BKPC_PCCR_TEMPCS_POSS); + MODIFY_REG(BKPC->PCCR, BKPC_PCCR_TSENSECS_MSK, sel << BKPC_PCCR_TSENSECS_POSS); - if (sel == TEMP_SOURCE_LOSC) + if (sel == TSENSE_SOURCE_LOSC) { SET_BIT(BKPC->CR, BKPC_CR_LOSCEN_MSK); } - else if (sel == TEMP_SOURCE_LRC) + else if (sel == TSENSE_SOURCE_LRC) { SET_BIT(BKPC->CR, BKPC_CR_LRCEN_MSK); } @@ -113,7 +115,7 @@ void temp_source_selcet(temp_source_sel_t sel) * @} */ -/** @addtogroup TEMP_Public_Functions_Group2 Peripheral Control functions +/** @addtogroup TSENSE_Public_Functions_Group2 Peripheral Control functions * @brief Peripheral Control functions * * @verbatim @@ -121,9 +123,9 @@ void temp_source_selcet(temp_source_sel_t sel) ##### Peripheral Control functions ##### ============================================================================== [..] This section provides functions allowing to: - (+) temp_get_value() API can get the current temperature. - (+) temp_get_value_by_it() API can get the current temperature by interrupt. - (+) temp_irq_handle() API can handle the interrupt request. + (+) ald_tsense_get_value() API can get the current temperature. + (+) ald_tsense_get_value_by_it() API can get the current temperature by interrupt. + (+) ald_tsense_irq_handler() API can handle the interrupt request. @endverbatim * @{ @@ -131,28 +133,33 @@ void temp_source_selcet(temp_source_sel_t sel) /** * @brief Get the current temperature - * @param temp: The value of current temperature. + * @param tsense: The value of current temperature. * @retval ALD status: * @arg @ref OK The value is valid * @arg @ref ERROR The value is invalid */ -ald_status_t temp_get_value(uint16_t *temp) +ald_status_t ald_tsense_get_value(uint16_t *tsense) { - TEMP_UNLOCK(); - SET_BIT(TEMP->IFCR, TEMP_IFCR_TEMP_MSK); - SET_BIT(TEMP->CR, TEMP_CR_EN_MSK); - TEMP_LOCK(); + uint32_t tmp = 0; + + TSENSE_UNLOCK(); + SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK); + SET_BIT(TSENSE->CR, TSENSE_CR_EN_MSK); + TSENSE_LOCK(); + + while ((!(READ_BIT(TSENSE->IF, TSENSE_IF_TSENSE_MSK))) && (tmp++ < 1000000)); - while (!(READ_BIT(TEMP->IF, TEMP_IF_TEMP_MSK))); + if (tmp >= 1000000) + return TIMEOUT; - TEMP_UNLOCK(); - SET_BIT(TEMP->IFCR, TEMP_IFCR_TEMP_MSK); - TEMP_LOCK(); + TSENSE_UNLOCK(); + SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK); + TSENSE_LOCK(); - if (READ_BIT(TEMP->DR, TEMP_DR_ERR_MSK)) + if (READ_BIT(TSENSE->DR, TSENSE_DR_ERR_MSK)) return ERROR; - *temp = READ_BITS(TEMP->DR, TEMP_DR_DATA_MSK, TEMP_DR_DATA_POSS); + *tsense = READ_BITS(TSENSE->DR, TSENSE_DR_DATA_MSK, TSENSE_DR_DATA_POSS); return OK; } @@ -161,40 +168,43 @@ ald_status_t temp_get_value(uint16_t *temp) * @param cbk: The callback function * @retval None */ -void temp_get_value_by_it(temp_cbk cbk) +void ald_tsense_get_value_by_it(tsense_cbk cbk) { - __temp_cbk = cbk; + __tsense_cbk = cbk; - TEMP_UNLOCK(); - SET_BIT(TEMP->IFCR, TEMP_IFCR_TEMP_MSK); - SET_BIT(TEMP->IE, TEMP_IE_TEMP_MSK); - SET_BIT(TEMP->CR, TEMP_CR_EN_MSK); - TEMP_LOCK(); + TSENSE_UNLOCK(); + SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK); + SET_BIT(TSENSE->IE, TSENSE_IE_TSENSE_MSK); + SET_BIT(TSENSE->CR, TSENSE_CR_EN_MSK); + TSENSE_LOCK(); return; } /** - * @brief This function handles TEMP interrupt request. + * @brief This function handles TSENSE interrupt request. * @retval None */ -void temp_irq_handle(void) +void ald_tsense_irq_handler(void) { - TEMP_UNLOCK(); - SET_BIT(TEMP->IFCR, TEMP_IFCR_TEMP_MSK); - TEMP_LOCK(); + TSENSE_UNLOCK(); + SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK); + TSENSE_LOCK(); - if (__temp_cbk == NULL) + if (__tsense_cbk == NULL) return; - if (READ_BIT(TEMP->DR, TEMP_DR_ERR_MSK)) + if (READ_BIT(TSENSE->DR, TSENSE_DR_ERR_MSK)) { - __temp_cbk(0, ERROR); + __tsense_cbk(0, ERROR); return; } - __temp_cbk(READ_BITS(TEMP->DR, TEMP_DR_DATA_MSK, TEMP_DR_DATA_POSS), OK); + __tsense_cbk(READ_BITS(TSENSE->DR, TSENSE_DR_DATA_MSK, TSENSE_DR_DATA_POSS), OK); + TSENSE_UNLOCK(); + SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK); + TSENSE_LOCK(); return; } /** @@ -203,7 +213,7 @@ void temp_irq_handle(void) /** * @} */ -#endif /* ALD_TEMP */ +#endif /* ALD_TSENSE */ /** * @} */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_uart.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_uart.c similarity index 82% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_uart.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_uart.c index 32cdbe143f..ee0751ad8d 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_uart.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_uart.c @@ -32,19 +32,19 @@ (##) UART pins configuration: (+++) Enable the clock for the UART GPIOs. (+++) Configure the UART pins (TX as alternate function pull-up, RX as alternate function Input). - (##) NVIC configuration if you need to use interrupt process (uart_send_by_it() - and uart_recv_by_it() APIs): + (##) NVIC configuration if you need to use interrupt process (ald_uart_send_by_it() + and ald_uart_recv_by_it() APIs): (+++) Configure the uart interrupt priority. (+++) Enable the NVIC UART IRQ handle. - (##) DMA Configuration if you need to use DMA process (uart_send_by_dma() - and uart_recv_by_dma() APIs): + (##) DMA Configuration if you need to use DMA process (ald_uart_send_by_dma() + and ald_uart_recv_by_dma() APIs): (+++) Select the DMA Tx/Rx channel. (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware flow control and Mode(Receiver/Transmitter) in the hperh Init structure. - (#) Initialize the UART registers by calling the uart_init() API. + (#) Initialize the UART registers by calling the ald_uart_init() API. [..] Three operation modes are available within this driver: @@ -52,16 +52,16 @@ *** Polling mode IO operation *** ================================= [..] - (+) Send an amount of data in blocking mode using uart_send() - (+) Receive an amount of data in blocking mode using uart_recv() + (+) Send an amount of data in blocking mode using ald_uart_send() + (+) Receive an amount of data in blocking mode using ald_uart_recv() *** Interrupt mode IO operation *** =================================== [..] - (+) Send an amount of data in non blocking mode using uart_send_by_it() + (+) Send an amount of data in non blocking mode using ald_uart_send_by_it() (+) At transmission end of transfer hperh->tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->tx_cplt_cbk() - (+) Receive an amount of data in non blocking mode using uart_recv_by_it() + (+) Receive an amount of data in non blocking mode using ald_uart_recv_by_it() (+) At reception end of transfer hperh->rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->rx_cplt_cbk() (+) In case of transfer Error, hperh->error_cbk() function is executed and user can @@ -70,17 +70,17 @@ *** DMA mode IO operation *** ============================== [..] - (+) Send an amount of data in non blocking mode (DMA) using uart_send_by_dma() + (+) Send an amount of data in non blocking mode (DMA) using ald_uart_send_by_dma() (+) At transmission end of transfer hperh->tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->tx_cplt_cbk() - (+) Receive an amount of data in non blocking mode (DMA) using uart_recv_by_dma() + (+) Receive an amount of data in non blocking mode (DMA) using ald_uart_recv_by_dma() (+) At reception end of transfer hperh->rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->rx_cplt_cbk() (+) In case of transfer Error, hperh->error_cbk() function is executed and user can add his own code by customization of function pointer hperh->error_cbk() - (+) Pause the DMA Transfer using uart_dma_pause() - (+) Resume the DMA Transfer using uart_dma_resume() - (+) Stop the DMA Transfer using uart_dma_stop() + (+) Pause the DMA Transfer using ald_uart_dma_pause() + (+) Resume the DMA Transfer using ald_uart_dma_resume() + (+) Stop the DMA Transfer using ald_uart_dma_stop() @endverbatim ****************************************************************************** @@ -115,10 +115,10 @@ static void uart_dma_send_cplt(void *arg) uart_handle_t *hperh = (uart_handle_t *)arg; if (hperh->state == UART_STATE_BUSY_TX) - uart_dma_req_config(hperh, DISABLE); + ald_uart_dma_req_config(hperh, DISABLE); hperh->tx_count = 0; - uart_interrupt_config(hperh, UART_IT_TC, ENABLE); + ald_uart_interrupt_config(hperh, UART_IT_TC, ENABLE); return; } @@ -132,7 +132,7 @@ static void uart_dma_recv_cplt(void *arg) uart_handle_t *hperh = (uart_handle_t *)arg; if (hperh->state == UART_STATE_BUSY_RX) - uart_dma_req_config(hperh, DISABLE); + ald_uart_dma_req_config(hperh, DISABLE); hperh->rx_count = 0; CLEAR_BIT(hperh->state, UART_STATE_RX_MASK); @@ -156,7 +156,7 @@ static void uart_dma_error(void *arg) hperh->tx_count = 0; hperh->state = UART_STATE_READY; hperh->err_code |= UART_ERROR_DMA; - uart_dma_req_config(hperh, DISABLE); + ald_uart_dma_req_config(hperh, DISABLE); if (hperh->error_cbk) hperh->error_cbk(hperh); @@ -180,12 +180,12 @@ static ald_status_t uart_wait_flag(uart_handle_t *hperh, uart_status_t flag, fla if (timeout == 0) return ERROR; - tick = __get_tick(); + tick = ald_get_tick(); /* Waiting for flag */ - while ((uart_get_status(hperh, flag)) != status) + while ((ald_uart_get_status(hperh, flag)) != status) { - if (((__get_tick()) - tick) > timeout) + if (((ald_get_tick()) - tick) > timeout) return TIMEOUT; } @@ -206,9 +206,9 @@ static ald_status_t __uart_send_by_it(uart_handle_t *hperh) if (--hperh->tx_count == 0) { - uart_clear_flag_status(hperh, UART_IF_TC); - uart_interrupt_config(hperh, UART_IT_TXS, DISABLE); - uart_interrupt_config(hperh, UART_IT_TC, ENABLE); + ald_uart_clear_flag_status(hperh, UART_IF_TC); + ald_uart_interrupt_config(hperh, UART_IT_TXS, DISABLE); + ald_uart_interrupt_config(hperh, UART_IT_TC, ENABLE); } return OK; @@ -224,8 +224,9 @@ static ald_status_t __uart_end_send_by_it(uart_handle_t *hperh) if (!(READ_BIT(hperh->perh->SR, UART_SR_TEM_MSK))) return OK; - uart_interrupt_config(hperh, UART_IT_TC, DISABLE); + ald_uart_interrupt_config(hperh, UART_IT_TC, DISABLE); CLEAR_BIT(hperh->state, UART_STATE_TX_MASK); + if (hperh->tx_cplt_cbk) hperh->tx_cplt_cbk(hperh); @@ -246,7 +247,7 @@ static ald_status_t __uart_recv_by_it(uart_handle_t *hperh) if (--hperh->rx_count == 0) { - uart_interrupt_config(hperh, UART_IT_RXRD, DISABLE); + ald_uart_interrupt_config(hperh, UART_IT_RXRD, DISABLE); CLEAR_BIT(hperh->state, UART_STATE_RX_MASK); if (hperh->rx_cplt_cbk) @@ -280,11 +281,11 @@ static ald_status_t __uart_recv_by_it(uart_handle_t *hperh) (++) Parity (++) Hardware flow control (+) For RS485 mode, user also need configure some parameters by - uart_rs485_config(): + ald_uart_rs485_config(): (++) Enable/disable normal point mode - (++) Enable/disable auto-direction - (++) Enable/disable address detection invert - (++) Enable/disable address for compare + (++) Enable/disable auto-direction + (++) Enable/disable address detection invert + (++) Enable/disable address for compare @endverbatim * @{ @@ -296,7 +297,7 @@ static ald_status_t __uart_recv_by_it(uart_handle_t *hperh) * the configuration information for the specified uart module. * @retval None */ -void uart_reset(uart_handle_t *hperh) +void ald_uart_reset(uart_handle_t *hperh) { assert_param(IS_UART_ALL(hperh->perh)); @@ -322,7 +323,7 @@ void uart_reset(uart_handle_t *hperh) * the configuration information for the specified UART module. * @retval None */ -void uart_init(uart_handle_t *hperh) +void ald_uart_init(uart_handle_t *hperh) { uint32_t tmp; @@ -334,7 +335,7 @@ void uart_init(uart_handle_t *hperh) assert_param(IS_UART_MODE(hperh->init.mode)); assert_param(IS_UART_HARDWARE_FLOW_CONTROL(hperh->init.fctl)); - uart_reset(hperh); + ald_uart_reset(hperh); tmp = READ_REG(hperh->perh->LCR); MODIFY_REG(tmp, UART_LCR_DLS_MSK, hperh->init.word_length << UART_LCR_DLS_POSS); @@ -344,7 +345,7 @@ void uart_init(uart_handle_t *hperh) WRITE_REG(hperh->perh->LCR, tmp); MODIFY_REG(hperh->perh->MCR, UART_MCR_AFCEN_MSK, hperh->init.fctl << UART_MCR_AFCEN_POS); SET_BIT(hperh->perh->LCR, UART_LCR_BRWEN_MSK); - WRITE_REG(hperh->perh->BRR, cmu_get_pclk1_clock() / hperh->init.baud); + WRITE_REG(hperh->perh->BRR, ald_cmu_get_pclk1_clock() / hperh->init.baud); CLEAR_BIT(hperh->perh->LCR, UART_LCR_BRWEN_MSK); SET_BIT(hperh->perh->FCR, UART_FCR_FIFOEN_MSK); SET_BIT(hperh->perh->FCR, UART_FCR_RFRST_MSK); @@ -366,6 +367,7 @@ void uart_init(uart_handle_t *hperh) if (hperh->init.fctl) SET_BIT(hperh->perh->MCR, UART_MCR_RTSCTRL_MSK); + if (hperh->init.mode == UART_MODE_IrDA) SET_BIT(hperh->perh->LCR, UART_LCR_RXINV_MSK); @@ -382,7 +384,7 @@ void uart_init(uart_handle_t *hperh) * @param config: Specifies the RS485 parameters. * @retval None */ -void uart_rs485_config(uart_handle_t *hperh, uart_rs485_config_t *config) +void ald_uart_rs485_config(uart_handle_t *hperh, uart_rs485_config_t *config) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_FUNC_STATE(config->normal)); @@ -424,20 +426,20 @@ void uart_rs485_config(uart_handle_t *hperh, uart_rs485_config_t *config) a communication error is detected. (#) Blocking mode APIs are: - (++) uart_send() - (++) uart_recv() + (++) ald_uart_send() + (++) ald_uart_recv() (#) Non Blocking mode APIs with Interrupt are: - (++) uart_send_by_it() - (++) uart_recv_by_it() - (++) uart_irq_handle() + (++) ald_uart_send_by_it() + (++) ald_uart_recv_by_it() + (++) ald_uart_irq_handler() (#) Non Blocking mode functions with DMA are: - (++) uart_send_by_dma() - (++) uart_recv_by_dma() - (++) uart_dma_pause() - (++) uart_dma_resume() - (++) uart_dma_stop() + (++) ald_uart_send_by_dma() + (++) ald_uart_recv_by_dma() + (++) ald_uart_dma_pause() + (++) ald_uart_dma_resume() + (++) ald_uart_dma_stop() (#) A set of transfer complete callbacks are provided in non blocking mode: (++) hperh->tx_cplt_cbk() @@ -456,7 +458,7 @@ void uart_rs485_config(uart_handle_t *hperh, uart_rs485_config_t *config) * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_send(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_uart_send(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { assert_param(IS_UART_ALL(hperh->perh)); @@ -506,7 +508,7 @@ ald_status_t uart_send(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32 * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_recv(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_uart_recv(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { assert_param(IS_UART_ALL(hperh->perh)); @@ -549,7 +551,7 @@ ald_status_t uart_recv(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32 * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_send_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_uart_send_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) { assert_param(IS_UART_ALL(hperh->perh)); @@ -568,8 +570,8 @@ ald_status_t uart_send_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) SET_BIT(hperh->state, UART_STATE_TX_MASK); __UNLOCK(hperh); - if (((uart_get_status(hperh, UART_STATUS_TBEM)) == SET) - && ((uart_get_flag_status(hperh, UART_IF_TXS)) == RESET)) + if (((ald_uart_get_status(hperh, UART_STATUS_TBEM)) == SET) + && ((ald_uart_get_flag_status(hperh, UART_IF_TXS)) == RESET)) { WRITE_REG(hperh->perh->TBR, (*hperh->tx_buf++ & 0xFF)); --hperh->tx_count; @@ -577,11 +579,11 @@ ald_status_t uart_send_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) if (hperh->tx_count == 0) { - uart_interrupt_config(hperh, UART_IT_TC, ENABLE); + ald_uart_interrupt_config(hperh, UART_IT_TC, ENABLE); return OK; } - uart_interrupt_config(hperh, UART_IT_TXS, ENABLE); + ald_uart_interrupt_config(hperh, UART_IT_TXS, ENABLE); return OK; } @@ -592,7 +594,7 @@ ald_status_t uart_send_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) * @param size: Amount of data to be received * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_recv_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_uart_recv_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) { assert_param(IS_UART_ALL(hperh->perh)); @@ -610,7 +612,7 @@ ald_status_t uart_recv_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) SET_BIT(hperh->state, UART_STATE_RX_MASK); __UNLOCK(hperh); - uart_interrupt_config(hperh, UART_IT_RXRD, ENABLE); + ald_uart_interrupt_config(hperh, UART_IT_RXRD, ENABLE); return OK; } #ifdef ALD_DMA @@ -622,7 +624,7 @@ ald_status_t uart_recv_by_it(uart_handle_t *hperh, uint8_t *buf, uint16_t size) * @param channel: DMA channel as UART transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_send_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_uart_send_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { assert_param(IS_UART_ALL(hperh->perh)); @@ -648,7 +650,7 @@ ald_status_t uart_send_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, hperh->hdmatx.err_cbk = uart_dma_error; hperh->hdmatx.err_arg = (void *)hperh; - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->TBR; hperh->hdmatx.config.size = size; @@ -673,13 +675,13 @@ ald_status_t uart_send_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, else if (hperh->perh == UART3) hperh->hdmatx.config.msel = DMA_MSEL_UART3; else - ; /* do nothing */ + ; /* do nothing */ - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); __UNLOCK(hperh); - uart_clear_flag_status(hperh, UART_IF_TC); - uart_dma_req_config(hperh, ENABLE); + ald_uart_clear_flag_status(hperh, UART_IF_TC); + ald_uart_dma_req_config(hperh, ENABLE); return OK; } @@ -692,7 +694,7 @@ ald_status_t uart_send_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, * @param channel: DMA channel as UART receive * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_recv_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_uart_recv_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { assert_param(IS_UART_ALL(hperh->perh)); @@ -717,7 +719,7 @@ ald_status_t uart_recv_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, hperh->hdmarx.err_cbk = uart_dma_error; hperh->hdmarx.err_arg = (void *)hperh; - dma_config_struct(&hperh->hdmarx.config); + ald_dma_config_struct(&hperh->hdmarx.config); hperh->hdmarx.config.src = (void *)&hperh->perh->RBR; hperh->hdmarx.config.dst = (void *)buf; hperh->hdmarx.config.size = size; @@ -744,9 +746,9 @@ ald_status_t uart_recv_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, else ; - dma_config_basic(&hperh->hdmarx); + ald_dma_config_basic(&hperh->hdmarx); __UNLOCK(hperh); - uart_dma_req_config(hperh, ENABLE); + ald_uart_dma_req_config(hperh, ENABLE); return OK; } @@ -756,11 +758,11 @@ ald_status_t uart_recv_by_dma(uart_handle_t *hperh, uint8_t *buf, uint16_t size, * @param hperh: Pointer to a uart_handle_t structure. * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_dma_pause(uart_handle_t *hperh) +ald_status_t ald_uart_dma_pause(uart_handle_t *hperh) { assert_param(IS_UART_ALL(hperh->perh)); - uart_dma_req_config(hperh, DISABLE); + ald_uart_dma_req_config(hperh, DISABLE); return OK; } @@ -769,11 +771,11 @@ ald_status_t uart_dma_pause(uart_handle_t *hperh) * @param hperh: Pointer to a uart_handle_t structure. * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_dma_resume(uart_handle_t *hperh) +ald_status_t ald_uart_dma_resume(uart_handle_t *hperh) { assert_param(IS_UART_ALL(hperh->perh)); - uart_dma_req_config(hperh, ENABLE); + ald_uart_dma_req_config(hperh, ENABLE); return OK; } @@ -782,11 +784,11 @@ ald_status_t uart_dma_resume(uart_handle_t *hperh) * @param hperh: Pointer to a uart_handle_t structure. * @retval Status, see @ref ald_status_t. */ -ald_status_t uart_dma_stop(uart_handle_t *hperh) +ald_status_t ald_uart_dma_stop(uart_handle_t *hperh) { assert_param(IS_UART_ALL(hperh->perh)); - uart_dma_req_config(hperh, DISABLE); + ald_uart_dma_req_config(hperh, DISABLE); hperh->state = UART_STATE_READY; return OK; } @@ -797,40 +799,40 @@ ald_status_t uart_dma_stop(uart_handle_t *hperh) * @param hperh: Pointer to a uart_handle_t structure. * @retval None */ -void uart_irq_handle(uart_handle_t *hperh) +void ald_uart_irq_handler(uart_handle_t *hperh) { assert_param(IS_UART_ALL(hperh->perh)); /* Handle parity error */ - if ((uart_get_status(hperh, UART_STATUS_PE)) != RESET) + if ((ald_uart_get_status(hperh, UART_STATUS_PE)) != RESET) hperh->err_code |= UART_ERROR_PE; /* Handle frame error */ - if ((uart_get_status(hperh, UART_STATUS_FE)) != RESET) + if ((ald_uart_get_status(hperh, UART_STATUS_FE)) != RESET) hperh->err_code |= UART_ERROR_FE; /* Handle overflow error */ - if ((uart_get_status(hperh, UART_STATUS_OE)) != RESET) + if ((ald_uart_get_status(hperh, UART_STATUS_OE)) != RESET) hperh->err_code |= UART_ERROR_ORE; /* Receive */ - if ((uart_get_mask_flag_status(hperh, UART_IF_RXRD)) != RESET) + if ((ald_uart_get_mask_flag_status(hperh, UART_IF_RXRD)) != RESET) { - uart_clear_flag_status(hperh, UART_IF_RXRD); + ald_uart_clear_flag_status(hperh, UART_IF_RXRD); __uart_recv_by_it(hperh); } - /* Transmite */ - if ((uart_get_mask_flag_status(hperh, UART_IF_TXS)) != RESET) + /* Transmit */ + if ((ald_uart_get_mask_flag_status(hperh, UART_IF_TXS)) != RESET) { - uart_clear_flag_status(hperh, UART_IF_TXS); + ald_uart_clear_flag_status(hperh, UART_IF_TXS); __uart_send_by_it(hperh); } - /* End Transmite */ - if ((uart_get_mask_flag_status(hperh, UART_IF_TC)) != RESET) + /* End Transmit */ + if ((ald_uart_get_mask_flag_status(hperh, UART_IF_TC)) != RESET) { - uart_clear_flag_status(hperh, UART_IF_TC); + ald_uart_clear_flag_status(hperh, UART_IF_TC); __uart_end_send_by_it(hperh); } @@ -856,18 +858,18 @@ void uart_irq_handle(uart_handle_t *hperh) ============================================================================== [..] This subsection provides a set of functions allowing to control the UART: - (+) uart_interrupt_config() API can be helpful to configure UART interrupt source. - (+) uart_dma_req_config() API can be helpful to configure UART DMA request. - (+) uart_tx_fifo_config() API can be helpful to configure UART TX FIFO paramters. - (+) uart_rx_fifo_config() API can be helpful to configure UART RX FIFO paramters. - (+) uart_lin_send_break() API can send a frame of break in LIN mode. - (+) uart_lin_detect_break_len_config() API can be helpful to configure the length of break frame. - (+) uart_auto_baud_config() API can be helpful to configure detection data mode. - (+) uart_get_it_status() API can get the status of interrupt source. - (+) uart_get_status() API can get the status of UART_SR register. - (+) uart_get_flag_status() API can get the status of UART flag. - (+) uart_get_mask_flag_status() API can get status os flag and interrupt source. - (+) uart_clear_flag_status() API can clear UART flag. + (+) ald_uart_interrupt_config() API can be helpful to configure UART interrupt source. + (+) ald_uart_dma_req_config() API can be helpful to configure UART DMA request. + (+) ald_uart_tx_fifo_config() API can be helpful to configure UART TX FIFO paramters. + (+) ald_uart_rx_fifo_config() API can be helpful to configure UART RX FIFO paramters. + (+) ald_uart_lin_send_break() API can send a frame of break in LIN mode. + (+) ald_uart_lin_detect_break_len_config() API can be helpful to configure the length of break frame. + (+) ald_uart_auto_baud_config() API can be helpful to configure detection data mode. + (+) ald_uart_get_it_status() API can get the status of interrupt source. + (+) ald_uart_get_status() API can get the status of UART_SR register. + (+) ald_uart_get_flag_status() API can get the status of UART flag. + (+) ald_uart_get_mask_flag_status() API can get status os flag and interrupt source. + (+) ald_uart_clear_flag_status() API can clear UART flag. @endverbatim * @{ @@ -884,7 +886,7 @@ void uart_irq_handle(uart_handle_t *hperh) * @arg DISABLE * @retval None */ -void uart_interrupt_config(uart_handle_t *hperh, uart_it_t it, type_func_t state) +void ald_uart_interrupt_config(uart_handle_t *hperh, uart_it_t it, type_func_t state) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_IT(it)); @@ -907,7 +909,7 @@ void uart_interrupt_config(uart_handle_t *hperh, uart_it_t it, type_func_t state * @arg DISABLE * @retval None */ -void uart_dma_req_config(uart_handle_t *hperh, type_func_t state) +void ald_uart_dma_req_config(uart_handle_t *hperh, type_func_t state) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_FUNC_STATE(state)); @@ -927,7 +929,7 @@ void uart_dma_req_config(uart_handle_t *hperh, type_func_t state) * @param level: Transmit fifo level. * @retval None */ -void uart_tx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t level) +void ald_uart_tx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t level) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_TXFIFO_TYPE(config)); @@ -947,7 +949,7 @@ void uart_tx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t lev * @param level: Receive fifo level. * @retval None */ -void uart_rx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t level) +void ald_uart_rx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t level) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_RXFIFO_TYPE(config)); @@ -965,7 +967,7 @@ void uart_rx_fifo_config(uart_handle_t *hperh, uart_rxfifo_t config, uint8_t lev * @param hperh: Pointer to a uart_handle_t structure. * @retval None */ -void uart_lin_send_break(uart_handle_t *hperh) +void ald_uart_lin_send_break(uart_handle_t *hperh) { assert_param(IS_UART_ALL(hperh->perh)); @@ -981,7 +983,7 @@ void uart_lin_send_break(uart_handle_t *hperh) * @arg LIN_BREAK_LEN_11B * @retval None */ -void uart_lin_detect_break_len_config(uart_handle_t *hperh, uart_lin_break_len_t len) +void ald_uart_lin_detect_break_len_config(uart_handle_t *hperh, uart_lin_break_len_t len) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_LIN_BREAK_LEN(len)); @@ -999,7 +1001,7 @@ void uart_lin_detect_break_len_config(uart_handle_t *hperh, uart_lin_break_len_t * @arg UART_ABRMOD_0_TO_1 * @retval None */ -void uart_auto_baud_config(uart_handle_t *hperh, uart_auto_baud_mode_t mode) +void ald_uart_auto_baud_config(uart_handle_t *hperh, uart_auto_baud_mode_t mode) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_AUTO_BAUD_MODE(mode)); @@ -1016,7 +1018,7 @@ void uart_auto_baud_config(uart_handle_t *hperh, uart_auto_baud_mode_t mode) * @param timeout: Timeout duration * @retval The ALD status. */ -ald_status_t uart_rs485_send_addr(uart_handle_t *hperh, uint16_t addr, uint32_t timeout) +ald_status_t ald_uart_rs485_send_addr(uart_handle_t *hperh, uint16_t addr, uint32_t timeout) { assert_param(IS_UART_ALL(hperh->perh)); @@ -1053,7 +1055,7 @@ ald_status_t uart_rs485_send_addr(uart_handle_t *hperh, uint16_t addr, uint32_t * - 0: RESET * - 1: SET */ -it_status_t uart_get_it_status(uart_handle_t *hperh, uart_it_t it) +it_status_t ald_uart_get_it_status(uart_handle_t *hperh, uart_it_t it) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_IT(it)); @@ -1073,7 +1075,7 @@ it_status_t uart_get_it_status(uart_handle_t *hperh, uart_it_t it) * - 0: RESET * - 1: SET */ -flag_status_t uart_get_status(uart_handle_t *hperh, uart_status_t status) +flag_status_t ald_uart_get_status(uart_handle_t *hperh, uart_status_t status) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_STATUS(status)); @@ -1094,7 +1096,7 @@ flag_status_t uart_get_status(uart_handle_t *hperh, uart_status_t status) * - 0: RESET * - 1: SET */ -flag_status_t uart_get_flag_status(uart_handle_t *hperh, uart_flag_t flag) +flag_status_t ald_uart_get_flag_status(uart_handle_t *hperh, uart_flag_t flag) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_IF(flag)); @@ -1114,7 +1116,7 @@ flag_status_t uart_get_flag_status(uart_handle_t *hperh, uart_flag_t flag) * - 0: RESET * - 1: SET */ -flag_status_t uart_get_mask_flag_status(uart_handle_t *hperh, uart_flag_t flag) +flag_status_t ald_uart_get_mask_flag_status(uart_handle_t *hperh, uart_flag_t flag) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_IF(flag)); @@ -1132,7 +1134,7 @@ flag_status_t uart_get_mask_flag_status(uart_handle_t *hperh, uart_flag_t flag) * This parameter can be one of the @ref uart_flag_t. * @retval None */ -void uart_clear_flag_status(uart_handle_t *hperh, uart_flag_t flag) +void ald_uart_clear_flag_status(uart_handle_t *hperh, uart_flag_t flag) { assert_param(IS_UART_ALL(hperh->perh)); assert_param(IS_UART_IF(flag)); @@ -1155,8 +1157,8 @@ void uart_clear_flag_status(uart_handle_t *hperh, uart_flag_t flag) This subsection provides a set of functions allowing to return the State of UART communication process, return Peripheral Errors occurred during communication process - (+) uart_get_state() API can be helpful to check in run-time the state of the UART peripheral. - (+) uart_get_error() check in run-time errors that could be occurred during communication. + (+) ald_uart_get_state() API can be helpful to check in run-time the state of the UART peripheral. + (+) ald_uart_get_error() check in run-time errors that could be occurred during communication. @endverbatim * @{ @@ -1167,7 +1169,7 @@ void uart_clear_flag_status(uart_handle_t *hperh, uart_flag_t flag) * @param hperh: Pointer to a uart_handle_t structure. * @retval ALD state */ -uart_state_t uart_get_state(uart_handle_t *hperh) +uart_state_t ald_uart_get_state(uart_handle_t *hperh) { return hperh->state; } @@ -1177,7 +1179,7 @@ uart_state_t uart_get_state(uart_handle_t *hperh) * @param hperh: Pointer to a uart_handle_t structure. * @retval UART Error Code */ -uint32_t uart_get_error(uart_handle_t *hperh) +uint32_t ald_uart_get_error(uart_handle_t *hperh) { return hperh->err_code; } diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_usart.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_usart.c similarity index 85% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_usart.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_usart.c index 69641cb060..18672dd07e 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_usart.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_usart.c @@ -32,12 +32,12 @@ (##) USART pins configuration: (+++) Enable the clock for the USART GPIOs. (+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input). - (##) NVIC configuration if you need to use interrupt process (usart_send_by_it() - and usart_recv_by_it() APIs): + (##) NVIC configuration if you need to use interrupt process (ald_usart_send_by_it() + and ald_usart_recv_by_it() APIs): (+++) Configure the USARTx interrupt priority. (+++) Enable the NVIC USART IRQ handle. - (##) DMA Configuration if you need to use DMA process (usart_send_by_dma() - and usart_recv_by_dma() APIs): + (##) DMA Configuration if you need to use DMA process (ald_usart_send_by_dma() + and ald_usart_recv_by_dma() APIs): (+++) Declare a DMA handle structure for the Tx/Rx channel. (+++) Enable the DMAx interface clock. (+++) Configure the declared DMA handle structure with the required @@ -49,20 +49,20 @@ flow control and mode(Receiver/Transmitter) in the hperh Init structure. (#) For the USART asynchronous mode, initialize the USART registers by calling - the usart_init() API. + the ald_usart_init() API. (#) For the USART Half duplex mode, initialize the USART registers by calling - the usart_half_duplex_init() API. + the ald_usart_half_duplex_init() API. (#) For the LIN mode, initialize the USART registers by calling the usart_lin_init() API. (#) For the Multi-Processor mode, initialize the USART registers by calling - the usart_multi_processor_init() API. + the ald_usart_multi_processor_init() API. [..] (@) The specific USART interrupts (Transmission complete interrupt, RXNE interrupt and Error Interrupts) will be managed using the function - usart_interrupt_config inside the transmit and receive process. + ald_usart_interrupt_config inside the transmit and receive process. [..] Three operation modes are available within this driver : @@ -70,17 +70,17 @@ *** Polling mode IO operation *** ================================= [..] Asynchronous: - (+) Send an amount of data in blocking mode using usart_send() - (+) Receive an amount of data in blocking mode using usart_recv() + (+) Send an amount of data in blocking mode using ald_usart_send() + (+) Receive an amount of data in blocking mode using ald_usart_recv() [..] Synchronous: - (+) Send an amount of data in blocking mode using usart_send_sync() - (+) Receive an amount of data in blocking mode using usart_recv_sync() + (+) Send an amount of data in blocking mode using ald_usart_send_sync() + (+) Receive an amount of data in blocking mode using ald_usart_recv_sync() *** Interrupt mode IO operation *** =================================== [..] Asynchronous: - (+) Send an amount of data in non blocking mode using usart_send_by_it() + (+) Send an amount of data in non blocking mode using ald_usart_send_by_it() (+) At transmission end of transfer hperh->tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->tx_cplt_cbk() (+) Receive an amount of data in non blocking mode using USART_recv_by_it() @@ -89,7 +89,7 @@ (+) In case of transfer Error, hperh->error_cbk() function is executed and user can add his own code by customization of function pointer hperh->error_cbk() [..] Synchronous: - (+) Send an amount of data in non blocking mode using usart_send_by_it_sync() + (+) Send an amount of data in non blocking mode using ald_usart_send_by_it_sync() (+) At transmission end of transfer hperh->tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->tx_cplt_cbk() (+) Receive an amount of data in non blocking mode using USART_recv_by_it_sync() @@ -101,27 +101,27 @@ *** DMA mode IO operation *** ============================== [..] Asynchronous: - (+) Send an amount of data in non blocking mode (DMA) using usart_send_by_dma() + (+) Send an amount of data in non blocking mode (DMA) using ald_usart_send_by_dma() (+) At transmission end of transfer hperh->tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->tx_cplt_cbk() - (+) Receive an amount of data in non blocking mode (DMA) using usart_recv_by_dma() + (+) Receive an amount of data in non blocking mode (DMA) using ald_usart_recv_by_dma() (+) At reception end of transfer hperh->rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->rx_cplt_cbk() (+) In case of transfer Error, hperh->error_cbk()() function is executed and user can add his own code by customization of function pointer hperh->error_cbk() [..] Synchronous: - (+) Send an amount of data in non blocking mode (DMA) using usart_send_by_dma_sync() + (+) Send an amount of data in non blocking mode (DMA) using ald_usart_send_by_dma_sync() (+) At transmission end of transfer hperh->tx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->tx_cplt_cbk() - (+) Receive an amount of data in non blocking mode (DMA) using usart_recv_by_dma_sync() + (+) Receive an amount of data in non blocking mode (DMA) using ald_usart_recv_by_dma_sync() (+) At reception end of transfer hperh->rx_cplt_cbk() is executed and user can add his own code by customization of function pointer hperh->rx_cplt_cbk() (+) In case of transfer Error, hperh->error_cbk()() function is executed and user can add his own code by customization of function pointer hperh->error_cbk() [..] Utilities: - (+) Pause the DMA Transfer using usart_dma_pause() - (+) Resume the DMA Transfer using usart_dma_resume() - (+) Stop the DMA Transfer using usart_dma_stop() + (+) Pause the DMA Transfer using ald_usart_dma_pause() + (+) Resume the DMA Transfer using ald_usart_dma_resume() + (+) Stop the DMA Transfer using ald_usart_dma_stop() *** USART ALD driver macros list *** ============================================= @@ -212,8 +212,8 @@ static ald_status_t usart_wait_flag(usart_handle_t *hperh, usart_flag_t flag, fl (++) Hardware flow control (++) Receiver/transmitter modes [..] - The usart_init(), usart_half_duplex_init(), usart_lin_init(), usart_multi_processor_init() - and usart_clock_init() APIs follow respectively the USART asynchronous, USART Half duplex, + The ald_usart_init(), ald_usart_half_duplex_init(), usart_lin_init(), ald_usart_multi_processor_init() + and ald_usart_clock_init() APIs follow respectively the USART asynchronous, USART Half duplex, LIN, Multi-Processor and synchronous configuration procedures. @endverbatim @@ -245,7 +245,7 @@ static ald_status_t usart_wait_flag(usart_handle_t *hperh, usart_flag_t flag, fl * the configuration information for the specified USART module. * @retval None */ -void usart_reset(usart_handle_t *hperh) +void ald_usart_reset(usart_handle_t *hperh) { assert_param(IS_USART(hperh->perh)); @@ -270,14 +270,14 @@ void usart_reset(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_init(usart_handle_t *hperh) +ald_status_t ald_usart_init(usart_handle_t *hperh) { assert_param(IS_USART(hperh->perh)); assert_param(IS_USART_HARDWARE_FLOW_CONTROL(hperh->init.fctl)); assert_param(IS_USART_WORD_LENGTH(hperh->init.word_length)); assert_param(IS_FUNC_STATE(hperh->init.over_sampling)); - usart_reset(hperh); + ald_usart_reset(hperh); hperh->state = USART_STATE_BUSY; USART_DISABLE(hperh); usart_set_config(hperh); @@ -305,13 +305,13 @@ ald_status_t usart_init(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_half_duplex_init(usart_handle_t *hperh) +ald_status_t ald_usart_half_duplex_init(usart_handle_t *hperh) { assert_param(IS_USART(hperh->perh)); assert_param(IS_USART_WORD_LENGTH(hperh->init.word_length)); assert_param(IS_FUNC_STATE(hperh->init.over_sampling)); - usart_reset(hperh); + ald_usart_reset(hperh); hperh->state = USART_STATE_BUSY; USART_DISABLE(hperh); usart_set_config(hperh); @@ -343,7 +343,7 @@ ald_status_t usart_half_duplex_init(usart_handle_t *hperh) * @arg USART_WAKEUP_ADDR: Wakeup by an address mark * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_multi_processor_init(usart_handle_t *hperh, uint8_t addr, usart_wakeup_t wakeup) +ald_status_t ald_usart_multi_processor_init(usart_handle_t *hperh, uint8_t addr, usart_wakeup_t wakeup) { assert_param(IS_USART(hperh->perh)); assert_param(IS_USART_WAKEUP(wakeup)); @@ -351,7 +351,7 @@ ald_status_t usart_multi_processor_init(usart_handle_t *hperh, uint8_t addr, usa assert_param(IS_USART_WORD_LENGTH(hperh->init.word_length)); assert_param(IS_FUNC_STATE(hperh->init.over_sampling)); - usart_reset(hperh); + ald_usart_reset(hperh); hperh->state = USART_STATE_BUSY; USART_DISABLE(hperh); usart_set_config(hperh); @@ -381,13 +381,13 @@ ald_status_t usart_multi_processor_init(usart_handle_t *hperh, uint8_t addr, usa * @param init: USART Clock Init Structure. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_clock_init(usart_handle_t *hperh, usart_clock_init_t *init) +ald_status_t ald_usart_clock_init(usart_handle_t *hperh, usart_clock_init_t *init) { assert_param(IS_USART(hperh->perh)); assert_param(IS_USART_WORD_LENGTH(hperh->init.word_length)); assert_param(IS_FUNC_STATE(hperh->init.over_sampling)); - usart_reset(hperh); + ald_usart_reset(hperh); hperh->state = USART_STATE_BUSY; USART_DISABLE(hperh); usart_set_config(hperh); @@ -445,20 +445,20 @@ ald_status_t usart_clock_init(usart_handle_t *hperh, usart_clock_init_t *init) a communication error is detected. (#) Blocking mode APIs are: - (++) usart_send() - (++) usart_recv() + (++) ald_usart_send() + (++) ald_usart_recv() (#) Non Blocking mode APIs with Interrupt are: - (++) usart_send_by_it() - (++) usart_recv_by_it() + (++) ald_usart_send_by_it() + (++) ald_usart_recv_by_it() (++) urart_irq_handle() (#) Non Blocking mode functions with DMA are: - (++) usart_send_by_dma() - (++) usart_recv_by_dma() - (++) usart_dma_pause() - (++) usart_dma_resume() - (++) usart_dma_stop() + (++) ald_usart_send_by_dma() + (++) ald_usart_recv_by_dma() + (++) ald_usart_dma_pause() + (++) ald_usart_dma_resume() + (++) ald_usart_dma_stop() (#) A set of Transfer Complete Callbacks are provided in non blocking mode: (++) hperh->tx_cplt_cbk() @@ -483,7 +483,7 @@ ald_status_t usart_clock_init(usart_handle_t *hperh, usart_clock_init_t *init) * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_send(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_usart_send(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { if ((hperh->state != USART_STATE_READY) && (hperh->state != USART_STATE_BUSY_RX)) return BUSY; @@ -547,7 +547,7 @@ ald_status_t usart_send(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_recv(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_usart_recv(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { if ((hperh->state != USART_STATE_READY) && (hperh->state != USART_STATE_BUSY_TX)) return BUSY; @@ -607,7 +607,7 @@ ald_status_t usart_recv(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint * @param size: Amount of data to be sent * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_send_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_usart_send_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size) { if ((hperh->state != USART_STATE_READY) && (hperh->state != USART_STATE_BUSY_RX)) return BUSY; @@ -624,7 +624,7 @@ ald_status_t usart_send_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size hperh->err_code = USART_ERROR_NONE; __UNLOCK(hperh); - usart_interrupt_config(hperh, USART_IT_TXE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_TXE, ENABLE); return OK; } @@ -637,7 +637,7 @@ ald_status_t usart_send_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size * @param size: Amount of data to be received * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_recv_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_usart_recv_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size) { if ((hperh->state != USART_STATE_READY) && (hperh->state != USART_STATE_BUSY_TX)) return BUSY; @@ -654,9 +654,9 @@ ald_status_t usart_recv_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size hperh->err_code = USART_ERROR_NONE; __UNLOCK(hperh); - usart_interrupt_config(hperh, USART_IT_PE, ENABLE); - usart_interrupt_config(hperh, USART_IT_ERR, ENABLE); - usart_interrupt_config(hperh, USART_IT_RXNE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, ENABLE); return OK; } @@ -669,7 +669,7 @@ ald_status_t usart_recv_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size * @param size: Maximum amount of data to be received * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_recv_frame_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_usart_recv_frame_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_t size) { if ((hperh->state != USART_STATE_READY) && (hperh->state != USART_STATE_BUSY_TX)) return BUSY; @@ -686,9 +686,9 @@ ald_status_t usart_recv_frame_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_ hperh->err_code = USART_ERROR_NONE; __UNLOCK(hperh); - usart_interrupt_config(hperh, USART_IT_PE, ENABLE); - usart_interrupt_config(hperh, USART_IT_ERR, ENABLE); - usart_interrupt_config(hperh, USART_IT_RXNE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, ENABLE); __frame_mode = 1; return OK; @@ -704,7 +704,7 @@ ald_status_t usart_recv_frame_by_it(usart_handle_t *hperh, uint8_t *buf, uint16_ * @param channel: DMA channel as USART transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_send_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_usart_send_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { if ((hperh->state != USART_STATE_READY) && (hperh->state != USART_STATE_BUSY_RX)) return BUSY; @@ -730,7 +730,7 @@ ald_status_t usart_send_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t siz hperh->hdmatx.err_arg = (void *)hperh; /* Configure USART DMA transmit */ - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; hperh->hdmatx.config.size = size; @@ -747,10 +747,10 @@ ald_status_t usart_send_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t siz hperh->hdmatx.config.data_width = DMA_DATA_SIZE_HALFWORD; } - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); __UNLOCK(hperh); - usart_clear_flag_status(hperh, USART_FLAG_TC); + ald_usart_clear_flag_status(hperh, USART_FLAG_TC); SET_BIT(hperh->perh->CON2, USART_CON2_TXDMAEN_MSK); return OK; @@ -767,7 +767,7 @@ ald_status_t usart_send_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t siz * the parity bit (MSB position) * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { if ((hperh->state != USART_STATE_READY) && (hperh->state != USART_STATE_BUSY_TX)) return BUSY; @@ -792,7 +792,7 @@ ald_status_t usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t siz hperh->hdmarx.err_arg = (void *)hperh; /* Configure DMA Receive */ - dma_config_struct(&hperh->hdmarx.config); + ald_dma_config_struct(&hperh->hdmarx.config); hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)buf; hperh->hdmarx.config.size = size; @@ -809,7 +809,7 @@ ald_status_t usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t siz hperh->hdmarx.config.data_width = DMA_DATA_SIZE_HALFWORD; } - dma_config_basic(&hperh->hdmarx); + ald_dma_config_basic(&hperh->hdmarx); __UNLOCK(hperh); SET_BIT(hperh->perh->CON2, USART_CON2_RXDMAEN_MSK); @@ -847,27 +847,27 @@ ald_status_t usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t siz using DMA mode. The hperh->tx_cplt_cbk(), hperh->rx_cplt_cbk() and hperh->tx_rx_cplt_cbk() user callbacks will be executed respectively at the end of the transmit - or Receive process. The hperh->error_cbk() user callback will be - executed when a communication error is detected + or Receive process. The hperh->error_cbk() user callback will be + executed when a communication error is detected (#) Blocking mode APIs are : - (++) usart_send_sync() in simplex mode - (++) usart_recv_sync() in full duplex receive only - (++) usart_send_recv_sync() in full duplex mode + (++) ald_usart_send_sync() in simplex mode + (++) ald_usart_recv_sync() in full duplex receive only + (++) ald_usart_send_recv_sync() in full duplex mode (#) Non Blocking mode APIs with Interrupt are : - (++) usart_send_by_it_sync()in simplex mode - (++) usart_recv_by_it_sync() in full duplex receive only - (++) usart_send_recv_by_it_sync() in full duplex mode - (++) usart_irq_handle() + (++) ald_usart_send_by_it_sync()in simplex mode + (++) ald_usart_recv_by_it_sync() in full duplex receive only + (++) ald_usart_send_recv_by_it_sync() in full duplex mode + (++) ald_usart_irq_handler() (#) Non Blocking mode functions with DMA are : - (++) usart_send_by_dma_sync()in simplex mode - (++) usart_recv_by_dma_sync() in full duplex receive only + (++) ald_usart_send_by_dma_sync()in simplex mode + (++) ald_usart_recv_by_dma_sync() in full duplex receive only (++) usart_send_recv_by_dma_symc() in full duplex mode - (++) usart_dma_pause() - (++) usart_dma_resume() - (++) usart_dma_stop() + (++) ald_usart_dma_pause() + (++) ald_usart_dma_resume() + (++) ald_usart_dma_stop() (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: (++) hperh->tx_cplt_cbk() @@ -888,7 +888,7 @@ ald_status_t usart_recv_by_dma(usart_handle_t *hperh, uint8_t *buf, uint16_t siz * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_send_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_usart_send_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { if (hperh->state != USART_STATE_READY) return BUSY; @@ -945,7 +945,7 @@ ald_status_t usart_send_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_recv_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) +ald_status_t ald_usart_recv_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint32_t timeout) { if (hperh->state != USART_STATE_READY) return BUSY; @@ -1024,7 +1024,7 @@ ald_status_t usart_recv_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, * @param timeout: Timeout duration * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_send_recv_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout) +ald_status_t ald_usart_send_recv_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint32_t timeout) { if (hperh->state != USART_STATE_READY) return BUSY; @@ -1114,7 +1114,7 @@ ald_status_t usart_send_recv_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_ * @retval Status, see @ref ald_status_t. * @note The USART errors are not managed to avoid the overrun error. */ -ald_status_t usart_send_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_usart_send_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size) { if (hperh->state != USART_STATE_READY) return BUSY; @@ -1140,7 +1140,7 @@ ald_status_t usart_send_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t */ __UNLOCK(hperh); - usart_interrupt_config(hperh, USART_IT_TXE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_TXE, ENABLE); return OK; } @@ -1153,7 +1153,7 @@ ald_status_t usart_send_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t * @param size: Amount of data to be received * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_recv_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size) +ald_status_t ald_usart_recv_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size) { if (hperh->state != USART_STATE_READY) return BUSY; @@ -1170,9 +1170,9 @@ ald_status_t usart_recv_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t hperh->state = USART_STATE_BUSY_RX; __UNLOCK(hperh); - usart_interrupt_config(hperh, USART_IT_RXNE, ENABLE); - usart_interrupt_config(hperh, USART_IT_PE, ENABLE); - usart_interrupt_config(hperh, USART_IT_ERR, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, ENABLE); WRITE_REG(hperh->perh->DATA, (DUMMY_DATA & (uint16_t)0x01FF)); return OK; @@ -1187,7 +1187,7 @@ ald_status_t usart_recv_by_it_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t * @param size: Amount of data to be received * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_send_recv_by_it_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size) +ald_status_t ald_usart_send_recv_by_it_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size) { if (hperh->state != USART_STATE_READY) return BUSY; @@ -1207,10 +1207,10 @@ ald_status_t usart_send_recv_by_it_sync(usart_handle_t *hperh, uint8_t *tx_buf, hperh->state = USART_STATE_BUSY_TX_RX; __UNLOCK(hperh); - usart_interrupt_config(hperh, USART_IT_RXNE, ENABLE); - usart_interrupt_config(hperh, USART_IT_PE, ENABLE); - usart_interrupt_config(hperh, USART_IT_ERR, ENABLE); - usart_interrupt_config(hperh, USART_IT_TXE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_TXE, ENABLE); return OK; } @@ -1225,7 +1225,7 @@ ald_status_t usart_send_recv_by_it_sync(usart_handle_t *hperh, uint8_t *tx_buf, * @param channel: DMA channel as USART transmit * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_send_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) +ald_status_t ald_usart_send_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t channel) { if (hperh->state != USART_STATE_READY) return BUSY; @@ -1251,7 +1251,7 @@ ald_status_t usart_send_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_ hperh->hdmatx.err_arg = (void *)hperh; /* Configure DMA transmit */ - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; hperh->hdmatx.config.size = size; @@ -1268,10 +1268,10 @@ ald_status_t usart_send_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_ hperh->hdmatx.config.data_width = DMA_DATA_SIZE_HALFWORD; } - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); __UNLOCK(hperh); - usart_clear_flag_status(hperh, USART_FLAG_TC); + ald_usart_clear_flag_status(hperh, USART_FLAG_TC); SET_BIT(hperh->perh->CON2, USART_CON2_TXDMAEN_MSK); return OK; @@ -1289,7 +1289,7 @@ ald_status_t usart_send_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_ * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave. * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit. */ -ald_status_t usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel) +ald_status_t ald_usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel) { if (hperh->state != USART_STATE_READY) return BUSY; @@ -1308,6 +1308,7 @@ ald_status_t usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_ if (hperh->hdmatx.perh == NULL) hperh->hdmatx.perh = DMA0; + if (hperh->hdmarx.perh == NULL) hperh->hdmarx.perh = DMA0; @@ -1318,7 +1319,7 @@ ald_status_t usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_ hperh->hdmarx.err_arg = (void *)hperh; /* Configure DMA receive*/ - dma_config_struct(&hperh->hdmarx.config); + ald_dma_config_struct(&hperh->hdmarx.config); hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)buf; hperh->hdmarx.config.size = size; @@ -1335,13 +1336,13 @@ ald_status_t usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_ hperh->hdmarx.config.data_width = DMA_DATA_SIZE_HALFWORD; } - dma_config_basic(&hperh->hdmarx); + ald_dma_config_basic(&hperh->hdmarx); /* Enable the USART transmit DMA channel: the transmit channel is used in order * to generate in the non-blocking mode the clock to the slave device, * this mode isn't a simplex receive mode but a full-duplex receive one */ - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; hperh->hdmatx.config.size = size; @@ -1358,7 +1359,7 @@ ald_status_t usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_ hperh->hdmatx.config.data_width = DMA_DATA_SIZE_HALFWORD; } - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); USART_CLEAR_OREFLAG(hperh); __UNLOCK(hperh); @@ -1380,7 +1381,7 @@ ald_status_t usart_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *buf, uint16_ * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, +ald_status_t ald_usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, uint8_t *rx_buf, uint16_t size, uint8_t tx_channel, uint8_t rx_channel) { if (hperh->state != USART_STATE_READY) @@ -1400,6 +1401,7 @@ ald_status_t usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, if (hperh->hdmatx.perh == NULL) hperh->hdmatx.perh = DMA0; + if (hperh->hdmarx.perh == NULL) hperh->hdmarx.perh = DMA0; @@ -1414,7 +1416,7 @@ ald_status_t usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, hperh->hdmarx.err_arg = (void *)hperh; /* Configure DMA receive */ - dma_config_struct(&hperh->hdmarx.config); + ald_dma_config_struct(&hperh->hdmarx.config); hperh->hdmarx.config.src = (void *)&hperh->perh->DATA; hperh->hdmarx.config.dst = (void *)rx_buf; hperh->hdmarx.config.size = size; @@ -1431,10 +1433,10 @@ ald_status_t usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, hperh->hdmarx.config.data_width = DMA_DATA_SIZE_HALFWORD; } - dma_config_basic(&hperh->hdmarx); + ald_dma_config_basic(&hperh->hdmarx); /* Configure DMA transmit*/ - dma_config_struct(&hperh->hdmatx.config); + ald_dma_config_struct(&hperh->hdmatx.config); hperh->hdmatx.config.src = (void *)tx_buf; hperh->hdmatx.config.dst = (void *)&hperh->perh->DATA; hperh->hdmatx.config.size = size; @@ -1451,9 +1453,9 @@ ald_status_t usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, hperh->hdmatx.config.data_width = DMA_DATA_SIZE_HALFWORD; } - dma_config_basic(&hperh->hdmatx); + ald_dma_config_basic(&hperh->hdmatx); - usart_clear_flag_status(hperh, USART_FLAG_TC); + ald_usart_clear_flag_status(hperh, USART_FLAG_TC); USART_CLEAR_OREFLAG(hperh); __UNLOCK(hperh); SET_BIT(hperh->perh->CON2, USART_CON2_RXDMAEN_MSK); @@ -1477,7 +1479,7 @@ ald_status_t usart_send_recv_by_dma_sync(usart_handle_t *hperh, uint8_t *tx_buf, * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_dma_pause(usart_handle_t *hperh) +ald_status_t ald_usart_dma_pause(usart_handle_t *hperh) { __LOCK(hperh); @@ -1510,7 +1512,7 @@ ald_status_t usart_dma_pause(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_dma_resume(usart_handle_t *hperh) +ald_status_t ald_usart_dma_resume(usart_handle_t *hperh) { __LOCK(hperh); @@ -1545,7 +1547,7 @@ ald_status_t usart_dma_resume(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_dma_stop(usart_handle_t *hperh) +ald_status_t ald_usart_dma_stop(usart_handle_t *hperh) { CLEAR_BIT(hperh->perh->CON2, USART_CON2_TXDMAEN_MSK); CLEAR_BIT(hperh->perh->CON2, USART_CON2_RXDMAEN_MSK); @@ -1560,36 +1562,41 @@ ald_status_t usart_dma_stop(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval None */ -void usart_irq_handle(usart_handle_t *hperh) +void ald_usart_irq_handler(usart_handle_t *hperh) { uint32_t flag; uint32_t source; /* Handle parity error */ - flag = usart_get_flag_status(hperh, USART_FLAG_PE); - source = usart_get_it_status(hperh, USART_IT_PE); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_PE); + source = ald_usart_get_it_status(hperh, USART_IT_PE); + if ((flag != RESET) && (source != RESET)) hperh->err_code |= USART_ERROR_PE; /* Handle frame error */ - flag = usart_get_flag_status(hperh, USART_FLAG_FE); - source = usart_get_it_status(hperh, USART_IT_ERR); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_FE); + source = ald_usart_get_it_status(hperh, USART_IT_ERR); + if ((flag != RESET) && (source != RESET)) hperh->err_code |= USART_ERROR_FE; /* Handle noise error */ - flag = usart_get_flag_status(hperh, USART_FLAG_NE); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_NE); + if ((flag != RESET) && (source != RESET)) hperh->err_code |= USART_ERROR_NE; /* Handle overrun error */ - flag = usart_get_flag_status(hperh, USART_FLAG_ORE); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_ORE); + if ((flag != RESET) && (source != RESET)) hperh->err_code |= USART_ERROR_ORE; /* Handle idle error */ - flag = usart_get_flag_status(hperh, USART_FLAG_IDLE); - source = usart_get_it_status(hperh, USART_IT_IDLE); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_IDLE); + source = ald_usart_get_it_status(hperh, USART_IT_IDLE); + if ((flag != RESET) && (source != RESET)) __usart_recv_frame_cplt(hperh); @@ -1597,22 +1604,25 @@ void usart_irq_handle(usart_handle_t *hperh) if (READ_BIT(hperh->perh->CON1, USART_CON1_SCKEN_MSK) == 0) { /* Receiver */ - flag = usart_get_flag_status(hperh, USART_FLAG_RXNE); - source = usart_get_it_status(hperh, USART_IT_RXNE); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_RXNE); + source = ald_usart_get_it_status(hperh, USART_IT_RXNE); + if ((flag != RESET) && (source != RESET)) __usart_recv_by_it(hperh); /* Transmitter */ - flag = usart_get_flag_status(hperh, USART_FLAG_TXE); - source = usart_get_it_status(hperh, USART_IT_TXE); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_TXE); + source = ald_usart_get_it_status(hperh, USART_IT_TXE); + if ((flag != RESET) && (source != RESET)) __usart_send_by_it(hperh); } - else /* Handle synchronous */ + else /* Handle synchronous */ { /* Receiver */ - flag = usart_get_flag_status(hperh, USART_FLAG_RXNE); - source = usart_get_it_status(hperh, USART_IT_RXNE); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_RXNE); + source = ald_usart_get_it_status(hperh, USART_IT_RXNE); + if ((flag != RESET) && (source != RESET)) { if (hperh->state == USART_STATE_BUSY_RX) @@ -1622,8 +1632,9 @@ void usart_irq_handle(usart_handle_t *hperh) } /* Transmitter */ - flag = usart_get_flag_status(hperh, USART_FLAG_TXE); - source = usart_get_it_status(hperh, USART_IT_TXE); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_TXE); + source = ald_usart_get_it_status(hperh, USART_IT_TXE); + if ((flag != RESET) && (source != RESET)) { if (hperh->state == USART_STATE_BUSY_TX) @@ -1634,8 +1645,9 @@ void usart_irq_handle(usart_handle_t *hperh) } /* Handle transmitter end */ - flag = usart_get_flag_status(hperh, USART_FLAG_TC); - source = usart_get_it_status(hperh, USART_IT_TC); + flag = ald_usart_get_flag_status(hperh, USART_FLAG_TC); + source = ald_usart_get_it_status(hperh, USART_IT_TC); + if ((flag != RESET) && (source != RESET)) __usart_end_send_by_it(hperh); @@ -1668,14 +1680,14 @@ void usart_irq_handle(usart_handle_t *hperh) [..] This subsection provides a set of functions allowing to control the USART: (+) usart_lin_send_break() API can be helpful to transmit the break character. - (+) usart_multi_processor_enter_mute_mode() API can be helpful to enter the USART in mute mode. - (+) usart_multi_processor_exit_mute_mode() API can be helpful to exit the USART mute mode by software. - (+) usart_half_duplex_enable_send() API to enable the USART transmitter and disables the USART receiver in Half Duplex mode - (+) usart_half_duplex_enable_recv() API to enable the USART receiver and disables the USART transmitter in Half Duplex mode - (+) usart_interrupt_config() API to Enables/Disables the specified USART interrupts - (+) usart_get_flag_status() API to get USART flag status - (+) usart_clear_flag_status() API to clear USART flag status - (+) usart_get_it_status() API to Checks whether the specified USART interrupt has occurred or not + (+) ald_usart_multi_processor_enter_mute_mode() API can be helpful to enter the USART in mute mode. + (+) ald_usart_multi_processor_exit_mute_mode() API can be helpful to exit the USART mute mode by software. + (+) ald_usart_half_duplex_enable_send() API to enable the USART transmitter and disables the USART receiver in Half Duplex mode + (+) ald_usart_half_duplex_enable_recv() API to enable the USART receiver and disables the USART transmitter in Half Duplex mode + (+) ald_usart_interrupt_config() API to Enables/Disables the specified USART interrupts + (+) ald_usart_get_flag_status() API to get USART flag status + (+) ald_usart_clear_flag_status() API to clear USART flag status + (+) ald_usart_get_it_status() API to Checks whether the specified USART interrupt has occurred or not @endverbatim * @{ @@ -1687,7 +1699,7 @@ void usart_irq_handle(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_multi_processor_enter_mute_mode(usart_handle_t *hperh) +ald_status_t ald_usart_multi_processor_enter_mute_mode(usart_handle_t *hperh) { assert_param(IS_USART(hperh->perh)); @@ -1707,7 +1719,7 @@ ald_status_t usart_multi_processor_enter_mute_mode(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_multi_processor_exit_mute_mode(usart_handle_t *hperh) +ald_status_t ald_usart_multi_processor_exit_mute_mode(usart_handle_t *hperh) { assert_param(IS_USART(hperh->perh)); @@ -1727,7 +1739,7 @@ ald_status_t usart_multi_processor_exit_mute_mode(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_half_duplex_enable_send(usart_handle_t *hperh) +ald_status_t ald_usart_half_duplex_enable_send(usart_handle_t *hperh) { __LOCK(hperh); @@ -1746,7 +1758,7 @@ ald_status_t usart_half_duplex_enable_send(usart_handle_t *hperh) * the configuration information for the specified USART module. * @retval Status, see @ref ald_status_t. */ -ald_status_t usart_half_duplex_enable_recv(usart_handle_t *hperh) +ald_status_t ald_usart_half_duplex_enable_recv(usart_handle_t *hperh) { __LOCK(hperh); @@ -1764,14 +1776,14 @@ ald_status_t usart_half_duplex_enable_recv(usart_handle_t *hperh) * @param hperh: Pointer to a usart_handle_t structure that contains * the configuration information for the specified USART module. * @param req: specifies the DMA request. - * @arg USART_dma_req_tx: USART DMA transmit request - * @arg USART_dma_req_rx: USART DMA receive request + * @arg USART_dma_req_tx: USART DMA transmit request + * @arg USART_dma_req_rx: USART DMA receive request * @param state: New state of the DMA Request sources. - * @arg ENABLE + * @arg ENABLE * @arg DISABLE * @return: None */ -void usart_dma_req_config(usart_handle_t *hperh, usart_dma_req_t req, type_func_t state) +void ald_usart_dma_req_config(usart_handle_t *hperh, usart_dma_req_t req, type_func_t state) { assert_param(IS_USART(hperh->perh)); assert_param(IS_USART_DMAREQ(req)); @@ -1804,7 +1816,7 @@ void usart_dma_req_config(usart_handle_t *hperh, usart_dma_req_t req, type_func_ * - DISABLE * @retval None */ -void usart_interrupt_config(usart_handle_t *hperh, usart_it_t it, type_func_t state) +void ald_usart_interrupt_config(usart_handle_t *hperh, usart_it_t it, type_func_t state) { uint8_t idx; @@ -1850,7 +1862,7 @@ void usart_interrupt_config(usart_handle_t *hperh, usart_it_t it, type_func_t st * - SET * - RESET */ -flag_status_t usart_get_flag_status(usart_handle_t *hperh, usart_flag_t flag) +flag_status_t ald_usart_get_flag_status(usart_handle_t *hperh, usart_flag_t flag) { flag_status_t status = RESET; @@ -1880,7 +1892,7 @@ flag_status_t usart_get_flag_status(usart_handle_t *hperh, usart_flag_t flag) * @note TXE flag is cleared only by a write to the USART_DR register. * @retval None */ -void usart_clear_flag_status(usart_handle_t *hperh, usart_flag_t flag) +void ald_usart_clear_flag_status(usart_handle_t *hperh, usart_flag_t flag) { assert_param(IS_USART(hperh->perh)); assert_param(IS_USART_CLEAR_FLAG(flag)); @@ -1893,22 +1905,22 @@ void usart_clear_flag_status(usart_handle_t *hperh, usart_flag_t flag) * @param hperh: Pointer to a usart_handle_t structure that contains * the configuration information for the specified USART module. * @param it: Specifies the USART interrupt source to check. - * This parameter can be one of the following values: - * @arg USART_IT_CTS: CTS change interrupt - * @arg USART_IT_LBD: LIN Break detection interrupt - * @arg USART_IT_TXE: Tansmit Data Register empty interrupt - * @arg USART_IT_TC: Transmission complete interrupt - * @arg USART_IT_RXNE: Receive Data register not empty interrupt - * @arg USART_IT_IDLE: Idle line detection interrupt - * @arg USART_IT_ORE: OverRun Error interrupt - * @arg USART_IT_NE: Noise Error interrupt - * @arg USART_IT_FE: Framing Error interrupt - * @arg USART_IT_PE: Parity Error interrupt + * This parameter can be one of the following values: + * @arg USART_IT_CTS: CTS change interrupt + * @arg USART_IT_LBD: LIN Break detection interrupt + * @arg USART_IT_TXE: Tansmit Data Register empty interrupt + * @arg USART_IT_TC: Transmission complete interrupt + * @arg USART_IT_RXNE: Receive Data register not empty interrupt + * @arg USART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_ORE: OverRun Error interrupt + * @arg USART_IT_NE: Noise Error interrupt + * @arg USART_IT_FE: Framing Error interrupt + * @arg USART_IT_PE: Parity Error interrupt * @retval Status * - SET * - RESET */ -it_status_t usart_get_it_status(usart_handle_t *hperh, usart_it_t it) +it_status_t ald_usart_get_it_status(usart_handle_t *hperh, usart_it_t it) { uint8_t idx; it_status_t status = RESET; @@ -1963,8 +1975,8 @@ it_status_t usart_get_it_status(usart_handle_t *hperh, usart_it_t it) This subsection provides a set of functions allowing to return the State of USART communication process, return Peripheral Errors occurred during communication process - (+) usart_get_state() API can be helpful to check in run-time the state of the USART peripheral. - (+) usart_get_error() check in run-time errors that could be occurred during communication. + (+) ald_usart_get_state() API can be helpful to check in run-time the state of the USART peripheral. + (+) ald_usart_get_error() check in run-time errors that could be occurred during communication. @endverbatim * @{ @@ -1976,7 +1988,7 @@ it_status_t usart_get_it_status(usart_handle_t *hperh, usart_it_t it) * the configuration information for the specified USART module. * @retval USART state */ -usart_state_t usart_get_state(usart_handle_t *hperh) +usart_state_t ald_usart_get_state(usart_handle_t *hperh) { return hperh->state; } @@ -1987,7 +1999,7 @@ usart_state_t usart_get_state(usart_handle_t *hperh) * the configuration information for the specified USART. * @retval USART Error Code */ -uint32_t usart_get_error(usart_handle_t *hperh) +uint32_t ald_usart_get_error(usart_handle_t *hperh) { return hperh->err_code; } @@ -2017,7 +2029,7 @@ static void usart_dma_send_cplt(void *arg) hperh->tx_count = 0; CLEAR_BIT(hperh->perh->CON2, USART_CON2_TXDMAEN_MSK); - usart_interrupt_config(hperh, USART_IT_TC, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_TC, ENABLE); } /** @@ -2076,16 +2088,16 @@ static ald_status_t usart_wait_flag(usart_handle_t *hperh, usart_flag_t flag, fl if (timeout == 0) return OK; - tick = __get_tick(); + tick = ald_get_tick(); - while ((usart_get_flag_status(hperh, flag)) != status) + while ((ald_usart_get_flag_status(hperh, flag)) != status) { - if (((__get_tick()) - tick) > timeout) + if (((ald_get_tick()) - tick) > timeout) { - usart_interrupt_config(hperh, USART_IT_TXE, DISABLE); - usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); - usart_interrupt_config(hperh, USART_IT_PE, DISABLE); - usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_TXE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); return TIMEOUT; } @@ -2117,8 +2129,8 @@ static ald_status_t __usart_send_by_it(usart_handle_t *hperh) if (--hperh->tx_count == 0) { - usart_interrupt_config(hperh, USART_IT_TXE, DISABLE); - usart_interrupt_config(hperh, USART_IT_TC, ENABLE); + ald_usart_interrupt_config(hperh, USART_IT_TXE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_TC, ENABLE); } return OK; @@ -2133,7 +2145,7 @@ static ald_status_t __usart_send_by_it(usart_handle_t *hperh) */ static ald_status_t __usart_end_send_by_it(usart_handle_t *hperh) { - usart_interrupt_config(hperh, USART_IT_TC, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_TC, DISABLE); CLEAR_BIT(hperh->state, USART_STATE_TX_MASK); if (hperh->tx_cplt_cbk != NULL) @@ -2173,19 +2185,19 @@ static ald_status_t __usart_recv_by_it(usart_handle_t *hperh) *hperh->rx_buf++ = (uint8_t)(hperh->perh->DATA & 0x7F); } - if (__frame_mode && ((usart_get_it_status(hperh, USART_IT_IDLE)) == RESET)) - usart_interrupt_config(hperh, USART_IT_IDLE, ENABLE); + if (__frame_mode && ((ald_usart_get_it_status(hperh, USART_IT_IDLE)) == RESET)) + ald_usart_interrupt_config(hperh, USART_IT_IDLE, ENABLE); if (--hperh->rx_count == 0) { - usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); CLEAR_BIT(hperh->state, USART_STATE_RX_MASK); __frame_mode = 0; if (hperh->state == USART_STATE_READY) { - usart_interrupt_config(hperh, USART_IT_PE, DISABLE); - usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); } if (hperh->rx_cplt_cbk != NULL) @@ -2206,8 +2218,8 @@ static ald_status_t __usart_recv_frame_cplt(usart_handle_t *hperh) if ((hperh->state != USART_STATE_BUSY_RX) && (hperh->state != USART_STATE_BUSY_TX_RX)) return BUSY; - usart_interrupt_config(hperh, USART_IT_IDLE, DISABLE); - usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_IDLE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); CLEAR_BIT(hperh->state, USART_STATE_RX_MASK); __frame_mode = 0; @@ -2215,8 +2227,8 @@ static ald_status_t __usart_recv_frame_cplt(usart_handle_t *hperh) if (hperh->state == USART_STATE_READY) { - usart_interrupt_config(hperh, USART_IT_PE, DISABLE); - usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); } if (hperh->rx_cplt_cbk != NULL) @@ -2267,9 +2279,9 @@ static ald_status_t __usart_recv_by_it_sync(usart_handle_t *hperh) if (hperh->rx_count == 0) { - usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); - usart_interrupt_config(hperh, USART_IT_PE, DISABLE); - usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); hperh->state = USART_STATE_READY; if (hperh->rx_cplt_cbk != NULL) @@ -2292,7 +2304,7 @@ static ald_status_t __usart_send_recv_by_it_sync(usart_handle_t *hperh) if (hperh->tx_count != 0) { - if (usart_get_flag_status(hperh, USART_FLAG_TXE) != RESET) + if (ald_usart_get_flag_status(hperh, USART_FLAG_TXE) != RESET) { if (hperh->init.word_length == USART_WORD_LENGTH_9B) { @@ -2312,13 +2324,13 @@ static ald_status_t __usart_send_recv_by_it_sync(usart_handle_t *hperh) } if (--hperh->tx_count == 0) - usart_interrupt_config(hperh, USART_IT_TXE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_TXE, DISABLE); } } if (hperh->rx_count != 0) { - if (usart_get_flag_status(hperh, USART_FLAG_RXNE) != RESET) + if (ald_usart_get_flag_status(hperh, USART_FLAG_RXNE) != RESET) { if (hperh->init.word_length == USART_WORD_LENGTH_9B) { @@ -2346,9 +2358,9 @@ static ald_status_t __usart_send_recv_by_it_sync(usart_handle_t *hperh) if (hperh->rx_count == 0) { - usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); - usart_interrupt_config(hperh, USART_IT_PE, DISABLE); - usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_RXNE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_PE, DISABLE); + ald_usart_interrupt_config(hperh, USART_IT_ERR, DISABLE); hperh->state = USART_STATE_READY; @@ -2407,13 +2419,14 @@ static void usart_set_config(usart_handle_t *hperh) if (READ_BIT(hperh->perh->CON0, (1 << 15))) { /* Integer part computing in case Oversampling mode is 8 Samples */ - integer = ((25 * cmu_get_pclk1_clock()) / (2 * (hperh->init.baud))); + integer = ((25 * ald_cmu_get_pclk1_clock()) / (2 * (hperh->init.baud))); } else { /* Integer part computing in case Oversampling mode is 16 Samples */ - integer = ((25 * cmu_get_pclk1_clock()) / (4 * (hperh->init.baud))); + integer = ((25 * ald_cmu_get_pclk1_clock()) / (4 * (hperh->init.baud))); } + tmp = (integer / 100) << 4; /* Determine the fractional part */ diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_wdt.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_wdt.c similarity index 88% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_wdt.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_wdt.c index cbe2921ee9..acf092a278 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_wdt.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/ald_wdt.c @@ -44,7 +44,7 @@ * @param interrupt: Enable or disable interrupt. * @retval None */ -void wwdt_init(uint32_t load, wwdt_win_t win, type_func_t interrupt) +void ald_wwdt_init(uint32_t load, wwdt_win_t win, type_func_t interrupt) { assert_param(IS_WWDT_WIN_TYPE(win)); assert_param(IS_FUNC_STATE(interrupt)); @@ -64,7 +64,7 @@ void wwdt_init(uint32_t load, wwdt_win_t win, type_func_t interrupt) * @brief Start the WWDT * @retval None */ -void wwdt_start(void) +void ald_wwdt_start(void) { WWDT_UNLOCK(); SET_BIT(WWDT->CON, WWDT_CON_EN_MSK); @@ -77,7 +77,7 @@ void wwdt_start(void) * @brief Get the free-running downcounter value * @retval Value */ -uint32_t wwdt_get_value(void) +uint32_t ald_wwdt_get_value(void) { return WWDT->VALUE; } @@ -86,7 +86,7 @@ uint32_t wwdt_get_value(void) * @brief Get interrupt state * @retval Value */ -it_status_t wwdt_get_flag_status(void) +it_status_t ald_wwdt_get_flag_status(void) { if (READ_BIT(WWDT->RIS, WWDT_RIS_WWDTIF_MSK)) return SET; @@ -98,7 +98,7 @@ it_status_t wwdt_get_flag_status(void) * @brief Clear interrupt state * @retval None */ -void wwdt_clear_flag_status(void) +void ald_wwdt_clear_flag_status(void) { WRITE_REG(WWDT->INTCLR, 1); return; @@ -108,7 +108,7 @@ void wwdt_clear_flag_status(void) * @brief Refreshes the WWDT * @retval None */ -void wwdt_feed_dog(void) +void ald_wwdt_feed_dog(void) { WWDT_UNLOCK(); WRITE_REG(WWDT->INTCLR, 0x1); @@ -130,7 +130,7 @@ void wwdt_feed_dog(void) * @param interrupt: Enable or disable interrupt. * @retval None */ -void iwdt_init(uint32_t load, type_func_t interrupt) +void ald_iwdt_init(uint32_t load, type_func_t interrupt) { assert_param(IS_FUNC_STATE(interrupt)); @@ -148,7 +148,7 @@ void iwdt_init(uint32_t load, type_func_t interrupt) * @brief Start the IWDT * @retval None */ -void iwdt_start(void) +void ald_iwdt_start(void) { IWDT_UNLOCK(); SET_BIT(IWDT->CON, IWDT_CON_EN_MSK); @@ -161,7 +161,7 @@ void iwdt_start(void) * @brief Get the free-running downcounter value * @retval Value */ -uint32_t iwdt_get_value(void) +uint32_t ald_iwdt_get_value(void) { return IWDT->VALUE; } @@ -170,7 +170,7 @@ uint32_t iwdt_get_value(void) * @brief Get interrupt state * @retval Value */ -it_status_t iwdt_get_flag_status(void) +it_status_t ald_iwdt_get_flag_status(void) { if (READ_BIT(IWDT->RIS, IWDT_RIS_WDTIF_MSK)) return SET; @@ -182,7 +182,7 @@ it_status_t iwdt_get_flag_status(void) * @brief Clear interrupt state * @retval None */ -void iwdt_clear_flag_status(void) +void ald_iwdt_clear_flag_status(void) { WRITE_REG(IWDT->INTCLR, 1); return; @@ -192,7 +192,7 @@ void iwdt_clear_flag_status(void) * @brief Refreshes the WWDT * @retval None */ -void iwdt_feed_dog(void) +void ald_iwdt_feed_dog(void) { IWDT_UNLOCK(); WRITE_REG(IWDT->INTCLR, 1); diff --git a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/utils.c b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/utils.c similarity index 78% rename from bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/utils.c rename to bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/utils.c index 24c6bfdf45..596bc38fbf 100644 --- a/bsp/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/utils.c +++ b/bsp/essemi/es32f0654/libraries/ES32F065x_ALD_StdPeriph_Driver/Source/utils.c @@ -37,14 +37,14 @@ /** * @brief ALD version number */ -#define __ALD_VERSION_MAIN (0x01) /**< [31:24] main version */ -#define __ALD_VERSION_SUB1 (0x00) /**< [23:16] sub1 version */ -#define __ALD_VERSION_SUB2 (0x00) /**< [15:8] sub2 version */ -#define __ALD_VERSION_RC (0x00) /**< [7:0] release candidate */ -#define __ALD_VERSION ((__ALD_VERSION_MAIN << 24) | \ - (__ALD_VERSION_SUB1 << 16) | \ - (__ALD_VERSION_SUB2 << 8 ) | \ - (__ALD_VERSION_RC)) +#define __ALD_VERSION_MAIN (0x01) /**< [31:24] main version */ +#define __ALD_VERSION_SUB1 (0x00) /**< [23:16] sub1 version */ +#define __ALD_VERSION_SUB2 (0x00) /**< [15:8] sub2 version */ +#define __ALD_VERSION_RC (0x00) /**< [7:0] release candidate */ +#define __ALD_VERSION ((__ALD_VERSION_MAIN << 24) | \ + (__ALD_VERSION_SUB1 << 16) | \ + (__ALD_VERSION_SUB2 << 8 ) | \ + (__ALD_VERSION_RC)) /** * @} */ @@ -82,11 +82,11 @@ uint32_t __systick_interval = SYSTICK_INTERVAL_1MS; can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms. - (++) Time base configuration function (__init_tick()) is called automatically - at the beginning of the program after reset by mcu_ald_init() or at - any time when clock is configured. + (++) Time base configuration function (ald_tick_init()) is called automatically + at the beginning of the program after reset by ald_cmu_init() or at + any time when clock is configured. (++) Source of time base is configured to generate interrupts at regular - time intervals. Care must be taken if __delay_ms() is called from a + time intervals. Care must be taken if ald_delay_ms() is called from a peripheral ISR process, the Tick interrupt line must have higher priority (numerically lower) than the peripheral interrupt. Otherwise the caller ISR process will be blocked. @@ -108,12 +108,12 @@ uint32_t __systick_interval = SYSTICK_INTERVAL_1MS; * The tick variable is incremented each 1ms in its ISR. * @retval None */ -void mcu_ald_init(void) +void ald_cmu_init(void) { - cmu_clock_config_default(); - __init_tick(TICK_INT_PRIORITY); + ald_cmu_clock_config_default(); + ald_tick_init(TICK_INT_PRIORITY); #ifdef ALD_DMA - dma_init(DMA0); + ald_dma_init(DMA0); #endif return; } @@ -124,7 +124,7 @@ void mcu_ald_init(void) * Tick interrupt priority. * @note In the default implementation, SysTick timer is the source of time base. * It is used to generate interrupts at regular time intervals. - * Care must be taken if __delay_ms() is called from a peripheral ISR process, + * Care must be taken if ald_delay_ms() is called from a peripheral ISR process, * The SysTick interrupt must have higher priority (numerically lower) * than the peripheral interrupt. Otherwise the caller ISR process will be blocked. * The function is declared as __weak to be overwritten in case of other @@ -132,10 +132,10 @@ void mcu_ald_init(void) * @param prio: Tick interrupt priority. * @retval None */ -__weak void __init_tick(uint32_t prio) +__weak void ald_tick_init(uint32_t prio) { /* Configure the SysTick IRQ */ - SysTick_Config(cmu_get_clock() / SYSTICK_INTERVAL_1MS); + SysTick_Config(ald_cmu_get_sys_clock() / SYSTICK_INTERVAL_1MS); if (prio != 3) NVIC_SetPriority(SysTick_IRQn, prio); @@ -152,11 +152,11 @@ __weak void __init_tick(uint32_t prio) * @arg @ref SYSTICK_INTERVAL_1000MS 1 second * @retval None */ -void systick_interval_select(systick_interval_t value) +void ald_systick_interval_select(systick_interval_t value) { assert_param(IS_SYSTICK_INTERVAL(value)); - SysTick_Config(cmu_get_clock() / value); + SysTick_Config(ald_cmu_get_sys_clock() / value); __systick_interval = value; if (TICK_INT_PRIORITY != 3) @@ -198,7 +198,7 @@ void systick_interval_select(systick_interval_t value) * implementations in user file. * @retval None */ -__weak void __inc_tick(void) +__weak void ald_inc_tick_weak(void) { ++lib_tick; } @@ -209,7 +209,7 @@ __weak void __inc_tick(void) * other implementations in user file. * @retval None */ -__weak void systick_irq_cbk(void) +__weak void ald_systick_irq_cbk(void) { /* do nothing */ return; @@ -219,10 +219,10 @@ __weak void systick_irq_cbk(void) * @brief This function invoked by Systick ISR each 1ms. * @retval None */ -__isr__ void SysTick_Handler(void) +__isr__ void ald_inc_tick(void) { - __inc_tick(); - systick_irq_cbk(); + ald_inc_tick_weak(); + ald_systick_irq_cbk(); return; } @@ -233,7 +233,7 @@ __isr__ void SysTick_Handler(void) * implementations in user file. * @retval tick value */ -__weak uint32_t __get_tick(void) +__weak uint32_t ald_get_tick(void) { return lib_tick; } @@ -249,37 +249,37 @@ __weak uint32_t __get_tick(void) * @param delay: specifies the delay time length, in milliseconds. * @retval None */ -__weak void __delay_ms(__IO uint32_t delay) +__weak void ald_delay_ms(__IO uint32_t delay) { uint32_t tick, __delay; switch (__systick_interval) { - case SYSTICK_INTERVAL_1MS: - __delay = delay; - break; + case SYSTICK_INTERVAL_1MS: + __delay = delay; + break; - case SYSTICK_INTERVAL_10MS: - __delay = delay / 10; - break; + case SYSTICK_INTERVAL_10MS: + __delay = delay / 10; + break; - case SYSTICK_INTERVAL_100MS: - __delay = delay / 100; - break; + case SYSTICK_INTERVAL_100MS: + __delay = delay / 100; + break; - case SYSTICK_INTERVAL_1000MS: - __delay = delay / 1000; - break; + case SYSTICK_INTERVAL_1000MS: + __delay = delay / 1000; + break; - default: - __delay = delay; - break; + default: + __delay = delay; + break; } - tick = __get_tick(); + tick = ald_get_tick(); __delay = __delay == 0 ? 1 : __delay; - while ((__get_tick() - tick) < __delay) + while ((ald_get_tick() - tick) < __delay) ; } @@ -287,13 +287,13 @@ __weak void __delay_ms(__IO uint32_t delay) * @brief Suspend Tick increment. * @note In the default implementation, SysTick timer is the source of time base. * It is used to generate interrupts at regular time intervals. - * Once __suspend_tick() is called, the the SysTick interrupt + * Once ald_suspend_tick() is called, the the SysTick interrupt * will be disabled and so Tick increment is suspended. * @note This function is declared as __weak to be overwritten * in case of other implementations in user file. * @retval None */ -__weak void __suspend_tick(void) +__weak void ald_suspend_tick(void) { CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); } @@ -302,13 +302,13 @@ __weak void __suspend_tick(void) * @brief Resume Tick increment. * @note In the default implementation, SysTick timer is the source of * time base. It is used to generate interrupts at regular time - * intervals. Once __resume_tick() is called, the the SysTick + * intervals. Once ald_resume_tick() is called, the the SysTick * interrupt will be enabled and so Tick increment is resumed. * @note This function is declared as __weak to be overwritten * in case of other implementations in user file. * @retval None */ -__weak void __resume_tick(void) +__weak void ald_resume_tick(void) { SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); } @@ -317,7 +317,7 @@ __weak void __resume_tick(void) * @brief This method returns the ALD revision * @retval version: 0xXYZR (8bits for each decimal, R for RC) */ -uint32_t get_ald_version(void) +uint32_t ald_get_ald_version(void) { return __ALD_VERSION; } @@ -330,9 +330,9 @@ uint32_t get_ald_version(void) * @param timeout: Timeout duration. * @retval Status, see @ref ald_status_t. */ -ald_status_t __wait_flag(uint32_t *reg, uint32_t bit, flag_status_t status, uint32_t timeout) +ald_status_t ald_wait_flag(uint32_t *reg, uint32_t bit, flag_status_t status, uint32_t timeout) { - uint32_t tick = __get_tick(); + uint32_t tick = ald_get_tick(); assert_param(timeout > 0); @@ -340,7 +340,7 @@ ald_status_t __wait_flag(uint32_t *reg, uint32_t bit, flag_status_t status, uint { while (!(IS_BIT_SET(*reg, bit))) { - if (((__get_tick()) - tick) > timeout) + if (((ald_get_tick()) - tick) > timeout) return TIMEOUT; } } @@ -348,7 +348,7 @@ ald_status_t __wait_flag(uint32_t *reg, uint32_t bit, flag_status_t status, uint { while ((IS_BIT_SET(*reg, bit))) { - if (((__get_tick()) - tick) > timeout) + if (((ald_get_tick()) - tick) > timeout) return TIMEOUT; } } @@ -365,7 +365,7 @@ ald_status_t __wait_flag(uint32_t *reg, uint32_t bit, flag_status_t status, uint * @arg DISABLE * @retval None */ -void mcu_irq_config(IRQn_Type irq, uint8_t prio, type_func_t status) +void ald_mcu_irq_config(IRQn_Type irq, uint8_t prio, type_func_t status) { assert_param(IS_FUNC_STATE(status)); assert_param(IS_PRIO(prio)); @@ -387,7 +387,7 @@ void mcu_irq_config(IRQn_Type irq, uint8_t prio, type_func_t status) * @brief Get the system tick. * @retval The value of current tick. */ -uint32_t mcu_get_tick(void) +uint32_t ald_mcu_get_tick(void) { uint32_t load = SysTick->LOAD; uint32_t val = SysTick->VAL; @@ -399,7 +399,7 @@ uint32_t mcu_get_tick(void) * @brief Get the CPU ID. * @retval CPU ID. */ -uint32_t mcu_get_cpu_id(void) +uint32_t ald_mcu_get_cpu_id(void) { return SCB->CPUID; } diff --git a/bsp/es32f0654/libraries/SConscript b/bsp/essemi/es32f0654/libraries/SConscript similarity index 96% rename from bsp/es32f0654/libraries/SConscript rename to bsp/essemi/es32f0654/libraries/SConscript index 6da75a0262..04d2eae28b 100644 --- a/bsp/es32f0654/libraries/SConscript +++ b/bsp/essemi/es32f0654/libraries/SConscript @@ -22,6 +22,6 @@ path = [cwd + '/CMSIS/Device/EastSoft/ES32F065x/Include', cwd + '/CMSIS/Include', cwd + '/ES32F065x_ALD_StdPeriph_Driver/Include'] -group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path) +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, CPPDEFINES = ['ES32F065x']) Return('group') diff --git a/bsp/es32f0654/project.uvoptx b/bsp/essemi/es32f0654/project.uvoptx similarity index 100% rename from bsp/es32f0654/project.uvoptx rename to bsp/essemi/es32f0654/project.uvoptx diff --git a/bsp/es32f0654/project.uvprojx b/bsp/essemi/es32f0654/project.uvprojx similarity index 90% rename from bsp/es32f0654/project.uvprojx rename to bsp/essemi/es32f0654/project.uvprojx index e51102987c..724ef242af 100644 --- a/bsp/es32f0654/project.uvprojx +++ b/bsp/essemi/es32f0654/project.uvprojx @@ -330,9 +330,9 @@ 0 - + ES32F065x - .;..\..\include;applications;.;drivers;libraries\CMSIS\Device\EastSoft\ES32F065x\Include;libraries\CMSIS\Include;libraries\ES32F065x_ALD_StdPeriph_Driver\Include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m0;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\common + .;..\..\..\include;applications;.;drivers;libraries\CMSIS\Device\EastSoft\ES32F065x\Include;libraries\CMSIS\Include;libraries\ES32F065x_ALD_StdPeriph_Driver\Include;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m0;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\finsh;..\..\..\components\libc\compilers\common @@ -379,105 +379,98 @@ clock.c 1 - ..\..\src\clock.c + ..\..\..\src\clock.c components.c 1 - ..\..\src\components.c - - - - - cpu.c - 1 - ..\..\src\cpu.c + ..\..\..\src\components.c device.c 1 - ..\..\src\device.c + ..\..\..\src\device.c idle.c 1 - ..\..\src\idle.c + ..\..\..\src\idle.c ipc.c 1 - ..\..\src\ipc.c + ..\..\..\src\ipc.c irq.c 1 - ..\..\src\irq.c + ..\..\..\src\irq.c kservice.c 1 - ..\..\src\kservice.c + ..\..\..\src\kservice.c mem.c 1 - ..\..\src\mem.c + ..\..\..\src\mem.c mempool.c 1 - ..\..\src\mempool.c + ..\..\..\src\mempool.c object.c 1 - ..\..\src\object.c + ..\..\..\src\object.c scheduler.c 1 - ..\..\src\scheduler.c + ..\..\..\src\scheduler.c signal.c 1 - ..\..\src\signal.c + ..\..\..\src\signal.c thread.c 1 - ..\..\src\thread.c + ..\..\..\src\thread.c timer.c 1 - ..\..\src\timer.c + ..\..\..\src\timer.c @@ -587,6 +580,13 @@ libraries\ES32F065x_ALD_StdPeriph_Driver\Source\ald_flash.c + + + ald_flash_ext.c + 1 + libraries\ES32F065x_ALD_StdPeriph_Driver\Source\ald_flash_ext.c + + ald_gpio.c @@ -652,23 +652,23 @@ - ald_temp.c + ald_timer.c 1 - libraries\ES32F065x_ALD_StdPeriph_Driver\Source\ald_temp.c + libraries\ES32F065x_ALD_StdPeriph_Driver\Source\ald_timer.c - ald_timer.c + ald_trng.c 1 - libraries\ES32F065x_ALD_StdPeriph_Driver\Source\ald_timer.c + libraries\ES32F065x_ALD_StdPeriph_Driver\Source\ald_trng.c - ald_trng.c + ald_tsense.c 1 - libraries\ES32F065x_ALD_StdPeriph_Driver\Source\ald_trng.c + libraries\ES32F065x_ALD_StdPeriph_Driver\Source\ald_tsense.c @@ -713,35 +713,35 @@ backtrace.c 1 - ..\..\libcpu\arm\common\backtrace.c + ..\..\..\libcpu\arm\common\backtrace.c div0.c 1 - ..\..\libcpu\arm\common\div0.c + ..\..\..\libcpu\arm\common\div0.c showmem.c 1 - ..\..\libcpu\arm\common\showmem.c + ..\..\..\libcpu\arm\common\showmem.c cpuport.c 1 - ..\..\libcpu\arm\cortex-m0\cpuport.c + ..\..\..\libcpu\arm\cortex-m0\cpuport.c context_rvds.S 2 - ..\..\libcpu\arm\cortex-m0\context_rvds.S + ..\..\..\libcpu\arm\cortex-m0\context_rvds.S @@ -751,63 +751,63 @@ pin.c 1 - ..\..\components\drivers\misc\pin.c + ..\..\..\components\drivers\misc\pin.c serial.c 1 - ..\..\components\drivers\serial\serial.c + ..\..\..\components\drivers\serial\serial.c completion.c 1 - ..\..\components\drivers\src\completion.c + ..\..\..\components\drivers\src\completion.c dataqueue.c 1 - ..\..\components\drivers\src\dataqueue.c + ..\..\..\components\drivers\src\dataqueue.c pipe.c 1 - ..\..\components\drivers\src\pipe.c + ..\..\..\components\drivers\src\pipe.c ringblk_buf.c 1 - ..\..\components\drivers\src\ringblk_buf.c + ..\..\..\components\drivers\src\ringblk_buf.c ringbuffer.c 1 - ..\..\components\drivers\src\ringbuffer.c + ..\..\..\components\drivers\src\ringbuffer.c waitqueue.c 1 - ..\..\components\drivers\src\waitqueue.c + ..\..\..\components\drivers\src\waitqueue.c workqueue.c 1 - ..\..\components\drivers\src\workqueue.c + ..\..\..\components\drivers\src\workqueue.c @@ -817,21 +817,21 @@ shell.c 1 - ..\..\components\finsh\shell.c + ..\..\..\components\finsh\shell.c cmd.c 1 - ..\..\components\finsh\cmd.c + ..\..\..\components\finsh\cmd.c msh.c 1 - ..\..\components\finsh\msh.c + ..\..\..\components\finsh\msh.c diff --git a/bsp/es32f0654/rtconfig.h b/bsp/essemi/es32f0654/rtconfig.h similarity index 95% rename from bsp/es32f0654/rtconfig.h rename to bsp/essemi/es32f0654/rtconfig.h index 61cd5f891d..ab25a2d01b 100644 --- a/bsp/es32f0654/rtconfig.h +++ b/bsp/essemi/es32f0654/rtconfig.h @@ -39,7 +39,7 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLE_DEVICE_NAME "uart2" -#define RT_VER_NUM 0x40001 +#define RT_VER_NUM 0x40002 /* RT-Thread Components */ @@ -78,9 +78,6 @@ #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_PIN -/* Using WiFi */ - - /* Using USB */ @@ -92,10 +89,10 @@ /* Socket abstraction layer */ -/* light weight TCP/IP stack */ +/* Network interface device */ -/* Modbus master and slave stack */ +/* light weight TCP/IP stack */ /* AT commands */ @@ -144,13 +141,8 @@ /* miscellaneous packages */ -/* sample package */ - /* samples: kernel and components samples */ - -/* example package: hello */ - #define SOC_ES32F0654LT /* Hardware Drivers Config */ diff --git a/bsp/es32f0654/rtconfig.py b/bsp/essemi/es32f0654/rtconfig.py similarity index 100% rename from bsp/es32f0654/rtconfig.py rename to bsp/essemi/es32f0654/rtconfig.py diff --git a/bsp/es32f0654/template.uvoptx b/bsp/essemi/es32f0654/template.uvoptx similarity index 100% rename from bsp/es32f0654/template.uvoptx rename to bsp/essemi/es32f0654/template.uvoptx diff --git a/bsp/es32f0654/template.uvprojx b/bsp/essemi/es32f0654/template.uvprojx similarity index 100% rename from bsp/es32f0654/template.uvprojx rename to bsp/essemi/es32f0654/template.uvprojx -- Gitee From 2479d7de4a7db40f57f2f217a1fcb635a19caf17 Mon Sep 17 00:00:00 2001 From: Karl Zhang Date: Fri, 10 Jan 2020 21:56:24 +0800 Subject: [PATCH 056/110] LPC55S69: TFM: Preparation to add PS demo Link TFM PS APIs and veneer library. This is a preparation to add a demo in RTT which can call into TFM for secure services. Change-Id: I19ea617690d174a28af29b1804674bcaae59f838 Signed-off-by: Karl Zhang --- .../lpc55s69_nxp_evk/project_ns.uvoptx | 44 +++++++++++++++++++ .../lpc55s69_nxp_evk/project_ns.uvprojx | 22 +++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx index 7f28d506da..9459d78b20 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx @@ -1808,4 +1808,48 @@ + + TFM + 0 + 0 + 0 + 0 + + 10 + 131 + 1 + 0 + 0 + 0 + .\packages\trusted-firmware-m-v1.0-beta\interface\src\tfm_sst_api.c + tfm_sst_api.c + 0 + 0 + + + 10 + 132 + 1 + 0 + 0 + 0 + .\packages\trusted-firmware-m-v1.0-beta\interface\src\tfm_ns_lock_rt-thread.c + tfm_ns_lock_rt-thread.c + 0 + 0 + + + 10 + 133 + 3 + 0 + 0 + 0 + .\packages\trusted-firmware-m-v1.0-beta\cmake_build\install\export\tfm\veneers\s_veneers.o + s_veneers.o + 0 + 0 + + + diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx index 4cfb8a82cd..a149a896ff 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx @@ -339,7 +339,7 @@ --target=arm-arm-none-eabi CPU_LPC55S69JBD100_cm33_core0, RT_USING_ARM_LIBC, RT_USING_TFM - .;..\..\..\include;applications;board;board\MCUX_Config\board;..\Libraries\drivers;..\Libraries\drivers\config;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\dfs\include;..\..\..\components\dfs\filesystems\devfs;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\spi;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\finsh;..\..\..\components\libc\compilers\armlibc;..\..\..\components\libc\compilers\common;..\Libraries\LPC55S6X\CMSIS\Include;..\Libraries\LPC55S6X\components\codec;..\Libraries\LPC55S6X\LPC55S6X;..\Libraries\LPC55S6X\LPC55S6X\drivers;..\Libraries\LPC55S6X\middleware\sdmmc\inc;..\Libraries\LPC55S6X\middleware\sdmmc\port + .;..\..\..\include;applications;board;board\MCUX_Config\board;..\Libraries\drivers;..\Libraries\drivers\config;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\dfs\include;..\..\..\components\dfs\filesystems\devfs;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\spi;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\finsh;..\..\..\components\libc\compilers\armlibc;..\..\..\components\libc\compilers\common;..\Libraries\LPC55S6X\CMSIS\Include;..\Libraries\LPC55S6X\components\codec;..\Libraries\LPC55S6X\LPC55S6X;..\Libraries\LPC55S6X\LPC55S6X\drivers;..\Libraries\LPC55S6X\middleware\sdmmc\inc;..\Libraries\LPC55S6X\middleware\sdmmc\port;.\packages\trusted-firmware-m-v1.0-beta\interface\include @@ -1144,6 +1144,26 @@ + + TFM + + + tfm_sst_api.c + 1 + .\packages\trusted-firmware-m-v1.0-beta\interface\src\tfm_sst_api.c + + + tfm_ns_lock_rt-thread.c + 1 + .\packages\trusted-firmware-m-v1.0-beta\interface\src\tfm_ns_lock_rt-thread.c + + + s_veneers.o + 3 + .\packages\trusted-firmware-m-v1.0-beta\cmake_build\install\export\tfm\veneers\s_veneers.o + + + -- Gitee From cd95e4cd59601034954870a42484dbc9ce533c40 Mon Sep 17 00:00:00 2001 From: Kevin Peng Date: Fri, 10 Jan 2020 22:53:35 +0800 Subject: [PATCH 057/110] LPC55S69: Add Protected Storage demo This demo shows how protected storage works in RTT. It tests by write and read data over PSA APIs, then check the integrity. The test will run repeatedly, each time with different data. The TFM package does not support LPC55S69 board officially yet. Change-Id: Ib1cd4fc8166b21e3f774f092c95d2811d51123fe Signed-off-by: Kevin Peng Signed-off-by: Karl Zhang --- .../lpc55s69_nxp_evk/applications/main.c | 16 ++- .../lpc55s69_nxp_evk/applications/tfm_ps.c | 110 ++++++++++++++++++ .../lpc55s69_nxp_evk/project_ns.uvoptx | 12 ++ .../lpc55s69_nxp_evk/project_ns.uvprojx | 5 + 4 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 bsp/lpc55sxx/lpc55s69_nxp_evk/applications/tfm_ps.c diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/main.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/main.c index e03a8c6336..e0a2e3171f 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/main.c +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/main.c @@ -1,11 +1,13 @@ /* * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-10-24 Magicoe first version + * 2020-01-10 Kevin/Karl Add PS demo * */ @@ -16,8 +18,12 @@ /* GPIO1_4 is Blue LED */ #define LEDB_PIN GET_PINS(1, 4) +extern void protected_storage_demo_thread(void * parameters); + int main(void) { + rt_thread_t t_psa_ps_demo; + #if defined(__CC_ARM) rt_kprintf("using armcc, version: %d\n", __ARMCC_VERSION); #elif defined(__CLANG_ARM) @@ -27,7 +33,15 @@ int main(void) #elif defined(__GNUC__) rt_kprintf("using gcc, version: %d.%d\n", __GNUC__, __GNUC_MINOR__); #endif - + + t_psa_ps_demo = rt_thread_create("psa_ps_demo", + protected_storage_demo_thread, + RT_NULL, + 512, + ( RT_MAIN_THREAD_PRIORITY - 1), + 50); + if (t_psa_ps_demo != RT_NULL) rt_thread_startup(t_psa_ps_demo); + rt_pin_mode(LEDB_PIN, PIN_MODE_OUTPUT); /* Set GPIO as Output */ while (1) { diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/tfm_ps.c b/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/tfm_ps.c new file mode 100644 index 0000000000..2c99e47402 --- /dev/null +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/applications/tfm_ps.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-10 Kevin/Karl Add PS demo + * + */ + +#include +#include +#include "tfm_ns_lock.h" +#include "psa_protected_storage.h" + +#define TEST_UID_A 2U +#define ASSET_A "THEQUICKBROWNFOXJUMPSOVERALAZYDOG" +#define ASSET_A_SIZE (sizeof( ASSET_A ) - 1) +#define RESETDATA "THISIS" +#define RESETDATA_SIZE (sizeof( RESETDATA ) - 1) +#define READ_LENGTH (ASSET_A_SIZE > RESETDATA_SIZE ? \ + ASSET_A_SIZE : RESETDATA_SIZE) + +void protected_storage_demo_thread(void * parameters) +{ + psa_ps_status_t status; + const psa_ps_uid_t uid = TEST_UID_A; + const psa_ps_create_flags_t flags = PSA_PS_FLAG_NONE; + uint8_t write_data[] = ASSET_A; + const uint32_t data_length = ASSET_A_SIZE; + uint8_t rewrite_data[] = RESETDATA; + const uint32_t reset_data_length = RESETDATA_SIZE; + uint8_t get_data[READ_LENGTH]; + uint32_t counter = 0; + + tfm_ns_lock_init(); + + for ( ; ; ) + { + /* Call TF-M protected storage service and set the asset. */ + status = psa_ps_set(uid, data_length, write_data, flags); + if (status != PSA_PS_SUCCESS) + { + rt_kprintf("[Protected Storage Asset A Set Round %ld] Fail\r\n", counter); + for( ; ; ); + } + + rt_kprintf("[Protected Storage Asset A Set Round %ld] Success\r\n", counter); + + /* Read the asset. */ + status = psa_ps_get(uid, 0, data_length, get_data); + if (status != PSA_PS_SUCCESS) + { + rt_kprintf("[Protected Storage Asset A Get Round %ld] Fail\r\n", counter); + for ( ; ; ); + } + + rt_kprintf("[Protected Storage Asset A Get Round %ld] Success\r\n", counter); + + /* Check the read data. */ + if (memcmp(write_data, get_data, sizeof(write_data) - 1) != 0) + { + rt_kprintf("[Protected Storage Asset A Get Round %ld] Get the wrong data\r\n", counter); + for ( ; ; ); + } + + /* Change the asset. */ + status = psa_ps_set(uid, reset_data_length, rewrite_data, flags); + if (status != PSA_PS_SUCCESS) + { + rt_kprintf("[Protected Storage Asset A Reset Round %ld] Fail\r\n", counter); + } + + rt_kprintf("[Protected Storage Asset A Reset Round %ld] Success\r\n", counter); + + /* Read the asset. */ + status = psa_ps_get(uid, 0, reset_data_length, get_data); + if (status != PSA_PS_SUCCESS) + { + rt_kprintf("[Protected Storage Asset A Get Round %ld] Fail\r\n", counter); + for ( ; ; ); + } + + rt_kprintf("[Protected Storage Asset A Get Round %ld] Success\r\n", counter); + + /* Check the read data. */ + if (memcmp(rewrite_data, get_data, sizeof(rewrite_data) - 1) != 0) + { + rt_kprintf("[Protected Storage Asset A Get Round %ld] Get the wrong data\r\n", counter); + for ( ; ; ); + } + + /* Remove the asset. */ + status = psa_ps_remove(uid); + if (status != PSA_PS_SUCCESS) + { + rt_kprintf("[Protected Storage Asset A Remove Round %ld] Fail\r\n", counter); + for ( ; ; ); + } + + rt_kprintf("[Protected Storage Asset A Remove Round %ld] Success\r\n\n", counter); + + /* Wait for a second. */ + rt_thread_mdelay(1000); + counter++; + } +} + +// end file diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx index 9459d78b20..b6a39c92b3 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvoptx @@ -370,6 +370,18 @@ 0 0 + + 2 + 16 + 1 + 0 + 0 + 0 + .\applications\tfm_ps.c + tfm_ps.c + 0 + 0 + diff --git a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx index a149a896ff..26e8530af6 100644 --- a/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx +++ b/bsp/lpc55sxx/lpc55s69_nxp_evk/project_ns.uvprojx @@ -463,6 +463,11 @@ 1 applications\main.c + + tfm_ps.c + 1 + .\applications\tfm_ps.c + -- Gitee From 618eb1c0168b709395df439da165c6eceb3b7a73 Mon Sep 17 00:00:00 2001 From: xieyangrun Date: Wed, 15 Jan 2020 09:14:58 +0800 Subject: [PATCH 058/110] fixed whitespace character --- ChangeLog.md | 20 ++++++++++---------- src/components.c | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 7b3e87e373..aa32e1698c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -674,7 +674,7 @@ RT-Thread v2.0.1是2.0这个系列的bug修正版,而v2.1.0 alpha则是当前 * 修正USB host代码的编译错误; * 修正sensor框架回调函数的问题; * 修正pin设备注册时的设备名称问题; - + 而v2.1.0 alpha这个技术预览版则沿着最初设定的roadmap技术路线进行,这其中主要包括: * lwip更深度的集成:把它集成到RT-Thread的文件系统接口中,这样Linux/Unix下的一些socket网络应用能够更顺利的移植到RT-Thread上,也为以后可以应用到更多地方的select接口铺路。 @@ -687,7 +687,7 @@ RT-Thread v2.0.1是2.0这个系列的bug修正版,而v2.1.0 alpha则是当前 以下是自v2.0.0 RC版本以来的详细更改记录。后续我还会给出v2.0.0版本自v1.2.x版本的主要不同、看点,以及给出下一个版本的roadmap规划。 ## 内核 - + * console以RT_DEVICE_FLAG_STREAM参数打开字符设备; * 在rt_memheap_free中加入更多的断言检查; @@ -707,7 +707,7 @@ RT-Thread v2.0.1是2.0这个系列的bug修正版,而v2.1.0 alpha则是当前 * 添加VBUS组件用于Linux与RT-Thread系统之间,RT-Thread与RT-Thread系统之间通信(睿赛德服务公司捐赠); * 增加lwIP/NAT组件,可以做多个网口间的地址转换(Hicard); * 增加lwIP/DHCP服务端,用于向客户端分配IP地址(睿赛德服务公司提供); - + ## BSP * 修正LPC4357串口驱动初始化时过早打开中断的问题(nongxiaoming); @@ -818,7 +818,7 @@ v2.0.0版本的开发相对活跃些,开源社区提供了强有力的支持 * 启动timer前,对timer进行强制移除; * 在执行soft timer超时函数时,打开调度器锁; * 新增块设备的自动刷新参数,RT_DEVICE_CTRL_BLK_AUTOREFRESH; - + ## 工具 * 修正scons命令编译时,选择keil mdk (armcc)编译器时,命令行太长编译失败的问题; @@ -871,7 +871,7 @@ v2.0.0版本的开发相对活跃些,开源社区提供了强有力的支持 # RT-Thread 2.0.0 Alpha更改说明 发布时间:2014/4/8 - + RT-Thread 2.0.0分支的第一个技术预览版本,仅用于展示2.0.0发展分支的演化动向(按照roadmap,2.0.0这个分支会有一部分RT-Thread和Linux互补性的技术,为Linux增加更好的实时性,为RT-Thread增加更多的功能性,这份技术预览版正是朝着这个目标而努力),欢迎反馈建议和问题。 ## 组件 @@ -907,7 +907,7 @@ insmod rtvmm.ko # RT-Thread 1.2.1更改说明 发布时间: 2014/4/8 - + 在原有的1.2.0版本的bug修正版本,也是1.2.0系列的第一个修正版本,原则上不添加任何的新功能,我们尽量会按照每个季度一个修订版本的方式推进。大家在使用的过程中有什么问题还请反馈给我们,这些问题很可能会在下个版本中修正! 以下是更改记录: @@ -953,7 +953,7 @@ insmod rtvmm.ko 发布时间: 2014/1/6 实现roadmap中提到的大部分内容 - +​ 1,文档方面已完成《RT-Thread编程手册》,同时还有论坛上jiezhi童鞋的《一起来学RT-Thread系列连载教程》 2,BSP分支方面新增cortext-A8(beaglebone),cortext-R4(rm48x50),UNITY-2(SEP6200),lpc408x的移植 3,组件方面: @@ -1040,7 +1040,7 @@ insmod rtvmm.ko # RT-Thread 1.2.0RC更改说明 发布时间: 2013/10/10/ 10:19 - + 主要说明: 该版本新增ARM Cortex-A8的支持(BeagleBone),新增UNITY-2内核的支持(SEP6200),新增Ymodem协议。 变更履历 @@ -1135,7 +1135,7 @@ insmod rtvmm.ko 版本: RT-Thread 1.2.0 Beta 版本 发布时间: 2013/6/30 - +​ 进过开发人员三个月的努力,RT-Thread 1.2.0 Beta 版本如期发布。 该版本默认采用lwIP 1.4.1协议栈,USB device stack也进一步完善。加入 log_trace 子系统,加入组件初始化升级版本,加入 ARM Cortex-R 的移植。 @@ -1182,7 +1182,7 @@ insmod rtvmm.ko 版本: RT-Thread 1.2.0 Alpha版本 发布时间: 2013/4/10 - +​ 遵循2013年RT-Thread roadmap,RT-Thread 1.2.0 Alpha版本发布,Alpha意味着此版本为技术预览版,仅用于展示RT-Thread 1.2.0未来的发展方向,并不适合于开发正式产品。RT-Thread 1.2.0版本是1.1.x系列的下一个分支,这个分支主要体现的是RT-Thread 1.x系列的文档情况。当然也有一些功能、代码方面的增强。 伴随着新版本的到来,RT-Thread有几个重大的转变: diff --git a/src/components.c b/src/components.c index 362cf3203f..e7824b65ef 100644 --- a/src/components.c +++ b/src/components.c @@ -174,11 +174,11 @@ void main_thread_entry(void *parameter) { extern int main(void); extern int $Super$$main(void); - + #ifdef RT_USING_COMPONENTS_INIT /* RT-Thread components initialization */ rt_components_init(); -#endif +#endif #ifdef RT_USING_SMP rt_hw_secondary_cpu_up(); #endif -- Gitee From 3b87cb8ded4437316b74d220217c4440fdda249f Mon Sep 17 00:00:00 2001 From: xieyangrun Date: Wed, 15 Jan 2020 09:34:47 +0800 Subject: [PATCH 059/110] [src/timer.c]fixed rt_timer_list_next_timeout multi-task safe --- src/timer.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/timer.c b/src/timer.c index 3992cf6ff4..d85ee080b5 100644 --- a/src/timer.c +++ b/src/timer.c @@ -108,14 +108,23 @@ static void _rt_timer_init(rt_timer_t timer, static rt_tick_t rt_timer_list_next_timeout(rt_list_t timer_list[]) { struct rt_timer *timer; + register rt_base_t level; + rt_tick_t timeout_tick = RT_TICK_MAX; - if (rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) - return RT_TICK_MAX; + /* disable interrupt */ + level = rt_hw_interrupt_disable(); - timer = rt_list_entry(timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next, - struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]); + if (!rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) + { + timer = rt_list_entry(timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next, + struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]); + timeout_tick = timer->timeout_tick; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); - return timer->timeout_tick; + return timeout_tick; } rt_inline void _rt_timer_remove(rt_timer_t timer) -- Gitee From 0094765b311f3a13e3cc174ecc9313ef2fdb13ec Mon Sep 17 00:00:00 2001 From: xieyangrun Date: Wed, 15 Jan 2020 11:38:35 +0800 Subject: [PATCH 060/110] [stm32/libraries/HAL_Drivers/drv_eth.c]fixed read phy SR register return value conflicts with function's parameter --- bsp/stm32/libraries/HAL_Drivers/drv_eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_eth.c b/bsp/stm32/libraries/HAL_Drivers/drv_eth.c index 097a1622e5..4ead17dc23 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_eth.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_eth.c @@ -411,11 +411,11 @@ static void phy_linkchange() if (status & (PHY_AUTONEGO_COMPLETE_MASK | PHY_LINKED_STATUS_MASK)) { - rt_uint32_t SR; + rt_uint32_t SR = 0; phy_speed_new |= PHY_LINK; - SR = HAL_ETH_ReadPHYRegister(&EthHandle, PHY_Status_REG, (uint32_t *)&SR); + HAL_ETH_ReadPHYRegister(&EthHandle, PHY_Status_REG, (uint32_t *)&SR); LOG_D("phy control status reg is 0x%X", SR); if (PHY_Status_SPEED_100M(SR)) -- Gitee From d2a857e13a97f50559d0b88a983d902f422e2fc9 Mon Sep 17 00:00:00 2001 From: xieyangrun Date: Wed, 15 Jan 2020 13:45:30 +0800 Subject: [PATCH 061/110] [STM32/drv_pwm.c]fixed PWM timer init. --- bsp/stm32/libraries/HAL_Drivers/drv_pwm.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_pwm.c b/bsp/stm32/libraries/HAL_Drivers/drv_pwm.c index 2c2af0dcc0..23efb88df6 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_pwm.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_pwm.c @@ -205,7 +205,7 @@ static rt_err_t drv_pwm_get(TIM_HandleTypeDef *htim, struct rt_pwm_configuration tim_clock = HAL_RCC_GetPCLK1Freq() * 2; #endif } - + if (__HAL_TIM_GET_CLOCKDIVISION(htim) == TIM_CLOCKDIVISION_DIV2) { tim_clock = tim_clock / 2; @@ -323,9 +323,9 @@ static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device) tim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; #endif - if (HAL_TIM_Base_Init(tim) != HAL_OK) + if (HAL_TIM_PWM_Init(tim) != HAL_OK) { - LOG_E("%s time base init failed", device->name); + LOG_E("%s pwm init failed", device->name); result = -RT_ERROR; goto __exit; } @@ -338,13 +338,6 @@ static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device) goto __exit; } - if (HAL_TIM_PWM_Init(tim) != HAL_OK) - { - LOG_E("%s pwm init failed", device->name); - result = -RT_ERROR; - goto __exit; - } - master_config.MasterOutputTrigger = TIM_TRGO_RESET; master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(tim, &master_config) != HAL_OK) @@ -358,6 +351,8 @@ static rt_err_t stm32_hw_pwm_init(struct stm32_pwm *device) oc_config.Pulse = 0; oc_config.OCPolarity = TIM_OCPOLARITY_HIGH; oc_config.OCFastMode = TIM_OCFAST_DISABLE; + oc_config.OCNIdleState = TIM_OCNIDLESTATE_RESET; + oc_config.OCIdleState = TIM_OCIDLESTATE_RESET; /* config pwm channel */ if (device->channel & 0x01) @@ -551,7 +546,6 @@ static int stm32_pwm_init(void) /* register pwm device */ if (rt_device_pwm_register(&stm32_pwm_obj[i].pwm_device, stm32_pwm_obj[i].name, &drv_ops, &stm32_pwm_obj[i].tim_handle) == RT_EOK) { - LOG_D("%s register success", stm32_pwm_obj[i].name); } else -- Gitee From f117df8476f0b5d0e43d6e699da6cad5d1b2e120 Mon Sep 17 00:00:00 2001 From: whj4674672 Date: Wed, 15 Jan 2020 14:29:33 +0800 Subject: [PATCH 062/110] Porting for stm32h7xx spi --- bsp/stm32/libraries/HAL_Drivers/drv_spi.c | 17 +++ bsp/stm32/stm32h743-atk-apollo/README.md | 2 +- .../board/CubeMX_Config/.mxproject | 8 +- .../board/CubeMX_Config/CubeMX_Config.ioc | 115 +++++++++++------- .../CubeMX_Config/Inc/stm32h7xx_hal_conf.h | 4 +- .../board/CubeMX_Config/Src/main.c | 57 ++++++++- .../CubeMX_Config/Src/stm32h7xx_hal_msp.c | 67 ++++++++++ bsp/stm32/stm32h743-atk-apollo/board/Kconfig | 10 ++ bsp/stm32/stm32h743-atk-apollo/board/board.c | 5 +- 9 files changed, 229 insertions(+), 56 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drv_spi.c index 993e4cbc1a..914691d2be 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_spi.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_spi.c @@ -8,6 +8,7 @@ * 2018-11-5 SummerGift first version * 2018-12-11 greedyhao Porting for stm32f7xx * 2019-01-03 zylx modify DMA initialization and spixfer function + * 2020-01-15 whj4674672 Porting for stm32h7xx */ #include "board.h" @@ -147,6 +148,8 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur #if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) SPI_APB_CLOCK = HAL_RCC_GetPCLK1Freq(); +#elif defined(SOC_SERIES_STM32H7) + SPI_APB_CLOCK = HAL_RCC_GetSysClockFreq(); #else SPI_APB_CLOCK = HAL_RCC_GetPCLK2Freq(); #endif @@ -205,6 +208,20 @@ static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configur spi_handle->State = HAL_SPI_STATE_RESET; #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE; +#elif defined(SOC_SERIES_STM32H7) + spi_handle->Init.Mode = SPI_MODE_MASTER; + spi_handle->Init.NSS = SPI_NSS_SOFT; + spi_handle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE; + spi_handle->Init.NSSPolarity = SPI_NSS_POLARITY_LOW; + spi_handle->Init.CRCPolynomial = 7; + spi_handle->Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; + spi_handle->Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; + spi_handle->Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; + spi_handle->Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; + spi_handle->Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; + spi_handle->Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; + spi_handle->Init.IOSwap = SPI_IO_SWAP_DISABLE; + spi_handle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_08DATA; #endif if (HAL_SPI_Init(spi_handle) != HAL_OK) diff --git a/bsp/stm32/stm32h743-atk-apollo/README.md b/bsp/stm32/stm32h743-atk-apollo/README.md index cf813451fa..18240887f8 100644 --- a/bsp/stm32/stm32h743-atk-apollo/README.md +++ b/bsp/stm32/stm32h743-atk-apollo/README.md @@ -51,7 +51,7 @@ | **片上外设** | **支持情况** | **备注** | | GPIO | 支持 | PA0, PA1... PK15 ---> PIN: 0, 1...176 | | UART | 支持 | | -| SPI | 暂不支持 | | +| SPI | 支持 | SPI2 | | I2C | 暂不支持 | | | SDIO | 暂不支持 | | | RTC | 支持 | | diff --git a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/.mxproject index 00d07ece24..5c90788c8c 100644 --- a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/.mxproject +++ b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/.mxproject @@ -1,14 +1,14 @@ [PreviousGenFiles] -HeaderPath=D:/rt_thread/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Inc +HeaderPath=D:/rt_thread_master/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Inc HeaderFiles=stm32h7xx_it.h;stm32h7xx_hal_conf.h;main.h; -SourcePath=D:/rt_thread/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src +SourcePath=D:/rt_thread_master/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src SourceFiles=stm32h7xx_it.c;stm32h7xx_hal_msp.c;main.c; [PreviousLibFiles] -LibFiles=Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma2d.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_fmc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_sdram.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_iwdg.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ltdc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ltdc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dsi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_qspi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rtc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rtc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_mdma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h;Drivers/STM32H7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c_ex.h;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma2d.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sdram.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_iwdg.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dsi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma2d.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_fmc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_sdram.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_iwdg.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ltdc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ltdc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dsi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_qspi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rtc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rtc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_mdma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h;Drivers/STM32H7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c_ex.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h743xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/system_stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; +LibFiles=Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma2d.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_fmc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_sdram.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_iwdg.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ltdc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ltdc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dsi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_qspi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rtc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rtc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_mdma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h;Drivers/STM32H7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_exti.h;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma2d.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sdram.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_iwdg.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dsi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_cortex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma2d.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_fmc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_sdram.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_iwdg.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ltdc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_ltdc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dsi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_qspi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rtc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rtc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_tim_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_uart_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_rcc_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_flash_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_gpio_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_hsem.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_dma_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_mdma.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pwr_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_def.h;Drivers/STM32H7xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_i2c_ex.h;Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_exti.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h743xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Include/system_stm32h7xx.h;Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; [PreviousUsedKeilFiles] -SourceFiles=..\Src\main.c;..\Src\stm32h7xx_it.c;..\Src\stm32h7xx_hal_msp.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma2d.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sdram.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_iwdg.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dsi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;../\Src/system_stm32h7xx.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma2d.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sdram.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_iwdg.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dsi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;../\Src/system_stm32h7xx.c;../Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;null; +SourceFiles=..\Src\main.c;..\Src\stm32h7xx_it.c;..\Src\stm32h7xx_hal_msp.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma2d.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sdram.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_iwdg.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dsi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;../\Src/system_stm32h7xx.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma2d.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sdram.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_iwdg.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ltdc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dsi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rtc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c;../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c;../\Src/system_stm32h7xx.c;../Drivers/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c;null; HeaderPath=..\Drivers\STM32H7xx_HAL_Driver\Inc;..\Drivers\STM32H7xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32H7xx\Include;..\Drivers\CMSIS\Include;..\Inc; CDefines=USE_HAL_DRIVER;STM32H743xx;USE_HAL_DRIVER;STM32H743xx; diff --git a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/CubeMX_Config.ioc index 9008638850..aeab71c0cd 100644 --- a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/CubeMX_Config.ioc +++ b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/CubeMX_Config.ioc @@ -23,8 +23,9 @@ KeepUserPlacement=false Mcu.Family=STM32H7 Mcu.IP0=CORTEX_M7 Mcu.IP1=DEBUG -Mcu.IP10=SYS -Mcu.IP11=USART1 +Mcu.IP10=SPI2 +Mcu.IP11=SYS +Mcu.IP12=USART1 Mcu.IP2=DMA2D Mcu.IP3=FMC Mcu.IP4=IWDG1 @@ -33,7 +34,7 @@ Mcu.IP6=NVIC Mcu.IP7=QUADSPI Mcu.IP8=RCC Mcu.IP9=RTC -Mcu.IPNb=12 +Mcu.IPNb=13 Mcu.Name=STM32H743IITx Mcu.Package=LQFP176 Mcu.Pin0=PC13 @@ -73,53 +74,56 @@ Mcu.Pin39=PH10 Mcu.Pin4=PI10 Mcu.Pin40=PH11 Mcu.Pin41=PH12 -Mcu.Pin42=PD8 -Mcu.Pin43=PD9 -Mcu.Pin44=PD10 -Mcu.Pin45=PD14 -Mcu.Pin46=PD15 -Mcu.Pin47=PG2 -Mcu.Pin48=PG4 -Mcu.Pin49=PG5 +Mcu.Pin42=PB13 +Mcu.Pin43=PB14 +Mcu.Pin44=PB15 +Mcu.Pin45=PD8 +Mcu.Pin46=PD9 +Mcu.Pin47=PD10 +Mcu.Pin48=PD14 +Mcu.Pin49=PD15 Mcu.Pin5=PF0 -Mcu.Pin50=PG6 -Mcu.Pin51=PG7 -Mcu.Pin52=PG8 -Mcu.Pin53=PA9 -Mcu.Pin54=PA10 -Mcu.Pin55=PA13 (JTMS/SWDIO) -Mcu.Pin56=PH13 -Mcu.Pin57=PH14 -Mcu.Pin58=PH15 -Mcu.Pin59=PI0 +Mcu.Pin50=PG2 +Mcu.Pin51=PG4 +Mcu.Pin52=PG5 +Mcu.Pin53=PG6 +Mcu.Pin54=PG7 +Mcu.Pin55=PG8 +Mcu.Pin56=PA9 +Mcu.Pin57=PA10 +Mcu.Pin58=PA13 (JTMS/SWDIO) +Mcu.Pin59=PH13 Mcu.Pin6=PF1 -Mcu.Pin60=PI1 -Mcu.Pin61=PI2 -Mcu.Pin62=PA14 (JTCK/SWCLK) -Mcu.Pin63=PD0 -Mcu.Pin64=PD1 -Mcu.Pin65=PG11 -Mcu.Pin66=PG15 -Mcu.Pin67=PB6 -Mcu.Pin68=PE0 -Mcu.Pin69=PE1 +Mcu.Pin60=PH14 +Mcu.Pin61=PH15 +Mcu.Pin62=PI0 +Mcu.Pin63=PI1 +Mcu.Pin64=PI2 +Mcu.Pin65=PA14 (JTCK/SWCLK) +Mcu.Pin66=PD0 +Mcu.Pin67=PD1 +Mcu.Pin68=PG11 +Mcu.Pin69=PG15 Mcu.Pin7=PF2 -Mcu.Pin70=PI4 -Mcu.Pin71=PI5 -Mcu.Pin72=PI6 -Mcu.Pin73=PI7 -Mcu.Pin74=VP_DMA2D_VS_DMA2D -Mcu.Pin75=VP_IWDG1_VS_IWDG -Mcu.Pin76=VP_RTC_VS_RTC_Activate -Mcu.Pin77=VP_SYS_VS_Systick +Mcu.Pin70=PB6 +Mcu.Pin71=PE0 +Mcu.Pin72=PE1 +Mcu.Pin73=PI4 +Mcu.Pin74=PI5 +Mcu.Pin75=PI6 +Mcu.Pin76=PI7 +Mcu.Pin77=VP_DMA2D_VS_DMA2D +Mcu.Pin78=VP_IWDG1_VS_IWDG +Mcu.Pin79=VP_RTC_VS_RTC_Activate Mcu.Pin8=PF3 +Mcu.Pin80=VP_SYS_VS_Systick Mcu.Pin9=PF4 -Mcu.PinsNb=78 +Mcu.PinsNb=81 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32H743IITx -MxCube.Version=5.2.1 -MxDb.Version=DB.5.0.21 +MxCube.Version=5.3.0 +MxDb.Version=DB.5.0.30 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false @@ -141,6 +145,21 @@ PA14\ (JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK PA9.Locked=true PA9.Mode=Asynchronous PA9.Signal=USART1_TX +PB13.GPIOParameters=GPIO_Speed +PB13.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PB13.Locked=true +PB13.Mode=Full_Duplex_Master +PB13.Signal=SPI2_SCK +PB14.GPIOParameters=GPIO_Speed +PB14.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PB14.Locked=true +PB14.Mode=Full_Duplex_Master +PB14.Signal=SPI2_MISO +PB15.GPIOParameters=GPIO_Speed +PB15.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PB15.Locked=true +PB15.Mode=Full_Duplex_Master +PB15.Signal=SPI2_MOSI PB2.GPIOParameters=GPIO_Speed PB2.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PB2.Mode=Single Bank 1 @@ -288,10 +307,10 @@ ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false ProjectManager.CoupleFile=false ProjectManager.CustomerFirmwarePackage= -ProjectManager.DefaultFWLocation=false +ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32H743IITx -ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.4.0 +ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.5.0 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x200 @@ -308,7 +327,7 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=MDK-ARM V5 ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_FMC_Init-FMC-false-HAL-true,6-MX_DMA2D_Init-DMA2D-false-HAL-true,7-MX_LTDC_Init-LTDC-false-HAL-true,8-MX_RTC_Init-RTC-false-HAL-true,9-MX_IWDG1_Init-IWDG1-false-HAL-true,10-MX_QUADSPI_Init-QUADSPI-false-HAL-true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_FMC_Init-FMC-false-HAL-true,6-MX_DMA2D_Init-DMA2D-false-HAL-true,7-MX_LTDC_Init-LTDC-false-HAL-true,8-MX_RTC_Init-RTC-false-HAL-true,9-MX_IWDG1_Init-IWDG1-false-HAL-true,10-MX_QUADSPI_Init-QUADSPI-false-HAL-true,11-MX_SPI2_Init-SPI2-false-HAL-true RCC.ADCFreq_Value=50390625 RCC.AHB12Freq_Value=200000000 RCC.AHB4Freq_Value=200000000 @@ -466,6 +485,12 @@ SH.FMC_SDNRAS.0=FMC_SDNRAS,13b-sda1 SH.FMC_SDNRAS.ConfNb=1 SH.FMC_SDNWE.0=FMC_SDNWE,13b-sda1 SH.FMC_SDNWE.ConfNb=1 +SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4 +SPI2.CalculateBaudRate=100.0 MBits/s +SPI2.Direction=SPI_DIRECTION_2LINES +SPI2.IPParameters=VirtualType,Mode,Direction,BaudRatePrescaler,CalculateBaudRate +SPI2.Mode=SPI_MODE_MASTER +SPI2.VirtualType=VM_MASTER USART1.IPParameters=VirtualMode-Asynchronous USART1.VirtualMode-Asynchronous=VM_ASYNC VP_DMA2D_VS_DMA2D.Mode=DMA2D_Activate diff --git a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h index 8f082ec91d..39a66f1955 100644 --- a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h +++ b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h @@ -64,7 +64,7 @@ /* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_MMC_MODULE_ENABLED */ /* #define HAL_SPDIFRX_MODULE_ENABLED */ -/* #define HAL_SPI_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED /* #define HAL_SWPMI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED @@ -78,12 +78,12 @@ /* #define HAL_DSI_MODULE_ENABLED */ /* #define HAL_JPEG_MODULE_ENABLED */ /* #define HAL_MDIOS_MODULE_ENABLED */ -/* #define HAL_EXTI_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_MDMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_FLASH_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED #define HAL_PWR_MODULE_ENABLED #define HAL_I2C_MODULE_ENABLED #define HAL_CORTEX_MODULE_ENABLED diff --git a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src/main.c index 897ace06d1..a12215c0ab 100644 --- a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src/main.c @@ -73,6 +73,8 @@ QSPI_HandleTypeDef hqspi; RTC_HandleTypeDef hrtc; +SPI_HandleTypeDef hspi2; + UART_HandleTypeDef huart1; SDRAM_HandleTypeDef hsdram1; @@ -91,6 +93,7 @@ static void MX_LTDC_Init(void); static void MX_RTC_Init(void); static void MX_IWDG1_Init(void); static void MX_QUADSPI_Init(void); +static void MX_SPI2_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -142,6 +145,7 @@ int main(void) MX_RTC_Init(); MX_IWDG1_Init(); MX_QUADSPI_Init(); + MX_SPI2_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -221,8 +225,8 @@ void SystemClock_Config(void) Error_Handler(); } PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_LTDC - |RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_QSPI - |RCC_PERIPHCLK_FMC; + |RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_SPI2 + |RCC_PERIPHCLK_QSPI|RCC_PERIPHCLK_FMC; PeriphClkInitStruct.PLL3.PLL3M = 5; PeriphClkInitStruct.PLL3.PLL3N = 160; PeriphClkInitStruct.PLL3.PLL3P = 2; @@ -233,6 +237,7 @@ void SystemClock_Config(void) PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_D1HCLK; PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK; + PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) @@ -457,6 +462,54 @@ static void MX_RTC_Init(void) } +/** + * @brief SPI2 Initialization Function + * @param None + * @retval None + */ +static void MX_SPI2_Init(void) +{ + + /* USER CODE BEGIN SPI2_Init 0 */ + + /* USER CODE END SPI2_Init 0 */ + + /* USER CODE BEGIN SPI2_Init 1 */ + + /* USER CODE END SPI2_Init 1 */ + /* SPI2 parameter configuration*/ + hspi2.Instance = SPI2; + hspi2.Init.Mode = SPI_MODE_MASTER; + hspi2.Init.Direction = SPI_DIRECTION_2LINES; + hspi2.Init.DataSize = SPI_DATASIZE_4BIT; + hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi2.Init.NSS = SPI_NSS_SOFT; + hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; + hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi2.Init.TIMode = SPI_TIMODE_DISABLE; + hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi2.Init.CRCPolynomial = 0x0; + hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; + hspi2.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; + hspi2.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; + hspi2.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; + hspi2.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; + hspi2.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; + hspi2.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; + hspi2.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; + hspi2.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE; + hspi2.Init.IOSwap = SPI_IO_SWAP_DISABLE; + if (HAL_SPI_Init(&hspi2) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI2_Init 2 */ + + /* USER CODE END SPI2_Init 2 */ + +} + /** * @brief USART1 Initialization Function * @param None diff --git a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src/stm32h7xx_hal_msp.c b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src/stm32h7xx_hal_msp.c index 435f15593b..d33aeaf6ad 100644 --- a/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src/stm32h7xx_hal_msp.c +++ b/bsp/stm32/stm32h743-atk-apollo/board/CubeMX_Config/Src/stm32h7xx_hal_msp.c @@ -418,6 +418,73 @@ void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc) } +/** +* @brief SPI MSP Initialization +* This function configures the hardware resources used in this example +* @param hspi: SPI handle pointer +* @retval None +*/ +void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(hspi->Instance==SPI2) + { + /* USER CODE BEGIN SPI2_MspInit 0 */ + + /* USER CODE END SPI2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI2_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**SPI2 GPIO Configuration + PB13 ------> SPI2_SCK + PB14 ------> SPI2_MISO + PB15 ------> SPI2_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI2_MspInit 1 */ + + /* USER CODE END SPI2_MspInit 1 */ + } + +} + +/** +* @brief SPI MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hspi: SPI handle pointer +* @retval None +*/ +void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) +{ + if(hspi->Instance==SPI2) + { + /* USER CODE BEGIN SPI2_MspDeInit 0 */ + + /* USER CODE END SPI2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI2_CLK_DISABLE(); + + /**SPI2 GPIO Configuration + PB13 ------> SPI2_SCK + PB14 ------> SPI2_MISO + PB15 ------> SPI2_MOSI + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15); + + /* USER CODE BEGIN SPI2_MspDeInit 1 */ + + /* USER CODE END SPI2_MspDeInit 1 */ + } + +} + /** * @brief UART MSP Initialization * This function configures the hardware resources used in this example diff --git a/bsp/stm32/stm32h743-atk-apollo/board/Kconfig b/bsp/stm32/stm32h743-atk-apollo/board/Kconfig index 22e2c7820c..13f950b08b 100644 --- a/bsp/stm32/stm32h743-atk-apollo/board/Kconfig +++ b/bsp/stm32/stm32h743-atk-apollo/board/Kconfig @@ -54,6 +54,16 @@ menu "On-chip Peripheral Drivers" bool default n + menuconfig BSP_USING_SPI + bool "Enable SPI BUS" + default n + select RT_USING_SPI + if BSP_USING_SPI + config BSP_USING_SPI2 + bool "Enable SPI2 BUS" + default n + endif + config BSP_USING_QSPI bool "Enable QSPI BUS" select RT_USING_QSPI diff --git a/bsp/stm32/stm32h743-atk-apollo/board/board.c b/bsp/stm32/stm32h743-atk-apollo/board/board.c index 1180633282..682c2cb832 100644 --- a/bsp/stm32/stm32h743-atk-apollo/board/board.c +++ b/bsp/stm32/stm32h743-atk-apollo/board/board.c @@ -70,8 +70,8 @@ void SystemClock_Config(void) Error_Handler(); } PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_LTDC - |RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_QSPI - |RCC_PERIPHCLK_FMC; + |RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_SPI2 + |RCC_PERIPHCLK_QSPI|RCC_PERIPHCLK_FMC; PeriphClkInitStruct.PLL3.PLL3M = 5; PeriphClkInitStruct.PLL3.PLL3N = 160; PeriphClkInitStruct.PLL3.PLL3P = 2; @@ -82,6 +82,7 @@ void SystemClock_Config(void) PeriphClkInitStruct.PLL3.PLL3FRACN = 0; PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_D1HCLK; PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK; + PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) -- Gitee From 08f55d9fdaf4b680c2ef4956e894187a2608af79 Mon Sep 17 00:00:00 2001 From: bigmagic Date: Wed, 15 Jan 2020 16:38:22 +0800 Subject: [PATCH 063/110] add raspi3-32 in bsp --- bsp/raspberry-pi/raspi3-32/Kconfig | 2 +- libcpu/arm/cortex-a53/SConscript | 9 - libcpu/arm/cortex-a53/armv7.h | 74 ----- libcpu/arm/cortex-a53/context_gcc.S | 183 ----------- libcpu/arm/cortex-a53/cp15_gcc.S | 147 --------- libcpu/arm/cortex-a53/mmu.h | 51 ---- libcpu/arm/cortex-a53/stack.c | 72 ----- libcpu/arm/cortex-a53/start_gcc.S | 459 ---------------------------- libcpu/arm/cortex-a53/trap.c | 219 ------------- libcpu/arm/cortex-a53/vector_gcc.S | 51 ---- libcpu/arm/cortex-a7/SConscript | 9 - libcpu/arm/cortex-a7/armv7.h | 64 ---- libcpu/arm/cortex-a7/context_gcc.S | 105 ------- libcpu/arm/cortex-a7/cp15.h | 12 - libcpu/arm/cortex-a7/cp15_gcc.S | 140 --------- libcpu/arm/cortex-a7/cpu.c | 37 --- libcpu/arm/cortex-a7/interrupt.c | 136 --------- libcpu/arm/cortex-a7/mmu.c | 207 ------------- libcpu/arm/cortex-a7/stack.c | 68 ----- libcpu/arm/cortex-a7/start_gcc.S | 280 ----------------- libcpu/arm/cortex-a7/trap.c | 183 ----------- libcpu/arm/cortex-a7/vector_gcc.S | 65 ---- 22 files changed, 1 insertion(+), 2572 deletions(-) delete mode 100644 libcpu/arm/cortex-a53/SConscript delete mode 100644 libcpu/arm/cortex-a53/armv7.h delete mode 100644 libcpu/arm/cortex-a53/context_gcc.S delete mode 100644 libcpu/arm/cortex-a53/cp15_gcc.S delete mode 100644 libcpu/arm/cortex-a53/mmu.h delete mode 100644 libcpu/arm/cortex-a53/stack.c delete mode 100644 libcpu/arm/cortex-a53/start_gcc.S delete mode 100644 libcpu/arm/cortex-a53/trap.c delete mode 100644 libcpu/arm/cortex-a53/vector_gcc.S delete mode 100644 libcpu/arm/cortex-a7/SConscript delete mode 100644 libcpu/arm/cortex-a7/armv7.h delete mode 100644 libcpu/arm/cortex-a7/context_gcc.S delete mode 100644 libcpu/arm/cortex-a7/cp15.h delete mode 100644 libcpu/arm/cortex-a7/cp15_gcc.S delete mode 100644 libcpu/arm/cortex-a7/cpu.c delete mode 100644 libcpu/arm/cortex-a7/interrupt.c delete mode 100644 libcpu/arm/cortex-a7/mmu.c delete mode 100644 libcpu/arm/cortex-a7/stack.c delete mode 100644 libcpu/arm/cortex-a7/start_gcc.S delete mode 100644 libcpu/arm/cortex-a7/trap.c delete mode 100644 libcpu/arm/cortex-a7/vector_gcc.S diff --git a/bsp/raspberry-pi/raspi3-32/Kconfig b/bsp/raspberry-pi/raspi3-32/Kconfig index 06cbe1128f..f7693c8378 100644 --- a/bsp/raspberry-pi/raspi3-32/Kconfig +++ b/bsp/raspberry-pi/raspi3-32/Kconfig @@ -8,7 +8,7 @@ config BSP_DIR config RTT_DIR string option env="RTT_ROOT" - default "../.." + default "../../.." config PKGS_DIR string diff --git a/libcpu/arm/cortex-a53/SConscript b/libcpu/arm/cortex-a53/SConscript deleted file mode 100644 index eb4ee7a585..0000000000 --- a/libcpu/arm/cortex-a53/SConscript +++ /dev/null @@ -1,9 +0,0 @@ -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') -CPPPATH = [cwd] - -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/libcpu/arm/cortex-a53/armv7.h b/libcpu/arm/cortex-a53/armv7.h deleted file mode 100644 index 859b0371b7..0000000000 --- a/libcpu/arm/cortex-a53/armv7.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2006-2019, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-09-15 Bernard first version - */ - -#ifndef __ARMV7_H__ -#define __ARMV7_H__ - -/* the exception stack without VFP registers */ -struct rt_hw_exp_stack -{ - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long sp; - unsigned long lr; - unsigned long pc; - unsigned long cpsr; -}; - -struct rt_hw_stack -{ - unsigned long cpsr; - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long lr; - unsigned long pc; -}; - -#define USERMODE 0x10 -#define FIQMODE 0x11 -#define IRQMODE 0x12 -#define SVCMODE 0x13 -#define MONITORMODE 0x16 -#define ABORTMODE 0x17 -#define HYPMODE 0x1b -#define UNDEFMODE 0x1b -#define MODEMASK 0x1f -#define NOINT 0xc0 - -#define T_Bit (1<<5) -#define F_Bit (1<<6) -#define I_Bit (1<<7) -#define A_Bit (1<<8) -#define E_Bit (1<<9) -#define J_Bit (1<<24) - -#endif diff --git a/libcpu/arm/cortex-a53/context_gcc.S b/libcpu/arm/cortex-a53/context_gcc.S deleted file mode 100644 index cb95558f7a..0000000000 --- a/libcpu/arm/cortex-a53/context_gcc.S +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2006-2019, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-05 Bernard the first version - * 2019-07-28 zdzn add smp support - */ - -#include "../rtconfig.h" -.section .text, "ax" - -#ifdef RT_USING_SMP -#define rt_hw_interrupt_disable rt_hw_local_irq_disable -#define rt_hw_interrupt_enable rt_hw_local_irq_enable -#endif - -/* - * rt_base_t rt_hw_interrupt_disable(); - */ -.globl rt_hw_interrupt_disable -rt_hw_interrupt_disable: - mrs r0, cpsr - cpsid i - bx lr - -/* - * void rt_hw_interrupt_enable(rt_base_t level); - */ -.globl rt_hw_interrupt_enable -rt_hw_interrupt_enable: - msr cpsr, r0 - bx lr - -/* - * void rt_hw_context_switch_to(rt_uint32 to, struct rt_thread *to_thread); - * r0 --> to (thread stack) - * r1 --> to_thread - */ -.globl rt_hw_context_switch_to -rt_hw_context_switch_to: - ldr sp, [r0] @ get new task stack pointer - -#ifdef RT_USING_SMP - mov r0, r1 - bl rt_cpus_lock_status_restore -#endif /*RT_USING_SMP*/ - b rt_hw_context_switch_exit - -.section .bss.share.isr -_guest_switch_lvl: - .word 0 - -.globl vmm_virq_update - -.section .text.isr, "ax" -/* - * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to, struct rt_thread *to_thread); - * r0 --> from (from_thread stack) - * r1 --> to (to_thread stack) - * r2 --> to_thread - */ -.globl rt_hw_context_switch -rt_hw_context_switch: - stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) - stmfd sp!, {r0-r12, lr} @ push lr & register file - - mrs r4, cpsr - tst lr, #0x01 - orrne r4, r4, #0x20 @ it's thumb code - - stmfd sp!, {r4} @ push cpsr - -#ifdef RT_USING_LWP - stmfd sp, {r13, r14}^ @ push usr_sp usr_lr - sub sp, #8 -#endif -#ifdef RT_USING_FPU - /* fpu context */ - vmrs r6, fpexc - tst r6, #(1<<30) - beq 1f - vstmdb sp!, {d0-d15} - vstmdb sp!, {d16-d31} - vmrs r5, fpscr - stmfd sp!, {r5} -1: - stmfd sp!, {r6} -#endif - - str sp, [r0] @ store sp in preempted tasks TCB - ldr sp, [r1] @ get new task stack pointer - -#ifdef RT_USING_SMP - mov r0, r2 - bl rt_cpus_lock_status_restore -#endif /*RT_USING_SMP*/ - b rt_hw_context_switch_exit - -/* - * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); - */ -.equ Mode_USR, 0x10 -.equ Mode_FIQ, 0x11 -.equ Mode_IRQ, 0x12 -.equ Mode_SVC, 0x13 -.equ Mode_ABT, 0x17 -.equ Mode_UND, 0x1B -.equ Mode_SYS, 0x1F - -.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled -.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled - -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -.globl rt_hw_context_switch_interrupt -rt_hw_context_switch_interrupt: -#ifdef RT_USING_SMP - /* r0 :svc_mod context - * r1 :addr of from_thread's sp - * r2 :addr of to_thread's sp - * r3 :to_thread's tcb - */ - - str r0, [r1] - - ldr sp, [r2] - mov r0, r3 - bl rt_cpus_lock_status_restore - - b rt_hw_context_switch_exit - -#else /*RT_USING_SMP*/ - ldr r2, =rt_thread_switch_interrupt_flag - ldr r3, [r2] - cmp r3, #1 - beq _reswitch - ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread - mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 - str r0, [ip] - str r3, [r2] -_reswitch: - ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread - str r1, [r2] - bx lr -#endif /*RT_USING_SMP*/ - -.global rt_hw_context_switch_exit -rt_hw_context_switch_exit: - -#ifdef RT_USING_SMP -#ifdef RT_USING_SIGNALS - mov r0, sp - cps #Mode_IRQ - bl rt_signal_check - cps #Mode_SVC - mov sp, r0 -#endif -#endif -#ifdef RT_USING_FPU -/* fpu context */ - ldmfd sp!, {r6} - vmsr fpexc, r6 - tst r6, #(1<<30) - beq 1f - ldmfd sp!, {r5} - vmsr fpscr, r5 - vldmia sp!, {d16-d31} - vldmia sp!, {d0-d15} - -#endif - -#ifdef RT_USING_LWP - ldmfd sp, {r13, r14}^ /* usr_sp, usr_lr */ - add sp, #8 -#endif - ldmfd sp!, {r4} - msr spsr_cxsf, r4 /* original mode */ - ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ - diff --git a/libcpu/arm/cortex-a53/cp15_gcc.S b/libcpu/arm/cortex-a53/cp15_gcc.S deleted file mode 100644 index db2e6143ae..0000000000 --- a/libcpu/arm/cortex-a53/cp15_gcc.S +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2006-2019, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-05 Bernard the first version - */ - -.globl rt_cpu_get_smp_id -rt_cpu_get_smp_id: - mrc p15, #0, r0, c0, c0, #5 - bx lr - -.globl rt_cpu_vector_set_base -rt_cpu_vector_set_base: - /* clear SCTRL.V to customize the vector address */ - mrc p15, #0, r1, c1, c0, #0 - bic r1, #(1 << 13) - mcr p15, #0, r1, c1, c0, #0 - /* set up the vector address */ - mcr p15, #0, r0, c12, c0, #0 - dsb - bx lr - -.globl rt_hw_cpu_dcache_enable -rt_hw_cpu_dcache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_hw_cpu_icache_enable -rt_hw_cpu_icache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -_FLD_MAX_WAY: - .word 0x3ff -_FLD_MAX_IDX: - .word 0x7ff - -.globl set_timer_counter -set_timer_counter: - mcr p15, #0, r0, c14, c3, #0 @ write virtual timer timerval register - bx lr -.globl set_timer_control -set_timer_control: - mcr p15, #0, r0, c14, c3, #1 @ write virtual timer control register - bx lr - -.globl rt_cpu_dcache_clean_flush -rt_cpu_dcache_clean_flush: - push {r4-r11} - dmb - mrc p15, #1, r0, c0, c0, #1 @ read clid register - ands r3, r0, #0x7000000 @ get level of coherency - mov r3, r3, lsr #23 - beq finished - mov r10, #0 -loop1: - add r2, r10, r10, lsr #1 - mov r1, r0, lsr r2 - and r1, r1, #7 - cmp r1, #2 - blt skip - mcr p15, #2, r10, c0, c0, #0 - isb - mrc p15, #1, r1, c0, c0, #0 - and r2, r1, #7 - add r2, r2, #4 - ldr r4, _FLD_MAX_WAY - ands r4, r4, r1, lsr #3 - clz r5, r4 - ldr r7, _FLD_MAX_IDX - ands r7, r7, r1, lsr #13 -loop2: - mov r9, r4 -loop3: - orr r11, r10, r9, lsl r5 - orr r11, r11, r7, lsl r2 - mcr p15, #0, r11, c7, c14, #2 - subs r9, r9, #1 - bge loop3 - subs r7, r7, #1 - bge loop2 -skip: - add r10, r10, #2 - cmp r3, r10 - bgt loop1 - -finished: - dsb - isb - pop {r4-r11} - bx lr - -.globl rt_cpu_icache_flush -rt_cpu_icache_flush: - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate - dsb - isb - bx lr - -.globl rt_hw_cpu_dcache_disable -rt_hw_cpu_dcache_disable: - push {r4-r11, lr} - bl rt_cpu_dcache_clean_flush - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - pop {r4-r11, lr} - bx lr - -.globl rt_hw_cpu_icache_disable -rt_hw_cpu_icache_disable: - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_cpu_mmu_disable -rt_cpu_mmu_disable: - mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #1 - mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit - dsb - bx lr - -.globl rt_cpu_mmu_enable -rt_cpu_mmu_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x001 - mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit - dsb - bx lr - -.globl rt_cpu_tlb_set -rt_cpu_tlb_set: - mcr p15, #0, r0, c2, c0, #0 - dmb - bx lr diff --git a/libcpu/arm/cortex-a53/mmu.h b/libcpu/arm/cortex-a53/mmu.h deleted file mode 100644 index 6b0c25e990..0000000000 --- a/libcpu/arm/cortex-a53/mmu.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef MMU_H__ -#define MMU_H__ -#include -#include -#include -#include "cp15.h" - -#define DESC_SEC (0x2) -#define CB (3 << 2) //cache_on, write_back -#define CNB (2 << 2) //cache_on, write_through -#define NCB (1 << 2) //cache_off,WR_BUF on -#define NCNB (0 << 2) //cache_off,WR_BUF off -#define AP_RW (3 << 10) //supervisor=RW, user=RW -#define AP_RO (2 << 10) //supervisor=RW, user=RO -#define XN (1 << 4) // eXecute Never -#define SHARED (1 << 16) /* shareable */ -#define SHAREDEVICE (1 << 2) /* shared device */ -#define STRONGORDER (0 << 2) /* strong ordered */ -#define MEMWBWA ((1 << 12) | (3 << 2)) /* write back, write allocate */ - -#define DOMAIN_FAULT (0x0) -#define DOMAIN_CHK (0x1) -#define DOMAIN_NOTCHK (0x3) -#define DOMAIN0 (0x0 << 5) -#define DOMAIN1 (0x1 << 5) - -#define DOMAIN0_ATTR (DOMAIN_CHK << 0) -#define DOMAIN1_ATTR (DOMAIN_FAULT << 2) - -/* Read/Write, cache, write back */ -#define RW_CB (AP_RW | DOMAIN0 | CB | DESC_SEC) -/* Read/Write, cache, write through */ -#define RW_CNB (AP_RW | DOMAIN0 | CNB | DESC_SEC) -/* Read/Write without cache and write buffer */ -#define RW_NCNB (AP_RW | DOMAIN0 | NCNB | DESC_SEC) -/* Read/Write without cache and write buffer, no execute */ -#define RW_NCNBXN (AP_RW | DOMAIN0 | NCNB | DESC_SEC | XN) -/* Read/Write without cache and write buffer */ -#define RW_FAULT (AP_RW | DOMAIN1 | NCNB | DESC_SEC) - -/* device mapping type */ -#define DEVICE_MEM (SHARED | SHAREDEVICE | RW_NCNBXN) -/* normal memory mapping type */ -#define NORMAL_MEM (SHARED | AP_RW | DOMAIN0 | MEMWBWA | DESC_SEC) -#define STRONG_ORDER_MEM (SHARED | AP_RO | XN | DESC_SEC) -#define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000) - -void rt_hw_change_mmu_table(rt_uint32_t vaddrStart, - rt_uint32_t size, - rt_uint32_t paddrStart, rt_uint32_t attr); -#endif diff --git a/libcpu/arm/cortex-a53/stack.c b/libcpu/arm/cortex-a53/stack.c deleted file mode 100644 index c2c60fbf49..0000000000 --- a/libcpu/arm/cortex-a53/stack.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2006-2019, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-09-23 Bernard the first version - * 2011-10-05 Bernard add thumb mode - */ -#include -#include -#include - -/** - * @addtogroup AM33xx - */ -/*@{*/ - -/** - * This function will initialize thread stack - * - * @param tentry the entry of thread - * @param parameter the parameter of entry - * @param stack_addr the beginning stack address - * @param texit the function will be called when thread exit - * - * @return stack address - */ -rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, - rt_uint8_t *stack_addr, void *texit) -{ - rt_uint32_t *stk; - - stack_addr += sizeof(rt_uint32_t); - stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); - stk = (rt_uint32_t *)stack_addr; - *(--stk) = (rt_uint32_t)tentry; /* entry point */ - *(--stk) = (rt_uint32_t)texit; /* lr */ - *(--stk) = 0xdeadbeef; /* r12 */ - *(--stk) = 0xdeadbeef; /* r11 */ - *(--stk) = 0xdeadbeef; /* r10 */ - *(--stk) = 0xdeadbeef; /* r9 */ - *(--stk) = 0xdeadbeef; /* r8 */ - *(--stk) = 0xdeadbeef; /* r7 */ - *(--stk) = 0xdeadbeef; /* r6 */ - *(--stk) = 0xdeadbeef; /* r5 */ - *(--stk) = 0xdeadbeef; /* r4 */ - *(--stk) = 0xdeadbeef; /* r3 */ - *(--stk) = 0xdeadbeef; /* r2 */ - *(--stk) = 0xdeadbeef; /* r1 */ - *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - - /* cpsr */ - if ((rt_uint32_t)tentry & 0x01) - *(--stk) = SVCMODE | 0x20; /* thumb mode */ - else - *(--stk) = SVCMODE; /* arm mode */ - -#ifdef RT_USING_LWP - *(--stk) = 0; /* user lr */ - *(--stk) = 0; /* user sp*/ -#endif -#ifdef RT_USING_FPU - *(--stk) = 0; /* not use fpu*/ -#endif - - /* return task's current stack address */ - return (rt_uint8_t *)stk; -} - -/*@}*/ diff --git a/libcpu/arm/cortex-a53/start_gcc.S b/libcpu/arm/cortex-a53/start_gcc.S deleted file mode 100644 index ec74213f07..0000000000 --- a/libcpu/arm/cortex-a53/start_gcc.S +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2006-2019, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-05 Bernard the first version - * 2019-07-28 zdzn add smp support - */ - -#include "../rtconfig.h" -.equ Mode_USR, 0x10 -.equ Mode_FIQ, 0x11 -.equ Mode_IRQ, 0x12 -.equ Mode_SVC, 0x13 -.equ Mode_ABT, 0x17 -.equ Mode_UND, 0x1B -.equ Mode_SYS, 0x1F - -.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled -.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled - -#ifdef RT_USING_FPU -.equ UND_Stack_Size, 0x00000400 -#else -.equ UND_Stack_Size, 0x00000000 -#endif -.equ SVC_Stack_Size, 0x00000400 -.equ ABT_Stack_Size, 0x00000000 -.equ RT_FIQ_STACK_PGSZ, 0x00000000 -.equ RT_IRQ_STACK_PGSZ, 0x00000800 -.equ USR_Stack_Size, 0x00000400 - -#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ - RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) - -.section .data.share.isr -/* stack */ - -#ifdef RT_USING_SMP -.globl stack_start0 -.globl stack_top0 -.globl stack_start1 -.globl stack_top1 -.globl stack_start2 -.globl stack_top2 -.globl stack_start3 -.globl stack_top3 -stack_start0: -.rept ISR_Stack_Size -.byte 0 -.endr -stack_top0: - -stack_start1: -.rept ISR_Stack_Size -.byte 0 -.endr -stack_top1: - -stack_start2: -.rept ISR_Stack_Size -.byte 0 -.endr -stack_top2: - -stack_start3: -.rept ISR_Stack_Size -.byte 0 -.endr -stack_top3: - -.globl boot_indicate -boot_indicate: -.rept 16 -.byte 0 -.endr - -#else -.globl stack_start -.globl stack_top -stack_start: -.rept ISR_Stack_Size -.byte 0 -.endr -stack_top: -#endif - - -.text -/* reset entry */ -.globl _reset -_reset: - - /* Disable IRQ & FIQ */ - cpsid if - - /* Check for HYP mode */ - mrs r0, cpsr_all - and r0, r0, #0x1F - mov r8, #0x1A - cmp r0, r8 - beq overHyped - b continue - -overHyped: /* Get out of HYP mode */ - ldr r1, =continue - msr ELR_hyp, r1 - mrs r1, cpsr_all - and r1, r1, #0x1f ;@ CPSR_MODE_MASK - orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR - msr SPSR_hyp, r1 - eret - -continue: - - /* disable mmu */ - bl rt_cpu_mmu_disable - /* set the cpu to SVC32 mode and disable interrupt */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0x13 - msr cpsr_c, r0 -#ifdef RT_USING_SMP - mrc p15, 0, r0, c0, c0, 5 - ubfx r0, r0, #0, #2 - cmp r0, #0 - beq 1f - /* write boot indicate */ - ldr r5, = boot_indicate - str r0, [r5, r0, lsl #2] - bl secondary_cpu_start - b . -1: -#endif - /* setup stack */ -#ifdef RT_USING_SMP - ldr r0, =stack_top0 -#else - ldr r0, =stack_top -#endif - bl stack_setup - - /* clear .bss */ - mov r0,#0 /* get a zero */ - ldr r1,=__bss_start /* bss start */ - ldr r2,=__bss_end /* bss end */ - -bss_loop: - cmp r1,r2 /* check if data to clear */ - strlo r0,[r1],#4 /* clear 4 bytes */ - blo bss_loop /* loop until done */ - bl rt_hw_init_mmu_table - bl init_mbox_mmu_map - bl rt_hw_mmu_init - - /* start RT-Thread Kernel */ - ldr pc, _rtthread_startup -_rtthread_startup: - .word rtthread_startup - -stack_setup: - - @ Set the startup stack for svc - mov sp, r0 - - @ Enter Undefined Instruction Mode and set its Stack Pointer - msr cpsr_c, #Mode_UND|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #UND_Stack_Size - - @ Enter Abort Mode and set its Stack Pointer - msr cpsr_c, #Mode_ABT|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #ABT_Stack_Size - - @ Enter FIQ Mode and set its Stack Pointer - msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #RT_FIQ_STACK_PGSZ - - @ Enter IRQ Mode and set its Stack Pointer - msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #RT_IRQ_STACK_PGSZ - - /* come back to SVC mode */ - msr cpsr_c, #Mode_SVC|I_Bit|F_Bit - bx lr - -.text - -/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ -.section .text.isr, "ax" - .align 5 -.globl vector_fiq -vector_fiq: - stmfd sp!,{r0-r7,lr} - bl rt_hw_trap_fiq - ldmfd sp!,{r0-r7,lr} - subs pc, lr, #4 - -.globl rt_interrupt_enter -.globl rt_interrupt_leave -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread - -.globl rt_current_thread -.globl vmm_thread -.globl vmm_virq_check - - .align 5 -.globl vector_irq -vector_irq: -#ifdef RT_USING_SMP - clrex - - stmfd sp!, {r0, r1} - cps #Mode_SVC - mov r0, sp /* svc_sp */ - mov r1, lr /* svc_lr */ - - cps #Mode_IRQ - sub lr, lr, #4 - stmfd r0!, {r1, lr} /* svc_lr, svc_pc */ - stmfd r0!, {r2 - r12} - ldmfd sp!, {r1, r2} /* original r0, r1 */ - stmfd r0!, {r1 - r2} - mrs r1, spsr /* original mode */ - stmfd r0!, {r1} - -#ifdef RT_USING_LWP - stmfd r0, {r13, r14}^ /* usr_sp, usr_lr */ - sub r0, #8 -#endif -#ifdef RT_USING_FPU - /* fpu context */ - vmrs r6, fpexc - tst r6, #(1<<30) - beq 1f - vstmdb r0!, {d0-d15} - vstmdb r0!, {d16-d31} - vmrs r5, fpscr - stmfd r0!, {r5} -1: - stmfd r0!, {r6} -#endif - mov r8, r0 - - bl rt_interrupt_enter - bl rt_hw_trap_irq - bl rt_interrupt_leave - - cps #Mode_SVC - mov sp, r8 - mov r0, r8 - - bl rt_scheduler_do_irq_switch - - b rt_hw_context_switch_exit - -#else - stmfd sp!, {r0-r12,lr} - - bl rt_interrupt_enter - bl rt_hw_trap_irq - bl rt_interrupt_leave - - @ if rt_thread_switch_interrupt_flag set, jump to - @ rt_hw_context_switch_interrupt_do and don't return - ldr r0, =rt_thread_switch_interrupt_flag - ldr r1, [r0] - cmp r1, #1 - beq rt_hw_context_switch_interrupt_do - - ldmfd sp!, {r0-r12,lr} - subs pc, lr, #4 - -rt_hw_context_switch_interrupt_do: - mov r1, #0 @ clear flag - str r1, [r0] - - mov r1, sp @ r1 point to {r0-r3} in stack - add sp, sp, #4*4 - ldmfd sp!, {r4-r12,lr}@ reload saved registers - mrs r0, spsr @ get cpsr of interrupt thread - sub r2, lr, #4 @ save old task's pc to r2 - - @ Switch to SVC mode with no interrupt. If the usr mode guest is - @ interrupted, this will just switch to the stack of kernel space. - @ save the registers in kernel space won't trigger data abort. - msr cpsr_c, #I_Bit|F_Bit|Mode_SVC - - stmfd sp!, {r2} @ push old task's pc - stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 - ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread - stmfd sp!, {r1-r4} @ push old task's r0-r3 - stmfd sp!, {r0} @ push old task's cpsr - -#ifdef RT_USING_LWP - stmfd sp, {r13, r14}^ @push usr_sp, usr_lr - sub sp, #8 -#endif -#ifdef RT_USING_FPU - /* fpu context */ - vmrs r6, fpexc - tst r6, #(1<<30) - beq 1f - vstmdb sp!, {d0-d15} - vstmdb sp!, {d16-d31} - vmrs r5, fpscr - stmfd sp!, {r5} -1: - stmfd sp!, {r6} -#endif - - ldr r4, =rt_interrupt_from_thread - ldr r5, [r4] - str sp, [r5] @ store sp in preempted tasks's TCB - - ldr r6, =rt_interrupt_to_thread - ldr r6, [r6] - ldr sp, [r6] @ get new task's stack pointer - -#ifdef RT_USING_FPU -/* fpu context */ - ldmfd sp!, {r6} - vmsr fpexc, r6 - tst r6, #(1<<30) - beq 1f - ldmfd sp!, {r5} - vmsr fpscr, r5 - vldmia sp!, {d16-d31} - vldmia sp!, {d0-d15} -1: -#endif - -#ifdef RT_USING_LWP - ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr - add sp, #8 -#endif - - ldmfd sp!, {r4} @ pop new task's cpsr to spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr - -#endif - -.macro push_svc_reg - sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ - stmia sp, {r0 - r12} @/* Calling r0-r12 */ - mov r0, sp - mrs r6, spsr @/* Save CPSR */ - str lr, [r0, #15*4] @/* Push PC */ - str r6, [r0, #16*4] @/* Push CPSR */ - cps #Mode_SVC - str sp, [r0, #13*4] @/* Save calling SP */ - str lr, [r0, #14*4] @/* Save calling PC */ -.endm - - .align 5 - .globl vector_swi -vector_swi: - push_svc_reg - bl rt_hw_trap_swi - b . - - .align 5 - .globl vector_undef -vector_undef: - push_svc_reg - cps #Mode_UND - bl rt_hw_trap_undef -#ifdef RT_USING_FPU - ldr lr, [sp, #15*4] - ldmia sp, {r0 - r12} - add sp, sp, #17 * 4 - movs pc, lr -#endif - b . - - .align 5 - .globl vector_pabt -vector_pabt: - push_svc_reg - bl rt_hw_trap_pabt - b . - - .align 5 - .globl vector_dabt -vector_dabt: - push_svc_reg - bl rt_hw_trap_dabt - b . - - .align 5 - .globl vector_resv -vector_resv: - push_svc_reg - bl rt_hw_trap_resv - b . - -#ifdef RT_USING_SMP - -.global secondary_cpu_start -secondary_cpu_start: - /* set vector base */ - mrc p15, 0, r0, c1, c0, 0 - bic r0, #(1<<13) - mcr p15, 0, r0, c1, c0, 0 - - /* setup stack */ - mrc p15, 0, r0, c0, c0, 5 - ubfx r0, r0, #0, #2 - ldr r1, =stack_top0 - ldr r2, =ISR_Stack_Size - mul r3, r2, r0 - add r0, r1, r3 - bl stack_setup - /* initialize the mmu table and enable mmu */ - bl rt_hw_mmu_init - b secondary_cpu_c_start - -#endif - -;@ void arm_smp_enable(void); -.globl arm_smp_enable -arm_smp_enable: - mrc p15, 0, r0, c1, c0, 1 ;@ set SMP bit in ACTLR - orr r0, r0, #0x40 - mcr p15, 0, r0, c1, c0, 1 - bx lr -/* - mrrc p15, 1, r0, r1, c15 - orr r0, r0, #0x40 - mcrr p15, 1, r0, r1, c15 - dsb - isb - bx lr -*/ -.text -;@ void arm_smp_disable(void); -.globl arm_smp_disable - -arm_smp_disable: - mrc p15, 0, r0, c1, c0, 1 ;@ clear SMP bit in ACTLR - bic r0, r0, #0x40 - mcr p15, 0, r0, c1, c0, 1 - bx lr -/* - mrrc p15, 1, r0, r1, c15 - bic r0, r0, #0x40 - mcrr p15, 1, r0, r1, c15 - bx lr -*/ - diff --git a/libcpu/arm/cortex-a53/trap.c b/libcpu/arm/cortex-a53/trap.c deleted file mode 100644 index f83f183695..0000000000 --- a/libcpu/arm/cortex-a53/trap.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2006-2019, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - * 2019-07-28 zdzn add smp support - * 2019-08-09 zhangjun fixup the problem of smp startup and scheduling issues, - * write addr to mailbox3 to startup smp, and we use mailbox0 for ipi - */ - -#include -#include -#include - -#include "armv7.h" - -extern struct rt_thread *rt_current_thread; -#ifdef RT_USING_FINSH -extern long list_thread(void); -#endif - - -/** - * this function will show registers of CPU - * - * @param regs the registers point - */ -void rt_hw_show_register(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("Execption:\n"); - rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); - rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); - rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); - rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); - rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); - rt_kprintf("cpsr:0x%08x\n", regs->cpsr); -} - - -/** - * When comes across an instruction which it cannot handle, - * it takes the undefined instruction trap. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("undefined instruction:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * The software interrupt instruction (SWI) is used for entering - * Supervisor mode, usually to request a particular supervisor - * function. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("software interrupt:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during an instruction prefetch. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("prefetch abort:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during a data access. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("data abort:"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * Normally, system will never reach here - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("reserved trap:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -void rt_hw_trap_irq(void) -{ - void *param; - uint32_t irq; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - uint32_t value = 0; - value = IRQ_PEND_BASIC & 0x3ff; -#ifdef RT_USING_SMP - uint32_t mailbox_data; - uint32_t cpu_id = rt_hw_cpu_id(); - uint32_t int_source = CORE_IRQSOURCE(cpu_id); - mailbox_data = IPI_MAILBOX_CLEAR(cpu_id); - if (int_source & 0x0f) - { - if (int_source & 0x08) - { - isr_func = isr_table[IRQ_ARM_TIMER].handler; -#ifdef RT_USING_INTERRUPT_INFO - isr_table[IRQ_ARM_TIMER].counter++; -#endif - if (isr_func) - { - param = isr_table[IRQ_ARM_TIMER].param; - isr_func(IRQ_ARM_TIMER, param); - } - } - } - if (int_source & 0xf0) - { - /*it's a ipi interrupt*/ - if (mailbox_data & 0x1) - { - /* clear mailbox */ - IPI_MAILBOX_CLEAR(cpu_id) = mailbox_data; - isr_func = isr_table[IRQ_ARM_MAILBOX].handler; -#ifdef RT_USING_INTERRUPT_INFO - isr_table[IRQ_ARM_MAILBOX].counter++; -#endif - if (isr_func) - { - param = isr_table[IRQ_ARM_MAILBOX].param; - isr_func(IRQ_ARM_MAILBOX, param); - } - } - else - CORE_MAILBOX3_CLEAR(cpu_id) = mailbox_data; - } -#endif - /* local interrupt*/ - if (value) - { - if (value & (1 << 8)) - { - value = IRQ_PEND1; - irq = __rt_ffs(value) - 1; - } - else if (value & (1 << 9)) - { - value = IRQ_PEND2; - irq = __rt_ffs(value) + 31; - } - else - { - value &= 0x0f; - irq = __rt_ffs(value) + 63; - } - - /* get interrupt service routine */ - isr_func = isr_table[irq].handler; -#ifdef RT_USING_INTERRUPT_INFO - isr_table[irq].counter++; -#endif - if (isr_func) - { - /* Interrupt for myself. */ - param = isr_table[irq].param; - /* turn to interrupt service routine */ - isr_func(irq, param); - } - } -} - -void rt_hw_trap_fiq(void) -{ - -} diff --git a/libcpu/arm/cortex-a53/vector_gcc.S b/libcpu/arm/cortex-a53/vector_gcc.S deleted file mode 100644 index eebfe9c13b..0000000000 --- a/libcpu/arm/cortex-a53/vector_gcc.S +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2006-2019, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2013-07-05 Bernard the first version - */ - -.section .vectors, "ax" -.code 32 - -.globl system_vectors -system_vectors: - ldr pc, _vector_reset - ldr pc, _vector_undef - ldr pc, _vector_swi - ldr pc, _vector_pabt - ldr pc, _vector_dabt - ldr pc, _vector_resv - ldr pc, _vector_irq - ldr pc, _vector_fiq - -.globl _reset -.globl vector_undef -.globl vector_swi -.globl vector_pabt -.globl vector_dabt -.globl vector_resv -.globl vector_irq -.globl vector_fiq - -_vector_reset: - .word _reset -_vector_undef: - .word vector_undef -_vector_swi: - .word vector_swi -_vector_pabt: - .word vector_pabt -_vector_dabt: - .word vector_dabt -_vector_resv: - .word vector_resv -_vector_irq: - .word vector_irq -_vector_fiq: - .word vector_fiq - -.balignl 16,0xdeadbeef diff --git a/libcpu/arm/cortex-a7/SConscript b/libcpu/arm/cortex-a7/SConscript deleted file mode 100644 index eb4ee7a585..0000000000 --- a/libcpu/arm/cortex-a7/SConscript +++ /dev/null @@ -1,9 +0,0 @@ -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') -CPPPATH = [cwd] - -group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/libcpu/arm/cortex-a7/armv7.h b/libcpu/arm/cortex-a7/armv7.h deleted file mode 100644 index a07d9de2a9..0000000000 --- a/libcpu/arm/cortex-a7/armv7.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef __ARMV7_H__ -#define __ARMV7_H__ - -/* the exception stack without VFP registers */ -struct rt_hw_exp_stack -{ - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long sp; - unsigned long lr; - unsigned long pc; - unsigned long cpsr; -}; - -struct rt_hw_stack -{ - unsigned long cpsr; - unsigned long r0; - unsigned long r1; - unsigned long r2; - unsigned long r3; - unsigned long r4; - unsigned long r5; - unsigned long r6; - unsigned long r7; - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long fp; - unsigned long ip; - unsigned long lr; - unsigned long pc; -}; - -#define USERMODE 0x10 -#define FIQMODE 0x11 -#define IRQMODE 0x12 -#define SVCMODE 0x13 -#define MONITORMODE 0x16 -#define ABORTMODE 0x17 -#define HYPMODE 0x1b -#define UNDEFMODE 0x1b -#define MODEMASK 0x1f -#define NOINT 0xc0 - -#define T_Bit (1<<5) -#define F_Bit (1<<6) -#define I_Bit (1<<7) -#define A_Bit (1<<8) -#define E_Bit (1<<9) -#define J_Bit (1<<24) - -#endif diff --git a/libcpu/arm/cortex-a7/context_gcc.S b/libcpu/arm/cortex-a7/context_gcc.S deleted file mode 100644 index 48402739f9..0000000000 --- a/libcpu/arm/cortex-a7/context_gcc.S +++ /dev/null @@ -1,105 +0,0 @@ -/* - * File : context.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Development Team - * - * 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; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2013-07-05 Bernard the first version - */ - -.section .text, "ax" -/* - * rt_base_t rt_hw_interrupt_disable(); - */ -.globl rt_hw_interrupt_disable -rt_hw_interrupt_disable: - mrs r0, cpsr - cpsid i - bx lr - -/* - * void rt_hw_interrupt_enable(rt_base_t level); - */ -.globl rt_hw_interrupt_enable -rt_hw_interrupt_enable: - msr cpsr_c, r0 - bx lr - -/* - * void rt_hw_context_switch_to(rt_uint32 to); - * r0 --> to - */ -.globl rt_hw_context_switch_to -rt_hw_context_switch_to: - ldr sp, [r0] @ get new task stack pointer - - ldmfd sp!, {r4} @ pop new task spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc - -.section .bss.share.isr -_guest_switch_lvl: - .word 0 - -.globl vmm_virq_update - -.section .text.isr, "ax" -/* - * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); - * r0 --> from - * r1 --> to - */ -.globl rt_hw_context_switch -rt_hw_context_switch: - stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) - stmfd sp!, {r0-r12, lr} @ push lr & register file - - mrs r4, cpsr - tst lr, #0x01 - orrne r4, r4, #0x20 @ it's thumb code - - stmfd sp!, {r4} @ push cpsr - - str sp, [r0] @ store sp in preempted tasks TCB - ldr sp, [r1] @ get new task stack pointer - - ldmfd sp!, {r4} @ pop new task cpsr to spsr - msr spsr_cxsf, r4 - ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr - -/* - * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); - */ -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -.globl rt_hw_context_switch_interrupt -rt_hw_context_switch_interrupt: - ldr r2, =rt_thread_switch_interrupt_flag - ldr r3, [r2] - cmp r3, #1 - beq _reswitch - ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread - mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 - str r0, [ip] - str r3, [r2] -_reswitch: - ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread - str r1, [r2] - bx lr diff --git a/libcpu/arm/cortex-a7/cp15.h b/libcpu/arm/cortex-a7/cp15.h deleted file mode 100644 index ebea3f0fe3..0000000000 --- a/libcpu/arm/cortex-a7/cp15.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __CP15_H__ -#define __CP15_H__ - -unsigned long rt_cpu_get_smp_id(void); - -void rt_cpu_mmu_disable(void); -void rt_cpu_mmu_enable(void); -void rt_cpu_tlb_set(volatile unsigned long*); - -void rt_cpu_vector_set_base(unsigned int addr); - -#endif diff --git a/libcpu/arm/cortex-a7/cp15_gcc.S b/libcpu/arm/cortex-a7/cp15_gcc.S deleted file mode 100644 index f1ed6492aa..0000000000 --- a/libcpu/arm/cortex-a7/cp15_gcc.S +++ /dev/null @@ -1,140 +0,0 @@ -/* - * File : cp15_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Development Team - * http://www.rt-thread.org - * - * 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; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2013-07-05 Bernard the first version - */ - -.globl rt_cpu_get_smp_id -rt_cpu_get_smp_id: - mrc p15, #0, r0, c0, c0, #5 - bx lr - -.globl rt_cpu_vector_set_base -rt_cpu_vector_set_base: - mcr p15, #0, r0, c12, c0, #0 - dsb - bx lr - -.globl rt_hw_cpu_dcache_enable -rt_hw_cpu_dcache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_hw_cpu_icache_enable -rt_hw_cpu_icache_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -_FLD_MAX_WAY: - .word 0x3ff -_FLD_MAX_IDX: - .word 0x7ff - -.globl rt_cpu_dcache_clean_flush -rt_cpu_dcache_clean_flush: - push {r4-r11} - dmb - mrc p15, #1, r0, c0, c0, #1 @ read clid register - ands r3, r0, #0x7000000 @ get level of coherency - mov r3, r3, lsr #23 - beq finished - mov r10, #0 -loop1: - add r2, r10, r10, lsr #1 - mov r1, r0, lsr r2 - and r1, r1, #7 - cmp r1, #2 - blt skip - mcr p15, #2, r10, c0, c0, #0 - isb - mrc p15, #1, r1, c0, c0, #0 - and r2, r1, #7 - add r2, r2, #4 - ldr r4, _FLD_MAX_WAY - ands r4, r4, r1, lsr #3 - clz r5, r4 - ldr r7, _FLD_MAX_IDX - ands r7, r7, r1, lsr #13 -loop2: - mov r9, r4 -loop3: - orr r11, r10, r9, lsl r5 - orr r11, r11, r7, lsl r2 - mcr p15, #0, r11, c7, c14, #2 - subs r9, r9, #1 - bge loop3 - subs r7, r7, #1 - bge loop2 -skip: - add r10, r10, #2 - cmp r3, r10 - bgt loop1 - -finished: - dsb - isb - pop {r4-r11} - bx lr - -.globl rt_hw_cpu_dcache_disable -rt_hw_cpu_dcache_disable: - push {r4-r11, lr} - bl rt_cpu_dcache_clean_flush - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00000004 - mcr p15, #0, r0, c1, c0, #0 - pop {r4-r11, lr} - bx lr - -.globl rt_hw_cpu_icache_disable -rt_hw_cpu_icache_disable: - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #0x00001000 - mcr p15, #0, r0, c1, c0, #0 - bx lr - -.globl rt_cpu_mmu_disable -rt_cpu_mmu_disable: - mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb - mrc p15, #0, r0, c1, c0, #0 - bic r0, r0, #1 - mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit - dsb - bx lr - -.globl rt_cpu_mmu_enable -rt_cpu_mmu_enable: - mrc p15, #0, r0, c1, c0, #0 - orr r0, r0, #0x001 - mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit - dsb - bx lr - -.globl rt_cpu_tlb_set -rt_cpu_tlb_set: - mcr p15, #0, r0, c2, c0, #0 - dmb - bx lr diff --git a/libcpu/arm/cortex-a7/cpu.c b/libcpu/arm/cortex-a7/cpu.c deleted file mode 100644 index 8bf16d19e8..0000000000 --- a/libcpu/arm/cortex-a7/cpu.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * File : cpu.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Develop Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2011-09-15 Bernard first version - */ - -#include -#include -#include - -/** - * @addtogroup AM33xx - */ -/*@{*/ - -/** shutdown CPU */ -void rt_hw_cpu_shutdown() -{ - rt_uint32_t level; - rt_kprintf("shutdown...\n"); - - level = rt_hw_interrupt_disable(); - while (level) - { - RT_ASSERT(0); - } -} - -/*@}*/ diff --git a/libcpu/arm/cortex-a7/interrupt.c b/libcpu/arm/cortex-a7/interrupt.c deleted file mode 100644 index d502977c3e..0000000000 --- a/libcpu/arm/cortex-a7/interrupt.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * File : interrupt.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013-2014, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2018/5/3 Bernard first version - */ - -#include -#include - -#include "cp15.h" -#include - -#define MAX_HANDLERS 64 - -extern volatile rt_uint8_t rt_interrupt_nest; - -/* exception and interrupt handler table */ -struct rt_irq_desc isr_table[MAX_HANDLERS]; - -rt_uint32_t rt_interrupt_from_thread; -rt_uint32_t rt_interrupt_to_thread; -rt_uint32_t rt_thread_switch_interrupt_flag; - -extern int system_vectors; - -static void default_isr_handler(int vector, void *param) -{ - rt_kprintf("unhandled irq: %d\n", vector); -} - -/** - * This function will initialize hardware interrupt - */ -void rt_hw_interrupt_init(void) -{ - uint32_t index; - - /* mask all of interrupts */ - IRQ_DISABLE_BASIC = 0x000000ff; - IRQ_DISABLE1 = 0xffffffff; - IRQ_DISABLE2 = 0xffffffff; - - for (index = 0; index < MAX_HANDLERS; index ++) - { - isr_table[index].handler = default_isr_handler; - isr_table[index].param = NULL; -#ifdef RT_USING_INTERRUPT_INFO - rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX); - isr_table[index].counter = 0; -#endif - } - - /* init interrupt nest, and context in thread sp */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; -} - -/** - * This function will mask a interrupt. - * @param vector the interrupt number - */ -void rt_hw_interrupt_mask(int vector) -{ - if (vector < 8) - { - IRQ_DISABLE_BASIC = (1 << vector); - } - else if (vector < 32) - { - IRQ_DISABLE1 = (1 << vector); - } - else - { - vector = vector % 32; - IRQ_DISABLE2 = (1 << vector); - } -} - -/** - * This function will un-mask a interrupt. - * @param vector the interrupt number - */ -void rt_hw_interrupt_umask(int vector) -{ - if (vector < 8) - { - IRQ_ENABLE_BASIC = (1 << vector); - } - else if (vector < 32) - { - IRQ_ENABLE1 = (1 << vector); - } - else - { - vector = vector % 32; - IRQ_ENABLE2 = (1 << vector); - } -} - -/** - * This function will install a interrupt service routine to a interrupt. - * @param vector the interrupt number - * @param new_handler the interrupt service routine to be installed - * @param old_handler the old interrupt service routine - */ -rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, - void *param, const char *name) -{ - rt_isr_handler_t old_handler = RT_NULL; - - if (vector < MAX_HANDLERS) - { - old_handler = isr_table[vector].handler; - - if (handler != RT_NULL) - { -#ifdef RT_USING_INTERRUPT_INFO - rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); -#endif /* RT_USING_INTERRUPT_INFO */ - isr_table[vector].handler = handler; - isr_table[vector].param = param; - } - } - - return old_handler; -} diff --git a/libcpu/arm/cortex-a7/mmu.c b/libcpu/arm/cortex-a7/mmu.c deleted file mode 100644 index b2503e4260..0000000000 --- a/libcpu/arm/cortex-a7/mmu.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * File : mmu.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2012-01-10 bernard porting to AM1808 - */ - -#include -#include -#include - -#include "cp15.h" - -#define DESC_SEC (0x2) -#define CB (3<<2) //cache_on, write_back -#define CNB (2<<2) //cache_on, write_through -#define NCB (1<<2) //cache_off,WR_BUF on -#define NCNB (0<<2) //cache_off,WR_BUF off -#define AP_RW (3<<10) //supervisor=RW, user=RW -#define AP_RO (2<<10) //supervisor=RW, user=RO -#define XN (1<<4) // eXecute Never - -#define DOMAIN_FAULT (0x0) -#define DOMAIN_CHK (0x1) -#define DOMAIN_NOTCHK (0x3) -#define DOMAIN0 (0x0<<5) -#define DOMAIN1 (0x1<<5) - -#define DOMAIN0_ATTR (DOMAIN_CHK<<0) -#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) - -/* Read/Write, cache, write back */ -#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) -/* Read/Write, cache, write through */ -#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) -/* Read/Write without cache and write buffer */ -#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) -/* Read/Write without cache and write buffer, no execute */ -#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN) -/* Read/Write without cache and write buffer */ -#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) - -/* dump 2nd level page table */ -void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) -{ - int i; - int fcnt = 0; - - for (i = 0; i < 256; i++) - { - rt_uint32_t pte2 = ptb[i]; - if ((pte2 & 0x3) == 0) - { - if (fcnt == 0) - rt_kprintf(" "); - rt_kprintf("%04x: ", i); - fcnt++; - if (fcnt == 16) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - continue; - } - if (fcnt != 0) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - - rt_kprintf(" %04x: %x: ", i, pte2); - if ((pte2 & 0x3) == 0x1) - { - rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n", - ((pte2 >> 7) | (pte2 >> 4))& 0xf, - (pte2 >> 15) & 0x1, - ((pte2 >> 10) | (pte2 >> 2)) & 0x1f); - } - else - { - rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n", - ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1, - ((pte2 >> 4) | (pte2 >> 2)) & 0x1f); - } - } -} - -void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) -{ - int i; - int fcnt = 0; - - rt_kprintf("page table@%p\n", ptb); - for (i = 0; i < 1024*4; i++) - { - rt_uint32_t pte1 = ptb[i]; - if ((pte1 & 0x3) == 0) - { - rt_kprintf("%03x: ", i); - fcnt++; - if (fcnt == 16) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - continue; - } - if (fcnt != 0) - { - rt_kprintf("fault\n"); - fcnt = 0; - } - - rt_kprintf("%03x: %08x: ", i, pte1); - if ((pte1 & 0x3) == 0x3) - { - rt_kprintf("LPAE\n"); - } - else if ((pte1 & 0x3) == 0x1) - { - rt_kprintf("pte,ns:%d,domain:%d\n", - (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf); - /* - *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000) - * - 0x80000000 + 0xC0000000)); - */ - } - else if (pte1 & (1 << 18)) - { - rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n", - (pte1 >> 19) & 0x1, - ((pte1 >> 13) | (pte1 >> 10))& 0xf, - (pte1 >> 4) & 0x1, - ((pte1 >> 10) | (pte1 >> 2)) & 0x1f); - } - else - { - rt_kprintf("section,ns:%d,ap:%x," - "xn:%d,texcb:%02x,domain:%d\n", - (pte1 >> 19) & 0x1, - ((pte1 >> 13) | (pte1 >> 10))& 0xf, - (pte1 >> 4) & 0x1, - (((pte1 & (0x7 << 12)) >> 10) | - ((pte1 & 0x0c) >> 2)) & 0x1f, - (pte1 >> 5) & 0xf); - } - } -} - -/* level1 page table, each entry for 1MB memory. */ -volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024))); -void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, - rt_uint32_t vaddrEnd, - rt_uint32_t paddrStart, - rt_uint32_t attr) -{ - volatile rt_uint32_t *pTT; - volatile int i, nSec; - pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20); - nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); - for(i = 0; i <= nSec; i++) - { - *pTT = attr | (((paddrStart >> 20) + i) << 20); - pTT++; - } -} - -unsigned long rt_hw_set_domain_register(unsigned long domain_val) -{ - unsigned long old_domain; - - asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain)); - asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory"); - - return old_domain; -} - -void rt_hw_mmu_init(void) -{ - rt_hw_cpu_dcache_disable(); - rt_hw_cpu_icache_disable(); - rt_cpu_mmu_disable(); - - /* set page table */ - /* 4G 1:1 memory */ - rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB); - /* IO memory region */ - rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN); - - /*rt_hw_cpu_dump_page_table(MMUTable);*/ - rt_hw_set_domain_register(0x55555555); - - rt_cpu_tlb_set(MMUTable); - - rt_cpu_mmu_enable(); - - rt_hw_cpu_icache_enable(); - rt_hw_cpu_dcache_enable(); -} - diff --git a/libcpu/arm/cortex-a7/stack.c b/libcpu/arm/cortex-a7/stack.c deleted file mode 100644 index e60e8c7170..0000000000 --- a/libcpu/arm/cortex-a7/stack.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * File : stack.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2011-09-23 Bernard the first version - * 2011-10-05 Bernard add thumb mode - */ -#include -#include -#include - -/** - * @addtogroup AM33xx - */ -/*@{*/ - -/** - * This function will initialize thread stack - * - * @param tentry the entry of thread - * @param parameter the parameter of entry - * @param stack_addr the beginning stack address - * @param texit the function will be called when thread exit - * - * @return stack address - */ -rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, - rt_uint8_t *stack_addr, void *texit) -{ - rt_uint32_t *stk; - - stack_addr += sizeof(rt_uint32_t); - stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); - stk = (rt_uint32_t *)stack_addr; - *(--stk) = (rt_uint32_t)tentry; /* entry point */ - *(--stk) = (rt_uint32_t)texit; /* lr */ - *(--stk) = 0xdeadbeef; /* r12 */ - *(--stk) = 0xdeadbeef; /* r11 */ - *(--stk) = 0xdeadbeef; /* r10 */ - *(--stk) = 0xdeadbeef; /* r9 */ - *(--stk) = 0xdeadbeef; /* r8 */ - *(--stk) = 0xdeadbeef; /* r7 */ - *(--stk) = 0xdeadbeef; /* r6 */ - *(--stk) = 0xdeadbeef; /* r5 */ - *(--stk) = 0xdeadbeef; /* r4 */ - *(--stk) = 0xdeadbeef; /* r3 */ - *(--stk) = 0xdeadbeef; /* r2 */ - *(--stk) = 0xdeadbeef; /* r1 */ - *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ - - /* cpsr */ - if ((rt_uint32_t)tentry & 0x01) - *(--stk) = SVCMODE | 0x20; /* thumb mode */ - else - *(--stk) = SVCMODE; /* arm mode */ - - /* return task's current stack address */ - return (rt_uint8_t *)stk; -} - -/*@}*/ diff --git a/libcpu/arm/cortex-a7/start_gcc.S b/libcpu/arm/cortex-a7/start_gcc.S deleted file mode 100644 index b60ad6a38f..0000000000 --- a/libcpu/arm/cortex-a7/start_gcc.S +++ /dev/null @@ -1,280 +0,0 @@ -/* - * File : start_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013-2014, RT-Thread Development Team - * - * 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; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2013-07-05 Bernard the first version - */ - -.equ Mode_USR, 0x10 -.equ Mode_FIQ, 0x11 -.equ Mode_IRQ, 0x12 -.equ Mode_SVC, 0x13 -.equ Mode_ABT, 0x17 -.equ Mode_UND, 0x1B -.equ Mode_SYS, 0x1F - -.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled -.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled - -.equ UND_Stack_Size, 0x00000000 -.equ SVC_Stack_Size, 0x00000100 -.equ ABT_Stack_Size, 0x00000000 -.equ RT_FIQ_STACK_PGSZ, 0x00000000 -.equ RT_IRQ_STACK_PGSZ, 0x00000100 -.equ USR_Stack_Size, 0x00000100 - -#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ - RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) - -.section .data.share.isr -/* stack */ -.globl stack_start -.globl stack_top - -.align 3 -stack_start: -.rept ISR_Stack_Size -.byte 0 -.endr -stack_top: - -.text -/* reset entry */ -.globl _reset -_reset: - /* Disable IRQ & FIQ */ - cpsid if - - /* Check for HYP mode */ - mrs r0, cpsr_all - and r0, r0, #0x1F - mov r8, #0x1A - cmp r0, r8 - beq overHyped - b continue - -overHyped: /* Get out of HYP mode */ - ldr r1, =continue - msr ELR_hyp, r1 - mrs r1, cpsr_all - and r1, r1, #0x1f ;@ CPSR_MODE_MASK - orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR - msr SPSR_hyp, r1 - eret - -continue: - - /* disable smp */ - bl arm_smp_disable - - /* disable mmu */ - bl rt_cpu_mmu_disable - /* set the cpu to SVC32 mode and disable interrupt */ - mrs r0, cpsr - bic r0, r0, #0x1f - orr r0, r0, #0x13 - msr cpsr_c, r0 - - /* setup stack */ - bl stack_setup - - /* clear .bss */ - mov r0,#0 /* get a zero */ - ldr r1,=__bss_start /* bss start */ - ldr r2,=__bss_end /* bss end */ - -bss_loop: - cmp r1,r2 /* check if data to clear */ - strlo r0,[r1],#4 /* clear 4 bytes */ - blo bss_loop /* loop until done */ - - /* start RT-Thread Kernel */ - ldr pc, _rtthread_startup -_rtthread_startup: - .word rtthread_startup - -stack_setup: - ldr r0, =stack_top - - @ Set the startup stack for svc - mov sp, r0 - sub r0, r0, #SVC_Stack_Size - - @ Enter Undefined Instruction Mode and set its Stack Pointer - msr cpsr_c, #Mode_UND|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #UND_Stack_Size - - @ Enter Abort Mode and set its Stack Pointer - msr cpsr_c, #Mode_ABT|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #ABT_Stack_Size - - @ Enter FIQ Mode and set its Stack Pointer - msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #RT_FIQ_STACK_PGSZ - - @ Enter IRQ Mode and set its Stack Pointer - msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit - mov sp, r0 - sub r0, r0, #RT_IRQ_STACK_PGSZ - - /* come back to SVC mode */ - msr cpsr_c, #Mode_SVC|I_Bit|F_Bit - bx lr - -.text -;@ void arm_smp_enable(void); -.globl arm_smp_enable -arm_smp_enable: - mrc p15, 0, r0, c1, c0, 1 ;@ set SMP bit in ACTLR - orr r0, r0, #0x40 - mcr p15, 0, r0, c1, c0, 1 - bx lr - -.text -;@ void arm_smp_disable(void); -.globl arm_smp_disable -arm_smp_disable: - mrc p15, 0, r0, c1, c0, 1 ;@ clear SMP bit in ACTLR - bic r0, r0, #0x40 - mcr p15, 0, r0, c1, c0, 1 - bx lr - -/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ -.section .text.isr, "ax" - .align 5 -.globl vector_fiq -vector_fiq: - stmfd sp!,{r0-r7,lr} - bl rt_hw_trap_fiq - ldmfd sp!,{r0-r7,lr} - subs pc, lr, #4 - -.globl rt_interrupt_enter -.globl rt_interrupt_leave -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread - -.globl rt_current_thread -.globl vmm_thread -.globl vmm_virq_check - - .align 5 -.globl vector_irq -vector_irq: - stmfd sp!, {r0-r12,lr} - - bl rt_interrupt_enter - bl rt_hw_trap_irq - bl rt_interrupt_leave - - @ if rt_thread_switch_interrupt_flag set, jump to - @ rt_hw_context_switch_interrupt_do and don't return - ldr r0, =rt_thread_switch_interrupt_flag - ldr r1, [r0] - cmp r1, #1 - beq rt_hw_context_switch_interrupt_do - - ldmfd sp!, {r0-r12,lr} - subs pc, lr, #4 - -rt_hw_context_switch_interrupt_do: - mov r1, #0 @ clear flag - str r1, [r0] - - mov r1, sp @ r1 point to {r0-r3} in stack - add sp, sp, #4*4 - ldmfd sp!, {r4-r12,lr}@ reload saved registers - mrs r0, spsr @ get cpsr of interrupt thread - sub r2, lr, #4 @ save old task's pc to r2 - - @ Switch to SVC mode with no interrupt. If the usr mode guest is - @ interrupted, this will just switch to the stack of kernel space. - @ save the registers in kernel space won't trigger data abort. - msr cpsr_c, #I_Bit|F_Bit|Mode_SVC - - stmfd sp!, {r2} @ push old task's pc - stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 - ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread - stmfd sp!, {r1-r4} @ push old task's r0-r3 - stmfd sp!, {r0} @ push old task's cpsr - - ldr r4, =rt_interrupt_from_thread - ldr r5, [r4] - str sp, [r5] @ store sp in preempted tasks's TCB - - ldr r6, =rt_interrupt_to_thread - ldr r6, [r6] - ldr sp, [r6] @ get new task's stack pointer - - ldmfd sp!, {r4} @ pop new task's cpsr to spsr - msr spsr_cxsf, r4 - - ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr - -.macro push_svc_reg - sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ - stmia sp, {r0 - r12} @/* Calling r0-r12 */ - mov r0, sp - mrs r6, spsr @/* Save CPSR */ - str lr, [r0, #15*4] @/* Push PC */ - str r6, [r0, #16*4] @/* Push CPSR */ - cps #Mode_SVC - str sp, [r0, #13*4] @/* Save calling SP */ - str lr, [r0, #14*4] @/* Save calling PC */ -.endm - - .align 5 - .globl vector_swi -vector_swi: - push_svc_reg - bl rt_hw_trap_swi - b . - - .align 5 - .globl vector_undef -vector_undef: - push_svc_reg - bl rt_hw_trap_undef - b . - - .align 5 - .globl vector_pabt -vector_pabt: - push_svc_reg - bl rt_hw_trap_pabt - b . - - .align 5 - .globl vector_dabt -vector_dabt: - push_svc_reg - bl rt_hw_trap_dabt - b . - - .align 5 - .globl vector_resv -vector_resv: - push_svc_reg - bl rt_hw_trap_resv - b . diff --git a/libcpu/arm/cortex-a7/trap.c b/libcpu/arm/cortex-a7/trap.c deleted file mode 100644 index 3012c26e2c..0000000000 --- a/libcpu/arm/cortex-a7/trap.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * File : trap.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Develop Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2013-07-20 Bernard first version - */ - -#include -#include -#include - -#include "armv7.h" - -extern struct rt_thread *rt_current_thread; -#ifdef RT_USING_FINSH -extern long list_thread(void); -#endif - -/** - * this function will show registers of CPU - * - * @param regs the registers point - */ -void rt_hw_show_register(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("Execption:\n"); - rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); - rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); - rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); - rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); - rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); - rt_kprintf("cpsr:0x%08x\n", regs->cpsr); -} - -/** - * When comes across an instruction which it cannot handle, - * it takes the undefined instruction trap. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("undefined instruction:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * The software interrupt instruction (SWI) is used for entering - * Supervisor mode, usually to request a particular supervisor - * function. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("software interrupt:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during an instruction prefetch. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("prefetch abort:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * An abort indicates that the current memory access cannot be completed, - * which occurs during a data access. - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("data abort:"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -/** - * Normally, system will never reach here - * - * @param regs system registers - * - * @note never invoke this function in application - */ -void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) -{ - rt_kprintf("reserved trap:\n"); - rt_hw_show_register(regs); -#ifdef RT_USING_FINSH - list_thread(); -#endif - rt_hw_cpu_shutdown(); -} - -void rt_hw_trap_irq(void) -{ - void *param; - rt_isr_handler_t isr_func; - extern struct rt_irq_desc isr_table[]; - - uint32_t value = 0; - - // rt_kprintf("pend basic: 0x%08x\n", IRQ_PEND_BASIC); - // rt_kprintf(" pend1: 0x%08x\n", IRQ_PEND1); - // rt_kprintf(" pend2: 0x%08x\n", IRQ_PEND2); - - value = IRQ_PEND_BASIC & 0x3ff; - if (value) - { - uint32_t irq; - - if (value & (1 << 8)) - { - value = IRQ_PEND1; - irq = __rt_ffs(value) - 1; - } - else if (value & (1 << 9)) - { - value = IRQ_PEND2; - irq = __rt_ffs(value) + 31; - } - else - { - value &= 0x0f; - irq = __rt_ffs(value) - 1; - } - - /* get interrupt service routine */ - isr_func = isr_table[irq].handler; -#ifdef RT_USING_INTERRUPT_INFO - isr_table[irq].counter++; -#endif - if (isr_func) - { - /* Interrupt for myself. */ - param = isr_table[irq].param; - /* turn to interrupt service routine */ - isr_func(irq, param); - } - } -} - -void rt_hw_trap_fiq(void) -{ - /* TODO */ -} diff --git a/libcpu/arm/cortex-a7/vector_gcc.S b/libcpu/arm/cortex-a7/vector_gcc.S deleted file mode 100644 index 17c2d69c30..0000000000 --- a/libcpu/arm/cortex-a7/vector_gcc.S +++ /dev/null @@ -1,65 +0,0 @@ -/* - * File : vector_gcc.S - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2013, RT-Thread Development Team - * - * 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; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2013-07-05 Bernard the first version - */ - -.section .vectors, "ax" -.code 32 - -.globl system_vectors -system_vectors: - ldr pc, _vector_reset - ldr pc, _vector_undef - ldr pc, _vector_swi - ldr pc, _vector_pabt - ldr pc, _vector_dabt - ldr pc, _vector_resv - ldr pc, _vector_irq - ldr pc, _vector_fiq - -.globl _reset -.globl vector_undef -.globl vector_swi -.globl vector_pabt -.globl vector_dabt -.globl vector_resv -.globl vector_irq -.globl vector_fiq - -_vector_reset: - .word _reset -_vector_undef: - .word vector_undef -_vector_swi: - .word vector_swi -_vector_pabt: - .word vector_pabt -_vector_dabt: - .word vector_dabt -_vector_resv: - .word vector_resv -_vector_irq: - .word vector_irq -_vector_fiq: - .word vector_fiq - -.balignl 16,0xdeadbeef -- Gitee From f922bf2e31193768822f68d1e3c1d82ea578ed27 Mon Sep 17 00:00:00 2001 From: bigmagic Date: Wed, 15 Jan 2020 16:46:19 +0800 Subject: [PATCH 064/110] Add comment information --- libcpu/aarch64/cortex-a53/armv8.h | 6 +++--- libcpu/aarch64/cortex-a53/context_gcc.S | 5 +++++ libcpu/aarch64/cortex-a53/cp15.h | 2 +- libcpu/aarch64/cortex-a53/cpu_gcc.S | 4 ++++ libcpu/aarch64/cortex-a53/entry_point.S | 9 +++++++++ libcpu/aarch64/cortex-a53/interrupt.h | 9 +++++++++ libcpu/aarch64/cortex-a53/mmu.c | 2 +- libcpu/aarch64/cortex-a53/mmu.h | 9 +++++++++ libcpu/aarch64/cortex-a53/trap.c | 4 ++++ libcpu/aarch64/cortex-a53/vector_gcc.S | 4 ++++ 10 files changed, 49 insertions(+), 5 deletions(-) diff --git a/libcpu/aarch64/cortex-a53/armv8.h b/libcpu/aarch64/cortex-a53/armv8.h index 28ed50e1ac..4350890544 100644 --- a/libcpu/aarch64/cortex-a53/armv8.h +++ b/libcpu/aarch64/cortex-a53/armv8.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -8,8 +8,8 @@ * 2011-09-15 Bernard first version */ -#ifndef __ARMV7_H__ -#define __ARMV7_H__ +#ifndef __ARMV8_H__ +#define __ARMV8_H__ /* the exception stack without VFP registers */ struct rt_hw_exp_stack diff --git a/libcpu/aarch64/cortex-a53/context_gcc.S b/libcpu/aarch64/cortex-a53/context_gcc.S index 3812eb4b1a..f58ea1b15d 100644 --- a/libcpu/aarch64/cortex-a53/context_gcc.S +++ b/libcpu/aarch64/cortex-a53/context_gcc.S @@ -1,4 +1,9 @@ /* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: * Date Author Notes * 2018-10-06 ZhaoXiaowei the first version */ diff --git a/libcpu/aarch64/cortex-a53/cp15.h b/libcpu/aarch64/cortex-a53/cp15.h index 26f6ef1a31..91c37d679f 100644 --- a/libcpu/aarch64/cortex-a53/cp15.h +++ b/libcpu/aarch64/cortex-a53/cp15.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/libcpu/aarch64/cortex-a53/cpu_gcc.S b/libcpu/aarch64/cortex-a53/cpu_gcc.S index ab9a5706ae..b8c8b8768c 100644 --- a/libcpu/aarch64/cortex-a53/cpu_gcc.S +++ b/libcpu/aarch64/cortex-a53/cpu_gcc.S @@ -1,4 +1,8 @@ /* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * * Date Author Notes * 2018-10-06 ZhaoXiaowei the first version */ diff --git a/libcpu/aarch64/cortex-a53/entry_point.S b/libcpu/aarch64/cortex-a53/entry_point.S index 098cd9a840..6d2c69226b 100644 --- a/libcpu/aarch64/cortex-a53/entry_point.S +++ b/libcpu/aarch64/cortex-a53/entry_point.S @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Date Author Notes + * 2020-01-15 bigmagic the first version + */ + .section ".text.entrypoint" .set EL1_stack, __el1_stack diff --git a/libcpu/aarch64/cortex-a53/interrupt.h b/libcpu/aarch64/cortex-a53/interrupt.h index 6e86516045..0c20f79bcc 100644 --- a/libcpu/aarch64/cortex-a53/interrupt.h +++ b/libcpu/aarch64/cortex-a53/interrupt.h @@ -1,4 +1,13 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + #ifndef __INTERRUPT_H__ #define __INTERRUPT_H__ diff --git a/libcpu/aarch64/cortex-a53/mmu.c b/libcpu/aarch64/cortex-a53/mmu.c index 17b40c3b47..29934b26a4 100644 --- a/libcpu/aarch64/cortex-a53/mmu.c +++ b/libcpu/aarch64/cortex-a53/mmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/libcpu/aarch64/cortex-a53/mmu.h b/libcpu/aarch64/cortex-a53/mmu.h index 022d200f96..5bef609486 100644 --- a/libcpu/aarch64/cortex-a53/mmu.h +++ b/libcpu/aarch64/cortex-a53/mmu.h @@ -1,3 +1,12 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-15 bigmagic the first version + */ #ifndef MMU_H__ #define MMU_H__ #include diff --git a/libcpu/aarch64/cortex-a53/trap.c b/libcpu/aarch64/cortex-a53/trap.c index aa639ea596..13ae6d1b9e 100644 --- a/libcpu/aarch64/cortex-a53/trap.c +++ b/libcpu/aarch64/cortex-a53/trap.c @@ -1,4 +1,8 @@ /* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * * Date Author Notes * 2018-10-06 ZhaoXiaowei the first version */ diff --git a/libcpu/aarch64/cortex-a53/vector_gcc.S b/libcpu/aarch64/cortex-a53/vector_gcc.S index 0efbf4e540..fc88cce7f8 100644 --- a/libcpu/aarch64/cortex-a53/vector_gcc.S +++ b/libcpu/aarch64/cortex-a53/vector_gcc.S @@ -1,4 +1,8 @@ /* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * * Date Author Notes * 2018-10-06 ZhaoXiaowei the first version */ -- Gitee From 114288878e85c6f5c3de22019eb5a9d4a842993c Mon Sep 17 00:00:00 2001 From: bigmagic Date: Wed, 15 Jan 2020 17:19:49 +0800 Subject: [PATCH 065/110] [bsp/raspberry-pi] add raspi2/cpu --- bsp/raspberry-pi/raspi2/SConstruct | 2 +- bsp/raspberry-pi/raspi2/cpu/SConscript | 9 + bsp/raspberry-pi/raspi2/cpu/armv7.h | 64 +++++ bsp/raspberry-pi/raspi2/cpu/context_gcc.S | 105 ++++++++ bsp/raspberry-pi/raspi2/cpu/cp15.h | 12 + bsp/raspberry-pi/raspi2/cpu/cp15_gcc.S | 140 +++++++++++ bsp/raspberry-pi/raspi2/cpu/cpu.c | 37 +++ bsp/raspberry-pi/raspi2/cpu/interrupt.c | 136 +++++++++++ bsp/raspberry-pi/raspi2/cpu/mmu.c | 207 ++++++++++++++++ bsp/raspberry-pi/raspi2/cpu/stack.c | 68 ++++++ bsp/raspberry-pi/raspi2/cpu/start_gcc.S | 280 ++++++++++++++++++++++ bsp/raspberry-pi/raspi2/cpu/trap.c | 183 ++++++++++++++ bsp/raspberry-pi/raspi2/cpu/vector_gcc.S | 65 +++++ 13 files changed, 1307 insertions(+), 1 deletion(-) create mode 100644 bsp/raspberry-pi/raspi2/cpu/SConscript create mode 100644 bsp/raspberry-pi/raspi2/cpu/armv7.h create mode 100644 bsp/raspberry-pi/raspi2/cpu/context_gcc.S create mode 100644 bsp/raspberry-pi/raspi2/cpu/cp15.h create mode 100644 bsp/raspberry-pi/raspi2/cpu/cp15_gcc.S create mode 100644 bsp/raspberry-pi/raspi2/cpu/cpu.c create mode 100644 bsp/raspberry-pi/raspi2/cpu/interrupt.c create mode 100644 bsp/raspberry-pi/raspi2/cpu/mmu.c create mode 100644 bsp/raspberry-pi/raspi2/cpu/stack.c create mode 100644 bsp/raspberry-pi/raspi2/cpu/start_gcc.S create mode 100644 bsp/raspberry-pi/raspi2/cpu/trap.c create mode 100644 bsp/raspberry-pi/raspi2/cpu/vector_gcc.S diff --git a/bsp/raspberry-pi/raspi2/SConstruct b/bsp/raspberry-pi/raspi2/SConstruct index e94a364d9d..e5acdb2554 100644 --- a/bsp/raspberry-pi/raspi2/SConstruct +++ b/bsp/raspberry-pi/raspi2/SConstruct @@ -22,7 +22,7 @@ Export('RTT_ROOT') Export('rtconfig') # prepare building environment -objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False) +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True) # make a building DoBuilding(TARGET, objs) diff --git a/bsp/raspberry-pi/raspi2/cpu/SConscript b/bsp/raspberry-pi/raspi2/cpu/SConscript new file mode 100644 index 0000000000..eb4ee7a585 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S') +CPPPATH = [cwd] + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/raspberry-pi/raspi2/cpu/armv7.h b/bsp/raspberry-pi/raspi2/cpu/armv7.h new file mode 100644 index 0000000000..a07d9de2a9 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/armv7.h @@ -0,0 +1,64 @@ +#ifndef __ARMV7_H__ +#define __ARMV7_H__ + +/* the exception stack without VFP registers */ +struct rt_hw_exp_stack +{ + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long sp; + unsigned long lr; + unsigned long pc; + unsigned long cpsr; +}; + +struct rt_hw_stack +{ + unsigned long cpsr; + unsigned long r0; + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long fp; + unsigned long ip; + unsigned long lr; + unsigned long pc; +}; + +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define MONITORMODE 0x16 +#define ABORTMODE 0x17 +#define HYPMODE 0x1b +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 + +#define T_Bit (1<<5) +#define F_Bit (1<<6) +#define I_Bit (1<<7) +#define A_Bit (1<<8) +#define E_Bit (1<<9) +#define J_Bit (1<<24) + +#endif diff --git a/bsp/raspberry-pi/raspi2/cpu/context_gcc.S b/bsp/raspberry-pi/raspi2/cpu/context_gcc.S new file mode 100644 index 0000000000..48402739f9 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/context_gcc.S @@ -0,0 +1,105 @@ +/* + * File : context.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * 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; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.section .text, "ax" +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mrs r0, cpsr + cpsid i + bx lr + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + msr cpsr_c, r0 + bx lr + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * r0 --> to + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + ldr sp, [r0] @ get new task stack pointer + + ldmfd sp!, {r4} @ pop new task spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc + +.section .bss.share.isr +_guest_switch_lvl: + .word 0 + +.globl vmm_virq_update + +.section .text.isr, "ax" +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * r0 --> from + * r1 --> to + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) + stmfd sp!, {r0-r12, lr} @ push lr & register file + + mrs r4, cpsr + tst lr, #0x01 + orrne r4, r4, #0x20 @ it's thumb code + + stmfd sp!, {r4} @ push cpsr + + str sp, [r0] @ store sp in preempted tasks TCB + ldr sp, [r1] @ get new task stack pointer + + ldmfd sp!, {r4} @ pop new task cpsr to spsr + msr spsr_cxsf, r4 + ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + ldr r2, =rt_thread_switch_interrupt_flag + ldr r3, [r2] + cmp r3, #1 + beq _reswitch + ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread + mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1 + str r0, [ip] + str r3, [r2] +_reswitch: + ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread + str r1, [r2] + bx lr diff --git a/bsp/raspberry-pi/raspi2/cpu/cp15.h b/bsp/raspberry-pi/raspi2/cpu/cp15.h new file mode 100644 index 0000000000..ebea3f0fe3 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/cp15.h @@ -0,0 +1,12 @@ +#ifndef __CP15_H__ +#define __CP15_H__ + +unsigned long rt_cpu_get_smp_id(void); + +void rt_cpu_mmu_disable(void); +void rt_cpu_mmu_enable(void); +void rt_cpu_tlb_set(volatile unsigned long*); + +void rt_cpu_vector_set_base(unsigned int addr); + +#endif diff --git a/bsp/raspberry-pi/raspi2/cpu/cp15_gcc.S b/bsp/raspberry-pi/raspi2/cpu/cp15_gcc.S new file mode 100644 index 0000000000..f1ed6492aa --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/cp15_gcc.S @@ -0,0 +1,140 @@ +/* + * File : cp15_gcc.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * http://www.rt-thread.org + * + * 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; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.globl rt_cpu_get_smp_id +rt_cpu_get_smp_id: + mrc p15, #0, r0, c0, c0, #5 + bx lr + +.globl rt_cpu_vector_set_base +rt_cpu_vector_set_base: + mcr p15, #0, r0, c12, c0, #0 + dsb + bx lr + +.globl rt_hw_cpu_dcache_enable +rt_hw_cpu_dcache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_hw_cpu_icache_enable +rt_hw_cpu_icache_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +_FLD_MAX_WAY: + .word 0x3ff +_FLD_MAX_IDX: + .word 0x7ff + +.globl rt_cpu_dcache_clean_flush +rt_cpu_dcache_clean_flush: + push {r4-r11} + dmb + mrc p15, #1, r0, c0, c0, #1 @ read clid register + ands r3, r0, #0x7000000 @ get level of coherency + mov r3, r3, lsr #23 + beq finished + mov r10, #0 +loop1: + add r2, r10, r10, lsr #1 + mov r1, r0, lsr r2 + and r1, r1, #7 + cmp r1, #2 + blt skip + mcr p15, #2, r10, c0, c0, #0 + isb + mrc p15, #1, r1, c0, c0, #0 + and r2, r1, #7 + add r2, r2, #4 + ldr r4, _FLD_MAX_WAY + ands r4, r4, r1, lsr #3 + clz r5, r4 + ldr r7, _FLD_MAX_IDX + ands r7, r7, r1, lsr #13 +loop2: + mov r9, r4 +loop3: + orr r11, r10, r9, lsl r5 + orr r11, r11, r7, lsl r2 + mcr p15, #0, r11, c7, c14, #2 + subs r9, r9, #1 + bge loop3 + subs r7, r7, #1 + bge loop2 +skip: + add r10, r10, #2 + cmp r3, r10 + bgt loop1 + +finished: + dsb + isb + pop {r4-r11} + bx lr + +.globl rt_hw_cpu_dcache_disable +rt_hw_cpu_dcache_disable: + push {r4-r11, lr} + bl rt_cpu_dcache_clean_flush + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00000004 + mcr p15, #0, r0, c1, c0, #0 + pop {r4-r11, lr} + bx lr + +.globl rt_hw_cpu_icache_disable +rt_hw_cpu_icache_disable: + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #0x00001000 + mcr p15, #0, r0, c1, c0, #0 + bx lr + +.globl rt_cpu_mmu_disable +rt_cpu_mmu_disable: + mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb + mrc p15, #0, r0, c1, c0, #0 + bic r0, r0, #1 + mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit + dsb + bx lr + +.globl rt_cpu_mmu_enable +rt_cpu_mmu_enable: + mrc p15, #0, r0, c1, c0, #0 + orr r0, r0, #0x001 + mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit + dsb + bx lr + +.globl rt_cpu_tlb_set +rt_cpu_tlb_set: + mcr p15, #0, r0, c2, c0, #0 + dmb + bx lr diff --git a/bsp/raspberry-pi/raspi2/cpu/cpu.c b/bsp/raspberry-pi/raspi2/cpu/cpu.c new file mode 100644 index 0000000000..8bf16d19e8 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/cpu.c @@ -0,0 +1,37 @@ +/* + * File : cpu.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-09-15 Bernard first version + */ + +#include +#include +#include + +/** + * @addtogroup AM33xx + */ +/*@{*/ + +/** shutdown CPU */ +void rt_hw_cpu_shutdown() +{ + rt_uint32_t level; + rt_kprintf("shutdown...\n"); + + level = rt_hw_interrupt_disable(); + while (level) + { + RT_ASSERT(0); + } +} + +/*@}*/ diff --git a/bsp/raspberry-pi/raspi2/cpu/interrupt.c b/bsp/raspberry-pi/raspi2/cpu/interrupt.c new file mode 100644 index 0000000000..d502977c3e --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/interrupt.c @@ -0,0 +1,136 @@ +/* + * File : interrupt.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013-2014, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2018/5/3 Bernard first version + */ + +#include +#include + +#include "cp15.h" +#include + +#define MAX_HANDLERS 64 + +extern volatile rt_uint8_t rt_interrupt_nest; + +/* exception and interrupt handler table */ +struct rt_irq_desc isr_table[MAX_HANDLERS]; + +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +extern int system_vectors; + +static void default_isr_handler(int vector, void *param) +{ + rt_kprintf("unhandled irq: %d\n", vector); +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + uint32_t index; + + /* mask all of interrupts */ + IRQ_DISABLE_BASIC = 0x000000ff; + IRQ_DISABLE1 = 0xffffffff; + IRQ_DISABLE2 = 0xffffffff; + + for (index = 0; index < MAX_HANDLERS; index ++) + { + isr_table[index].handler = default_isr_handler; + isr_table[index].param = NULL; +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX); + isr_table[index].counter = 0; +#endif + } + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + if (vector < 8) + { + IRQ_DISABLE_BASIC = (1 << vector); + } + else if (vector < 32) + { + IRQ_DISABLE1 = (1 << vector); + } + else + { + vector = vector % 32; + IRQ_DISABLE2 = (1 << vector); + } +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + if (vector < 8) + { + IRQ_ENABLE_BASIC = (1 << vector); + } + else if (vector < 32) + { + IRQ_ENABLE1 = (1 << vector); + } + else + { + vector = vector % 32; + IRQ_ENABLE2 = (1 << vector); + } +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if (vector < MAX_HANDLERS) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} diff --git a/bsp/raspberry-pi/raspi2/cpu/mmu.c b/bsp/raspberry-pi/raspi2/cpu/mmu.c new file mode 100644 index 0000000000..b2503e4260 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/mmu.c @@ -0,0 +1,207 @@ +/* + * File : mmu.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-01-10 bernard porting to AM1808 + */ + +#include +#include +#include + +#include "cp15.h" + +#define DESC_SEC (0x2) +#define CB (3<<2) //cache_on, write_back +#define CNB (2<<2) //cache_on, write_through +#define NCB (1<<2) //cache_off,WR_BUF on +#define NCNB (0<<2) //cache_off,WR_BUF off +#define AP_RW (3<<10) //supervisor=RW, user=RW +#define AP_RO (2<<10) //supervisor=RW, user=RO +#define XN (1<<4) // eXecute Never + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) + +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) + +/* Read/Write, cache, write back */ +#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) +/* Read/Write, cache, write through */ +#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) +/* Read/Write without cache and write buffer */ +#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) +/* Read/Write without cache and write buffer, no execute */ +#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN) +/* Read/Write without cache and write buffer */ +#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) + +/* dump 2nd level page table */ +void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + for (i = 0; i < 256; i++) + { + rt_uint32_t pte2 = ptb[i]; + if ((pte2 & 0x3) == 0) + { + if (fcnt == 0) + rt_kprintf(" "); + rt_kprintf("%04x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf(" %04x: %x: ", i, pte2); + if ((pte2 & 0x3) == 0x1) + { + rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, + (pte2 >> 15) & 0x1, + ((pte2 >> 10) | (pte2 >> 2)) & 0x1f); + } + else + { + rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n", + ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1, + ((pte2 >> 4) | (pte2 >> 2)) & 0x1f); + } + } +} + +void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb) +{ + int i; + int fcnt = 0; + + rt_kprintf("page table@%p\n", ptb); + for (i = 0; i < 1024*4; i++) + { + rt_uint32_t pte1 = ptb[i]; + if ((pte1 & 0x3) == 0) + { + rt_kprintf("%03x: ", i); + fcnt++; + if (fcnt == 16) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + continue; + } + if (fcnt != 0) + { + rt_kprintf("fault\n"); + fcnt = 0; + } + + rt_kprintf("%03x: %08x: ", i, pte1); + if ((pte1 & 0x3) == 0x3) + { + rt_kprintf("LPAE\n"); + } + else if ((pte1 & 0x3) == 0x1) + { + rt_kprintf("pte,ns:%d,domain:%d\n", + (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf); + /* + *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000) + * - 0x80000000 + 0xC0000000)); + */ + } + else if (pte1 & (1 << 18)) + { + rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + ((pte1 >> 10) | (pte1 >> 2)) & 0x1f); + } + else + { + rt_kprintf("section,ns:%d,ap:%x," + "xn:%d,texcb:%02x,domain:%d\n", + (pte1 >> 19) & 0x1, + ((pte1 >> 13) | (pte1 >> 10))& 0xf, + (pte1 >> 4) & 0x1, + (((pte1 & (0x7 << 12)) >> 10) | + ((pte1 & 0x0c) >> 2)) & 0x1f, + (pte1 >> 5) & 0xf); + } + } +} + +/* level1 page table, each entry for 1MB memory. */ +volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024))); +void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart, + rt_uint32_t vaddrEnd, + rt_uint32_t paddrStart, + rt_uint32_t attr) +{ + volatile rt_uint32_t *pTT; + volatile int i, nSec; + pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20); + nSec = (vaddrEnd >> 20) - (vaddrStart >> 20); + for(i = 0; i <= nSec; i++) + { + *pTT = attr | (((paddrStart >> 20) + i) << 20); + pTT++; + } +} + +unsigned long rt_hw_set_domain_register(unsigned long domain_val) +{ + unsigned long old_domain; + + asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain)); + asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory"); + + return old_domain; +} + +void rt_hw_mmu_init(void) +{ + rt_hw_cpu_dcache_disable(); + rt_hw_cpu_icache_disable(); + rt_cpu_mmu_disable(); + + /* set page table */ + /* 4G 1:1 memory */ + rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB); + /* IO memory region */ + rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN); + + /*rt_hw_cpu_dump_page_table(MMUTable);*/ + rt_hw_set_domain_register(0x55555555); + + rt_cpu_tlb_set(MMUTable); + + rt_cpu_mmu_enable(); + + rt_hw_cpu_icache_enable(); + rt_hw_cpu_dcache_enable(); +} + diff --git a/bsp/raspberry-pi/raspi2/cpu/stack.c b/bsp/raspberry-pi/raspi2/cpu/stack.c new file mode 100644 index 0000000000..e60e8c7170 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/stack.c @@ -0,0 +1,68 @@ +/* + * File : stack.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2011, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-09-23 Bernard the first version + * 2011-10-05 Bernard add thumb mode + */ +#include +#include +#include + +/** + * @addtogroup AM33xx + */ +/*@{*/ + +/** + * This function will initialize thread stack + * + * @param tentry the entry of thread + * @param parameter the parameter of entry + * @param stack_addr the beginning stack address + * @param texit the function will be called when thread exit + * + * @return stack address + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + rt_uint32_t *stk; + + stack_addr += sizeof(rt_uint32_t); + stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8); + stk = (rt_uint32_t *)stack_addr; + *(--stk) = (rt_uint32_t)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0xdeadbeef; /* r12 */ + *(--stk) = 0xdeadbeef; /* r11 */ + *(--stk) = 0xdeadbeef; /* r10 */ + *(--stk) = 0xdeadbeef; /* r9 */ + *(--stk) = 0xdeadbeef; /* r8 */ + *(--stk) = 0xdeadbeef; /* r7 */ + *(--stk) = 0xdeadbeef; /* r6 */ + *(--stk) = 0xdeadbeef; /* r5 */ + *(--stk) = 0xdeadbeef; /* r4 */ + *(--stk) = 0xdeadbeef; /* r3 */ + *(--stk) = 0xdeadbeef; /* r2 */ + *(--stk) = 0xdeadbeef; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + + /* cpsr */ + if ((rt_uint32_t)tentry & 0x01) + *(--stk) = SVCMODE | 0x20; /* thumb mode */ + else + *(--stk) = SVCMODE; /* arm mode */ + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} + +/*@}*/ diff --git a/bsp/raspberry-pi/raspi2/cpu/start_gcc.S b/bsp/raspberry-pi/raspi2/cpu/start_gcc.S new file mode 100644 index 0000000000..b60ad6a38f --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/start_gcc.S @@ -0,0 +1,280 @@ +/* + * File : start_gcc.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013-2014, RT-Thread Development Team + * + * 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; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.equ Mode_USR, 0x10 +.equ Mode_FIQ, 0x11 +.equ Mode_IRQ, 0x12 +.equ Mode_SVC, 0x13 +.equ Mode_ABT, 0x17 +.equ Mode_UND, 0x1B +.equ Mode_SYS, 0x1F + +.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled +.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled + +.equ UND_Stack_Size, 0x00000000 +.equ SVC_Stack_Size, 0x00000100 +.equ ABT_Stack_Size, 0x00000000 +.equ RT_FIQ_STACK_PGSZ, 0x00000000 +.equ RT_IRQ_STACK_PGSZ, 0x00000100 +.equ USR_Stack_Size, 0x00000100 + +#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ + RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ) + +.section .data.share.isr +/* stack */ +.globl stack_start +.globl stack_top + +.align 3 +stack_start: +.rept ISR_Stack_Size +.byte 0 +.endr +stack_top: + +.text +/* reset entry */ +.globl _reset +_reset: + /* Disable IRQ & FIQ */ + cpsid if + + /* Check for HYP mode */ + mrs r0, cpsr_all + and r0, r0, #0x1F + mov r8, #0x1A + cmp r0, r8 + beq overHyped + b continue + +overHyped: /* Get out of HYP mode */ + ldr r1, =continue + msr ELR_hyp, r1 + mrs r1, cpsr_all + and r1, r1, #0x1f ;@ CPSR_MODE_MASK + orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR + msr SPSR_hyp, r1 + eret + +continue: + + /* disable smp */ + bl arm_smp_disable + + /* disable mmu */ + bl rt_cpu_mmu_disable + /* set the cpu to SVC32 mode and disable interrupt */ + mrs r0, cpsr + bic r0, r0, #0x1f + orr r0, r0, #0x13 + msr cpsr_c, r0 + + /* setup stack */ + bl stack_setup + + /* clear .bss */ + mov r0,#0 /* get a zero */ + ldr r1,=__bss_start /* bss start */ + ldr r2,=__bss_end /* bss end */ + +bss_loop: + cmp r1,r2 /* check if data to clear */ + strlo r0,[r1],#4 /* clear 4 bytes */ + blo bss_loop /* loop until done */ + + /* start RT-Thread Kernel */ + ldr pc, _rtthread_startup +_rtthread_startup: + .word rtthread_startup + +stack_setup: + ldr r0, =stack_top + + @ Set the startup stack for svc + mov sp, r0 + sub r0, r0, #SVC_Stack_Size + + @ Enter Undefined Instruction Mode and set its Stack Pointer + msr cpsr_c, #Mode_UND|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #UND_Stack_Size + + @ Enter Abort Mode and set its Stack Pointer + msr cpsr_c, #Mode_ABT|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #ABT_Stack_Size + + @ Enter FIQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #RT_FIQ_STACK_PGSZ + + @ Enter IRQ Mode and set its Stack Pointer + msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit + mov sp, r0 + sub r0, r0, #RT_IRQ_STACK_PGSZ + + /* come back to SVC mode */ + msr cpsr_c, #Mode_SVC|I_Bit|F_Bit + bx lr + +.text +;@ void arm_smp_enable(void); +.globl arm_smp_enable +arm_smp_enable: + mrc p15, 0, r0, c1, c0, 1 ;@ set SMP bit in ACTLR + orr r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + bx lr + +.text +;@ void arm_smp_disable(void); +.globl arm_smp_disable +arm_smp_disable: + mrc p15, 0, r0, c1, c0, 1 ;@ clear SMP bit in ACTLR + bic r0, r0, #0x40 + mcr p15, 0, r0, c1, c0, 1 + bx lr + +/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */ +.section .text.isr, "ax" + .align 5 +.globl vector_fiq +vector_fiq: + stmfd sp!,{r0-r7,lr} + bl rt_hw_trap_fiq + ldmfd sp!,{r0-r7,lr} + subs pc, lr, #4 + +.globl rt_interrupt_enter +.globl rt_interrupt_leave +.globl rt_thread_switch_interrupt_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread + +.globl rt_current_thread +.globl vmm_thread +.globl vmm_virq_check + + .align 5 +.globl vector_irq +vector_irq: + stmfd sp!, {r0-r12,lr} + + bl rt_interrupt_enter + bl rt_hw_trap_irq + bl rt_interrupt_leave + + @ if rt_thread_switch_interrupt_flag set, jump to + @ rt_hw_context_switch_interrupt_do and don't return + ldr r0, =rt_thread_switch_interrupt_flag + ldr r1, [r0] + cmp r1, #1 + beq rt_hw_context_switch_interrupt_do + + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + +rt_hw_context_switch_interrupt_do: + mov r1, #0 @ clear flag + str r1, [r0] + + mov r1, sp @ r1 point to {r0-r3} in stack + add sp, sp, #4*4 + ldmfd sp!, {r4-r12,lr}@ reload saved registers + mrs r0, spsr @ get cpsr of interrupt thread + sub r2, lr, #4 @ save old task's pc to r2 + + @ Switch to SVC mode with no interrupt. If the usr mode guest is + @ interrupted, this will just switch to the stack of kernel space. + @ save the registers in kernel space won't trigger data abort. + msr cpsr_c, #I_Bit|F_Bit|Mode_SVC + + stmfd sp!, {r2} @ push old task's pc + stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4 + ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread + stmfd sp!, {r1-r4} @ push old task's r0-r3 + stmfd sp!, {r0} @ push old task's cpsr + + ldr r4, =rt_interrupt_from_thread + ldr r5, [r4] + str sp, [r5] @ store sp in preempted tasks's TCB + + ldr r6, =rt_interrupt_to_thread + ldr r6, [r6] + ldr sp, [r6] @ get new task's stack pointer + + ldmfd sp!, {r4} @ pop new task's cpsr to spsr + msr spsr_cxsf, r4 + + ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr + +.macro push_svc_reg + sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */ + stmia sp, {r0 - r12} @/* Calling r0-r12 */ + mov r0, sp + mrs r6, spsr @/* Save CPSR */ + str lr, [r0, #15*4] @/* Push PC */ + str r6, [r0, #16*4] @/* Push CPSR */ + cps #Mode_SVC + str sp, [r0, #13*4] @/* Save calling SP */ + str lr, [r0, #14*4] @/* Save calling PC */ +.endm + + .align 5 + .globl vector_swi +vector_swi: + push_svc_reg + bl rt_hw_trap_swi + b . + + .align 5 + .globl vector_undef +vector_undef: + push_svc_reg + bl rt_hw_trap_undef + b . + + .align 5 + .globl vector_pabt +vector_pabt: + push_svc_reg + bl rt_hw_trap_pabt + b . + + .align 5 + .globl vector_dabt +vector_dabt: + push_svc_reg + bl rt_hw_trap_dabt + b . + + .align 5 + .globl vector_resv +vector_resv: + push_svc_reg + bl rt_hw_trap_resv + b . diff --git a/bsp/raspberry-pi/raspi2/cpu/trap.c b/bsp/raspberry-pi/raspi2/cpu/trap.c new file mode 100644 index 0000000000..3012c26e2c --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/trap.c @@ -0,0 +1,183 @@ +/* + * File : trap.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2013-07-20 Bernard first version + */ + +#include +#include +#include + +#include "armv7.h" + +extern struct rt_thread *rt_current_thread; +#ifdef RT_USING_FINSH +extern long list_thread(void); +#endif + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ +void rt_hw_show_register(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); + rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); + rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); + rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); + rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); + rt_kprintf("cpsr:0x%08x\n", regs->cpsr); +} + +/** + * When comes across an instruction which it cannot handle, + * it takes the undefined instruction trap. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("undefined instruction:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * The software interrupt instruction (SWI) is used for entering + * Supervisor mode, usually to request a particular supervisor + * function. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("software interrupt:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during an instruction prefetch. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("prefetch abort:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during a data access. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("data abort:"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +/** + * Normally, system will never reach here + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) +{ + rt_kprintf("reserved trap:\n"); + rt_hw_show_register(regs); +#ifdef RT_USING_FINSH + list_thread(); +#endif + rt_hw_cpu_shutdown(); +} + +void rt_hw_trap_irq(void) +{ + void *param; + rt_isr_handler_t isr_func; + extern struct rt_irq_desc isr_table[]; + + uint32_t value = 0; + + // rt_kprintf("pend basic: 0x%08x\n", IRQ_PEND_BASIC); + // rt_kprintf(" pend1: 0x%08x\n", IRQ_PEND1); + // rt_kprintf(" pend2: 0x%08x\n", IRQ_PEND2); + + value = IRQ_PEND_BASIC & 0x3ff; + if (value) + { + uint32_t irq; + + if (value & (1 << 8)) + { + value = IRQ_PEND1; + irq = __rt_ffs(value) - 1; + } + else if (value & (1 << 9)) + { + value = IRQ_PEND2; + irq = __rt_ffs(value) + 31; + } + else + { + value &= 0x0f; + irq = __rt_ffs(value) - 1; + } + + /* get interrupt service routine */ + isr_func = isr_table[irq].handler; +#ifdef RT_USING_INTERRUPT_INFO + isr_table[irq].counter++; +#endif + if (isr_func) + { + /* Interrupt for myself. */ + param = isr_table[irq].param; + /* turn to interrupt service routine */ + isr_func(irq, param); + } + } +} + +void rt_hw_trap_fiq(void) +{ + /* TODO */ +} diff --git a/bsp/raspberry-pi/raspi2/cpu/vector_gcc.S b/bsp/raspberry-pi/raspi2/cpu/vector_gcc.S new file mode 100644 index 0000000000..17c2d69c30 --- /dev/null +++ b/bsp/raspberry-pi/raspi2/cpu/vector_gcc.S @@ -0,0 +1,65 @@ +/* + * File : vector_gcc.S + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2013, RT-Thread Development Team + * + * 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; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2013-07-05 Bernard the first version + */ + +.section .vectors, "ax" +.code 32 + +.globl system_vectors +system_vectors: + ldr pc, _vector_reset + ldr pc, _vector_undef + ldr pc, _vector_swi + ldr pc, _vector_pabt + ldr pc, _vector_dabt + ldr pc, _vector_resv + ldr pc, _vector_irq + ldr pc, _vector_fiq + +.globl _reset +.globl vector_undef +.globl vector_swi +.globl vector_pabt +.globl vector_dabt +.globl vector_resv +.globl vector_irq +.globl vector_fiq + +_vector_reset: + .word _reset +_vector_undef: + .word vector_undef +_vector_swi: + .word vector_swi +_vector_pabt: + .word vector_pabt +_vector_dabt: + .word vector_dabt +_vector_resv: + .word vector_resv +_vector_irq: + .word vector_irq +_vector_fiq: + .word vector_fiq + +.balignl 16,0xdeadbeef -- Gitee From 317e5bf4a4a66572d7675601bf424226af1314ce Mon Sep 17 00:00:00 2001 From: bigmagic Date: Wed, 15 Jan 2020 17:23:18 +0800 Subject: [PATCH 066/110] [bsp/raspi] remove "kernel7.img" from bsp --- bsp/raspberry-pi/raspi2/kernel7.img | Bin 91456 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 bsp/raspberry-pi/raspi2/kernel7.img diff --git a/bsp/raspberry-pi/raspi2/kernel7.img b/bsp/raspberry-pi/raspi2/kernel7.img deleted file mode 100755 index 82e849b25d9544e80bce3664bea3cd509f1df0b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91456 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 Date: Wed, 15 Jan 2020 21:05:12 +0800 Subject: [PATCH 067/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=20PWM9=5FCO?= =?UTF-8?q?NFIG=20=E9=BB=98=E8=AE=A4=E9=85=8D=E7=BD=AE=20=E5=92=8C=20TIM3?= =?UTF-8?q?=5FCONFIG=20=E9=BB=98=E8=AE=A4=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libraries/HAL_Drivers/config/f4/pwm_config.h | 11 +++++++++++ .../libraries/HAL_Drivers/config/f4/tim_config.h | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f4/pwm_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f4/pwm_config.h index 14d4aa2aff..3803303493 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f4/pwm_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f4/pwm_config.h @@ -61,6 +61,17 @@ extern "C" { #endif /* PWM5_CONFIG */ #endif /* BSP_USING_PWM5 */ +#ifdef BSP_USING_PWM9 +#ifndef PWM9_CONFIG +#define PWM9_CONFIG \ + { \ + .tim_handle.Instance = TIM9, \ + .name = "pwm9", \ + .channel = 0 \ + } +#endif /* PWM9_CONFIG */ +#endif /* BSP_USING_PWM9 */ + #ifdef BSP_USING_PWM12 #ifndef PWM12_CONFIG #define PWM12_CONFIG \ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f4/tim_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f4/tim_config.h index cd116d9e19..bc08f219b9 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f4/tim_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f4/tim_config.h @@ -27,6 +27,17 @@ extern "C" { } #endif /* TIM_DEV_INFO_CONFIG */ +#ifdef BSP_USING_TIM3 +#ifndef TIM3_CONFIG +#define TIM3_CONFIG \ + { \ + .tim_handle.Instance = TIM3, \ + .tim_irqn = TIM3_IRQn, \ + .name = "timer3", \ + } +#endif /* TIM3_CONFIG */ +#endif /* BSP_USING_TIM3 */ + #ifdef BSP_USING_TIM11 #ifndef TIM11_CONFIG #define TIM11_CONFIG \ -- Gitee From fe24ae7ca422a735f22fedb6ac03150ba49401a7 Mon Sep 17 00:00:00 2001 From: Watson Zeng Date: Thu, 16 Jan 2020 16:00:13 +0800 Subject: [PATCH 068/110] [bsp][synopsys] add basic new embarc bsp support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * the initial support of synopsys designware ARC processor using embARC_BSP, all synopsys ARC-based boards are supported: -ARC Software Development Platform -ARC EM Starter Kit -ARC EM Software Development Platform -ARC HS Development Kit -ARC IoT Development Kit * The embARC BSP is a new generation embARC software development package. ​It is designed to be the inter-layer between hardware and operating system. ​ BSP could hide the difference of hardware/boards, provide a unified interface to upper-layer. * the initial support of synopsys MWDT toolchain. The DesignWare® ARC® MetaWare Development Toolkit builds upon a 25-year legacy of industry-leading compiler and debugger products. It is a complete solution that contains all the components needed to support the development, debugging and tuning of embedded applications for the DesignWare ARC processors. * for detailed board information, pls go embarc.org. Signed-off-by: Watson Zeng --- bsp/synopsys/{emsk_em9d => boards}/.config | 254 ++- bsp/synopsys/{emsk_em9d => boards}/Kconfig | 1 + bsp/synopsys/boards/README.md | 128 ++ bsp/synopsys/{emsk_em9d => boards}/SConscript | 1 - bsp/synopsys/boards/SConstruct | 325 ++++ .../applications/SConscript | 0 .../applications/application.c | 0 .../applications/startup.c | 11 +- .../{emsk_em9d => boards}/drivers/Kconfig | 0 .../{emsk_em9d => boards}/drivers/SConscript | 0 .../board.c => boards/drivers/rt_board.c} | 261 +-- .../board.h => boards/drivers/rt_board.h} | 18 +- bsp/synopsys/boards/linker_template_gnu.ld | 169 ++ bsp/synopsys/boards/linker_template_mw.ld | 154 ++ bsp/synopsys/boards/rtconfig.h | 157 ++ .../{emsk_em9d => boards}/rtconfig.py | 52 +- bsp/synopsys/embarc/SConscript | 28 - bsp/synopsys/embarc/arc/arc_cache.c | 420 ----- bsp/synopsys/embarc/arc/arc_exc_asm.S | 201 --- bsp/synopsys/embarc/arc/arc_exception.c | 501 ------ bsp/synopsys/embarc/arc/arc_timer.c | 211 --- .../embarc/arc/startup/arc_cxx_support.c | 168 -- bsp/synopsys/embarc/arc/startup/arc_startup.S | 262 --- .../embarc/device/designware/gpio/dw_gpio.c | 481 ----- .../embarc/device/designware/gpio/dw_gpio.h | 145 -- .../embarc/device/designware/iic/dw_iic.c | 1584 ----------------- .../embarc/device/designware/iic/dw_iic.h | 242 --- .../embarc/device/designware/iic/dw_iic_hal.h | 186 -- .../device/designware/iic/dw_iic_hal_cfg.h | 82 - .../embarc/device/designware/spi/dw_spi.c | 1337 -------------- .../embarc/device/designware/spi/dw_spi.h | 190 -- .../embarc/device/designware/spi/dw_spi_hal.h | 141 -- .../device/designware/spi/dw_spi_hal_cfg.h | 58 - .../embarc/device/designware/uart/dw_uart.c | 956 ---------- .../embarc/device/designware/uart/dw_uart.h | 141 -- .../device/designware/uart/dw_uart_hal.h | 253 --- .../embarc/device/device_hal/inc/dev_common.h | 173 -- .../embarc/device/device_hal/inc/dev_gpio.h | 424 ----- .../embarc/device/device_hal/inc/dev_iic.h | 526 ------ .../embarc/device/device_hal/inc/dev_spi.h | 577 ------ .../embarc/device/device_hal/inc/dev_uart.h | 475 ----- bsp/synopsys/embarc/inc/arc/arc.h | 436 ----- bsp/synopsys/embarc/inc/arc/arc_asm_common.h | 541 ------ bsp/synopsys/embarc/inc/arc/arc_builtin.h | 301 ---- bsp/synopsys/embarc/inc/arc/arc_cache.h | 321 ---- bsp/synopsys/embarc/inc/arc/arc_em.h | 133 -- bsp/synopsys/embarc/inc/arc/arc_exception.h | 461 ----- .../embarc/inc/arc/arc_feature_config.h | 397 ----- bsp/synopsys/embarc/inc/arc/arc_timer.h | 99 -- bsp/synopsys/embarc/inc/embARC_debug.h | 94 - bsp/synopsys/embarc/inc/embARC_error.h | 156 -- bsp/synopsys/embarc/inc/embARC_toolchain.h | 121 -- bsp/synopsys/emsk_em9d/README.md | 77 - bsp/synopsys/emsk_em9d/SConstruct | 53 - .../emsk_em9d/drivers/arc_core_config.h | 229 --- bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c | 324 ---- bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h | 51 - bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c | 210 --- bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h | 52 - .../emsk_em9d/drivers/embARC_BSP_config.h | 39 - .../emsk_em9d/drivers/emsk_hardware.h | 85 - bsp/synopsys/emsk_em9d/drivers/mux.c | 67 - bsp/synopsys/emsk_em9d/drivers/mux.h | 147 -- bsp/synopsys/emsk_em9d/drivers/mux_hal.h | 29 - bsp/synopsys/emsk_em9d/emsk_em9d.ld | 114 -- bsp/synopsys/emsk_em9d/figures/emsk_board.jpg | Bin 483486 -> 0 bytes bsp/synopsys/emsk_em9d/openocd.log | 9 - bsp/synopsys/emsk_em9d/rtconfig.h | 143 -- libcpu/arc/em/SConscript | 4 +- .../arc/em/{contex_gcc.S => contex_gcc_mw.S} | 162 +- libcpu/arc/em/cpuport.c | 28 +- 71 files changed, 1399 insertions(+), 14777 deletions(-) rename bsp/synopsys/{emsk_em9d => boards}/.config (55%) rename bsp/synopsys/{emsk_em9d => boards}/Kconfig (94%) create mode 100644 bsp/synopsys/boards/README.md rename bsp/synopsys/{emsk_em9d => boards}/SConscript (82%) create mode 100644 bsp/synopsys/boards/SConstruct rename bsp/synopsys/{emsk_em9d => boards}/applications/SConscript (100%) rename bsp/synopsys/{emsk_em9d => boards}/applications/application.c (100%) rename bsp/synopsys/{emsk_em9d => boards}/applications/startup.c (81%) rename bsp/synopsys/{emsk_em9d => boards}/drivers/Kconfig (100%) rename bsp/synopsys/{emsk_em9d => boards}/drivers/SConscript (100%) rename bsp/synopsys/{emsk_em9d/drivers/board.c => boards/drivers/rt_board.c} (40%) rename bsp/synopsys/{emsk_em9d/drivers/board.h => boards/drivers/rt_board.h} (30%) create mode 100644 bsp/synopsys/boards/linker_template_gnu.ld create mode 100644 bsp/synopsys/boards/linker_template_mw.ld create mode 100644 bsp/synopsys/boards/rtconfig.h rename bsp/synopsys/{emsk_em9d => boards}/rtconfig.py (30%) delete mode 100644 bsp/synopsys/embarc/SConscript delete mode 100644 bsp/synopsys/embarc/arc/arc_cache.c delete mode 100644 bsp/synopsys/embarc/arc/arc_exc_asm.S delete mode 100644 bsp/synopsys/embarc/arc/arc_exception.c delete mode 100644 bsp/synopsys/embarc/arc/arc_timer.c delete mode 100644 bsp/synopsys/embarc/arc/startup/arc_cxx_support.c delete mode 100644 bsp/synopsys/embarc/arc/startup/arc_startup.S delete mode 100644 bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c delete mode 100644 bsp/synopsys/embarc/device/designware/gpio/dw_gpio.h delete mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic.c delete mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic.h delete mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h delete mode 100644 bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h delete mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi.c delete mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi.h delete mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h delete mode 100644 bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h delete mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart.c delete mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart.h delete mode 100644 bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_common.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h delete mode 100644 bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_asm_common.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_builtin.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_cache.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_em.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_exception.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_feature_config.h delete mode 100644 bsp/synopsys/embarc/inc/arc/arc_timer.h delete mode 100644 bsp/synopsys/embarc/inc/embARC_debug.h delete mode 100644 bsp/synopsys/embarc/inc/embARC_error.h delete mode 100644 bsp/synopsys/embarc/inc/embARC_toolchain.h delete mode 100644 bsp/synopsys/emsk_em9d/README.md delete mode 100644 bsp/synopsys/emsk_em9d/SConstruct delete mode 100644 bsp/synopsys/emsk_em9d/drivers/arc_core_config.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c delete mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c delete mode 100644 bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/mux.c delete mode 100644 bsp/synopsys/emsk_em9d/drivers/mux.h delete mode 100644 bsp/synopsys/emsk_em9d/drivers/mux_hal.h delete mode 100644 bsp/synopsys/emsk_em9d/emsk_em9d.ld delete mode 100644 bsp/synopsys/emsk_em9d/figures/emsk_board.jpg delete mode 100644 bsp/synopsys/emsk_em9d/openocd.log delete mode 100644 bsp/synopsys/emsk_em9d/rtconfig.h rename libcpu/arc/em/{contex_gcc.S => contex_gcc_mw.S} (61%) diff --git a/bsp/synopsys/emsk_em9d/.config b/bsp/synopsys/boards/.config similarity index 55% rename from bsp/synopsys/emsk_em9d/.config rename to bsp/synopsys/boards/.config index 8451f5d956..6ae650f8cc 100644 --- a/bsp/synopsys/emsk_em9d/.config +++ b/bsp/synopsys/boards/.config @@ -6,7 +6,8 @@ # # RT-Thread Kernel # -CONFIG_RT_NAME_MAX=8 +CONFIG_RT_NAME_MAX=16 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_SMP is not set CONFIG_RT_ALIGN_SIZE=4 # CONFIG_RT_THREAD_PRIORITY_8 is not set @@ -18,11 +19,14 @@ CONFIG_RT_USING_OVERFLOW_CHECK=y CONFIG_RT_USING_HOOK=y CONFIG_RT_USING_IDLE_HOOK=y CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 -CONFIG_IDLE_THREAD_STACK_SIZE=256 -# CONFIG_RT_USING_TIMER_SOFT is not set +CONFIG_IDLE_THREAD_STACK_SIZE=1024 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=512 CONFIG_RT_DEBUG=y CONFIG_RT_DEBUG_COLOR=y -# CONFIG_RT_DEBUG_INIT_CONFIG is not set +CONFIG_RT_DEBUG_INIT_CONFIG=y +CONFIG_RT_DEBUG_INIT=1 # CONFIG_RT_DEBUG_THREAD_CONFIG is not set # CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set # CONFIG_RT_DEBUG_IPC_CONFIG is not set @@ -47,10 +51,11 @@ CONFIG_RT_USING_MESSAGEQUEUE=y # Memory Management # CONFIG_RT_USING_MEMPOOL=y -# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_MEMHEAP=y # CONFIG_RT_USING_NOHEAP is not set CONFIG_RT_USING_SMALL_MEM=y # CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set # CONFIG_RT_USING_MEMTRACE is not set CONFIG_RT_USING_HEAP=y @@ -63,7 +68,8 @@ CONFIG_RT_USING_DEVICE=y CONFIG_RT_USING_CONSOLE=y CONFIG_RT_CONSOLEBUF_SIZE=128 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" -CONFIG_RT_VER_NUM=0x40000 +CONFIG_RT_VER_NUM=0x40002 +CONFIG_RT_USING_CPU_FFS=y # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set # @@ -99,47 +105,39 @@ CONFIG_FINSH_ARG_MAX=10 # # Device virtual file system # -CONFIG_RT_USING_DFS=y -CONFIG_DFS_USING_WORKDIR=y -CONFIG_DFS_FILESYSTEMS_MAX=2 -CONFIG_DFS_FILESYSTEM_TYPES_MAX=2 -CONFIG_DFS_FD_MAX=16 -# CONFIG_RT_USING_DFS_MNTTABLE is not set -# CONFIG_RT_USING_DFS_ELMFAT is not set -CONFIG_RT_USING_DFS_DEVFS=y -# CONFIG_RT_USING_DFS_ROMFS is not set -# CONFIG_RT_USING_DFS_RAMFS is not set -# CONFIG_RT_USING_DFS_UFFS is not set -# CONFIG_RT_USING_DFS_JFFS2 is not set -# CONFIG_RT_USING_DFS_NFS is not set +# CONFIG_RT_USING_DFS is not set # # Device Drivers # CONFIG_RT_USING_DEVICE_IPC=y -CONFIG_RT_PIPE_BUFSZ=512 +CONFIG_RT_PIPE_BUFSZ=1024 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=4096 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=8 CONFIG_RT_USING_SERIAL=y -CONFIG_RT_SERIAL_USING_DMA=y +# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_RB_BUFSZ=1024 # CONFIG_RT_USING_CAN is not set # CONFIG_RT_USING_HWTIMER is not set # CONFIG_RT_USING_CPUTIME is not set # CONFIG_RT_USING_I2C is not set -CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_PIN is not set # CONFIG_RT_USING_ADC is not set # CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set -# CONFIG_RT_USING_MTD is not set # CONFIG_RT_USING_PM is not set # CONFIG_RT_USING_RTC is not set # CONFIG_RT_USING_SDIO is not set # CONFIG_RT_USING_SPI is not set # CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_AUDIO is not set - -# -# Using WiFi -# +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set # CONFIG_RT_USING_WIFI is not set # @@ -151,10 +149,9 @@ CONFIG_RT_USING_PIN=y # # POSIX layer and C standard library # -CONFIG_RT_USING_LIBC=y +# CONFIG_RT_USING_LIBC is not set # CONFIG_RT_USING_PTHREADS is not set -# CONFIG_RT_USING_POSIX is not set -# CONFIG_RT_USING_MODULE is not set +# CONFIG_RT_LIBC_USING_TIME is not set # # Network @@ -163,88 +160,22 @@ CONFIG_RT_USING_LIBC=y # # Socket abstraction layer # -CONFIG_RT_USING_SAL=y +# CONFIG_RT_USING_SAL is not set # -# protocol stack implement +# Network interface device # -CONFIG_SAL_USING_LWIP=y -CONFIG_SAL_USING_AT=y -# CONFIG_SAL_USING_POSIX is not set -CONFIG_SAL_SOCKETS_NUM=16 -CONFIG_SAL_PROTO_FAMILIES_NUM=4 +# CONFIG_RT_USING_NETDEV is not set # # light weight TCP/IP stack # -CONFIG_RT_USING_LWIP=y -# CONFIG_RT_USING_LWIP141 is not set -CONFIG_RT_USING_LWIP202=y -# CONFIG_RT_USING_LWIP210 is not set -# CONFIG_RT_USING_LWIP_IPV6 is not set -CONFIG_RT_LWIP_IGMP=y -CONFIG_RT_LWIP_ICMP=y -# CONFIG_RT_LWIP_SNMP is not set -CONFIG_RT_LWIP_DNS=y -CONFIG_RT_LWIP_DHCP=y -CONFIG_IP_SOF_BROADCAST=1 -CONFIG_IP_SOF_BROADCAST_RECV=1 - -# -# Static IPv4 Address -# -CONFIG_RT_LWIP_IPADDR="192.168.1.30" -CONFIG_RT_LWIP_GWADDR="192.168.1.1" -CONFIG_RT_LWIP_MSKADDR="255.255.255.0" -CONFIG_RT_LWIP_UDP=y -CONFIG_RT_LWIP_TCP=y -# CONFIG_RT_LWIP_RAW is not set -# CONFIG_RT_LWIP_PPP is not set -CONFIG_RT_MEMP_NUM_NETCONN=8 -CONFIG_RT_LWIP_PBUF_NUM=16 -CONFIG_RT_LWIP_RAW_PCB_NUM=4 -CONFIG_RT_LWIP_UDP_PCB_NUM=4 -CONFIG_RT_LWIP_TCP_PCB_NUM=4 -CONFIG_RT_LWIP_TCP_SEG_NUM=40 -CONFIG_RT_LWIP_TCP_SND_BUF=8196 -CONFIG_RT_LWIP_TCP_WND=8196 -CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10 -CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=8 -CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=1024 -# CONFIG_LWIP_NO_RX_THREAD is not set -# CONFIG_LWIP_NO_TX_THREAD is not set -CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12 -CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024 -CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8 -# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set -CONFIG_LWIP_NETIF_STATUS_CALLBACK=1 -CONFIG_SO_REUSE=1 -CONFIG_LWIP_SO_RCVTIMEO=1 -CONFIG_LWIP_SO_SNDTIMEO=1 -CONFIG_LWIP_SO_RCVBUF=1 -# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=0 -# CONFIG_RT_LWIP_STATS is not set -# CONFIG_RT_LWIP_DEBUG is not set - -# -# Modbus master and slave stack -# -# CONFIG_RT_USING_MODBUS is not set +# CONFIG_RT_USING_LWIP is not set # # AT commands # -CONFIG_RT_USING_AT=y -# CONFIG_AT_DEBUG is not set -# CONFIG_AT_USING_SERVER is not set -CONFIG_AT_USING_CLIENT=y -CONFIG_AT_CLIENT_NUM_MAX=1 -CONFIG_AT_USING_SOCKET=y -CONFIG_AT_USING_CLI=y -# CONFIG_AT_PRINT_RAW_CMD is not set -CONFIG_AT_SW_VERSION_NUM=0x10200 -# CONFIG_LWIP_USING_DHCPD is not set +# CONFIG_RT_USING_AT is not set # # VBUS(Virtual Software BUS) @@ -254,7 +185,6 @@ CONFIG_AT_SW_VERSION_NUM=0x10200 # # Utilities # -# CONFIG_RT_USING_LOGTRACE is not set # CONFIG_RT_USING_RYM is not set # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set @@ -268,10 +198,14 @@ CONFIG_AT_SW_VERSION_NUM=0x10200 # # CONFIG_PKG_USING_PAHOMQTT is not set # CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set # CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set # CONFIG_PKG_USING_WEBTERMINAL is not set # CONFIG_PKG_USING_CJSON is not set # CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set # CONFIG_PKG_USING_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set @@ -289,25 +223,14 @@ CONFIG_AT_SW_VERSION_NUM=0x10200 # Wiced WiFi # # CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set # CONFIG_PKG_USING_COAP is not set # CONFIG_PKG_USING_NOPOLL is not set # CONFIG_PKG_USING_NETUTILS is not set -CONFIG_PKG_USING_AT_DEVICE=y -CONFIG_PKG_AT_DEVICE_PATH="/packages/iot/at_device" -CONFIG_PKG_AT_INIT_BY_THREAD=y -# CONFIG_AT_DEVICE_M26 is not set -# CONFIG_AT_DEVICE_EC20 is not set -CONFIG_AT_DEVICE_ESP8266=y -# CONFIG_AT_DEVICE_NOT_SELECTED is not set -CONFIG_AT_DEVICE_SOCKETS_NUM=5 -CONFIG_AT_DEVICE_NAME="uart0" -CONFIG_AT_DEVICE_RECV_BUFF_LEN=512 -CONFIG_AT_DEVICE_WIFI_SSID="embarc" -CONFIG_AT_DEVICE_WIFI_PASSWORD="qazwsxedc" -CONFIG_PKG_USING_AT_DEVICE_LATEST_VERSION=y -# CONFIG_PKG_USING_AT_DEVICE_V100 is not set -# CONFIG_PKG_USING_AT_DEVICE_V110 is not set -CONFIG_PKG_AT_DEVICE_VER="latest" +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set # # IoT Cloud @@ -316,6 +239,25 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # CONFIG_PKG_USING_GAGENT_CLOUD is not set # CONFIG_PKG_USING_ALI_IOTKIT is not set # CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOTHUB is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set # # security packages @@ -336,6 +278,9 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # # CONFIG_PKG_USING_OPENMV is not set # CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set # # tools packages @@ -344,6 +289,16 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # CONFIG_PKG_USING_EASYFLASH is not set # CONFIG_PKG_USING_EASYLOGGER is not set # CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set # # system packages @@ -357,17 +312,50 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # CONFIG_PKG_USING_SQLITE is not set # CONFIG_PKG_USING_RTI is not set # CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_CMSIS is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +CONFIG_PKG_USING_EMBARC_BSP=y +CONFIG_PKG_EMBARC_BSP_PATH="/packages/system/embARC_bsp" +CONFIG_PKG_USING_EMBARC_BSP_UPSTREAM_VERSION=y +# CONFIG_PKG_USING_EMBARC_BSP_MASTER_VERSION is not set +CONFIG_PKG_EMBARC_BSP_VER="upstream" # # peripheral libraries and drivers # -# CONFIG_PKG_USING_STM32F4_HAL is not set -# CONFIG_PKG_USING_STM32F4_DRIVERS is not set +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set # CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_SHT2X is not set -# CONFIG_PKG_USING_AHT10 is not set -# CONFIG_PKG_USING_AP3216C is not set +# CONFIG_PKG_USING_SHT3X is not set # CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set # # miscellaneous packages @@ -378,13 +366,15 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # CONFIG_PKG_USING_MINILZO is not set # CONFIG_PKG_USING_QUICKLZ is not set # CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set # CONFIG_PKG_USING_CANFESTIVAL is not set # CONFIG_PKG_USING_ZLIB is not set # CONFIG_PKG_USING_DSTR is not set - -# -# sample package -# +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set # # samples: kernel and components samples @@ -393,11 +383,15 @@ CONFIG_PKG_AT_DEVICE_VER="latest" # CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set # CONFIG_PKG_USING_NETWORK_SAMPLES is not set # CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set - -# -# example package: hello -# # CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_UKAL is not set CONFIG_SOC_EMSK=y CONFIG_EMSK_USING_UART0=y CONFIG_EMSK_USING_UART1=y diff --git a/bsp/synopsys/emsk_em9d/Kconfig b/bsp/synopsys/boards/Kconfig similarity index 94% rename from bsp/synopsys/emsk_em9d/Kconfig rename to bsp/synopsys/boards/Kconfig index 1bdec3c71f..cfab678244 100644 --- a/bsp/synopsys/emsk_em9d/Kconfig +++ b/bsp/synopsys/boards/Kconfig @@ -23,6 +23,7 @@ config SOC_EMSK select ARCH_ARC_EM select RT_USING_COMPONENTS_INIT # select RT_USING_USER_MAIN + select RT_USING_CPU_FFS default y source "$BSP_DIR/drivers/Kconfig" diff --git a/bsp/synopsys/boards/README.md b/bsp/synopsys/boards/README.md new file mode 100644 index 0000000000..aee6059cfc --- /dev/null +++ b/bsp/synopsys/boards/README.md @@ -0,0 +1,128 @@ +# Synopsys ARC Boards support with embARC_BSP + +## embARC_BSP + +The embARC Board support Package (BSP) is a software distributions aimed at facilitating +the development and evaluation of embedded systems based on ARCv2 processors, which is +designed to provide a minimal board support package for ARC users by defining +consistent and simple software interfaces to the processors and onboard devices. + +The embARC BSP is a new generation embARC software development package. ​ +It is designed to be the inter-layer between hardware and operating system. ​ +BSP could hide the difference of hardware/boards, provide a unified interface to upper-layer. ​ +In the scenarios that no OS is required, embARC BSP can also standalone and work in baremetal. + +embARC_BSP features: + +* Support MetaWare & GNU toolchains​ +* Support all development boards and tcf​ +* Support various build systems and compiling environments, + such as ARC MetaWare & GNU IDE, makefile​ +* Designware and Subsystem drivers, including UART and GPIO, I2C, SPI, etc. ​ +* No middleware, no OS​ +* Easy to port to different platform / OS​ +* One example (UART, GPIO, timer)​ +* Code coverage reach 100% in test. ​ +* MISRA-C compliance​ +* C & C++ support, assembly support + +## Supported Boards + +* [ARC Software Development Platform](https://www.synopsys.com/dw/ipdir.php?ds=arc-software-development-platform) +* [ARC EM Starter Kit](https://www.synopsys.com/dw/ipdir.php?ds=arc_em_starter_kit) +* [ARC EM Software Development Platform](https://www.synopsys.com/dw/ipdir.php?ds=arc-em-software-development-platform) +* [ARC HS Development Kit](https://www.synopsys.com/dw/ipdir.php?ds=arc-hs-development-kit) +* [ARC IoT Development Kit](https://www.synopsys.com/dw/ipdir.php?ds=arc_iot_development_kit) + + +## Software Requirement + +### embarc_bsp + +There are two ways to get embarc_bsp: + +#### use RT-Thread ENV tool: + +embARC_BSP has been configured as package module, you can just run the command `pkgs --update` in /bsp/synopsys/boards +folder using ENV tool. + +#### without RT-Thread ENV tool: + +We can get it from github: [embarc_bsp](https://github.com/foss-for-synopsys-dwc-arc-processors) + +The default path for embarc_bsp is /bsp/synopsys/boards/packages/embARC_bsp-upstream, +when you use other path, please set the environment variable `EMBARC_BSP_ROOT`. + +### Toolchain + +Now both GNU and MetaWare Toolchain are supported, set the System environment variable RTT_CC select the toolchain. + +GNU: + + set RTT_CC=gnu + +MetaWare: + + set RTT_CC=mw + +#### GNU + +The ARC GNU Toolchain offers all of the benefits of open source tools, including complete source code and a large install base. The ARC GNU IDE Installer consists of Eclipse IDE with [ARC GNU plugin for Eclipse](https://github.com/foss-for-synopsys-dwc-arc-processors/arc_gnu_eclipse/releases), [ARC GNU prebuilt toolchain](https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases) and [OpenOCD for ARC](https://github.com/foss-for-synopsys-dwc-arc-processors/openocd>) + +Here, the ARC GNU toolchain is installed to `c:\arc_gnu`. If not, please change the path configuration in rtconfig.py. + +When you use GNU Toolchain, you need to install [Zadig](http://zadig.akeo.ie) to replace the default FTDI driver with WinUSB driver. See [How to Use OpenOCD on Windows](https://github.com/foss-for-synopsys-dwc-arc-processors/arc_gnu_eclipse/wiki/How-to-Use-OpenOCD-on-Windows>) for more information. + +#### MetaWare +The [DesignWare ARC MetaWare Development Toolkit](https://www.synopsys.com/dw/ipdir.php?ds=sw_metaware) builds on a long legacy of industry-leading compiler and debugger products for embedded applications. It is a complete solution that contains all the components needed to support the development, debugging, and tuning of embedded applications for the DesignWare® ARC® processors. + +Here, the ARC MetaWare toolchain is installed to `C:\ARC\MetaWare`. If not, please change the path configuration in rtconfig.py. + + + + + +## Build & Debug + +### Build embarc_lib + +please run the following cmds to build embarc_lib + + cd /bsp/synopsys/boards + scons --embarc_build + +### Build + +please run the following cmds to build + + cd /bsp/synopsys/boards + scons + +### Debug + +After compile, please use the following cmds to debug + + scons --gdb #use gdb debugger + scons --mdb #use mdb debugger + + +### How to choose different boards + +There are some parameters we can use in scons, for example: + + scons --BOARD=emsk --BD_VER=23 --CUR_CORE=arcem9d --TOOLCHAIN=mw --OLEVEL=O2 + + * BOARD: choose the board, we can set: `emsk, iotdk, emsdp, hsdk, axs`. + * BD_VER: choose the board version, some boards have different versions, for example, + we can set: `10, 22, 23` for emsk board. + * CUR_CORE: choose the arc cores, some boards have different cores, for example, + we can set: `arcem7d, arcem9d, arcem11d` for emsk board. + * TOOLCHAIN: choose the toolchain to build embarc_lib, we can set: `mw, gnu`. + * OLEVEL: choose the build optimize level, we can set: `O0, O2, Os`. + +For more information, you can run the command `scons -h`. + + +## Maintainer +- [vonhust](https://github.com/vonhust) +- [IRISZZW](https://github.com/IRISZZW) diff --git a/bsp/synopsys/emsk_em9d/SConscript b/bsp/synopsys/boards/SConscript similarity index 82% rename from bsp/synopsys/emsk_em9d/SConscript rename to bsp/synopsys/boards/SConscript index 86b6c891cd..2e95f4716c 100644 --- a/bsp/synopsys/emsk_em9d/SConscript +++ b/bsp/synopsys/boards/SConscript @@ -8,7 +8,6 @@ list = os.listdir(cwd) ASFLAGS = ' -I' + cwd -objs = objs + SConscript(os.path.join(cwd, '../embarc/SConscript')) for d in list: path = os.path.join(cwd, d) diff --git a/bsp/synopsys/boards/SConstruct b/bsp/synopsys/boards/SConstruct new file mode 100644 index 0000000000..a66e7ec76a --- /dev/null +++ b/bsp/synopsys/boards/SConstruct @@ -0,0 +1,325 @@ +import os +import sys + +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] + + +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +if os.getenv('EMBARC_BSP_ROOT'): + EMBARC_BSP_ROOT = os.getenv('EMBARC_BSP_ROOT') +else: + EMBARC_BSP_ROOT = RTT_ROOT + '/bsp/synopsys/boards/packages/embARC_bsp-upstream' + +if not os.path.isdir(EMBARC_BSP_ROOT): + print('Cannot found embarc_bsp root directory, please check EMBARC_BSP_ROOT') + print(EMBARC_BSP_ROOT) + exit(-1) + +SUPPORTED_BOARD_DIR = EMBARC_BSP_ROOT + '/board' +SUPPORTED_BOARD = [d for d in os.listdir(SUPPORTED_BOARD_DIR) if os.path.isdir(os.path.join(SUPPORTED_BOARD_DIR,d))] +print 'supported BOARD = ' + str(SUPPORTED_BOARD) + +AddOption('--BOARD', + dest = 'BOARD', + type='string', + nargs=1, + action = 'store', + default = 'emsk', + help = 'select board') + +AddOption('--BD_VER', + dest = 'BD_VER', + type='string', + nargs=1, + action = 'store', + default = '23', + help = 'select bd_ver') + +AddOption('--CUR_CORE', + dest = 'CUR_CORE', + type='string', + nargs=1, + action = 'store', + default = 'arcem9d', + help = 'select cur_core') + +AddOption('--TOOLCHAIN', + dest = 'TOOLCHAIN', + type='string', + nargs=1, + action = 'store', + default = 'gnu', + help = 'select toolchain') + +AddOption('--OLEVEL', + dest = 'OLEVEL', + type='string', + nargs=1, + action = 'store', + default = 'O2', + help = 'select optimize level') + +AddOption('--mdb', + dest = 'mdb', + action = 'store_true', + default = False, + help = 'use mdb to debug the elf') + +AddOption('--gdb', + dest = 'gdb', + action = 'store_true', + default = False, + help = 'use gdb to debug the elf') + +AddOption('--embarc_build', + dest = 'embarc_build', + action = 'store_true', + default = False, + help = 'to generate embarc_lib') + +AddOption('--embarc_clean', + dest = 'embarc_clean', + action = 'store_true', + default = False, + help = 'to clean embarc_lib') + +if GetOption('BOARD'): + board = GetOption('BOARD') + if board not in SUPPORTED_BOARD: + print 'board %s not supported, available boards:' % board + print SUPPORTED_BOARD + exit(0) + else: + BOARD = board + print 'get BOARD = [%s]' % board + +if BOARD == 'emsdp': + SUPPORTED_BD_VER = ['rev2'] +else: + SUPPORTED_BD_VER_DIR = SUPPORTED_BOARD_DIR + '/' + BOARD + '/configs' + SUPPORTED_BD_VER = [d for d in os.listdir(SUPPORTED_BD_VER_DIR) if os.path.isdir(os.path.join(SUPPORTED_BD_VER_DIR,d))] +print 'supported BD_VER = ' + str(SUPPORTED_BD_VER) + +if GetOption('BD_VER'): + bd_ver = GetOption('BD_VER') + if bd_ver not in SUPPORTED_BD_VER: + print 'bd_ver %s not supported, available bd_ver:' % bd_ver + print SUPPORTED_BD_VER + exit(0) + else: + BD_VER = bd_ver + print 'get BD_VER = [%s]' % BD_VER + +if BOARD == 'emsdp': + SUPPORTED_CORE_DIR = SUPPORTED_BOARD_DIR + '/' + BOARD + '/rev2/configs' + SUPPORTED_CORE = [d for d in os.listdir(SUPPORTED_CORE_DIR) if os.path.isdir(os.path.join(SUPPORTED_CORE_DIR,d))] +else: + SUPPORTED_CORE_DIR = SUPPORTED_BD_VER_DIR + '/' + BD_VER + '/tcf' + SUPPORTED_CORE = [os.path.splitext(d)[0] for d in os.listdir(SUPPORTED_CORE_DIR)] + +print 'supported CUR_CORE = ' + str(SUPPORTED_CORE) + +if GetOption('CUR_CORE'): + cur_core = GetOption('CUR_CORE') + if cur_core not in SUPPORTED_CORE: + print 'cur_core %s not supported, available cur_core:' % cur_core + print SUPPORTED_CORE + exit(0) + else: + CUR_CORE = cur_core + print 'get CUR_CORE = [%s]' % CUR_CORE + +SUPPORTED_TOOLCHAIN = ['mw', 'gnu'] + +print 'supported TOOLCHAIN = ' + str(SUPPORTED_TOOLCHAIN) + +if GetOption('TOOLCHAIN'): + toolchain = GetOption('TOOLCHAIN') + if toolchain not in SUPPORTED_TOOLCHAIN: + print 'toolchain %s not supported, available toolchain:' % toolchain + print SUPPORTED_TOOLCHAIN + exit(0) + else: + TOOLCHAIN = toolchain + print 'get TOOLCHAIN = [%s]' % TOOLCHAIN + +SUPPORTED_OLEVEL = ['O0', 'O2', 'Os'] + +print 'supported OLEVEL = ' + str(SUPPORTED_OLEVEL) + +if GetOption('OLEVEL'): + olevel = GetOption('OLEVEL') + if olevel not in SUPPORTED_OLEVEL: + print 'olevel %s not supported, available olevel:' % toolchain + print SUPPORTED_OLEVEL + exit(0) + else: + OLEVEL = olevel + print 'get OLEVEL = [%s]' % olevel + + + +EMBARC_LIB_PATH = EMBARC_BSP_ROOT + '/obj_%s_%s/%s_%s'%(BOARD, BD_VER, TOOLCHAIN, CUR_CORE) +# print 'EMBARC_LIB_PATH = %s'%EMBARC_LIB_PATH + +TARGET = 'rtthread_snps_embarc.elf' +# print 'TARGET = %s'%TARGET + +# ip_ph_dir = EMBARC_BSP_ROOT + '/device/peripheral' +# ip_ph_path = [os.path.join(ip_ph_dir,d) for d in os.listdir(ip_ph_dir) if os.path.isdir(os.path.join(ip_ph_dir,d))] + +if BOARD == 'emsdp': + board_inc_path = [SUPPORTED_CORE_DIR, SUPPORTED_CORE_DIR + '/%s/include'%CUR_CORE] +else: + board_inc_path = [EMBARC_BSP_ROOT + '/board/%s/configs/%s'%(BOARD, BD_VER)] + +# print 'board_inc_path = %s' % board_inc_path +# print 'ip_dw_path = %s' % ip_dw_path +# print 'ip_ss_path = %s' % ip_ss_path +# print 'ip_ph_path = %s' % ip_ph_path + +EMBARC_CPPPATH = [ EMBARC_BSP_ROOT, + EMBARC_BSP_ROOT + '/include', + EMBARC_BSP_ROOT + '/board', + EMBARC_LIB_PATH + '/embARC_generated', + ] + board_inc_path +#print "EMBARC_CPPPATH: %s"%EMBARC_CPPPATH + +if TOOLCHAIN == 'mw': + EXEC_PATH = 'C:/ARC/MetaWare/arc/bin' + MAKE = 'gmake' + PREFIX = '' + CC = 'ccac' + CXX = 'ccac' + AS = 'ccac' + AR = 'arac' + LINK = 'ccac' + TARGET_EXT = 'elf' + SIZE = 'sizeac' + OBJDUMP = 'elfdumpac' + OBJCPY = 'elf2bin' + DBG = 'mdb' + + OPT_ARG_FILE = ' @' + EMBARC_LIB_PATH + '/embARC_generated/ccac.arg ' + MDB_ARG_FILE = ' @' + EMBARC_LIB_PATH + '/embARC_generated/mdb.arg ' + COMMON_COMPILE_OPT = ' -Hnoccm -Hnosdata -Wincompatible-pointer-types -Hnocopyr -Hpurge -fdata-sections -g -%s '%(OLEVEL) + COMMON_DEFINES = ' -DBOARD_%s -D__MW__ -DEMBARC_TCF_GENERATED ' % BOARD.upper() + + CFLAGS = OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + ' -Hnocplus ' + CXXFLAGS = OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + AFLAGS = ' -c' + OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + ' -Hasmcpp -I%s -I%s/embARC_generated -I%s/include '%(EMBARC_BSP_ROOT, EMBARC_LIB_PATH, EMBARC_BSP_ROOT) + + LINKER_SCRIPT_FILE = RTT_ROOT + '/bsp/synopsys/boards/linker_template_mw.ld' + LINK_SCRIPT = EMBARC_LIB_PATH + '/linker_mw.ldf' + + LFLAGS = ' -Hhostlink ' + OPT_ARG_FILE + ' -Hnocopyr -Hnosdata -Hnocrt -Hldopt=-Coutput=rtthread_snps_embarc.map -Hldopt=-Csections -Hldopt=-Ccrossfunc -Hldopt=-Csize -zstdout %s' % LINK_SCRIPT + +elif TOOLCHAIN == 'gnu': + EXEC_PATH = 'C:/arc_gnu/bin' + MAKE = 'make' + PREFIX = 'arc-elf32-' + CC = PREFIX + 'gcc' + CXX = PREFIX + 'g++' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + DBG = PREFIX + 'gdb' + + OPT_ARG_FILE = ' @' + EMBARC_LIB_PATH + '/embARC_generated/gcc.arg ' + MDB_ARG_FILE = ' @' + EMBARC_LIB_PATH + '/embARC_generated/mdb.arg ' + COMMON_COMPILE_OPT = ' -ffunction-sections -fdata-sections -mno-sdata -g -%s '%(OLEVEL) + COMMON_DEFINES = ' -DBOARD_%s -D__GNU__ -DEMBARC_TCF_GENERATED ' % BOARD.upper() + + CFLAGS = OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + ' -std=gnu99 ' + CXXFLAGS = OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + AFLAGS = ' -c ' + OPT_ARG_FILE + COMMON_COMPILE_OPT + COMMON_DEFINES + ' -x assembler-with-cpp -I%s -I%s/embARC_generated -I%s/include '%(EMBARC_BSP_ROOT, EMBARC_LIB_PATH, EMBARC_BSP_ROOT) + + LINKER_SCRIPT_FILE = RTT_ROOT + '/bsp/synopsys/boards/linker_template_gnu.ld' + LINK_SCRIPT = EMBARC_LIB_PATH + '/linker_gnu.ldf' + + LFLAGS = ' --specs=nsim.specs ' + OPT_ARG_FILE + ' -mno-sdata -nostartfiles -Wl,--gc-sections,-Map=rtthread_snps_embarc.map,-cref,-u,system_vectors -T %s ' % LINK_SCRIPT + + OPENOCD_SCRIPT_ROOT = EXEC_PATH + '/../share/openocd/scripts' + OPENOCD_CFG_FILE = OPENOCD_SCRIPT_ROOT + '/board/snps_em_sk_v2.2.cfg' + + OPENOCD_OPTIONS = '-s %s -f %s' % (OPENOCD_SCRIPT_ROOT, OPENOCD_CFG_FILE) + + DBG_HW_FLAGS = ''' -ex "target remote | openocd --pipe %s" -ex "load" ''' % OPENOCD_OPTIONS + +else : + print 'TOOLCHAIN %s is not supported, available toolchain:' % TOOLCHAIN + print SUPPORTED_TOOLCHAIN + exit(-1) + +env = Environment(ENV = os.environ, tools = ['mingw'], + AS = AS, ASFLAGS = AFLAGS, + CC = CC, CCFLAGS = CFLAGS, + AR = AR, ARFLAGS = '-rc', + LINK = LINK, LINKFLAGS = LFLAGS, + LIBS = ['embarc'], LIBPATH = EMBARC_LIB_PATH, + CPPPATH = EMBARC_CPPPATH + ) +env.PrependENVPath('PATH', EXEC_PATH) + +Export('RTT_ROOT') +Export('rtconfig') + +embarc_cd_cmd = ' cd %s '%EMBARC_BSP_ROOT +embarc_make_cmd = ' %s -f options/options.mk BOARD=%s BD_VER=%s CUR_CORE=%s TOOLCHAIN=%s V=1 OLEVEL=%s LINKER_SCRIPT_FILE=%s embarc_lib '%(MAKE,BOARD, BD_VER, CUR_CORE, TOOLCHAIN, OLEVEL, LINKER_SCRIPT_FILE) +embarc_clean_cmd = ' %s -f options/options.mk distclean '%MAKE + +if GetOption('embarc_build'): + print 'os.system: ' + embarc_cd_cmd + ' && ' + embarc_make_cmd + os.system(embarc_cd_cmd + ' && ' + embarc_make_cmd) + exit(0) + +if GetOption('embarc_clean'): + os.system(embarc_cd_cmd + ' && ' + embarc_clean_cmd) + exit(0) + +if GetOption('gdb'): + if os.path.isfile(TARGET): + os.system(DBG + DBG_HW_FLAGS + TARGET) + else: + print TARGET + 'not exist, please build first!!' + exit(0) + +if GetOption('mdb'): + if os.path.isfile(TARGET): + startup_path = EMBARC_BSP_ROOT + '/arc/startup' + if BOARD == 'nsim': + os.system('mdb -source_path=%s -nooptions -nogoifmain -toggle=include_local_symbols=1 -nsim -off=binary_stdin -off=binary_stdout \ + -on=load_at_paddr -on=reset_upon_restart -off=flush_pipe -off=cr_for_more -OKN %s '%(startup_path, MDB_ARG_FILE) + rtconfig.TARGET) + else: + os.system('mdb -source_path=%s -nooptions -nogoifmain -toggle=include_local_symbols=1 -hard -digilent '%startup_path + rtconfig.TARGET) + else: + print TARGET + 'not exist, please build first!!' + exit(0) + +# os.system(embarc_cd_cmd + ' && ' + embarc_make_cmd) + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +# if the linker script changed, relink the target +Depends(TARGET, LINK_SCRIPT) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/synopsys/emsk_em9d/applications/SConscript b/bsp/synopsys/boards/applications/SConscript similarity index 100% rename from bsp/synopsys/emsk_em9d/applications/SConscript rename to bsp/synopsys/boards/applications/SConscript diff --git a/bsp/synopsys/emsk_em9d/applications/application.c b/bsp/synopsys/boards/applications/application.c similarity index 100% rename from bsp/synopsys/emsk_em9d/applications/application.c rename to bsp/synopsys/boards/applications/application.c diff --git a/bsp/synopsys/emsk_em9d/applications/startup.c b/bsp/synopsys/boards/applications/startup.c similarity index 81% rename from bsp/synopsys/emsk_em9d/applications/startup.c rename to bsp/synopsys/boards/applications/startup.c index f561436272..817bf74c9a 100644 --- a/bsp/synopsys/emsk_em9d/applications/startup.c +++ b/bsp/synopsys/boards/applications/startup.c @@ -7,7 +7,12 @@ #include #include -#include +#include + +#ifdef RT_USING_HEAP +#define rt_system_heap_size 1024*64 +static rt_uint32_t rt_system_heap[rt_system_heap_size/4] = {0}; +#endif extern int rt_application_init(void); @@ -33,7 +38,7 @@ void rtthread_startup(void) /* initialize memory system */ #ifdef RT_USING_HEAP - rt_system_heap_init(HEAP_BEGIN, HEAP_END); + rt_system_heap_init((void *)rt_system_heap, (void *)(rt_system_heap+rt_system_heap_size)); #endif /* initialize scheduler system */ @@ -58,7 +63,7 @@ void rtthread_startup(void) return ; } -int board_main(void) +int main(void) { /* disable interrupt first */ rt_hw_interrupt_disable(); diff --git a/bsp/synopsys/emsk_em9d/drivers/Kconfig b/bsp/synopsys/boards/drivers/Kconfig similarity index 100% rename from bsp/synopsys/emsk_em9d/drivers/Kconfig rename to bsp/synopsys/boards/drivers/Kconfig diff --git a/bsp/synopsys/emsk_em9d/drivers/SConscript b/bsp/synopsys/boards/drivers/SConscript similarity index 100% rename from bsp/synopsys/emsk_em9d/drivers/SConscript rename to bsp/synopsys/boards/drivers/SConscript diff --git a/bsp/synopsys/emsk_em9d/drivers/board.c b/bsp/synopsys/boards/drivers/rt_board.c similarity index 40% rename from bsp/synopsys/emsk_em9d/drivers/board.c rename to bsp/synopsys/boards/drivers/rt_board.c index 449360f3a5..1e1b7e494b 100644 --- a/bsp/synopsys/emsk_em9d/drivers/board.c +++ b/bsp/synopsys/boards/drivers/rt_board.c @@ -10,57 +10,11 @@ #include #include -#include "board.h" -#include "inc/arc/arc_timer.h" -#include "inc/arc/arc_exception.h" +#include "rt_board.h" +#include "arc/arc_timer.h" +#include "arc/arc_exception.h" -#include "inc/embARC_error.h" -#include "mux.h" -#include "dw_uart_obj.h" - - -static void rt_hw_timer_isr(int vector, void *param) -{ - arc_timer_int_clear(BOARD_OS_TIMER_ID); - rt_tick_increase(); -} - -static void emsk_mux_init(void) -{ - MUX_REG *mux_regs; - - mux_regs = (MUX_REG *)(PERIPHERAL_BASE|REL_REGBASE_PINMUX); - mux_init(mux_regs); - - /** - * + Please refer to corresponding EMSK User Guide for detailed information - * -> Appendix: A Hardware Functional Description - * -> Pmods Configuration summary - * + Set up pin-multiplexer of all PMOD connections - * - PM1 J1: Upper row as UART 0, lower row as SPI Slave - * - PM2 J2: IIC 0 and run/halt signals - * - PM3 J3: GPIO Port A and Port C - * - PM4 J4: IIC 1 and Port D - * - PM5 J5: Upper row as SPI Master, lower row as Port A - * - PM6 J6: Upper row as SPI Master, lower row as Port A - */ - set_pmod_mux(mux_regs, PM1_UR_UART_0 | PM1_LR_SPI_S \ - | PM2_I2C_HRI \ - | PM3_GPIO_AC \ - | PM4_I2C_GPIO_D \ - | PM5_UR_SPI_M1 | PM5_LR_GPIO_A \ - | PM6_UR_SPI_M0 | PM6_LR_GPIO_A ); - - /** - * PM1 upper row as UART - * UM4:RXD, UM3:TXD - * UM2:RTS_N, UM1:CTS_N - */ - set_uart_map(mux_regs, 0xe4); -} - -static struct rt_serial_device _emsk_uart0; //abstracted serial for RTT -static struct rt_serial_device _emsk_uart1; +#include "embARC_error.h" static rt_err_t _configure(struct rt_serial_device *serial, struct serial_configure *cfg) { @@ -158,12 +112,7 @@ static int _getc(struct rt_serial_device *serial) } -static void _emsk_uart0_isr(void *ptr) -{ - rt_hw_serial_isr((struct rt_serial_device*)&_emsk_uart0, RT_SERIAL_EVENT_RX_IND); -} - -static const struct rt_uart_ops _emsk_uart0_ops = +static const struct rt_uart_ops uart_ops = { _configure, _control, @@ -171,18 +120,31 @@ static const struct rt_uart_ops _emsk_uart0_ops = _getc, }; -static void _emsk_uart1_isr(void *ptr) +static struct rt_serial_device uart0; +static struct rt_serial_device uart1; +static struct rt_serial_device uart2; +static struct rt_serial_device uart3; + +static void uart0_isr(void *ptr) { - rt_hw_serial_isr((struct rt_serial_device*)&_emsk_uart1, RT_SERIAL_EVENT_RX_IND); + rt_hw_serial_isr((struct rt_serial_device*)&uart0, RT_SERIAL_EVENT_RX_IND); } -static const struct rt_uart_ops _emsk_uart1_ops = +static void uart1_isr(void *ptr) { - _configure, - _control, - _putc, - _getc, -}; + rt_hw_serial_isr((struct rt_serial_device*)&uart1, RT_SERIAL_EVENT_RX_IND); +} + +static void uart2_isr(void *ptr) +{ + rt_hw_serial_isr((struct rt_serial_device*)&uart2, RT_SERIAL_EVENT_RX_IND); +} + +static void uart3_isr(void *ptr) +{ + rt_hw_serial_isr((struct rt_serial_device*)&uart3, RT_SERIAL_EVENT_RX_IND); +} + int rt_hw_uart_init(void) { @@ -198,86 +160,165 @@ int rt_hw_uart_init(void) config.invert = NRZ_NORMAL; config.bufsz = RT_SERIAL_RB_BUFSZ; - _emsk_uart0.ops = &_emsk_uart0_ops; - _emsk_uart0.config = config; + uart0.ops = &uart_ops; + uart0.config = config; - _emsk_uart1.ops = &_emsk_uart1_ops; - _emsk_uart1.config = config; + uart1.ops = &uart_ops; + uart1.config = config; - /* open UART1 for USB-UART interface */ - uart = uart_get_dev(DW_UART_1_ID); - /* default format: 8bits, no parity, 1 stop bits */ - ret = uart->uart_open(config.baud_rate); + uart2.ops = &uart_ops; + uart2.config = config; - if (ret != E_OPNED && ret != E_OK) { - return RT_ERROR; + uart3.ops = &uart_ops; + uart3.config = config; + + /* uart0 init */ + uart = uart_get_dev(0); + + if (uart != NULL) { + /* default format: 8bits, no parity, 1 stop bits */ + ret = uart->uart_open(config.baud_rate); + + if (ret != E_OPNED && ret != E_OK) { + return RT_ERROR; + } + + /* enable rx int */ + uart->uart_control(UART_CMD_SET_RXINT, (void *)0); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, uart0_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&uart0, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)0); + } + + /* uart1 init */ + uart = uart_get_dev(1); + + if (uart != NULL) { + /* default format: 8bits, no parity, 1 stop bits */ + ret = uart->uart_open(config.baud_rate); + + if (ret != E_OPNED && ret != E_OK) { + return RT_ERROR; + } + + /* enable rx int */ + uart->uart_control(UART_CMD_SET_RXINT, (void *)0); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, uart1_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&uart1, "uart1", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)1); } - /* enable rx int */ - uart->uart_control(UART_CMD_SET_RXINT, (void *)1); - /* use customized int isr */ - uart->uart_control(UART_CMD_SET_RXCB, _emsk_uart1_isr); - uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + /* uart2 init */ + uart = uart_get_dev(2); + + if (uart != NULL) { + /* default format: 8bits, no parity, 1 stop bits */ + ret = uart->uart_open(config.baud_rate); - rt_hw_serial_register(&_emsk_uart1, "uart1", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, - (void *)DW_UART_1_ID); + if (ret != E_OPNED && ret != E_OK) { + return RT_ERROR; + } - /* open UART0 in PMOD A*/ - uart = uart_get_dev(DW_UART_0_ID); - /* default format: 8bits, no parity, 1 stop bits */ - ret = uart->uart_open(config.baud_rate); + /* enable rx int */ + uart->uart_control(UART_CMD_SET_RXINT, (void *)0); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, uart2_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); - if (ret != E_OPNED && ret != E_OK) { - return RT_ERROR; + rt_hw_serial_register(&uart2, "uart2", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)2); } - /* enable rx int */ - uart->uart_control(UART_CMD_SET_RXINT, (void *)1); - /* use customized int isr */ - uart->uart_control(UART_CMD_SET_RXCB, _emsk_uart0_isr); - uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + /* uart3 init */ + uart = uart_get_dev(3); - rt_hw_serial_register(&_emsk_uart0, "uart0", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, - (void *)DW_UART_0_ID); + if (uart != NULL) { + /* default format: 8bits, no parity, 1 stop bits */ + ret = uart->uart_open(config.baud_rate); + + if (ret != E_OPNED && ret != E_OK) { + return RT_ERROR; + } + + /* enable rx int */ + uart->uart_control(UART_CMD_SET_RXINT, (void *)0); + /* use customized int isr */ + uart->uart_control(UART_CMD_SET_RXCB, uart3_isr); + uart->uart_control(UART_CMD_SET_RXINT_BUF, NULL); + + rt_hw_serial_register(&uart3, "uart3", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + (void *)3); + } return RT_EOK; } +#if defined BOARD_EMSK +#define CONSOLE_UART "uart1" +struct rt_serial_device *console_uart = &uart1; +#elif defined BOARD_IOTDK || defined BOARD_EMSDP || defined BOARD_NSIM +#define CONSOLE_UART "uart0" +struct rt_serial_device *console_uart = &uart0; +#elif defined BOARD_AXS +#define CONSOLE_UART "uart2" +struct rt_serial_device *console_uart = &uart2; +#elif defined BOARD_HSDK +#define CONSOLE_UART "uart3" +struct rt_serial_device *console_uart = &uart3; +#else +#error "no supported board selected!" +#endif + void rt_hw_console_output(const char *str) { while(*str != '\0') { if (*str == '\n') { - _putc(&_emsk_uart1,'\r'); + _putc(console_uart,'\r'); } - _putc(&_emsk_uart1,*str); + _putc(console_uart,*str); str++; } } +void rt_hw_board_init() +{ + rt_hw_uart_init(); + rt_components_board_init(); + rt_console_set_device(CONSOLE_UART); +} + + + +static void rt_hw_timer_isr(int vector, void *param) +{ + timer_int_clear(BOARD_OS_TIMER_ID); + rt_tick_increase(); +} + int rt_hw_timer_init(void) { unsigned int cyc = BOARD_CPU_CLOCK / RT_TICK_PER_SECOND; int_disable(BOARD_OS_TIMER_INTNO); /* disable os timer interrupt */ - arc_timer_stop(BOARD_OS_TIMER_ID); - arc_timer_start(BOARD_OS_TIMER_ID, TIMER_CTRL_IE | TIMER_CTRL_NH, cyc); + timer_stop(BOARD_OS_TIMER_ID); + timer_start(BOARD_OS_TIMER_ID, TIMER_CTRL_IE | TIMER_CTRL_NH, cyc); - int_handler_install(BOARD_OS_TIMER_INTNO, (INT_HANDLER)rt_hw_timer_isr); + int_handler_install(BOARD_OS_TIMER_INTNO, (INT_HANDLER_T)rt_hw_timer_isr); + int_pri_set(BOARD_OS_TIMER_INTNO, INT_PRI_MIN + 1); /* currently, firq(INT_PRI_MIN) not supported*/ int_enable(BOARD_OS_TIMER_INTNO); return 0; } INIT_BOARD_EXPORT(rt_hw_timer_init); - -void rt_hw_board_init() -{ - emsk_mux_init(); - - rt_hw_uart_init(); - rt_components_board_init(); - rt_console_set_device(RT_CONSOLE_DEVICE_NAME); -} diff --git a/bsp/synopsys/emsk_em9d/drivers/board.h b/bsp/synopsys/boards/drivers/rt_board.h similarity index 30% rename from bsp/synopsys/emsk_em9d/drivers/board.h rename to bsp/synopsys/boards/drivers/rt_board.h index aebf88bd42..734ffc8aa5 100644 --- a/bsp/synopsys/emsk_em9d/drivers/board.h +++ b/bsp/synopsys/boards/drivers/rt_board.h @@ -4,22 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __BOARD_H__ -#define __BOARD_H__ +#ifndef __RT_BOARD_H__ +#define __RT_BOARD_H__ -#include "emsk_hardware.h" - -#define BOARD_OS_TIMER_ID 0 -#define BOARD_OS_TIMER_INTNO 16 -#define BOARD_CPU_CLOCK 25000000 - -#if defined(__GNUC__) -extern int __start_heap; -#define HEAP_BEGIN ((void*)&__start_heap) -#endif - -extern int __end_heap; -#define HEAP_END (void*)(&__end_heap) +#include "board.h" void rt_hw_board_init(); diff --git a/bsp/synopsys/boards/linker_template_gnu.ld b/bsp/synopsys/boards/linker_template_gnu.ld new file mode 100644 index 0000000000..e253bc635c --- /dev/null +++ b/bsp/synopsys/boards/linker_template_gnu.ld @@ -0,0 +1,169 @@ +#define __ASSEMBLY__ +#include + +MEMORY +{ +#if (REGION_ICCM_SIZE != 0) + REGION_ICCM : ORIGIN = REGION_ICCM_START, LENGTH = REGION_ICCM_SIZE +#endif +#if (REGION_DCCM_SIZE !=0) + REGION_DCCM : ORIGIN = REGION_DCCM_START, LENGTH = REGION_DCCM_SIZE +#endif +#if (REGION_XCCM_SIZE != 0) + REGION_XCCM : ORIGIN = REGION_XCCM_START, LENGTH = REGION_XCCM_SIZE +#endif +#if (REGION_YCCM_SIZE != 0) + REGION_YCCM : ORIGIN = REGION_YCCM_START, LENGTH = REGION_YCCM_SIZE +#endif +#if (REGION_EXT_ROM_SIZE != 0) + REGION_EXT_ROM : ORIGIN = REGION_EXT_ROM_START, LENGTH = REGION_EXT_ROM_SIZE +#endif +#if (REGION_EXT_RAM_SIZE != 0) + REGION_EXT_RAM : ORIGIN = REGION_EXT_RAM_START, LENGTH = REGION_EXT_RAM_SIZE +#endif +} + +ENTRY(_start) + +SECTIONS +{ + .init : + { + . = . + IMAGE_HEAD_SIZE; + _f_init = .; + KEEP (*(.init_vector .init_vector.*)) + KEEP (*(.init_bootstrap .init_bootstrap.*)) + _e_init = .; + } > REGION_ROM + + .vector : ALIGN(1024) + { + _f_vector = .; + *(.vector .vector.*) + _e_vector = .; + } > REGION_ROM + +#if (REGION_XCCM_SIZE != 0) + .x_ccm (NOLOAD) : ALIGN(8) + { + _f_x_ccm = .; + *(.x_ccm .x_cmm.*) + _e_x_ccm = .; + } > REGION_XCCM +#endif + +#if (REGION_YCCM_SIZE != 0) + .y_ccm (NOLOAD) : ALIGN(8) + { + _f_y_ccm = .; + *(.y_ccm .y_ccm.*) + _e_y_ccm = .; + } > REGION_YCCM +#endif + .text : ALIGN(4) + { + _f_text = .; + *(.text .text.* .gnu.linkonce.t.*) + _e_text = .; + } > REGION_ROM + + .rodata : ALIGN(4) + { + _f_rodata = .; + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + . = ALIGN(4); + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + KEEP(*(SORT_BY_NAME(".ctors*"))) + LONG(0) + __CTOR_END__ = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP(*(SORT_BY_NAME(".init_array*"))) + __init_array_end = .; + + . = ALIGN(4); + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + KEEP(*(SORT_BY_NAME(".dtors*"))) + LONG(0) + __DTOR_END__ = .; + + *(.rodata .rodata.* .gnu.linkonce.r.*) + _e_rodata = .; + } > REGION_ROM + + .data : ALIGN(4) + { + _f_data = .; + *(.data .data.* .gnu.linkonce.d.*) + _f_sdata = .; + __SDATA_BEGIN__ = .; + *(.sdata .sdata.* .gnu.linkonce.s.*) + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + _f_sbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + _e_sbss = .; + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); +#if defined(EMBARC_UNIT_TEST) + . = ALIGN(8); + _f_embarc_unittest = .; + KEEP(*(.embarc_unittest)) + _e_embarc_unittest = .; +#endif + _e_sdata = .; + _e_data = .; + } > REGION_RAM AT > REGION_ROM + + .bss (NOLOAD) : ALIGN(8) + { + _f_bss = .; + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + _e_bss = .; + } > REGION_RAM + + .stack (NOLOAD) : + { + . = ALIGN(4); + _f_stack = .; + . = . + _STACKSIZE; + _e_stack = .; + } > REGION_RAM + + .heap (NOLOAD) : + { + . = ALIGN(4); + __start_heap = . ; + _f_heap = .; + . = . + _HEAPSIZE; + _e_heap = .; + __end_heap = . ; + } > REGION_RAM + + _load_addr_text = LOADADDR(.text); + _load_addr_rodata = LOADADDR(.rodata); + _load_addr_data = LOADADDR(.data); +} diff --git a/bsp/synopsys/boards/linker_template_mw.ld b/bsp/synopsys/boards/linker_template_mw.ld new file mode 100644 index 0000000000..248dc5ac4c --- /dev/null +++ b/bsp/synopsys/boards/linker_template_mw.ld @@ -0,0 +1,154 @@ +#define __ASSEMBLY__ +#include + +MEMORY { +#if (REGION_ICCM_SIZE != 0) + REGION_ICCM : ORIGIN = REGION_ICCM_START, LENGTH = REGION_ICCM_SIZE +#endif +#if (REGION_DCCM_SIZE !=0) + REGION_DCCM : ORIGIN = REGION_DCCM_START, LENGTH = REGION_DCCM_SIZE +#endif +#if (REGION_XCCM_SIZE != 0) + REGION_XCCM : ORIGIN = REGION_XCCM_START, LENGTH = REGION_XCCM_SIZE +#endif +#if (REGION_YCCM_SIZE != 0) + REGION_YCCM : ORIGIN = REGION_YCCM_START, LENGTH = REGION_YCCM_SIZE +#endif +#if (REGION_EXT_ROM_SIZE != 0) + REGION_EXT_ROM : ORIGIN = REGION_EXT_ROM_START, LENGTH = REGION_EXT_ROM_SIZE +#endif +#if (REGION_EXT_RAM_SIZE != 0) + REGION_EXT_RAM : ORIGIN = REGION_EXT_RAM_START, LENGTH = REGION_EXT_RAM_SIZE +#endif +} + +ENTRY(_start) + +SECTIONS { + + GROUP : { + .image_head: { + . = . + IMAGE_HEAD_SIZE; + } + .init_bootstrap:{ + _f_init = .; + *(.init_vector .init_vector.*) + *(.init_bootstrap .init_bootstrap.*) + _e_init = .; + } + .vector ALIGN(1024): { + _f_vector = .; + *(.vector .vector.*) + _e_vector = .; + } + } > REGION_ROM + +#if (REGION_XCCM_SIZE != 0) + GROUP (NOLOAD): { + .x_ccm ALIGN(8): { + _f_x_ccm = .; + *(.x_ccm) + *(.x_ccm.*) + _e_x_ccm = .; + } + } > REGION_XCCM +#endif + +#if (REGION_YCCM_SIZE != 0) + GROUP (NOLOAD): { + .y_ccm ALIGN(8): { + _f_y_ccm = .; + *(.y_ccm) + *(.y_ccm.*) + _e_y_ccm = .; + } + } > REGION_YCCM +#endif + + GROUP : { + + .text ALIGN(4): { + _f_text = .; + *(TYPE text) + *(.text*) + _e_text = .; + } + + .rodata ALIGN(4): { + _f_rodata = .; + + _fctors = .; + *(.ctors*) + _ectors = .; + _fdtors = .; + *(.dtors*) + _edtors = .; + _feh_frame = .; + *(.eh_frame*) + _eeh_frame = .; + + *(TYPE lit) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + *(FSymTab*) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + *(VSymTab*) + __vsymtab_end = .; + + . = ALIGN(4); + __rt_init_start = .; + *(.rti_fn*) + __rt_init_end = .; + . = ALIGN(4); + + _e_rodata = .; + } + + } > REGION_ROM + + + GROUP : { + .data ALIGN(8): { + _f_data = .; + _f_sdata = .; + *(.sdata) + *(.sbss) + _e_sdata = .; + *(TYPE data) + } +#if defined(EMBARC_UNIT_TEST) + .unit_test ALIGN(8): { + _f_embarc_unittest = .; + KEEP(*(".embarc_unittest")) + _e_embarc_unittest = .; + } +#endif + .tls ALIGN(8): { + *(.tls*) + _e_data = .; + } + } > REGION_RAM AT > REGION_ROM + + GROUP (NOLOAD) : { + .bss ALIGN(8): { + _f_bss = .; + *(TYPE bss) + _e_bss = .; + } + .stack ALIGN(4) SIZE(_STACKSIZE): {} + .heap? ALIGN(4) SIZE(_HEAPSIZE): {} + } > REGION_RAM + + _f_stack = ADDR(.stack); + _e_stack = ADDR(.stack) + SIZEOF(.stack); + _f_heap = ADDR(.heap); + _e_heap = ADDR(.heap) + SIZEOF(.heap); + + _load_addr_text = LOADADDR(.text); + _load_addr_rodata = LOADADDR(.rodata); + _load_addr_data = LOADADDR(.data); +} diff --git a/bsp/synopsys/boards/rtconfig.h b/bsp/synopsys/boards/rtconfig.h new file mode 100644 index 0000000000..6df6176c16 --- /dev/null +++ b/bsp/synopsys/boards/rtconfig.h @@ -0,0 +1,157 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 16 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 1024 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_DEBUG +#define RT_DEBUG_COLOR +#define RT_DEBUG_INIT_CONFIG +#define RT_DEBUG_INIT 1 + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_MEMHEAP +#define RT_USING_SMALL_MEM +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x40002 +#define RT_USING_CPU_FFS + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT + +/* C++ features */ + + +/* Command shell */ + +#define RT_USING_FINSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 1024 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 4096 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 8 +#define RT_USING_SERIAL +#define RT_SERIAL_RB_BUFSZ 1024 + +/* Using USB */ + + +/* POSIX layer and C standard library */ + + +/* Network */ + +/* Socket abstraction layer */ + + +/* Network interface device */ + + +/* light weight TCP/IP stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + +#define PKG_USING_EMBARC_BSP +#define PKG_USING_EMBARC_BSP_UPSTREAM_VERSION + +/* peripheral libraries and drivers */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + +#define SOC_EMSK +#define EMSK_USING_UART0 +#define EMSK_USING_UART1 + +#endif diff --git a/bsp/synopsys/emsk_em9d/rtconfig.py b/bsp/synopsys/boards/rtconfig.py similarity index 30% rename from bsp/synopsys/emsk_em9d/rtconfig.py rename to bsp/synopsys/boards/rtconfig.py index 7ba12867fd..0bafd172b5 100644 --- a/bsp/synopsys/emsk_em9d/rtconfig.py +++ b/bsp/synopsys/boards/rtconfig.py @@ -8,12 +8,15 @@ CROSS_TOOL='gcc' if os.getenv('RTT_CC'): CROSS_TOOL = os.getenv('RTT_CC') -# only support GNU GCC compiler -PLATFORM = 'gcc' -EXEC_PATH = 'C:/arc/gnu/bin' +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = 'C:/arc_gnu/bin' +elif CROSS_TOOL =='mw': + PLATFORM = 'mw' + EXEC_PATH = 'C:/ARC/MetaWare/arc/bin' -if os.getenv('RTT_EXEC_PATH'): - EXEC_PATH = os.getenv('RTT_EXEC_PATH') +# if os.getenv('RTT_EXEC_PATH'): +# EXEC_PATH = os.getenv('RTT_EXEC_PATH') BUILD = 'debug' @@ -30,31 +33,26 @@ if PLATFORM == 'gcc': OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' DBG = PREFIX + 'gdb' - DEVICE = ' -mno-sdata -Wall -mcpu=em4_fpus -mlittle-endian -mcode-density -mdiv-rem -mswap -mnorm -mmpy-option=6 -mbarrel-shifter -mfpu=fpus_all' - CFLAGS = DEVICE - AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' - LINK_SCRIPT = 'emsk_em9d.ld' - LFLAGS = DEVICE + ' -mno-sdata -nostartfiles -Wl,--gc-sections,-Map=emsk_em9d.map,-cref,-u,system_vectors -T %s' % LINK_SCRIPT - OPENOCD_SCRIPT_ROOT = 'C:/arc/gnu/share/openocd/scripts' - OPENOCD_CFG_FILE = OPENOCD_SCRIPT_ROOT + '/board/snps_em_sk_v2.2.cfg' + TARGET = 'rtthread_snps_embarc.elf' - OPENOCD_OPTIONS = '-s %s -f %s' % (OPENOCD_SCRIPT_ROOT, OPENOCD_CFG_FILE) - - DBG_HW_FLAGS = ''' -ex "target remote | openocd --pipe %s" -ex "load" ''' % OPENOCD_OPTIONS - - - TARGET = 'rtthread_snps_emsk_em9d.' + TARGET_EXT + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread_snps_embarc.bin\n' +\ + SIZE + ' $TARGET \n' - CPATH = '' - LPATH = '' +elif PLATFORM == 'mw': + # toolchains + CC = 'ccac' + CXX = 'ccac' + AS = 'ccac' + AR = 'arac' + LINK = 'ccac' + TARGET_EXT = 'elf' + SIZE = 'sizeac' + OBJDUMP = 'elfdumpac' + OBJCPY = 'elf2bin' + DBG = 'mdb' - if BUILD == 'debug': - CFLAGS += ' -O0 -gdwarf-2' - AFLAGS += ' -gdwarf-2' - else: - CFLAGS += ' -O2' + TARGET = 'rtthread_snps_embarc.elf' - POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' +\ + POST_ACTION = OBJCPY + ' $TARGET rtthread_snps_embarc.bin\n' +\ SIZE + ' $TARGET \n' - #POST_ACTION = DBG + DBG_HW_FLAGS + TARGET diff --git a/bsp/synopsys/embarc/SConscript b/bsp/synopsys/embarc/SConscript deleted file mode 100644 index 9e086739af..0000000000 --- a/bsp/synopsys/embarc/SConscript +++ /dev/null @@ -1,28 +0,0 @@ -from building import * - -cwd = GetCurrentDir() - -embarc_arc_hal_SRCS = Split(""" -arc/arc_cache.c -arc/arc_exc_asm.S -arc/arc_exception.c -arc/arc_timer.c -arc/startup/arc_cxx_support.c -arc/startup/arc_startup.S -device/designware/uart/dw_uart.c -device/designware/gpio/dw_gpio.c -""") - - -ASFLAGS = ' -I' + cwd - -src = embarc_arc_hal_SRCS - -path = [cwd, - cwd + '/arc', - cwd + '/arc/startup' - ] - -group = DefineGroup('embarc', src, depend = [], CPPPATH = path, ASFLAGS = ASFLAGS) - -Return('group') diff --git a/bsp/synopsys/embarc/arc/arc_cache.c b/bsp/synopsys/embarc/arc/arc_cache.c deleted file mode 100644 index 632a3e3291..0000000000 --- a/bsp/synopsys/embarc/arc/arc_cache.c +++ /dev/null @@ -1,420 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-15 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_MISC_CACHE - * \brief implementation of cache related functions - */ - -#include "inc/arc/arc_cache.h" - -#define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) - - -struct cache_config { - uint8_t ver; /* version */ - uint8_t assoc; /* Cache Associativity */ - uint16_t line; /* cache line/block size */ - uint32_t capacity; /* capacity */ -}; - - -static struct cache_config icache_config, dcache_config; - -/** - * \brief invalidate multi instruction cache lines - * - * \param[in] start_addr start address in instruction cache - * \param[in] size the bytes to be invalidated - * \return 0, succeeded, -1, failed - */ -int32_t icache_invalidate_mlines(uint32_t start_addr, uint32_t size) -{ - if (!icache_available()) return -1; - - if ((size == 0) || (size > icache_config.capacity)) { - return -1; - } - - uint32_t end_addr; - uint32_t line_size; - uint32_t status; - - line_size = (uint32_t)(icache_config.line); - end_addr = start_addr + size - 1; - start_addr &= (uint32_t)(~(line_size - 1)); - - status = cpu_lock_save(); - do { - _arc_aux_write(AUX_IC_IVIL, start_addr); - Asm("nop_s"); - Asm("nop_s"); - Asm("nop_s"); - start_addr += line_size; - } while (start_addr <= end_addr); - cpu_unlock_restore(status); - - return 0; -} - -/** - * \brief lock multi lines in instruction cache - * - * \param[in] start_addr start address in instruction cache - * \param[in] size the bytes to be locked - * \return 0, succeeded, -1, failed (cache already locked or other reasons) - */ -int32_t icache_lock_mlines(uint32_t start_addr, uint32_t size) -{ - if (!icache_available()) return -1; - - if ((size == 0) || (size > icache_config.capacity)) { - return -1; - } - - uint32_t end_addr; - uint32_t line_size; - uint32_t status; - int32_t ercd = 0; - - line_size = (uint32_t)(icache_config.line); - end_addr = start_addr + size - 1; - start_addr &= (uint32_t)(~(line_size - 1)); - - status = cpu_lock_save(); - do { - _arc_aux_write(AUX_IC_LIL, start_addr); - if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) { - start_addr += line_size; - } else { - ercd = -1; /* the operation failed */ - break; - } - } while (start_addr <= end_addr); - cpu_unlock_restore(status); - - return ercd; -} - -/** - * \brief directly write icache internal ram - * - * \param[in] cache_addr, icache internal address(way+index+offset) - * \param[in] tag cache tag to write (tag+lock bit+valid bit) - * \param[in] data cache data to write - * \return 0, succeeded, -1, failed - */ -int32_t icache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data) -{ - if (!icache_available()) return -1; - - if (_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS) { - return -1; - } - _arc_aux_write(AUX_IC_RAM_ADDR, cache_addr); - _arc_aux_write(AUX_IC_TAG, tag ); - _arc_aux_write(AUX_IC_DATA, data); - - return 0; -} - -/** - * \brief directly read icache internal ram - * - * \param[in] cache_addr, icache internal address(way+index+offset) - * \param[out] tag cache tag to read (tag+index+lock bit+valid bit) - * \param[out] data cache data to read - * \return 0, succeeded, -1, failed - */ -int32_t icache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data) -{ - if (!icache_available()) return -1; - - if (_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS) { - return -1; - } - _arc_aux_write(AUX_IC_RAM_ADDR, cache_addr); - *tag = _arc_aux_read(AUX_IC_TAG); - *data = _arc_aux_read(AUX_IC_DATA); - - return 0; -} - -/** - * \brief indirectly read icache internal ram - * - * \param[in] mem_addr, memory address - * \param[out] tag cache tag to read - * \param[out] data cache data to read - * \return 0, succeeded, -1, failed - */ -int32_t icache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data) -{ - if (!icache_available()) return -1; - - if (!(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS)) { - return -1; - } - _arc_aux_write(AUX_IC_RAM_ADDR, mem_addr); - if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) { - *tag = _arc_aux_read(AUX_IC_TAG); - *data = _arc_aux_read(AUX_IC_DATA); - } else { - return -1; /* the specified memory is not in icache */ - } - return 0; - } - -/** - * \brief invalidate multi data cache lines - * - * \param[in] start_addr start address in data cache - * \param[in] size the bytes to be invalidated - * \return 0, succeeded, -1, failed - */ -int32_t dcache_invalidate_mlines(uint32_t start_addr, uint32_t size) -{ - if (!dcache_available()) return -1; - - uint32_t end_addr; - uint32_t line_size; - uint32_t status; - - if ((size == 0) || (size > dcache_config.capacity)) { - return -1; - } - - line_size = (uint32_t)(dcache_config.line); - end_addr = start_addr + size - 1; - start_addr &= (uint32_t)(~(line_size - 1)); - - status = cpu_lock_save(); - do { - _arc_aux_write(AUX_DC_IVDL, start_addr); - Asm("nop_s"); - Asm("nop_s"); - Asm("nop_s"); - /* wait for flush completion */ - while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); - start_addr += line_size; - } while (start_addr <= end_addr); - cpu_unlock_restore(status); - - return 0; - -} - -/** - * \brief flush multi lines in data cache - * - * \param[in] start_addr start address - * \param[in] size the bytes to be flushed - * \return 0, succeeded, -1, failed - */ -int32_t dcache_flush_mlines(uint32_t start_addr, uint32_t size) -{ - if (!dcache_available()) return -1; - - if ((size == 0) || (size > dcache_config.capacity)) { - return -1; - } - - uint32_t end_addr; - uint32_t line_size; - uint32_t status; - - line_size = (uint32_t)(dcache_config.line); - end_addr = start_addr + size - 1; - start_addr &= (uint32_t)(~(line_size - 1)); - - status = cpu_lock_save(); - do { - _arc_aux_write(AUX_DC_FLDL, start_addr); - Asm("nop_s"); - Asm("nop_s"); - Asm("nop_s"); - /* wait for flush completion */ - while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); - start_addr += line_size; - } while (start_addr <= end_addr); - cpu_unlock_restore(status); - - return 0; -} - -/** - * \brief lock multi lines in data cache - * - * \param[in] start_addr start address in data cache - * \param[in] size the bytes to be locked - * \return 0, succeeded, -1, failed - */ -int32_t dcache_lock_mlines(uint32_t start_addr, uint32_t size) -{ - if (!dcache_available()) return -1; - - if ((size == 0) || (size > dcache_config.capacity)) { - return -1; - } - - uint32_t end_addr; - uint32_t line_size; - uint32_t status; - int32_t ercd = 0; - - line_size = (uint32_t)(dcache_config.line); - end_addr = start_addr + size - 1; - start_addr &= (uint32_t)(~(line_size - 1)); - - status = cpu_lock_save(); - do { - _arc_aux_write(AUX_DC_LDL, start_addr); - Asm("nop_s"); - if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) { - start_addr += line_size; - } else { - ercd = -1; /* the operation failed */ - break; - } - } while (start_addr <= end_addr); - cpu_unlock_restore(status); - - return ercd; -} - -/** - * \brief directly write dcache internal ram - * - * \param[in] cache_addr, dcache internal address(way+index+offset) - * \param[in] tag cache tag to write - * \param[in] data cache data to write - * \return 0, succeeded, -1, failed - */ -int32_t dcache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data) -{ - if (!dcache_available()) return -1; - - if (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS) { - return -1; - } - _arc_aux_write(AUX_DC_RAM_ADDR, cache_addr); - _arc_aux_write(AUX_DC_TAG, tag); - _arc_aux_write(AUX_DC_DATA, data); - - return 0; -} - -/** - * \brief directly read dcache internal ram - * - * \param[in] cache_addr, dcache internal address(way+index+offset) - * \param[out] tag cache tag to read - * \param[out] data cache data to read - * \return 0, succeeded, -1, failed - */ -int32_t dcache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data) -{ - if (!dcache_available()) return -1; - - if (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS) { - return -1; - } - _arc_aux_write(AUX_DC_RAM_ADDR, cache_addr); - *tag = _arc_aux_read(AUX_DC_TAG); - *data = _arc_aux_read(AUX_DC_DATA); - - return 0; -} - -/** - * \brief indirectly read dcache internal ram - * - * \param[in] mem_addr, memory address(tag+index+offset) - * \param[out] tag cache tag to read - * \param[out] data cache data to read - * \return 0, succeeded, -1, failed - */ -int32_t dcache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data) -{ - if (!dcache_available()) return -1; - - if (!(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS)) { - return -1; - } - _arc_aux_write(AUX_DC_RAM_ADDR, mem_addr); - if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) { - *tag = _arc_aux_read(AUX_DC_TAG); - *data = _arc_aux_read(AUX_DC_DATA); - } else { - return -1; /* the specified memory is not in dcache */ - } - return 0; - } - -/** - * \brief initialize cache - * 1. invalidate icache and dcache - * 2. Only support ARCv2 cache - */ -void arc_cache_init(void) -{ - uint32_t build_cfg; - - build_cfg = _arc_aux_read(AUX_BCR_D_CACHE); - - dcache_config.ver = build_cfg & 0xff; - - if (dcache_config.ver >= 0x04) { /* ARCv2 */ - dcache_enable(DC_CTRL_DISABLE_FLUSH_LOCKED | - DC_CTRL_INDIRECT_ACCESS | DC_CTRL_INVALID_FLUSH); - dcache_invalidate(); - dcache_config.assoc = 1 << ((build_cfg >> 8) & 0xf); - dcache_config.capacity = 512 << ((build_cfg >> 12) & 0xf); - dcache_config.line = 16 << ((build_cfg >> 16) & 0xf); - } - - build_cfg = _arc_aux_read(AUX_BCR_I_CACHE); - - icache_config.ver = build_cfg & 0xff; - - if (icache_config.ver >= 0x04) { /* ARCv2 */ - icache_config.assoc = 1 << ((build_cfg >> 8) & 0xf); - icache_config.capacity = 512 << ((build_cfg >> 12) & 0xf); - icache_config.line = 8 << ((build_cfg >> 16) & 0xf); - - icache_enable(IC_CTRL_IC_ENABLE); - icache_invalidate(); - } - -} diff --git a/bsp/synopsys/embarc/arc/arc_exc_asm.S b/bsp/synopsys/embarc/arc/arc_exc_asm.S deleted file mode 100644 index 7410db3154..0000000000 --- a/bsp/synopsys/embarc/arc/arc_exc_asm.S +++ /dev/null @@ -1,201 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-15 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_EXCEPTION_CPU - * \brief assembly part of exception and interrupt processing - */ - -/** - * \addtogroup ARC_HAL_EXCEPTION_CPU - * @{ - */ - -/* function documentation */ -/** - * \fn void exc_entry_cpu(void) - * \brief default entry of CPU exceptions, such as TLB miss and swap. - * - * \fn void exc_entry_int(void) - * \brief normal interrupt exception entry. - * In default, all interrupt exceptions are installed with normal entry. - * If FIRQ is required, exc_entry_firq should be the entry. - * - * \fn void exc_entry_firq(void) - * \brief firq exception entry - */ -/** }@ */ - -/** @cond EXCEPTION_ASM */ - -#define __ASSEMBLY__ -#include "inc/arc/arc.h" -#include "inc/arc/arc_asm_common.h" - - .file "arc_exc_asm.S" - -/* entry for cpu exception handling */ - .text - .global exc_entry_cpu - .weak exc_entry_cpu - .align 4 -exc_entry_cpu: - - EXCEPTION_PROLOGUE - - mov r3, sp /* as exception handler's para(exc_frame) */ - -/* exc_nest_count +1 */ - ld r0, [exc_nest_count] - add r0, r0, 1 - st r0, [exc_nest_count] - -/* find the exception cause */ - lr r0, [AUX_ECR] - lsr r0, r0, 16 - bmsk r0, r0, 7 - mov r1, exc_int_handler_table - ld.as r2, [r1, r0] - - mov r0, r3 - jl [r2] /* jump to exception handler where interrupts are not allowed! */ - -/* interrupts are not allowed */ -exc_return: - -/* exc_nest_count -1 */ - ld r0, [exc_nest_count] - sub r0, r0, 1 - st r0, [exc_nest_count] - - EXCEPTION_EPILOGUE - rtie - - -/****** entry for normal interrupt exception handling ******/ - .global exc_entry_int - .weak exc_entry_int - .align 4 -exc_entry_int: - clri /* disable interrupt */ - -#if ARC_FEATURE_FIRQ == 1 -#if ARC_FEATURE_RGF_NUM_BANKS > 1 - lr r0, [AUX_IRQ_ACT] /* check whether it is P0 interrupt */ - btst r0, 0 - bnz exc_entry_firq -#else - PUSH r10 - lr r10, [AUX_IRQ_ACT] - btst r10, 0 - POP r10 - bnz exc_entry_firq -#endif -#endif - INTERRUPT_PROLOGUE /* save scratch regs, this will be affected */ - - -/* exc_nest_count +1 */ - ld r0, [exc_nest_count] - add r0, r0, 1 - st r0, [exc_nest_count] - - - lr r0, [AUX_IRQ_CAUSE] - mov r1, exc_int_handler_table - ld.as r2, [r1, r0] /* r2 = _kernel_exc_tbl + irqno *4 */ - -/* for the case of software triggered interrupt */ - lr r3, [AUX_IRQ_HINT] - cmp r3, r0 - bne.d irq_hint_handled - xor r3, r3, r3 - sr r3, [AUX_IRQ_HINT] -irq_hint_handled: - seti /* enable higher priority interrupt */ - - mov r0, sp - jl [r2] /* jump to interrupt handler */ - -/* no interrupts are allowed from here */ -int_return: - clri /* disable interrupt */ - -/* exc_nest_count -1 */ - ld r0, [exc_nest_count] - sub r0, r0, 1 - st r0, [exc_nest_count] - - INTERRUPT_EPILOGUE - rtie - -/****** entry for fast irq exception handling ******/ - .global exc_entry_firq - .weak exc_entry_firq - .align 4 -exc_entry_firq: - clri /* disable interrupt */ - SAVE_FIQ_EXC_REGS - -/* exc_nest_count +1 */ - ld r0, [exc_nest_count] - add r0, r0, 1 - st r0, [exc_nest_count] - - lr r0, [AUX_IRQ_CAUSE] - mov r1, exc_int_handler_table - ld.as r2, [r1, r0] /* r2 = _kernel_exc_tbl + irqno *4 */ - -/* for the case of software triggered interrupt */ - lr r3, [AUX_IRQ_HINT] - cmp r3, r0 - bne.d firq_hint_handled - xor r3, r3, r3 - sr r3, [AUX_IRQ_HINT] -firq_hint_handled: - - jl [r2] /* jump to interrupt handler */ - -/* no interrupts are allowed from here */ -firq_return: - -/* exc_nest_count -1 */ - ld r0, [exc_nest_count] - sub r0, r0, 1 - st r0, [exc_nest_count] - - RESTORE_FIQ_EXC_REGS - rtie - -/** @endcond */ diff --git a/bsp/synopsys/embarc/arc/arc_exception.c b/bsp/synopsys/embarc/arc/arc_exception.c deleted file mode 100644 index a256b0b394..0000000000 --- a/bsp/synopsys/embarc/arc/arc_exception.c +++ /dev/null @@ -1,501 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-15 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT - * \brief C Implementation of exception and interrupt management - */ -#include "inc/arc/arc_exception.h" -#include "inc/arc/arc_cache.h" - -//#define DBG_LESS -//#include "embARC_debug.h" - -/** - * \addtogroup ARC_HAL_EXCEPTION_CPU - * @{ - * \var exc_entry_table - * \brief exception entry table - * - * install exception entry table to ARC_AUX_INT_VECT_BASE in startup. - * According to ARCv2 ISA, vectors are fetched in instruction space and thus - * may be present in ICCM, Instruction Cache, or - * main memory accessed by instruction fetch logic. - * So it is put into a specific section .vector. - * - * Please note that the exc_entry_table maybe cached in ARC. Some functions is - * defined in .s files. - * - */ - -/** - * \ingroup ARC_HAL_EXCEPTION_CPU - * \brief default cpu exception handler - * \param p_excinf pointer to the exception frame - */ -static void exc_handler_default(void *p_excinf) -{ - // uint32_t excpt_cause_reg = 0; - // uint32_t excpt_ret_reg = 0; - // uint32_t exc_no = 0; - - // excpt_cause_reg = _arc_aux_read(AUX_ECR); - // excpt_ret_reg = _arc_aux_read(AUX_ERRET); - // exc_no = (excpt_cause_reg >> 16) & 0xff; - - Asm("kflag 1"); -} - - -/** - * \ingroup ARC_HAL_EXCEPTION_INTERRUPT - * \brief default interrupt handler - * \param[in] p_excinf information for interrupt handler - */ -static void int_handler_default(void *p_excinf) -{ - // uint32_t int_cause_reg = 0; - - // int_cause_reg = _arc_aux_read(AUX_IRQ_CAUSE); - Asm("kflag 1"); -} - -__attribute__ ((aligned(1024), section(".vector"))) -EXC_ENTRY exc_entry_table[NUM_EXC_ALL] = { - [0] = _arc_reset, - [1 ... NUM_EXC_CPU-1] = exc_entry_cpu, - [NUM_EXC_CPU ... NUM_EXC_ALL-1] = exc_entry_int - }; -/** - * \var exc_int_handler_table - * \brief the cpu exception and interrupt exception handler table - * called in exc_entry_default and exc_entry_int - */ -EXC_HANDLER exc_int_handler_table[NUM_EXC_ALL] = { - [0 ... NUM_EXC_CPU-1] = exc_handler_default, - [NUM_EXC_CPU ... NUM_EXC_ALL-1] = int_handler_default -}; - -/** - * \var exc_nest_count - * \brief the counter for exc/int processing, =0 no int/exc - * >1 in int/exc processing - * @} - */ -uint32_t exc_nest_count; - -typedef struct aux_irq_ctrl_field { - /* note: little endian */ - uint32_t save_nr_gpr_pairs: 5; /** Indicates number of general-purpose register pairs saved, from 0 to 8/16 */ - uint32_t res: 4; /** Reserved */ - uint32_t save_blink: 1; /** Indicates whether to save and restore BLINK */ - uint32_t save_lp_regs: 1; /** Indicates whether to save and restore loop registers (LP_COUNT, LP_START, LP_END) */ - uint32_t save_u_to_u: 1; /** Indicates if user context is saved to user stack */ - uint32_t res2: 1; /** Reserved */ - uint32_t save_idx_regs: 1; /** Indicates whether to save and restore code-density registers (EI_BASE, JLI_BASE, LDI_BASE) */ - uint32_t res3: 18; /** Reserved */ -} aux_irq_ctrl_field_t; - -typedef union { - aux_irq_ctrl_field_t bits; - uint32_t value; -} aux_irq_ctrl_t; - -/** - * \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT - * \brief intialize the exception and interrupt handling - */ -void exc_int_init(void) -{ - uint32_t i; - uint32_t status; - aux_irq_ctrl_t ictrl; - - ictrl.value = 0; - -#ifndef ARC_FEATURE_RF16 - ictrl.bits.save_nr_gpr_pairs = 6; /* r0 to r11 (r12 saved manually) */ -#else - ictrl.bits.save_nr_gpr_pairs = 3; /* r0 to r3, r10, r11 */ -#endif - ictrl.bits.save_blink = 1; - ictrl.bits.save_lp_regs = 1; /* LP_COUNT, LP_START, LP_END */ - ictrl.bits.save_u_to_u = 0; /* user ctxt saved on kernel stack */ - ictrl.bits.save_idx_regs = 1; /* JLI, LDI, EI */ - - status = arc_lock_save(); - for (i = NUM_EXC_CPU; i < NUM_EXC_ALL; i++) { - /* interrupt level triggered, disabled, priority is the lowest */ - _arc_aux_write(AUX_IRQ_SELECT, i); - _arc_aux_write(AUX_IRQ_ENABLE, 0); - _arc_aux_write(AUX_IRQ_TRIGGER, 0); -#if defined(ARC_FEATURE_SEC_PRESENT) && (SECURESHIELD_VERSION < 2) - _arc_aux_write(AUX_IRQ_PRIORITY, (1 << AUX_IRQ_PRIORITY_BIT_S)|(INT_PRI_MAX - INT_PRI_MIN)); -#else - _arc_aux_write(AUX_IRQ_PRIORITY, INT_PRI_MAX - INT_PRI_MIN); -#endif - } - _arc_aux_write(AUX_IRQ_CTRL, ictrl.value); - - arc_unlock_restore(status); - - /** ipm should be set after cpu unlock restore to avoid reset of the status32 value */ - arc_int_ipm_set((INT_PRI_MAX - INT_PRI_MIN)); -} - -/** - * \ingroup ARC_HAL_EXCEPTION_CPU - * \brief install a CPU exception entry - * \param[in] excno exception number - * \param[in] entry the entry of exception to install - */ -int32_t exc_entry_install(const uint32_t excno, EXC_ENTRY entry) -{ - uint32_t status; - - EXC_ENTRY *table = (EXC_ENTRY *)_arc_aux_read(AUX_INT_VECT_BASE); - - if (excno < NUM_EXC_ALL && entry != NULL - && table[excno] != entry) { - status = cpu_lock_save(); - /* directly write to mem, as arc gets exception handler from mem not from cache */ - /* FIXME, here maybe icache is dirty, need to be invalidated */ - table[excno] = entry; - - if (_arc_aux_read(AUX_BCR_D_CACHE) > 0x2) { - /* dcache is available */ - dcache_flush_line((uint32_t)&table[excno]); - } - - if (_arc_aux_read(AUX_BCR_D_CACHE) > 0x2) { - /* icache is available */ - icache_invalidate_line((uint32_t)&table[excno]); - } - cpu_unlock_restore(status); - return 0; - } - return -1; -} - -/** - * \ingroup ARC_HAL_EXCEPTION_CPU - * \brief get the installed CPU exception entry - * \param[in] excno exception number - * \return the installed CPU exception entry - */ -EXC_ENTRY exc_entry_get(const uint32_t excno) -{ - if (excno < NUM_EXC_ALL) { - return exc_entry_table[excno]; - } - return NULL; -} - -/** - * \ingroup ARC_HAL_EXCEPTION_CPU - * \brief install an exception handler - * \param[in] excno exception number - * \param[in] handler the handler of exception to install - */ -int32_t exc_handler_install(const uint32_t excno, EXC_HANDLER handler) -{ - if (excno < NUM_EXC_ALL && handler != NULL) { - exc_int_handler_table[excno] = handler; - return 0; - } - - return -1; -} - -/** - * \ingroup ARC_HAL_EXCEPTION_CPU - * \brief get the installed exception handler - * \param[in] excno exception number - * \return the installed exception handler or NULL - */ -EXC_HANDLER exc_handler_get(const uint32_t excno) -{ - if (excno < NUM_EXC_ALL) { - return exc_int_handler_table[excno]; - } - - return NULL; -} - - -#ifndef EMBARC_OVERRIDE_ARC_INTERRUPT_MANAGEMENT -/** - * \brief disable the specific interrupt - * - * \param[in] intno interrupt number - */ -int32_t int_disable(const uint32_t intno) -{ - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - arc_int_disable(intno); - return 0; - } - - return -1; -} - -/** - * \brief enable the specific int - * - * \param[in] intno interrupt number - */ -int32_t int_enable(const uint32_t intno) -{ - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - arc_int_enable(intno); - return 0; - } - - return -1; -} - -/** - * \brief check whether the specific int is enabled - * - * \param[in] intno interrupt number - * \return 0 disabled, 1 enabled, < 0 error - */ -int32_t int_enabled(const uint32_t intno) -{ - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - _arc_aux_write(AUX_IRQ_SELECT, intno); - return _arc_aux_read(AUX_IRQ_ENABLE); - } - - return -1; -} - -/** - * \brief get the interrupt priority mask - * - * \returns interrupt priority mask, negative num - */ -int32_t int_ipm_get(void) -{ - return ((int32_t)arc_int_ipm_get() + INT_PRI_MIN); -} - - -/** - * \brief set the interrupt priority mask - * - * \param[in] intpri interrupt priority - */ -int32_t int_ipm_set(int32_t intpri) -{ - if (intpri >= INT_PRI_MIN && intpri <= INT_PRI_MAX) { - intpri = intpri - INT_PRI_MIN; - arc_int_ipm_set(intpri); - return 0; - } - - return -1; -} - - -/** - * \brief get current interrupt priority mask - * - * \param[in] intno interrupt number - * \return <0 interrupt priority, 0 error - */ -int32_t int_pri_get(const uint32_t intno) -{ - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - return (int32_t)arc_int_pri_get(intno) + INT_PRI_MIN; - } - - return 0; -} - - -/** - * \brief set interrupt priority - * - * \param[in] intno interrupt number - * \param[in] intpri interrupt priority - * \return <0 error, 0 ok - */ -int32_t int_pri_set(const uint32_t intno, int32_t intpri) -{ - uint32_t status; - - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - status = cpu_lock_save(); - intpri = intpri - INT_PRI_MIN; - arc_int_pri_set(intno,(uint32_t)intpri); - cpu_unlock_restore(status); - return 0; - } - return -1; -} - -/** - * \brief set interrupt secure or not secure - * This function is valid in secureshield v2 - * \param[in] intno interrupt number - * \param[in] secure, 0 for normal, >0 for secure - * \return <0 error, 0 ok - */ -int32_t int_secure_set(const uint32_t intno, uint32_t secure) -{ - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - arc_int_secure_set(intno, secure); - return 0; - } - return -1; - -} - - -/** - * \brief probe the pending status of interrupt - * - * \param[in] intno interrupt number - * - * \returns 1 pending, 0 no pending, -1 error - */ -int32_t int_probe(const uint32_t intno) -{ - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - return arc_int_probe(intno); - } - return -1; -} - - -/** - * \brief trigger the interrupt in software - * - * \param[in] intno interrupt number - * \return 0 ok, -1 error - */ -int32_t int_sw_trigger(const uint32_t intno) -{ - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - arc_int_sw_trigger(intno); - return 0; - } - return -1; -} - -/** - * \brief config the interrupt level triggered or pulse triggered - * - * \param[in] intno interrupt number - * \param[in] level, 0-level trigger, 1-pulse triggered - * \return 0 ok, -1 error - */ -int32_t int_level_config(const uint32_t intno, const uint32_t level) -{ - if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) { - arc_int_level_config(intno, level); - return 0; - } - return -1; -} - - -/** - * \brief lock cpu, disable interrupts - */ -void cpu_lock(void) -{ - arc_lock(); -} - -/** - * \brief unlock cpu, enable interrupts to happen - */ -void cpu_unlock(void) -{ - arc_unlock(); -} - -/** - * \brief lock cpu and return status - * - * \returns cpu status - */ -uint32_t cpu_lock_save(void) -{ - return arc_lock_save(); -} - -/** - * \brief unlock cpu with the specific status - * - * \param[in] status cpu status saved by cpu_lock_save - */ -void cpu_unlock_restore(const uint32_t status) -{ - arc_unlock_restore(status); -} - -/** - * \ingroup ARC_HAL_EXCEPTION_INTERRUPT - * \brief install an interrupt handler - * \param[in] intno interrupt number - * \param[in] handler interrupt handler to install - */ -int32_t int_handler_install(const uint32_t intno, INT_HANDLER handler) -{ - /*!< \todo parameter check ? */ - if (intno >= NUM_EXC_CPU) { - return exc_handler_install(intno, handler); - } - - return -1; -} - -/** - * \ingroup ARC_HAL_EXCEPTION_INTERRUPT - * \brief get the installed an interrupt handler - * \param[in] intno interrupt number - * \return the installed interrupt handler or NULL - */ -INT_HANDLER int_handler_get(const uint32_t intno) -{ - if (intno >= NUM_EXC_CPU) { - return exc_handler_get(intno); - } - - return NULL; -} -#endif /* EMBARC_OVERRIDE_ARC_INTERRUPT_MANAGEMENT */ diff --git a/bsp/synopsys/embarc/arc/arc_timer.c b/bsp/synopsys/embarc/arc/arc_timer.c deleted file mode 100644 index 3d0c4b4f83..0000000000 --- a/bsp/synopsys/embarc/arc/arc_timer.c +++ /dev/null @@ -1,211 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-15 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_MISC_TIMER - * \brief implementation of internal timer related functions - * \todo RTC support should be improved if RTC is enabled - */ -#include "inc/arc/arc_timer.h" -#include "inc/arc/arc.h" -#include "inc/arc/arc_builtin.h" - -/** - * \brief check whether the specific timer present - * \param[in] no timer number - * \retval 1 present - * \retval 0 not present - */ -int32_t arc_timer_present(const uint32_t no) -{ - uint32_t bcr = _arc_aux_read(AUX_BCR_TIMERS); - switch (no) { - case TIMER_0: - bcr = (bcr >> 8) & 1; - break; - case TIMER_1: - bcr = (bcr >> 9) & 1; - break; - case TIMER_RTC: - bcr = (bcr >> 10) & 1; - break; - default: - bcr = 0; - /* illegal argument so return false */ - break; - } - - return (int)bcr; -} - -/** - * \brief start the specific timer - * \param[in] no timer number - * \param[in] mode timer mode - * \param[in] val timer limit value (not for RTC) - * \return 0 success, -1 failure - */ -int32_t arc_timer_start(const uint32_t no, const uint32_t mode, const uint32_t val) -{ - if (arc_timer_present(no) == 0) { - return -1; - } - - switch (no) { - case TIMER_0: - _arc_aux_write(AUX_TIMER0_CTRL, 0); - _arc_aux_write(AUX_TIMER0_LIMIT, val); - _arc_aux_write(AUX_TIMER0_CTRL, mode); - _arc_aux_write(AUX_TIMER0_CNT, 0); - break; - case TIMER_1: - _arc_aux_write(AUX_TIMER1_CTRL, 0); - _arc_aux_write(AUX_TIMER1_LIMIT, val); - _arc_aux_write(AUX_TIMER1_CTRL, mode); - _arc_aux_write(AUX_TIMER1_CNT, 0); - break; - case TIMER_RTC: - _arc_aux_write(AUX_RTC_CTRL, mode); - break; - default: - return -1; - } - - return 0; -} - -/** - * \brief stop and clear the specific timer - * - * \param[in] no timer number - * \return 0 success, -1 failure - */ -int32_t arc_timer_stop(const uint32_t no) -{ - if (arc_timer_present(no) == 0) { - return -1; - } - - switch (no) { - case TIMER_0 : - _arc_aux_write(AUX_TIMER0_CTRL, 0); - _arc_aux_write(AUX_TIMER0_LIMIT,0); - _arc_aux_write(AUX_TIMER0_CNT, 0); - break; - case TIMER_1: - _arc_aux_write(AUX_TIMER1_CTRL, 0); - _arc_aux_write(AUX_TIMER1_LIMIT,0); - _arc_aux_write(AUX_TIMER1_CNT, 0); - break; - case TIMER_RTC: - _arc_aux_write(AUX_RTC_CTRL, TIMER_RTC_CLEAR); - break; - default: - return -1; - } - - return 0; -} - -/** - * \brief get timer current tick - * - * \param[in] no timer number - * \param[out] val, timer value - * \return 0 success, -1 failure - */ -int32_t arc_timer_current(const uint32_t no, void *val) -{ - if (arc_timer_present(no) == 0) { - return -1; - } - - switch (no) { - case TIMER_0 : - *((uint32_t *)val) = _arc_aux_read(AUX_TIMER0_CNT); - break; - case TIMER_1 : - *((uint32_t *)val) = _arc_aux_read(AUX_TIMER1_CNT); - break; - case TIMER_RTC: - *((uint64_t *)val) = _arc_aux_read(AUX_RTC_LOW); - break; - default : - return -1; - } - - return 0; -} - -/** - * \brief clear the interrupt pending bit of timer - * - * \param[in] no timer number - * \return 0 success, -1 failure - */ -int32_t arc_timer_int_clear(const uint32_t no) -{ - uint32_t val; - - if (arc_timer_present(no) == 0) { - return -1; - } - - switch (no) { - case TIMER_0 : - val = _arc_aux_read(AUX_TIMER0_CTRL); - val &= ~TIMER_CTRL_IP; - _arc_aux_write(AUX_TIMER0_CTRL, val); - break; - case TIMER_1 : - val = _arc_aux_read(AUX_TIMER1_CTRL); - val &= ~TIMER_CTRL_IP; - _arc_aux_write(AUX_TIMER1_CTRL, val); - break; - default : - return -1; - } - - return 0; -} - -/** - * \brief init internal timer - */ -void arc_timer_init(void) -{ - arc_timer_stop(TIMER_0); - arc_timer_stop(TIMER_1); - arc_timer_stop(TIMER_RTC); -} diff --git a/bsp/synopsys/embarc/arc/startup/arc_cxx_support.c b/bsp/synopsys/embarc/arc/startup/arc_cxx_support.c deleted file mode 100644 index af842fddc6..0000000000 --- a/bsp/synopsys/embarc/arc/startup/arc_cxx_support.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2012-2014 Wind River Systems, Inc. - * - * 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. - */ - -/* ------------------------------------------ - * Copyright (c) 2015, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2016-03-02 - * \author Wayne Ren(wei.ren@synopsys.com) ---------------------------------------------- */ -#include "embARC_BSP_config.h" -#if defined(__GNU__) -/* embARC's GNU C++ support takes reference from Zephyr (cpp_xxx.c) */ - -/** - * @file - Constructor module - * @brief - * The ctors section contains a list of function pointers that execute the - * C++ constructors of static global objects. These must be executed before - * the application's main() routine. - * - * NOTE: Not all compilers put those function pointers into the ctors section; - * some put them into the init_array section instead. - */ - -/* What a constructor function pointer looks like */ - -typedef void (*CtorFuncPtr)(void); - -/* Constructor function pointer list is generated by the linker script. */ - -extern CtorFuncPtr __CTOR_LIST__[]; -extern CtorFuncPtr __CTOR_END__[]; - -/** - * - * @brief Invoke all C++ style global object constructors - * - * This routine is invoked before the execution of the - * application's main(). - */ -void __do_global_ctors_aux(void) -{ - unsigned int nCtors; - - nCtors = (unsigned int)__CTOR_LIST__[0]; - - while (nCtors >= 1) { - __CTOR_LIST__[nCtors--](); - } -} - -typedef void (*DtorFuncPtr)(void); - -extern DtorFuncPtr __DTOR_LIST__[]; -extern DtorFuncPtr __DTOR_END__[]; - -/** - * - * @brief Invoke all C++ style global object destructors - * - * This routine is invoked after the execution of the - * application's main(). - */ -void __do_global_dtors_aux(void) -{ - unsigned int nDtors; - unsigned int i; - - nDtors = (unsigned int)__DTOR_LIST__[0]; - i = 0; - - while (i <= nDtors) { - __DTOR_LIST__[i++](); - } -} - -void *__dso_handle = 0; - -/** - * @brief Register destructor for a global object - * - * @param destructor the global object destructor function - * @param objptr global object pointer - * @param dso Dynamic Shared Object handle for shared libraries - * - * Function does nothing at the moment, assuming the global objects - * do not need to be deleted - * - * @return N/A - */ -int __cxa_atexit(void (*destructor)(void *), void *objptr, void *dso) -{ - return 0; -} - -typedef void (*func_ptr)(void); - -extern func_ptr __init_array_start[0]; -extern func_ptr __init_array_end[0]; - -/** - * @brief Execute initialization routines referenced in .init_array section - * - * @return N/A - */ -void __do_init_array_aux(void) -{ - for (func_ptr *func = __init_array_start; - func < __init_array_end; - func++) { - (*func)(); - } -} - -/** - * @brief Stub for pure virtual functions - * - * This routine is needed for linking C++ code that uses pure virtual - * functions. - * - * @return N/A - */ -void __cxa_pure_virtual(void) -{ - while (1) { - ; - } -} -#endif diff --git a/bsp/synopsys/embarc/arc/startup/arc_startup.S b/bsp/synopsys/embarc/arc/startup/arc_startup.S deleted file mode 100644 index 26a6fdb519..0000000000 --- a/bsp/synopsys/embarc/arc/startup/arc_startup.S +++ /dev/null @@ -1,262 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-15 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_STARTUP - * \brief assembly part of startup process - */ - -/** - * \addtogroup ARC_HAL_STARTUP - * @{ - */ -/** @cond STARTUP_ASM */ - -#define __ASSEMBLY__ -#include "embARC_BSP_config.h" -#include "inc/arc/arc.h" - - .file "arc_startup.S" - -.weak _f_sdata /* start of small data, defined in link script */ -.weak init_hardware_hook /* app hardware init hook */ -.weak init_software_hook /* app software init hook */ - -.extern board_main -.extern exc_entry_table - -/* initial vector table */ - .section .init_vector, "a" - .long _arc_reset - .section .init_bootstrap, "ax" - .global _arc_reset - .global _start - .align 4 -_start: -_arc_reset: -_arc_reset_stage1: - kflag STATUS32_RESET_VALUE - -/* STAGE 1 */ - -/* necessary hardware should be done first to speed up initialization - 1. system clk - 2. mem controller must be initialized before any access to external - mem. - 3. others -*/ -_arc_cache_init_start: - lr r0, [AUX_BCR_D_CACHE] - cmp r0, 2 - /* invalidate dcache */ - jle _arc_icache_init - mov r0, 1 - sr r0, [AUX_DC_IVDC] - sr r0, [AUX_DC_CTRL] -_arc_icache_init: - lr r0, [AUX_BCR_I_CACHE] - cmp r0, 2 - jle _arc_cache_init_end - /* invalidate icache */ - mov r0, 1 - sr r0, [AUX_IC_IVIC] - nop_s - nop_s - nop_s - sr r0, [AUX_IC_CTRL] - -_arc_cache_init_end: - mov r0, init_hardware_hook - cmp r0, 0 - jlne [r0] - -/* STAGE 2: init necessary registers */ - -_arc_reset_stage2: - mov r0, 0 - -/* interrupt related init */ - sr r0, [AUX_IRQ_ACT] - sr r0, [AUX_IRQ_CTRL] - sr r0, [AUX_IRQ_HINT] - -/* use the new vector table to replace the old one */ -#if defined(ARC_FEATURE_SEC_PRESENT) && (SECURESHIELD_VERSION < 2) - sr exc_entry_table, [AUX_INT_VECT_BASE_S] -#else - sr exc_entry_table, [AUX_INT_VECT_BASE] -#endif - -/* init stack */ -#if ARC_FEATURE_RGF_BANKED_REGS >= 16 && ARC_FEATURE_RGF_BANKED_REGS > 1 && ARC_FEATURE_FIRQ == 1 -#if _STACKSIZE < 512 -#error "not enough stack size for irq and firq" -#endif - -/* switch to register bank1 */ - lr r0, [AUX_STATUS32] - bic r0, r0, 0x70000 - or r0, r0, 0x10000 - kflag r0 -/* set sp, gp, fp in bank1 */ - mov sp, _e_stack - mov gp, _f_sdata - mov fp, 0 -/* come back to bank0 */ - lr r0, [AUX_STATUS32] - bic r0, r0, 0x70000 - kflag r0 - mov sp, _e_stack-256 -#else - mov sp, _e_stack /* init stack pointer */ -#endif - mov gp, _f_sdata /* init small-data base register */ - mov fp, 0 /* init fp register */ - -_arc_reset_stage3: -_s3_copy_text: - mov r0, _f_text - mov r1, _load_addr_text - cmp r0, r1 - -/* if load addr == run addr, no need to copy */ - jeq _s3_copy_rodata - mov r3, _e_text -_s3_copy_text_loop: - ld.ab r2, [r1, 4] - st.ab r2, [r0, 4] - cmp r0, r3 - jlt _s3_copy_text_loop -_s3_copy_rodata: - mov r0, _f_rodata - mov r1, _load_addr_rodata - cmp r0, r1 - -/* if load addr == run addr, no need to copy */ - jeq _s3_copy_data - mov r3, _e_rodata -_s3_copy_rodata_loop: - ld.ab r2, [r1, 4] - st.ab r2, [r0, 4] - cmp r0, r3 - jlt _s3_copy_rodata_loop -_s3_copy_data: - mov r0, _f_data - mov r1, _load_addr_data - cmp r0, r1 - jeq _s3_clear_bss - -/* if load addr == run addr, no need to copy */ - mov r3, _e_data -_s3_copy_data_loop: - ld.ab r2, [r1, 4] - st.ab r2, [r0, 4] - cmp r0, r3 - jlt _s3_copy_data_loop -_s3_clear_bss: - mov r0, _f_bss - mov r1, _e_bss - cmp r0, r1 - jge _arc_reset_call_main - mov r2, 0 -_s3_clear_bss_loop: - st.ab r2, [r0, 4] - cmp r0, r1 - jlt _s3_clear_bss_loop - -/* STAGE 3: go to main */ - -_arc_reset_call_main: - -/* \todo add cpp init here */ - mov r0, init_software_hook - cmp r0, 0 - jlne [r0] -/* board level library init */ -/* early init of interrupt and exception */ - jl exc_int_init -/* init cache */ - jl arc_cache_init -#if defined(__MW__) - jl _init -#elif defined(__GNU__) - jl __do_global_ctors_aux - jl __do_init_array_aux -#endif - jl board_main /* board-level main */ -#if defined(__MW__) - jl _fini -#elif defined(__GNU__) - jl __do_global_dtors_aux -#endif - .global _exit_loop - .global _exit_halt - .align 4 -_exit_halt: -_exit_loop: - flag 0x1 - nop - nop - nop - b _exit_loop - -#if defined(__MW__) - .global _init, _fini - .section ".init",text -_init: - .cfa_bf _init - push %blink - .cfa_push {%blink} - - .section ".init$999999", text, 1, 2, check_text_align=0 - pop %blink - .cfa_pop {%blink} - j [%blink] - .cfa_ef - - .section ".fini", text -_fini: - .cfa_bf _fini - push %blink - .cfa_push {%blink} - - .section ".fini$999999", text, 1, 2, check_text_align=0 - pop %blink - .cfa_pop {%blink} - j [%blink] - .cfa_ef -#endif -/** @endcond */ - -/** }@*/ diff --git a/bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c b/bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c deleted file mode 100644 index ce79414fc6..0000000000 --- a/bsp/synopsys/embarc/device/designware/gpio/dw_gpio.c +++ /dev/null @@ -1,481 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-22 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \defgroup DEVICE_DW_GPIO Designware GPIO Driver - * \ingroup DEVICE_DW - * \brief Designware GPIO Driver Implementation - */ - -/** - * \file - * \brief designware gpio driver - * \ingroup DEVICE_DW_GPIO - * \brief Designware GPIO driver - */ -#include "inc/embARC_toolchain.h" -#include "inc/embARC_error.h" -#include "inc/arc/arc_exception.h" - -#include "device/designware/gpio/dw_gpio.h" - -/** check expressions used in DesignWare GPIO driver implementation */ -#define DW_GPIO_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit) - -#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK -/** valid check of uart info object */ -#define VALID_CHK_GPIO_INFO_OBJECT(gpioinfo_obj_ptr) { \ - DW_GPIO_CHECK_EXP((gpioinfo_obj_ptr)!=NULL, E_OBJ); \ - DW_GPIO_CHECK_EXP(((gpioinfo_obj_ptr)->gpio_ctrl)!=NULL, E_OBJ); \ - } -#endif - -/** - * \defgroup DEVICE_DW_GPIO_STATIC DesignWare GPIO Driver Static Functions - * \ingroup DEVICE_DW_GPIO - * \brief Static or inline functions, variables for DesignWare GPIO handle gpio operations, - * only used in this file - * @{ - */ -Inline uint32_t dw_gpio_read_ext(DW_GPIO_PORT_PTR port) -{ - return port->regs->EXT_PORTS[port->no]; -} - -Inline uint32_t dw_gpio_read_dir(DW_GPIO_PORT_PTR port) -{ - return port->regs->SWPORTS[port->no].DDR; -} - -Inline uint32_t dw_gpio_read_dr(DW_GPIO_PORT_PTR port) -{ - return port->regs->SWPORTS[port->no].DR; -} - -Inline uint32_t dw_gpio_read_mthd(DW_GPIO_PORT_PTR port) -{ - return port->regs->INTEN; -} - -Inline void dw_gpio_int_enable(DW_GPIO_PORT_PTR port, uint32_t bit_mask) -{ - port->regs->INTEN |= bit_mask; -} - -Inline void dw_gpio_int_disable(DW_GPIO_PORT_PTR port, uint32_t bit_mask) -{ - port->regs->INTEN &= (~bit_mask); -} - -Inline void dw_gpio_int_mask(DW_GPIO_PORT_PTR port, uint32_t bit_mask) -{ - port->regs->INTMASK |= bit_mask; -} - -Inline void dw_gpio_int_unmask(DW_GPIO_PORT_PTR port, uint32_t bit_mask) -{ - port->regs->INTMASK &= (~bit_mask); -} - -Inline uint32_t dw_gpio_int_read_level(DW_GPIO_PORT_PTR port) -{ - return port->regs->INTTYPE_LEVEL; -} - -Inline uint32_t dw_gpio_int_read_polarity(DW_GPIO_PORT_PTR port) -{ - return port->regs->INT_POLARITY; -} - -Inline uint32_t dw_gpio_int_read_debounce(DW_GPIO_PORT_PTR port) -{ - return port->regs->DEBOUNCE; -} - -Inline uint32_t dw_gpio_int_read_status(DW_GPIO_PORT_PTR port) -{ - return port->regs->INTSTATUS; -} - -Inline void dw_gpio_int_clear(DW_GPIO_PORT_PTR port, uint32_t bit_mask) -{ - port->regs->PORTA_EOI = bit_mask; -} - -static void dw_gpio_int_write_level(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_level) -{ - uint32_t reg_val; - - reg_val = port->regs->INTTYPE_LEVEL; - reg_val &= (~bit_mask); - bit_level &= bit_mask; - reg_val |= bit_level; - - port->regs->INTTYPE_LEVEL = reg_val; -} - -static void dw_gpio_int_write_polarity(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_polarity) -{ - uint32_t reg_val; - - reg_val = port->regs->INT_POLARITY; - - reg_val &= (~bit_mask); - bit_polarity &= bit_mask; - reg_val |= bit_polarity; - - port->regs->INT_POLARITY = reg_val; -} - -static void dw_gpio_int_write_debounce(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_debounce) -{ - uint32_t reg_val; - - reg_val = port->regs->DEBOUNCE; - - reg_val &= (~bit_mask); - bit_debounce &= bit_mask; - reg_val |= bit_debounce; - - port->regs->DEBOUNCE = reg_val; -} - -static void dw_gpio_set_int_cfg(DW_GPIO_PORT_PTR port, DEV_GPIO_INT_CFG *int_cfg) -{ - dw_gpio_int_write_level(port, int_cfg->int_bit_mask, int_cfg->int_bit_type); - dw_gpio_int_write_polarity(port, int_cfg->int_bit_mask, int_cfg->int_bit_polarity); - dw_gpio_int_write_debounce(port, int_cfg->int_bit_mask, int_cfg->int_bit_debounce); -} - -static void dw_gpio_get_int_cfg(DW_GPIO_PORT_PTR port, DEV_GPIO_INT_CFG *int_cfg) -{ - int_cfg->int_bit_type = dw_gpio_int_read_level(port) & int_cfg->int_bit_mask; - int_cfg->int_bit_polarity = dw_gpio_int_read_polarity(port) & int_cfg->int_bit_mask; - int_cfg->int_bit_debounce = dw_gpio_int_read_debounce(port) & int_cfg->int_bit_mask; -} - -static void dw_gpio_write_dr(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t val) -{ - uint32_t temp_reg; - - temp_reg = port->regs->SWPORTS[port->no].DR; - temp_reg &= ~bit_mask; - val &= bit_mask; - temp_reg |= val; - - port->regs->SWPORTS[port->no].DR = temp_reg; -} - -static void dw_gpio_write_dir(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t val) -{ - uint32_t temp_reg; - - temp_reg = port->regs->SWPORTS[port->no].DDR; - temp_reg &= ~bit_mask; - val &= bit_mask; - temp_reg |= val; - - port->regs->SWPORTS[port->no].DDR = temp_reg; -} - -static uint32_t dw_gpio_read_val(DW_GPIO_PORT_PTR port) -{ - uint32_t val; - - val = dw_gpio_read_ext(port) & (~dw_gpio_read_dir(port)); - val |= dw_gpio_read_dr(port) & dw_gpio_read_dir(port); - - return val; -} - -/** @} end of group DEVICE_DW_GPIO_STATIC */ - -/* interface for DEV_GPIO */ -/** Open designware gpio device with specified io direction configuration */ -int32_t dw_gpio_open(DEV_GPIO *gpio_obj, uint32_t dir) -{ - int32_t ercd = E_OK; - DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); - - /* START ERROR CHECK */ - VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); - /* END OF ERROR CHECK */ - - DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); - DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); - - port_info_ptr->opn_cnt ++; - if (port_info_ptr->opn_cnt > 1) { /* opened before */ - if (dir == port_info_ptr->direction) { /* direction is the same */ - return E_OK; - } else { /* open with different direction */ - return E_OPNED; - } - } - - dw_gpio_write_dir(port, port->valid_bit_mask, dir); - - if (port->no == DW_GPIO_PORT_A) { - dw_gpio_int_clear(port, DW_GPIO_MASK_ALL); - dw_gpio_int_disable(port, DW_GPIO_MASK_ALL); - dw_gpio_int_unmask(port, DW_GPIO_MASK_ALL); - /* install gpio interrupt handler */ - int_handler_install(port->intno, port->int_handler); - int_disable(port->intno); - /** Set int type, int polarity and debounce configuration to default settings of device gpio */ - dw_gpio_set_int_cfg(port, (DEV_GPIO_INT_CFG *)(&gpio_int_cfg_default)); - port_info_ptr->method = dw_gpio_read_mthd(port); - } else { - port_info_ptr->method = DEV_GPIO_BITS_MTHD_DEFAULT; - } - - dw_gpio_write_dr(port, port->valid_bit_mask, 0); - - port_info_ptr->direction = dir; - port_info_ptr->extra = NULL; - -error_exit: - return ercd; -} - -/** Close designware gpio device */ -int32_t dw_gpio_close(DEV_GPIO *gpio_obj) -{ - int32_t ercd = E_OK; - DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); - - /* START ERROR CHECK */ - VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); - /* END OF ERROR CHECK */ - - DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); - DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); - - DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_OK); - - port_info_ptr->opn_cnt --; - if (port_info_ptr->opn_cnt == 0) { - dw_gpio_write_dr(port, port->valid_bit_mask, 0); - dw_gpio_write_dir(port, port->valid_bit_mask, 0); - if (port->no == DW_GPIO_PORT_A) { - dw_gpio_int_clear(port, DW_GPIO_MASK_ALL); - dw_gpio_int_disable(port, DW_GPIO_MASK_ALL); - int_disable(port->intno); - } - - port_info_ptr->direction = 0; - port_info_ptr->method = 0; - port_info_ptr->extra = NULL; - } else { - ercd = E_OPNED; - } - -error_exit: - return ercd; -} - -/** Read designware gpio device value */ -int32_t dw_gpio_read(DEV_GPIO *gpio_obj, uint32_t *val, uint32_t mask) -{ - int32_t ercd = E_OK; - DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); - - /* START ERROR CHECK */ - VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); - /* END OF ERROR CHECK */ - - DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); - DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); - DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED); - - DW_GPIO_CHECK_EXP(val!=NULL, E_PAR); - - //*val = dw_gpio_read_ext(port) & mask; - *val = dw_gpio_read_val(port) & mask; - -error_exit: - return ercd; -} - -/** Write designware gpio device value */ -int32_t dw_gpio_write(DEV_GPIO *gpio_obj, uint32_t val, uint32_t mask) -{ - int32_t ercd = E_OK; - DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); - - /* START ERROR CHECK */ - VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); - /* END OF ERROR CHECK */ - - DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); - DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); - DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED); - - dw_gpio_write_dr(port, mask, val); - -error_exit: - return ercd; -} - -/** Control designware gpio device */ -int32_t dw_gpio_control(DEV_GPIO *gpio_obj, uint32_t ctrl_cmd, void *param) -{ - int32_t ercd = E_OK; - DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); - - /* START ERROR CHECK */ - VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); - /* END OF ERROR CHECK */ - - DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); - DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ); - DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED); - - uint32_t val32; /** to receive unsigned int value */ - - if (ctrl_cmd == GPIO_CMD_SET_BIT_DIR_INPUT) { - val32 = (uint32_t)param; - dw_gpio_write_dir(port, val32, DW_GPIO_INPUT_ALL); - port_info_ptr->direction = dw_gpio_read_dir(port); - } else if (ctrl_cmd == GPIO_CMD_SET_BIT_DIR_OUTPUT) { - val32 = (uint32_t)param; - dw_gpio_write_dir(port, val32, DW_GPIO_OUTPUT_ALL); - port_info_ptr->direction = dw_gpio_read_dir(port); - } else if (ctrl_cmd == GPIO_CMD_GET_BIT_DIR) { - DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - port_info_ptr->direction = dw_gpio_read_dir(port); - *((int32_t *)param) = port_info_ptr->direction; - } else { - DW_GPIO_CHECK_EXP(port->no == DW_GPIO_PORT_A, E_NOSPT); - /* output pin cannot be used as interrupt */ - DEV_GPIO_INT_CFG *gpio_int_cfg; - DEV_GPIO_BIT_ISR *port_bit_isr; - - switch (ctrl_cmd) { - case GPIO_CMD_SET_BIT_INT_CFG: - DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - gpio_int_cfg = (DEV_GPIO_INT_CFG *)param; - dw_gpio_set_int_cfg(port, gpio_int_cfg); - break; - case GPIO_CMD_GET_BIT_INT_CFG: - DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - gpio_int_cfg = (DEV_GPIO_INT_CFG *)param; - /** read configuration, each bit stands for different configuration */ - dw_gpio_get_int_cfg(port, gpio_int_cfg); - break; - case GPIO_CMD_SET_BIT_ISR: - DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - port_bit_isr = (DEV_GPIO_BIT_ISR *)param; - if (port_bit_isr->int_bit_ofs < port->gpio_bit_isr->int_bit_max_cnt) { - port->gpio_bit_isr->int_bit_handler_ptr[port_bit_isr->int_bit_ofs] = port_bit_isr->int_bit_handler; - } else { - ercd = E_PAR; - } - break; - case GPIO_CMD_GET_BIT_ISR: - DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - port_bit_isr = (DEV_GPIO_BIT_ISR *)param; - if (port_bit_isr->int_bit_ofs < port->gpio_bit_isr->int_bit_max_cnt) { - port_bit_isr->int_bit_handler = port->gpio_bit_isr->int_bit_handler_ptr[port_bit_isr->int_bit_ofs]; - } else { - ercd = E_PAR; - } - break; - case GPIO_CMD_ENA_BIT_INT: - val32 = (uint32_t)param; - dw_gpio_int_enable(port, val32); - port_info_ptr->method = dw_gpio_read_mthd(port); - if (port_info_ptr->method) { - int_enable(port->intno); - } - break; - case GPIO_CMD_DIS_BIT_INT: - val32 = (uint32_t)param; - dw_gpio_int_disable(port, val32); - port_info_ptr->method = dw_gpio_read_mthd(port); - if (port_info_ptr->method == 0) { - int_disable(port->intno); - } - break; - case GPIO_CMD_GET_BIT_MTHD: - DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - port_info_ptr->method = dw_gpio_read_mthd(port); - *((int32_t *)param) = port_info_ptr->method; - break; - default: - ercd = E_NOSPT; - break; - } - } -error_exit: - return ercd; -} - -/** designware gpio interrupt process */ -int32_t dw_gpio_isr_handler(DEV_GPIO *gpio_obj, void *ptr) -{ - int32_t ercd = E_OK; - DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info); - - /* START ERROR CHECK */ - VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr); - /* END OF ERROR CHECK */ - - DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl); - DW_GPIO_CHECK_EXP(port->no == DW_GPIO_PORT_A, E_NOSPT); - - uint32_t i, gpio_bit_isr_state; - uint32_t max_int_bit_count = 0; - - /** read interrupt status */ - gpio_bit_isr_state = dw_gpio_int_read_status(port); - - if (port->gpio_bit_isr) { - max_int_bit_count = (port->gpio_bit_isr->int_bit_max_cnt); - } else { - dw_gpio_int_clear(port, gpio_bit_isr_state); - } - - for (i=0; igpio_bit_isr->int_bit_handler_ptr[i]) { - port->gpio_bit_isr->int_bit_handler_ptr[i](gpio_obj); - } - dw_gpio_int_clear(port, (1< - -#include "inc/embARC_toolchain.h" -#include "inc/embARC_error.h" - -#include "inc/arc/arc_exception.h" - -#include "device/designware/iic/dw_iic_hal.h" -#include "device/designware/iic/dw_iic.h" - -/** check expressions used in DesignWare IIC driver implementation */ -#define DW_IIC_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit) - -#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK -/** valid check of iic info object */ -#define VALID_CHK_IIC_INFO_OBJECT(iicinfo_obj_ptr) { \ - DW_IIC_CHECK_EXP((iicinfo_obj_ptr)!=NULL, E_OBJ); \ - DW_IIC_CHECK_EXP(((iicinfo_obj_ptr)->iic_ctrl)!=NULL, E_OBJ); \ - } -#endif - -/** - * \name DesignWare IIC Interrupt Callback Routine Select Marcos - * \brief DesignWare IIC interrupt callback routines select macros definitions - * @{ - */ -#define DW_IIC_RDY_SND (1U) /*!< ready to send callback */ -#define DW_IIC_RDY_RCV (2U) /*!< ready to receive callback */ -/** @} */ - -/** - * \defgroup DEVICE_DW_IIC_STATIC DesignWare IIC Driver Static Functions - * \ingroup DEVICE_DW_IIC - * \brief Static or inline functions, variables for DesignWare IIC handle iic operations, - * only used in this file. - * @{ - */ -/** Disable designware iic device */ -Inline void dw_iic_disable(DW_IIC_REG *iic_reg_ptr) -{ - iic_reg_ptr->IC_ENABLE = DW_IIC_DISABLE; -} -/** Enable designware iic device */ -Inline void dw_iic_enable(DW_IIC_REG *iic_reg_ptr) -{ - iic_reg_ptr->IC_ENABLE = DW_IIC_ENABLE; -} - -/** Clear all designware iic interrupt */ -Inline void dw_iic_clear_interrupt_all(DW_IIC_REG *iic_reg_ptr) -{ - (void)iic_reg_ptr->IC_CLR_INTR; -} - -/** test whether iic is ready to write, 1 ready, 0 not ready */ -Inline int32_t dw_iic_putready(DW_IIC_REG *iic_reg_ptr) -{ - return ((iic_reg_ptr->IC_STATUS & IC_STATUS_TFNF) != 0); -} -/** test whether iic is ready to receive, 1 ready, 0 not ready */ -Inline int32_t dw_iic_getready(DW_IIC_REG *iic_reg_ptr) -{ - return ((iic_reg_ptr->IC_STATUS & IC_STATUS_RFNE) != 0); -} -/** Write data into IIC TX FIFO with STOP/RESTART Condition, and R/W bit */ -Inline void dw_iic_putdata(DW_IIC_REG *iic_reg_ptr, uint32_t data) -{ - iic_reg_ptr->IC_DATA_CMD = data; -} - -/** Read Data from IIC RX FIFO */ -Inline uint32_t dw_iic_getdata(DW_IIC_REG *iic_reg_ptr) -{ - return (iic_reg_ptr->IC_DATA_CMD) & 0xff; -} - -/** Enable designware iic bit interrupt with mask */ -Inline void dw_iic_unmask_interrupt(DW_IIC_REG *iic_reg_ptr, uint32_t mask) -{ - iic_reg_ptr->IC_INTR_MASK |= mask; -} - -/** Disable designware iic bit interrupt with mask */ -Inline void dw_iic_mask_interrupt(DW_IIC_REG *iic_reg_ptr, uint32_t mask) -{ - iic_reg_ptr->IC_INTR_MASK &= ~mask; -} - -/** Get TX FIFO Length */ -Inline uint32_t dw_iic_get_txfifo_len(DW_IIC_REG *iic_reg_ptr) -{ - uint32_t txfifolen; - - txfifolen = ((iic_reg_ptr->IC_COMP_PARAM_1 >> 16) & 0xff) + 1; - - return txfifolen; -} - -/** Get RX FIFO Length */ -Inline uint32_t dw_iic_get_rxfifo_len(DW_IIC_REG *iic_reg_ptr) -{ - uint32_t rxfifolen; - - rxfifolen = ((iic_reg_ptr->IC_COMP_PARAM_1 >> 8) & 0xff) + 1; - - return rxfifolen; -} - -/** Set designware iic transfer in 7bit of 10bit addressing mode as a master */ -Inline void dw_iic_set_mstaddr_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode) -{ -#if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT - if (mode == IIC_7BIT_ADDRESS) { - iic_reg_ptr->IC_TAR &= ~IC_10BITADDR_MASTER; - } else { - iic_reg_ptr->IC_TAR |= IC_10BITADDR_MASTER; - } -#else - dw_iic_disable(iic_reg_ptr); - if (mode == IIC_7BIT_ADDRESS) { - iic_reg_ptr->IC_CON &= ~MST_10_BIT_ADDR_MODE; - } else { - iic_reg_ptr->IC_CON |= MST_10_BIT_ADDR_MODE; - } - dw_iic_enable(iic_reg_ptr); -#endif -} - -/** Set designware iic transfer in 7bit of 10bit addressing mode as a slave */ -Inline void dw_iic_set_slvaddr_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode) -{ - dw_iic_disable(iic_reg_ptr); - if (mode == IIC_7BIT_ADDRESS) { - iic_reg_ptr->IC_CON &= ~SLV_10_BIT_ADDR_MODE; - } else { - iic_reg_ptr->IC_CON |= SLV_10_BIT_ADDR_MODE; - } - dw_iic_enable(iic_reg_ptr); -} - -/** Set designware iic transfer target address for addressing any iic slave device as a master */ -Inline void dw_iic_set_taraddr(DW_IIC_REG *iic_reg_ptr, uint32_t address) -{ -#if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT - iic_reg_ptr->IC_TAR &= ~(IC_TAR_10BIT_ADDR_MASK); - iic_reg_ptr->IC_TAR |= (IC_TAR_10BIT_ADDR_MASK & address); -#else - dw_iic_disable(iic_reg_ptr); - iic_reg_ptr->IC_TAR &= ~(IC_TAR_10BIT_ADDR_MASK); - iic_reg_ptr->IC_TAR |= (IC_TAR_10BIT_ADDR_MASK & address); - dw_iic_enable(iic_reg_ptr); -#endif -} - -/** Set designware iic slave address as a slave */ -Inline void dw_iic_set_slvaddr(DW_IIC_REG *iic_reg_ptr, uint32_t address) -{ - dw_iic_disable(iic_reg_ptr); - iic_reg_ptr->IC_SAR &= ~(IC_SAR_10BIT_ADDR_MASK); - iic_reg_ptr->IC_SAR |= (IC_SAR_10BIT_ADDR_MASK & address); - dw_iic_enable(iic_reg_ptr); -} - -/** Select speed mode, and return proper speed mode configuration */ -Inline uint32_t dw_iic_select_speedmode(uint32_t speedmode) -{ - uint32_t speedcfg; - - if (speedmode == IIC_SPEED_STANDARD) { - speedcfg = IC_CON_SPEED_STANDARD; - } else if (speedmode == IIC_SPEED_FAST) { - speedcfg = IC_CON_SPEED_FAST; - } else if (speedmode == IIC_SPEED_FASTPLUS) { - speedcfg = IC_CON_SPEED_FAST; - } else if (speedmode == IIC_SPEED_HIGH) { - speedcfg = IC_CON_SPEED_HIGH; - } else { - speedcfg = IC_CON_SPEED_HIGH; - } - return speedcfg; -} -/** Set designware iic speed mode */ -Inline void dw_iic_set_speedmode(DW_IIC_REG *iic_reg_ptr, uint32_t speedmode) -{ - uint32_t ic_con_val; - - dw_iic_disable(iic_reg_ptr); - ic_con_val = iic_reg_ptr->IC_CON & (~IC_CON_SPEED_MASK); - ic_con_val |= dw_iic_select_speedmode(speedmode); - iic_reg_ptr->IC_CON = ic_con_val; - dw_iic_enable(iic_reg_ptr); -} - -/** Set designware working mode as master or slave */ -Inline void dw_iic_set_working_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode) -{ - uint32_t ic_con_val; - dw_iic_disable(iic_reg_ptr); - ic_con_val = iic_reg_ptr->IC_CON & (~IC_CON_MST_SLV_MODE_MASK); - if (mode == DEV_MASTER_MODE) { - ic_con_val |= IC_CON_ENA_MASTER_MODE; - } else { - ic_con_val |= IC_CON_ENA_SLAVE_MODE; - } - dw_iic_enable(iic_reg_ptr); -} - -/** Set IC_CLK frequency by configuration the *CNT registers for different speed modes */ -Inline void dw_iic_set_scl_cnt(DW_IIC_REG *iic_reg_ptr, DW_IIC_SCL_CNT *scl_cnt) -{ - dw_iic_disable(iic_reg_ptr); - iic_reg_ptr->IC_SS_SCL_HCNT = scl_cnt->ss_scl_hcnt; - iic_reg_ptr->IC_SS_SCL_LCNT = scl_cnt->ss_scl_lcnt; - iic_reg_ptr->IC_FS_SCL_HCNT = scl_cnt->fs_scl_hcnt; - iic_reg_ptr->IC_FS_SCL_LCNT = scl_cnt->fs_scl_lcnt; - iic_reg_ptr->IC_HS_SCL_HCNT = scl_cnt->hs_scl_hcnt; - iic_reg_ptr->IC_HS_SCL_LCNT = scl_cnt->hs_scl_lcnt; - dw_iic_enable(iic_reg_ptr); -} - -/** Set spike suppression configuration */ -Inline void dw_iic_set_spike_len(DW_IIC_REG *iic_reg_ptr, DW_IIC_SPKLEN *spklen) -{ - dw_iic_disable(iic_reg_ptr); - iic_reg_ptr->IC_FS_SPKLEN = spklen->fs_spklen; - iic_reg_ptr->IC_HS_SPKLEN = spklen->hs_spklen; - dw_iic_enable(iic_reg_ptr); -} - -Inline void dw_iic_flush_tx(DW_IIC_REG *iic_reg_ptr) -{ - (void)iic_reg_ptr->IC_CLR_INTR; -} - -Inline void dw_iic_flush_rx(DW_IIC_REG *iic_reg_ptr) -{ -} - -static uint32_t dw_iic_get_slv_state(DW_IIC_REG *iic_reg_ptr) -{ - uint32_t status; - uint32_t slv_state = IIC_SLAVE_STATE_FREE; - - status = iic_reg_ptr->IC_RAW_INTR_STAT; - if (status & IC_INTR_STAT_GEN_CALL) { - /* General Call address is received and it is acknowledged */ - slv_state |= IIC_SLAVE_STATE_GC_REQ; - } - if (status & IC_INTR_STAT_RX_FULL) { - /* master is attempting to write data to this slave */ - slv_state |= IIC_SLAVE_STATE_WR_REQ; - } - if (status & IC_INTR_STAT_RD_REQ) { - /* master is attempting to read data from this slave */ - slv_state |= IIC_SLAVE_STATE_RD_REQ; - } - if (status & IC_INTR_STAT_RX_DONE) { - /* master does not acknowledge a transmitted byte, and transmission is done */ - slv_state |= IIC_SLAVE_STATE_RD_DONE; - status = iic_reg_ptr->IC_CLR_RX_DONE; - } - if (status & IC_INTR_STAT_START_DET) { - /* a START or RESTART condition has occurred */ - slv_state |= IIC_SLAVE_STATE_START; - status = iic_reg_ptr->IC_CLR_START_DET; /* Clear it when read */ - } - if (status & IC_INTR_STAT_STOP_DET) { - /* a STOP condition has occurred */ - slv_state |= IIC_SLAVE_STATE_STOP; - status = iic_reg_ptr->IC_CLR_STOP_DET; /* Clear it when read */ - } - if (status & (IC_INTR_STAT_TX_ABRT|IC_INTR_STAT_TX_OVER\ - |IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { - /* error case */ - slv_state |= IIC_SLAVE_STATE_ERROR; - status = iic_reg_ptr->IC_CLR_TX_ABRT; /* Clear it when read */ - status = iic_reg_ptr->IC_CLR_TX_OVER; - status = iic_reg_ptr->IC_CLR_RX_OVER; - status = iic_reg_ptr->IC_CLR_RX_UNDER; - } - - return slv_state; -} - -/** Init Designware IIC Device into Master mode */ -static void dw_iic_master_init(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t speed_mode, uint32_t addr_mode, uint32_t tar_addr) -{ - uint32_t ic_con_val = 0; - DW_IIC_REG *iic_reg_ptr = iic_ctrl_ptr->dw_iic_regs; - - dw_iic_disable(iic_reg_ptr); - - /* disable all iic interrupt */ - iic_reg_ptr->IC_INTR_MASK = IC_INT_DISABLE_ALL; - - /* Set to 7bit addressing and update target address */ - iic_reg_ptr->IC_TAR = (tar_addr & IC_TAR_10BIT_ADDR_MASK) | IC_TAR_SPECIAL | IC_TAR_GC_OR_START; - /* master mode, restart enabled */ - ic_con_val = dw_iic_select_speedmode(speed_mode) | IC_CON_ENA_MASTER_MODE | IC_CON_RESTART_EN; - -#if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT - if (addr_mode == IIC_10BIT_ADDRESS) { - iic_reg_ptr->IC_TAR |= MST_10_BIT_ADDR_MODE; - } -#else - if (addr_mode == IIC_10BIT_ADDRESS) { - ic_con_val |= MST_10_BIT_ADDR_MODE; - } -#endif - /* Set final IC_CON value */ - iic_reg_ptr->IC_CON = ic_con_val; - /* FIFO threshold settings */ - iic_reg_ptr->IC_TX_TL = IIC_TX_THRESHOLD; - iic_reg_ptr->IC_RX_TL = IIC_RX_THRESHOLD; - /* Master code settings */ - iic_reg_ptr->IC_HS_MADDR = iic_ctrl_ptr->iic_master_code; - dw_iic_enable(iic_reg_ptr); - - /* Clock Settings */ - dw_iic_set_scl_cnt(iic_reg_ptr, &(iic_ctrl_ptr->iic_scl_cnt)); - dw_iic_set_spike_len(iic_reg_ptr, &(iic_ctrl_ptr->iic_spklen)); -} - -/** Init Designware IIC Device into Slave mode */ -static void dw_iic_slave_init(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t addr_mode, uint32_t slv_addr) -{ - uint32_t ic_con_val = 0; - DW_IIC_REG *iic_reg_ptr = iic_ctrl_ptr->dw_iic_regs; - - dw_iic_disable(iic_reg_ptr); - - /* disable all iic interrupt */ - iic_reg_ptr->IC_INTR_MASK = IC_INT_DISABLE_ALL; - - /* Set slave device address as a slave */ - iic_reg_ptr->IC_SAR = slv_addr & IC_SAR_10BIT_ADDR_MASK; - /* slave mode, 7 bit slave address */ - ic_con_val = IC_CON_ENA_SLAVE_MODE; - /* If addr mode select to be 10 bit address mode */ - if (addr_mode == IIC_10BIT_ADDRESS) { - ic_con_val |= SLV_10_BIT_ADDR_MODE; - } - - /* Set final IC_CON value */ - iic_reg_ptr->IC_CON = ic_con_val; - /* FIFO threshold settings */ - iic_reg_ptr->IC_TX_TL = IIC_TX_THRESHOLD; - iic_reg_ptr->IC_RX_TL = IIC_RX_THRESHOLD; - - dw_iic_enable(iic_reg_ptr); -} - -/** Check error for IIC master device */ -static int32_t dw_iic_mst_chkerr(DW_IIC_CTRL *iic_ctrl_ptr) -{ - uint32_t status; - int32_t ercd = IIC_ERR_NONE; - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - status = iic_reg_ptr->IC_RAW_INTR_STAT; - if (status & IC_INTR_STAT_TX_ABRT) { - status = iic_reg_ptr->IC_TX_ABRT_SOURCE; - if (status & IIC_MST_ABRT_LOST_BUS) { - ercd = IIC_ERR_LOST_BUS; - } else if (status & IIC_MST_ABRT_ADDR_NOACK) { - ercd = IIC_ERR_ADDR_NOACK; - } else if (status & IIC_MST_ABRT_DATA_NOACK) { - ercd = IIC_ERR_DATA_NOACK; - } else { - ercd = IIC_ERR_UNDEF; - } - status = iic_reg_ptr->IC_CLR_TX_ABRT; - } else { - if (status & IC_INTR_STAT_TX_OVER) { - iic_ctrl_ptr->iic_tx_over ++; - status = iic_reg_ptr->IC_CLR_TX_OVER; - } - if (status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { - iic_ctrl_ptr->iic_rx_over ++; - status = iic_reg_ptr->IC_CLR_RX_OVER; - status = iic_reg_ptr->IC_CLR_RX_UNDER; - } - } - return ercd; -} - -/** Check error for IIC slave device */ -static int32_t dw_iic_slv_chkerr(DW_IIC_CTRL *iic_ctrl_ptr) -{ - uint32_t status; - int32_t ercd = IIC_ERR_NONE; - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - status = iic_reg_ptr->IC_RAW_INTR_STAT; - if (status & IC_INTR_STAT_TX_ABRT) { - status = iic_reg_ptr->IC_TX_ABRT_SOURCE; - if (status & IIC_SLV_ABRT_LOST_BUS) { - ercd = IIC_ERR_LOST_BUS; - } else if (status & IC_TX_ABRT_SLVFLUSH_TXFIFO) { - /* Flush tx fifo */ - status = iic_reg_ptr->IC_TX_ABRT_SOURCE; - } else { - ercd = IIC_ERR_UNDEF; - } - status = iic_reg_ptr->IC_CLR_TX_ABRT; - } else { - if (status & IC_INTR_STAT_TX_OVER) { - iic_ctrl_ptr->iic_tx_over ++; - status = iic_reg_ptr->IC_CLR_TX_OVER; - } - if (status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { - iic_ctrl_ptr->iic_rx_over ++; - status = iic_reg_ptr->IC_CLR_RX_OVER; - status = iic_reg_ptr->IC_CLR_RX_UNDER; - } - } - return ercd; -} - -/** enable designware iic */ -static void dw_iic_enable_device(DEV_IIC_INFO *iic_info_ptr) -{ - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - if ((iic_info_ptr->status & DEV_ENABLED) == 0) { - dw_iic_enable(iic_reg_ptr); - iic_info_ptr->status |= DEV_ENABLED; - } -} - -/** disable designware iic */ -static void dw_iic_disable_device(DEV_IIC_INFO *iic_info_ptr) -{ - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - uint32_t i; - - for (i=0; iIC_ENABLE_STATUS & IC_ENABLE_STATUS_IC_EN) == 0) { - break; - } - } - iic_info_ptr->status &= ~DEV_ENABLED; -} - -static void dw_iic_reset_device(DEV_IIC_INFO *iic_info_ptr) -{ - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - dw_iic_disable_device(iic_info_ptr); - dw_iic_clear_interrupt_all(iic_reg_ptr); - iic_info_ptr->next_cond = IIC_MODE_STOP; - iic_info_ptr->cur_state = IIC_FREE; - iic_info_ptr->err_state = IIC_ERR_NONE; - iic_ctrl_ptr->iic_tx_over = 0; - iic_ctrl_ptr->iic_rx_over = 0; - dw_iic_enable_device(iic_info_ptr); -} - -/** Disable iic master interrupt for transmit or receive */ -static void dw_iic_mst_dis_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn) -{ - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - switch (cbrtn) { - case DW_IIC_RDY_SND: - dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_MST_TX_ENABLE); - iic_ctrl_ptr->int_status &= ~DW_IIC_TXINT_ENABLE; - break; - case DW_IIC_RDY_RCV: - dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_MST_RX_ENABLE); - iic_ctrl_ptr->int_status &= ~DW_IIC_RXINT_ENABLE; - break; - default: - break; - } -} - -/** Disable iic slave interrupt for transmit or receive */ -static void dw_iic_slv_dis_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn) -{ - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - switch (cbrtn) { - case DW_IIC_RDY_SND: - dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_SLV_TX_ENABLE); - iic_ctrl_ptr->int_status &= ~DW_IIC_TXINT_ENABLE; - break; - case DW_IIC_RDY_RCV: - dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_SLV_RX_ENABLE); - iic_ctrl_ptr->int_status &= ~DW_IIC_RXINT_ENABLE; - break; - default: - break; - } -} - -/** Enable iic master interrupt for transmit or receive */ -static void dw_iic_mst_ena_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn) -{ - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - switch (cbrtn) { - case DW_IIC_RDY_SND: - iic_ctrl_ptr->int_status |= DW_IIC_TXINT_ENABLE; - dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_MST_TX_ENABLE); - break; - case DW_IIC_RDY_RCV: - iic_ctrl_ptr->int_status |= DW_IIC_RXINT_ENABLE; - dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_MST_RX_ENABLE); - break; - default: - break; - } -} - -/** Enable iic slave interrupt for transmit or receive */ -static void dw_iic_slv_ena_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn) -{ - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - switch (cbrtn) { - case DW_IIC_RDY_SND: - iic_ctrl_ptr->int_status |= DW_IIC_TXINT_ENABLE; - dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_SLV_TX_ENABLE); - break; - case DW_IIC_RDY_RCV: - iic_ctrl_ptr->int_status |= DW_IIC_RXINT_ENABLE; - dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_SLV_RX_ENABLE); - break; - default: - break; - } -} - -/** - * \brief disable designware iic send or receive interrupt - * \param[in] DEV_IIC_INFO *iic_info_ptr - * \param[in] cbrtn control code of callback routine of send or receive - */ -static void dw_iic_dis_cbr(DEV_IIC_INFO *iic_info_ptr, uint32_t cbrtn) -{ - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - - if (iic_info_ptr->mode == DEV_MASTER_MODE) { - dw_iic_mst_dis_cbr(iic_ctrl_ptr, cbrtn); - } else { - dw_iic_slv_dis_cbr(iic_ctrl_ptr, cbrtn); - } - - if (iic_ctrl_ptr->int_status & DW_IIC_GINT_ENABLE) { - if ((iic_ctrl_ptr->int_status & (DW_IIC_RXINT_ENABLE|DW_IIC_TXINT_ENABLE)) == 0) { - int_disable(iic_ctrl_ptr->intno); - iic_ctrl_ptr->int_status &= ~DW_IIC_GINT_ENABLE; - } - } -} - -/** - * \brief enable DesignWare IIC send or receive interrupt - * \param[in] DEV_IIC_INFO *iic_info_ptr - * \param[in] cbrtn control code of callback routine of send or receive - */ -static void dw_iic_ena_cbr(DEV_IIC_INFO *iic_info_ptr, uint32_t cbrtn) -{ - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - - if (iic_info_ptr->mode == DEV_MASTER_MODE) { - dw_iic_mst_ena_cbr(iic_ctrl_ptr, cbrtn); - } else { - dw_iic_slv_ena_cbr(iic_ctrl_ptr, cbrtn); - } - - if ((iic_ctrl_ptr->int_status & DW_IIC_GINT_ENABLE) == 0) { - if (iic_ctrl_ptr->int_status & (DW_IIC_RXINT_ENABLE|DW_IIC_TXINT_ENABLE)) { - iic_ctrl_ptr->int_status |= DW_IIC_GINT_ENABLE; - int_enable(iic_ctrl_ptr->intno); - } - } -} - -/** - * \brief enable designware iic interrupt - * \param iic_info_ptr iic information structure pointer - */ -static void dw_iic_enable_interrupt(DEV_IIC_INFO *iic_info_ptr) -{ - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - - int_handler_install(iic_ctrl_ptr->intno, iic_ctrl_ptr->dw_iic_int_handler); - iic_ctrl_ptr->int_status |= DW_IIC_GINT_ENABLE; - int_enable(iic_ctrl_ptr->intno); /** enable iic interrupt */ -} -/** - * \brief disable designware iic interrupt - * \param iic_info_ptr iic information structure pointer - */ -static void dw_iic_disable_interrupt(DEV_IIC_INFO *iic_info_ptr) -{ - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - - /** disable iic send&receive interrupt after disable iic interrupt */ - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); - /* disable iic interrupt */ - int_disable(iic_ctrl_ptr->intno); - iic_ctrl_ptr->int_status &= ~(DW_IIC_GINT_ENABLE|DW_IIC_TXINT_ENABLE|DW_IIC_RXINT_ENABLE); -} - -/** abort current interrupt transmit transfer */ -static void dw_iic_abort_tx(DEV_IIC *iic_obj) -{ - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - - if (iic_ctrl_ptr->int_status & DW_IIC_TXINT_ENABLE) { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); - iic_info_ptr->status |= DEV_IN_TX_ABRT; - if (iic_info_ptr->iic_cbs.tx_cb != NULL) { - iic_info_ptr->iic_cbs.tx_cb(iic_obj); - } - iic_info_ptr->status &= ~(DEV_IN_TX_ABRT); - } -} - -/** abort current interrupt receive transfer */ -static void dw_iic_abort_rx(DEV_IIC *iic_obj) -{ - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - - if (iic_ctrl_ptr->int_status & DW_IIC_RXINT_ENABLE) { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); - iic_info_ptr->status |= DEV_IN_RX_ABRT; - if (iic_info_ptr->iic_cbs.rx_cb != NULL) { - iic_info_ptr->iic_cbs.rx_cb(iic_obj); - } - iic_info_ptr->status &= ~(DEV_IN_RX_ABRT); - } -} - -/** Get available transmit fifo count */ -static int32_t dw_iic_get_txavail(DW_IIC_CTRL *iic_ctrl_ptr) -{ - int32_t tx_avail = 0; - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - if (iic_ctrl_ptr->tx_fifo_len <= 1) { - if (dw_iic_putready(iic_reg_ptr) == 1) { - tx_avail = 1; - } else { - tx_avail = 0; - } - } else { - tx_avail = iic_ctrl_ptr->tx_fifo_len - iic_reg_ptr->IC_TXFLR; - } - return tx_avail; -} - -/** Get available receive fifo count */ -static int32_t dw_iic_get_rxavail(DW_IIC_CTRL *iic_ctrl_ptr) -{ - int32_t rx_avail = 0; - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - if (iic_ctrl_ptr->rx_fifo_len <= 1) { - if (dw_iic_getready(iic_reg_ptr) == 1) { - rx_avail = 1; - } else { - rx_avail = 0; - } - } else { - rx_avail = iic_reg_ptr->IC_RXFLR; - } - return rx_avail; -} - -/** - * IIC Master device transmit 1 data, - * next_cond can be \ref IC_DATA_CMD_STOP, - * \ref IC_DATA_CMD_RESTART and ref IC_DATA_CMD_NONE - */ -static int32_t dw_iic_mst_write_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t data, uint32_t next_cond) -{ - uint32_t i = 0; - int32_t ercd = IIC_ERR_NONE; - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - while (dw_iic_putready(iic_reg_ptr) == 0) { - if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT; - ercd = dw_iic_mst_chkerr(iic_ctrl_ptr); - if (ercd != IIC_ERR_NONE) return ercd; - } - dw_iic_putdata(iic_reg_ptr, data|IC_DATA_CMD_WRITE_REQ|next_cond); - - return ercd; -} - -/** IIC Slave device transmit 1 data */ -static int32_t dw_iic_slv_write_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t data) -{ - uint32_t i = 0; - int32_t ercd = IIC_ERR_NONE; - uint32_t slv_state, temp; - uint32_t ready2send = 0; - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - for (i = 0; i < iic_ctrl_ptr->retry_cnt; i++) { - ercd = dw_iic_slv_chkerr(iic_ctrl_ptr); - if (ercd != IIC_ERR_NONE) return ercd; - slv_state = iic_reg_ptr->IC_RAW_INTR_STAT; - if (slv_state & IC_INTR_STAT_RD_REQ) { - if (dw_iic_putready(iic_reg_ptr)) { - temp = iic_reg_ptr->IC_CLR_RD_REQ; - ready2send = 1; - break; - } - } else if (slv_state & IC_INTR_STAT_RX_DONE) { /* Put RX Done before STOP */ - temp = iic_reg_ptr->IC_CLR_RX_DONE; - return IIC_ERR_MSTSTOP; - } else if (slv_state & IC_INTR_STAT_STOP_DET) { - temp = iic_reg_ptr->IC_CLR_STOP_DET; - return IIC_ERR_MSTSTOP; - } - } - if (ready2send) { - dw_iic_putdata(iic_reg_ptr, data|IC_DATA_CMD_WRITE_REQ); - } else { - ercd = IIC_ERR_TIMEOUT; - } - - return ercd; -} - -/** - * IIC Master device receive 1 data, - * next_cond can be \ref IC_DATA_CMD_STOP, - * \ref IC_DATA_CMD_RESTART and ref IC_DATA_CMD_NONE - */ -static int32_t dw_iic_mst_read_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t *data, uint32_t next_cond) -{ - uint32_t i = 0; - int32_t ercd = IIC_ERR_NONE; - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - /* Issue a read request */ - while (dw_iic_putready(iic_reg_ptr) == 0) { - if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT; - ercd = dw_iic_mst_chkerr(iic_ctrl_ptr); - if (ercd != IIC_ERR_NONE) return ercd; - } - dw_iic_putdata(iic_reg_ptr, next_cond|IC_DATA_CMD_READ_REQ); - /* Wait to read data */ - i = 0; - while (dw_iic_getready(iic_reg_ptr) == 0) { - if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT; - ercd = dw_iic_mst_chkerr(iic_ctrl_ptr); - if (ercd != IIC_ERR_NONE) return ercd; - } - *data = dw_iic_getdata(iic_reg_ptr); - return ercd; -} - -/** IIC Slave device receive 1 data */ -static int32_t dw_iic_slv_read_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t *data) -{ - uint32_t i = 0; - int32_t ercd = IIC_ERR_NONE; - uint32_t slv_state, temp; - uint32_t ready2read = 0; - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - for (i = 0; i < iic_ctrl_ptr->retry_cnt; i++) { - ercd = dw_iic_slv_chkerr(iic_ctrl_ptr); - if (ercd != IIC_ERR_NONE) return ercd; - slv_state = iic_reg_ptr->IC_RAW_INTR_STAT; - if (slv_state & IC_INTR_STAT_START_DET) { - temp = iic_reg_ptr->IC_CLR_START_DET; - } - if (slv_state & IC_INTR_STAT_RX_FULL) { - if (dw_iic_getready(iic_reg_ptr)) { - ready2read = 1; - break; - } - } else if (slv_state & IC_INTR_STAT_STOP_DET) { - temp = iic_reg_ptr->IC_CLR_STOP_DET; - return IIC_ERR_MSTSTOP; - } - } - if (ready2read) { - *data = dw_iic_getdata(iic_reg_ptr); - } else { - ercd = IIC_ERR_TIMEOUT; - } - - return ercd; -} - -/** IIC Master transmit called in interrupt */ -static void dw_iic_mst_int_write(DEV_IIC *iic_obj) -{ - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs); - uint32_t iic_int_status; /** iic interrupt status */ - uint32_t last_cond, xmit_data, xmit_end = 0; - DEV_BUFFER *buf_ptr; - uint8_t *p_charbuf; - - if (iic_info_ptr->next_cond == IIC_MODE_STOP) { - last_cond = IC_DATA_CMD_STOP; - } else { - last_cond = IC_DATA_CMD_RESTART; - } - iic_int_status = (iic_reg_ptr->IC_INTR_STAT); - buf_ptr = &(iic_info_ptr->tx_buf); - p_charbuf = (uint8_t *)buf_ptr->buf; - if (p_charbuf) { - if (iic_int_status & IC_INTR_STAT_TX_EMPTY) { - xmit_end = 0; - while (dw_iic_putready(iic_reg_ptr)) { - xmit_data = (uint32_t)(p_charbuf[buf_ptr->ofs])|IC_DATA_CMD_WRITE_REQ; - if (buf_ptr->ofs == (buf_ptr->len-1)) { - xmit_end = 1; - xmit_data |= last_cond; - } else { - xmit_data |= IC_DATA_CMD_NONE; - } - buf_ptr->ofs ++; - dw_iic_putdata(iic_reg_ptr, xmit_data); - if (xmit_end) { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); - iic_info_ptr->cur_state = IIC_FREE; - if (iic_info_ptr->iic_cbs.tx_cb) { - iic_info_ptr->iic_cbs.tx_cb(iic_obj); - } - /* clear the send buffer pointer */ - memset(buf_ptr, 0, sizeof(DEV_BUFFER)); - break; - } - } - } - if (iic_int_status & IC_INTR_STAT_TX_OVER) { - iic_ctrl_ptr->iic_tx_over ++; - } - if (iic_int_status & IC_INTR_STAT_TX_ABRT) { - iic_info_ptr->err_state = dw_iic_mst_chkerr(iic_ctrl_ptr); - if (iic_info_ptr->err_state != IIC_ERR_NONE) { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); - iic_info_ptr->cur_state = IIC_FREE; - if (iic_info_ptr->iic_cbs.err_cb) { - iic_info_ptr->iic_cbs.err_cb(iic_obj); - } - /* clear the send buffer pointer */ - memset(buf_ptr, 0, sizeof(DEV_BUFFER)); - } - } - } else { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); - iic_info_ptr->cur_state = IIC_FREE; - } - /* Clear Interrupt */ - iic_int_status = iic_reg_ptr->IC_CLR_INTR; -} - -/** IIC Master receive called in interrupt */ -static void dw_iic_mst_int_read(DEV_IIC *iic_obj) -{ - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs); - uint32_t iic_int_status; /** iic interrupt status */ - uint32_t last_cond, xmit_data; - DEV_BUFFER *buf_ptr; - DW_IIC_BUFFER *dw_iic_rxbuf_ptr; - uint8_t *p_charbuf; - - if (iic_info_ptr->next_cond == IIC_MODE_STOP) { - last_cond = IC_DATA_CMD_STOP; - } else { - last_cond = IC_DATA_CMD_RESTART; - } - iic_int_status = (iic_reg_ptr->IC_INTR_STAT); - buf_ptr = &(iic_info_ptr->rx_buf); - p_charbuf = (uint8_t *)buf_ptr->buf; - if (p_charbuf) { - dw_iic_rxbuf_ptr = &(iic_ctrl_ptr->dw_iic_rxbuf); - if (iic_int_status & IC_INTR_STAT_TX_EMPTY) { - while (dw_iic_putready(iic_reg_ptr)) { - if (dw_iic_rxbuf_ptr->ofs >= dw_iic_rxbuf_ptr->len) { - dw_iic_mask_interrupt(iic_reg_ptr, IC_INTR_STAT_TX_EMPTY); - break; - } - xmit_data = IC_DATA_CMD_READ_REQ; - if (dw_iic_rxbuf_ptr->ofs == (dw_iic_rxbuf_ptr->len-1)) { - xmit_data |= last_cond; - } else { - xmit_data |= IC_DATA_CMD_NONE; - } - dw_iic_rxbuf_ptr->ofs ++; - dw_iic_putdata(iic_reg_ptr, xmit_data); - } - } - if (iic_int_status & IC_INTR_STAT_RX_FULL) { - while (dw_iic_getready(iic_reg_ptr)) { - p_charbuf[buf_ptr->ofs] = dw_iic_getdata(iic_reg_ptr); - buf_ptr->ofs ++; - if (buf_ptr->ofs >= buf_ptr->len) { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); - iic_info_ptr->cur_state = IIC_FREE; - if (iic_info_ptr->iic_cbs.rx_cb) { - iic_info_ptr->iic_cbs.rx_cb(iic_obj); - } - /* clear the send buffer pointer */ - memset(buf_ptr, 0, sizeof(DEV_BUFFER)); - dw_iic_rxbuf_ptr->ofs = 0; - dw_iic_rxbuf_ptr->len = 0; - break; - } - } - } - if (iic_int_status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { - iic_ctrl_ptr->iic_rx_over ++; - } - if (iic_int_status & IC_INTR_STAT_TX_ABRT) { - iic_info_ptr->err_state = dw_iic_mst_chkerr(iic_ctrl_ptr); - if (iic_info_ptr->err_state != IIC_ERR_NONE) { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); - iic_info_ptr->cur_state = IIC_FREE; - if (iic_info_ptr->iic_cbs.err_cb) { - iic_info_ptr->iic_cbs.err_cb(iic_obj); - } - /* clear the send buffer pointer */ - memset(buf_ptr, 0, sizeof(DEV_BUFFER)); - dw_iic_rxbuf_ptr->ofs = 0; - dw_iic_rxbuf_ptr->len = 0; - } - } - } else { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); - iic_info_ptr->cur_state = IIC_FREE; - } - /* Clear Interrupt */ - iic_int_status = iic_reg_ptr->IC_CLR_INTR; -} - -/** IIC Slave transmit called in interrupt */ -static void dw_iic_slv_int_process(DEV_IIC *iic_obj) -{ - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs); - uint32_t iic_int_status; /** iic interrupt status */ - - iic_int_status = (iic_reg_ptr->IC_INTR_STAT); - if (iic_int_status & IC_INTR_STAT_RD_REQ) { /* Read request from master */ - if (iic_info_ptr->iic_cbs.tx_cb) { - iic_info_ptr->iic_cbs.tx_cb(iic_obj); - } else { /* When tx callback function is not set disable this tx int for slave */ - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); - } - } - if (iic_int_status & IC_INTR_STAT_RX_FULL) { /* Write request from master */ - if (iic_info_ptr->iic_cbs.rx_cb) { - iic_info_ptr->iic_cbs.rx_cb(iic_obj); - } else { /* When rx callback function is not set disable this rx int for slave */ - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); - } - } - if (iic_int_status & IC_INTR_STAT_TX_OVER) { - iic_ctrl_ptr->iic_tx_over ++; - } - if (iic_int_status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) { - iic_ctrl_ptr->iic_rx_over ++; - } - if (iic_int_status & IC_INTR_STAT_TX_ABRT) { - iic_info_ptr->err_state = dw_iic_slv_chkerr(iic_ctrl_ptr); - if (iic_info_ptr->err_state != IIC_ERR_NONE) { - if (iic_info_ptr->iic_cbs.err_cb) { - iic_info_ptr->iic_cbs.err_cb(iic_obj); - } - } - } - /* Clear Interrupt */ - iic_int_status = iic_reg_ptr->IC_CLR_INTR; -} - -/** @} end of group DEVICE_DW_IIC_STATIC */ - -/** - * \defgroup DEVICE_DW_IIC_IMPLEMENT DesignWare IIC Driver Function API Implement - * \ingroup DEVICE_DW_IIC - * \brief implement device hal iic api with DesignWare IIC - * @{ - */ - -/** - * \brief open a designware iic device - * \param[in] iic_obj iic device object pointer - * \param[in] mode iic working mode (master or slave) - * \param[in] param When mode is \ref DEV_MASTER_MODE, param stands for \ref dev_iic_info::speed_mode "speed mode", - * when mode is \ref DEV_SLAVE_MODE, param stands for \ref dev_iic_info::slv_addr "slave device 7bit address" - * \retval E_OK Open successfully without any issues - * \retval E_OPNED If device was opened before with different parameters, - * then just increase the \ref dev_iic_info::opn_cnt "opn_cnt" and return \ref E_OPNED - * \retval E_OBJ Device object is not valid - * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first. - * \retval E_PAR Parameter is not valid - * \retval E_NOSPT Open settings are not supported - */ -int32_t dw_iic_open (DEV_IIC *iic_obj, uint32_t mode, uint32_t param) -{ - int32_t ercd = E_OK; - uint32_t support_modes; - uint32_t param2check; - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - - /* START ERROR CHECK */ - VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); - DW_IIC_CHECK_EXP((mode==DEV_MASTER_MODE)||(mode==DEV_SLAVE_MODE), E_PAR); - if (mode == DEV_MASTER_MODE) { - DW_IIC_CHECK_EXP((param>=IIC_SPEED_STANDARD) && (param<=IIC_SPEED_ULTRA), E_PAR); - } - /* END OF ERROR CHECK */ - - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - - /* Check supported modes, master or slave */ - support_modes = iic_ctrl_ptr->support_modes; - DW_IIC_CHECK_EXP( (((support_modes)&DW_IIC_MASTER_SUPPORTED)&&(mode == DEV_MASTER_MODE)) || \ - (((support_modes)&DW_IIC_SLAVE_SUPPORTED)&&(mode == DEV_SLAVE_MODE)), E_NOSPT); - - /** Check opened before use case */ - if (iic_info_ptr->opn_cnt > 0) { - if (mode != iic_info_ptr->mode) { - /* current working mode is different from passing mode */ - return E_SYS; - } - if (mode == DEV_MASTER_MODE) { /* param is speed_mode when as master */ - param2check = iic_info_ptr->speed_mode; - } else { /* param is slv_addr when as slave */ - param2check = iic_info_ptr->slv_addr; - } - iic_info_ptr->opn_cnt ++; - if (param != param2check) { /* open with different speed mode */ - return E_OPNED; - } else { - return E_OK; - } - } - /* auto increase open count */ - iic_info_ptr->opn_cnt ++; - - iic_info_ptr->mode = mode; - if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) { - iic_info_ptr->tar_addr &= IIC_7BIT_ADDRESS_MASK; - iic_info_ptr->slv_addr &= IIC_7BIT_ADDRESS_MASK; - } else { - iic_info_ptr->addr_mode = IIC_10BIT_ADDRESS; - iic_info_ptr->tar_addr &= IIC_10BIT_ADDRESS_MASK; - iic_info_ptr->slv_addr &= IIC_10BIT_ADDRESS_MASK; - } - -/* Do FIFO Length get before init */ -#if DW_IIC_CALC_FIFO_LEN_ENABLE - iic_ctrl_ptr->tx_fifo_len = dw_iic_get_txfifo_len(iic_ctrl_ptr->dw_iic_regs); - iic_ctrl_ptr->rx_fifo_len = dw_iic_get_rxfifo_len(iic_ctrl_ptr->dw_iic_regs); -#endif - - /* Disable device before init it */ - dw_iic_disable_device(iic_info_ptr); - - if (mode == DEV_MASTER_MODE) { - iic_info_ptr->speed_mode = param; - dw_iic_master_init(iic_ctrl_ptr, param, iic_info_ptr->addr_mode, iic_info_ptr->tar_addr); - } else { - iic_info_ptr->slv_addr = param; - dw_iic_slave_init(iic_ctrl_ptr, iic_info_ptr->addr_mode, param); - } - iic_info_ptr->status = DEV_ENABLED; - iic_info_ptr->cur_state = IIC_FREE; - iic_info_ptr->err_state = IIC_ERR_NONE; - iic_info_ptr->next_cond = IIC_MODE_STOP; - iic_info_ptr->extra = NULL; - - iic_ctrl_ptr->iic_tx_over = 0; - iic_ctrl_ptr->iic_rx_over = 0; - iic_ctrl_ptr->int_status = 0; - memset(&(iic_ctrl_ptr->dw_iic_rxbuf), 0, sizeof(DW_IIC_BUFFER)); - iic_ctrl_ptr->dw_iic_rxbuf.buf = &(iic_info_ptr->rx_buf); - /** install iic interrupt into system */ - dw_iic_disable_interrupt(iic_info_ptr); - int_handler_install(iic_ctrl_ptr->intno, iic_ctrl_ptr->dw_iic_int_handler); - memset(&(iic_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER)); - memset(&(iic_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER)); - memset(&(iic_info_ptr->iic_cbs), 0, sizeof(DEV_IIC_CBS)); - -error_exit: - return ercd; -} - -/** - * \brief Close a DesignWare IIC device - * \param[in] iic_obj iic device object pointer - * \retval E_OK Close successfully without any issues(including secenary that device is already closed) - * \retval E_OPNED Device is still opened, the device \ref dev_iic_info::opn_cnt "opn_cnt" decreased by 1 - * \retval E_OBJ Device object is not valid - */ -int32_t dw_iic_close (DEV_IIC *iic_obj) -{ - int32_t ercd = E_OK; - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - - /* START ERROR CHECK */ - VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); - DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_OK); - /* END OF ERROR CHECK */ - - iic_info_ptr->opn_cnt --; - if (iic_info_ptr->opn_cnt == 0) { - dw_iic_disable_interrupt(iic_info_ptr); - dw_iic_abort_tx(iic_obj); - dw_iic_abort_rx(iic_obj); - memset(&(iic_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER)); - memset(&(iic_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER)); - memset(&(iic_info_ptr->iic_cbs), 0, sizeof(DEV_IIC_CBS)); - dw_iic_disable_device(iic_info_ptr); - iic_info_ptr->status = DEV_DISABLED; - iic_info_ptr->next_cond = IIC_MODE_STOP; - iic_info_ptr->extra = NULL; - } else { - ercd = E_OPNED; - } - -error_exit: - return ercd; -} - -/** - * \brief Control iic by ctrl command - * \param[in] iic_obj iic device object pointer - * \param[in] ctrl_cmd \ref DEVICE_HAL_IIC_CTRLCMD "control command", to change or get some thing related to iic - * \param[in,out] param parameters that maybe argument of the command, - * or return values of the command, must not be NULL - * \retval E_OK Control device successfully - * \retval E_CLSED Device is not opened - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled - * \retval E_CTX Control device failed, due to different reasons like in transfer state - * \retval E_NOSPT Control command is not supported or not valid - */ -int32_t dw_iic_control (DEV_IIC *iic_obj, uint32_t ctrl_cmd, void *param) -{ - int32_t ercd = E_OK; - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - - /* START ERROR CHECK */ - VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); - DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED); - /* END OF ERROR CHECK */ - - uint32_t val32; /** to receive unsigned int value */ - DEV_BUFFER *devbuf; - - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl); - DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs); - - /* check whether current device is disabled */ - if ((iic_info_ptr->status & DEV_ENABLED) == 0) { - /** When device is disabled, - * only IIC_CMD_ENA_DEV, IIC_CMD_DIS_DEV, IIC_CMD_GET_STATUS, IIC_CMD_RESET - * are available, other commands will return E_SYS - */ - if ((ctrl_cmd != IIC_CMD_ENA_DEV) && \ - (ctrl_cmd != IIC_CMD_DIS_DEV) && \ - (ctrl_cmd != IIC_CMD_GET_STATUS) && \ - (ctrl_cmd != IIC_CMD_RESET) ) { - return E_SYS; - } - } - - switch (ctrl_cmd) { - /* Commmon commands for both master and slave mode */ - case IIC_CMD_GET_STATUS: - DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = iic_info_ptr->status; - break; - case IIC_CMD_ENA_DEV: - dw_iic_enable_device(iic_info_ptr); - break; - case IIC_CMD_DIS_DEV: - dw_iic_disable_device(iic_info_ptr); - break; - case IIC_CMD_RESET: - dw_iic_reset_device(iic_info_ptr); - break; - case IIC_CMD_FLUSH_TX: - dw_iic_flush_tx(iic_reg_ptr); - break; - case IIC_CMD_FLUSH_RX: - dw_iic_flush_rx(iic_reg_ptr); - break; - case IIC_CMD_SET_ADDR_MODE: - val32 = (uint32_t)param; - DW_IIC_CHECK_EXP((val32==IIC_7BIT_ADDRESS) || (val32==IIC_10BIT_ADDRESS), E_PAR); - if (iic_info_ptr->mode == DEV_MASTER_MODE) { - dw_iic_set_mstaddr_mode(iic_reg_ptr, val32); - } else { - dw_iic_set_slvaddr_mode(iic_reg_ptr, val32); - } - iic_info_ptr->addr_mode = val32; - break; - case IIC_CMD_GET_RXAVAIL: - DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = dw_iic_get_rxavail(iic_ctrl_ptr); - break; - case IIC_CMD_GET_TXAVAIL: - DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = dw_iic_get_txavail(iic_ctrl_ptr); - break; - case IIC_CMD_SET_TXCB: - DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - iic_info_ptr->iic_cbs.tx_cb = param; - break; - case IIC_CMD_SET_RXCB: - DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - iic_info_ptr->iic_cbs.rx_cb = param; - break; - case IIC_CMD_SET_ERRCB: - DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - iic_info_ptr->iic_cbs.err_cb = param; - break; - case IIC_CMD_ABORT_TX: - dw_iic_abort_tx(iic_obj); - if ((iic_info_ptr->mode == DEV_MASTER_MODE) \ - && (iic_info_ptr->cur_state == IIC_IN_TX)) { - iic_info_ptr->cur_state = IIC_FREE; - } - break; - case IIC_CMD_ABORT_RX: - dw_iic_abort_rx(iic_obj); - if ((iic_info_ptr->mode == DEV_MASTER_MODE) \ - && (iic_info_ptr->cur_state == IIC_IN_RX)) { - iic_info_ptr->cur_state = IIC_FREE; - } - break; - case IIC_CMD_SET_TXINT: - if (iic_info_ptr->mode == DEV_MASTER_MODE) { - DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_RX, E_CTX); - } - val32 = (uint32_t)param; - if (val32 == 0) { - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND); - iic_info_ptr->cur_state = IIC_FREE; - } else { - iic_info_ptr->cur_state = IIC_IN_TX; - dw_iic_ena_cbr(iic_info_ptr, DW_IIC_RDY_SND); - } - break; - case IIC_CMD_SET_RXINT: - if (iic_info_ptr->mode == DEV_MASTER_MODE) { - DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_TX, E_CTX); - } - val32 = (uint32_t)param; - if (val32 == 0) { - iic_info_ptr->cur_state = IIC_FREE; - dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV); - } else { - iic_info_ptr->cur_state = IIC_IN_RX; - dw_iic_ena_cbr(iic_info_ptr, DW_IIC_RDY_RCV); - } - break; - case IIC_CMD_SET_TXINT_BUF: - if (iic_info_ptr->mode == DEV_MASTER_MODE) { - DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_TX, E_CTX); - } - DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - if (param != NULL) { - devbuf = (DEV_BUFFER *)param; - iic_info_ptr->tx_buf = *devbuf; - iic_info_ptr->tx_buf.ofs = 0; - } else { - iic_info_ptr->tx_buf.buf = NULL; - iic_info_ptr->tx_buf.len = 0; - iic_info_ptr->tx_buf.ofs = 0; - } - break; - case IIC_CMD_SET_RXINT_BUF: - if (iic_info_ptr->mode == DEV_MASTER_MODE) { - DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_RX, E_CTX); - } - DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - if (param != NULL) { - devbuf = (DEV_BUFFER *)param; - iic_info_ptr->rx_buf = *devbuf; - iic_info_ptr->rx_buf.ofs = 0; - iic_ctrl_ptr->dw_iic_rxbuf.ofs = 0; - iic_ctrl_ptr->dw_iic_rxbuf.len = devbuf->len; - } else { - iic_info_ptr->rx_buf.buf = NULL; - iic_info_ptr->rx_buf.len = 0; - iic_info_ptr->rx_buf.ofs = 0; - iic_ctrl_ptr->dw_iic_rxbuf.ofs = 0; - iic_ctrl_ptr->dw_iic_rxbuf.len = 0; - } - break; - - /* Master mode only commands */ - case IIC_CMD_MST_SET_SPEED_MODE: - DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); - val32 = (uint32_t)param; - DW_IIC_CHECK_EXP((val32>=IIC_SPEED_STANDARD) && (val32<=IIC_SPEED_ULTRA), E_PAR); - dw_iic_set_speedmode(iic_reg_ptr, val32); - iic_info_ptr->speed_mode = val32; - break; - case IIC_CMD_MST_SET_TAR_ADDR: - DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); - if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) { - val32 = ((uint32_t)param) & IIC_7BIT_ADDRESS_MASK; - } else { - val32 = ((uint32_t)param) & IIC_10BIT_ADDRESS_MASK; - } - if (val32 != iic_info_ptr->tar_addr) { - dw_iic_set_taraddr(iic_reg_ptr, val32); - iic_info_ptr->tar_addr = val32; - } - break; - case IIC_CMD_MST_SET_NEXT_COND: - DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); - val32 = (uint32_t)param; - DW_IIC_CHECK_EXP((val32==IIC_MODE_STOP) || (val32==IIC_MODE_RESTART), E_PAR); - iic_info_ptr->next_cond = (uint32_t)param; - break; - - /* Slave mode only commands */ - case IIC_CMD_SLV_SET_SLV_ADDR: - DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_SLAVE_MODE, E_NOSPT); - if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) { - val32 = ((uint32_t)param) & IIC_7BIT_ADDRESS_MASK; - } else { - val32 = ((uint32_t)param) & IIC_10BIT_ADDRESS_MASK; - } - dw_iic_set_slvaddr(iic_reg_ptr, val32); - iic_info_ptr->slv_addr = val32; - break; - case IIC_CMD_SLV_GET_SLV_STATE: - DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_SLAVE_MODE, E_NOSPT); - DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((uint32_t *)param) = dw_iic_get_slv_state(iic_reg_ptr); - break; - - default: - ercd = E_NOSPT; - break; - } - -error_exit: - return ercd; -} - -/** - * \brief poll transmit data through DesignWare IIC as master or slave - * \param[in] iic_obj iic device object pointer - * \param[in] data data that need to send (data must be uint8_t type) - * \param[in] len data length need to send - * \retval >0 Byte count that was successfully sent for poll method, - * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state". - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid - * \retval E_CTX Device is still in transfer state - * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled - */ -int32_t dw_iic_write (DEV_IIC *iic_obj, const void *data, uint32_t len) -{ - int32_t ercd = E_OK; - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - - /* START ERROR CHECK */ - VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); - DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED); - DW_IIC_CHECK_EXP(iic_info_ptr->status & DEV_ENABLED, E_SYS); - DW_IIC_CHECK_EXP(data!=NULL, E_PAR); - DW_IIC_CHECK_EXP(len>0, E_PAR); - /* END OF ERROR CHECK */ - - int32_t i = 0; - uint32_t last_cond = 0; /* Last data for transmit, STOP or RESTART */ - int32_t error_state = IIC_ERR_NONE; - const uint8_t *p_charbuf = (const uint8_t *)data; - - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); - - if (iic_info_ptr->mode == DEV_MASTER_MODE) { /* Master mode transmit data */ - if (iic_info_ptr->next_cond == IIC_MODE_STOP) { - last_cond = IC_DATA_CMD_STOP; - } else { - last_cond = IC_DATA_CMD_RESTART; - } - - /* Try to transmit 0 -> (len-1) data */ - len = len - 1; /* Last data write differently */ - while (i < len) { - error_state = dw_iic_mst_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[i]), IC_DATA_CMD_NONE); - if (error_state != IIC_ERR_NONE) { - break; - } - i ++; - } - /* Try to transmit the last data with STOP or RESTART condition */ - if (error_state == IIC_ERR_NONE) { - error_state = dw_iic_mst_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[len]), last_cond); - if (error_state == IIC_ERR_NONE) { - i = i + 1; /* Add last data into send count */ - } - } - } else { /* Slave mode transmit data */ - while (i < len) { - error_state = dw_iic_slv_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[i])); - if (error_state != IIC_ERR_NONE) { - break; - } - i ++; - } - } - iic_info_ptr->err_state = error_state; - ercd = i; - -error_exit: - return ercd; -} - -/** - * \brief read data through DesignWare IIC - * \param[in] iic_obj iic device object pointer - * \param[out] data data that need to read (data must be uint8_t type) - * \param[in] len data count need to read - * \retval >0 Byte count that was successfully received for poll method, - * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state". - * \retval E_OBJ Device object is not valid or not exists - * \retval E_CTX Device is still in transfer state - * \retval E_PAR Parameter is not valid - * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled - */ -int32_t dw_iic_read (DEV_IIC *iic_obj, void *data, uint32_t len) -{ - int32_t ercd = E_OK; - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - - /* START ERROR CHECK */ - VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); - DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED); - DW_IIC_CHECK_EXP(iic_info_ptr->status & DEV_ENABLED, E_SYS); - DW_IIC_CHECK_EXP(data!=NULL, E_PAR); - DW_IIC_CHECK_EXP(len>0, E_PAR); - /* END OF ERROR CHECK */ - - int32_t i = 0; - uint32_t last_cond = 0; /* Last data for receive, STOP or RESTART */ - uint32_t val32 = 0; - int32_t error_state = IIC_ERR_NONE; - uint8_t *p_charbuf = (uint8_t *)data; - - DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl); - - if (iic_info_ptr->mode == DEV_MASTER_MODE) { /* Master mode receive data */ - if (iic_info_ptr->next_cond == IIC_MODE_STOP) { - last_cond = IC_DATA_CMD_STOP; - } else { - last_cond = IC_DATA_CMD_RESTART; - } - - /* Try to receive 0 -> (len-1) data */ - len = len - 1; /* Last data write differently */ - while (i < len) { - error_state = dw_iic_mst_read_data(iic_ctrl_ptr, &val32, IC_DATA_CMD_NONE); - if (error_state != IIC_ERR_NONE) { - break; - } else { - p_charbuf[i] = (uint8_t)val32; - } - i ++; - } - /* Try to receive the last data with STOP or RESTART condition */ - if (error_state == IIC_ERR_NONE) { - error_state = dw_iic_mst_read_data(iic_ctrl_ptr, &val32, last_cond); - if (error_state == IIC_ERR_NONE) { - p_charbuf[len] = (uint8_t)val32; - i = i + 1; /* Add last data into send count */ - } - } - } else { /* Slave mode receive data */ - while (i < len) { - error_state = dw_iic_slv_read_data(iic_ctrl_ptr, &val32); - if (error_state != IIC_ERR_NONE) { - break; - } else { - p_charbuf[i] = (uint8_t)val32; - } - i ++; - } - } - iic_info_ptr->err_state = error_state; - ercd = i; - -error_exit: - return ercd; -} - -/** - * \brief DesignWare IIC interrupt processing routine - * \param[in] iic_info_ptr DEV_IIC *iic_obj - * \param[in] ptr extra information - */ -void dw_iic_isr(DEV_IIC *iic_obj, void *ptr) -{ - int32_t ercd = E_OK; - DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info); - - /* START ERROR CHECK */ - VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr); - /* END OF ERROR CHECK */ - - if (iic_info_ptr->mode == DEV_MASTER_MODE) { - if (iic_info_ptr->cur_state == IIC_IN_TX) { - dw_iic_mst_int_write(iic_obj); - } else { - dw_iic_mst_int_read(iic_obj); - } - } else { - dw_iic_slv_int_process(iic_obj); - } - -error_exit: - return; -} -/** @} end of group DEVICE_DW_IIC_IMPLEMENT */ diff --git a/bsp/synopsys/embarc/device/designware/iic/dw_iic.h b/bsp/synopsys/embarc/device/designware/iic/dw_iic.h deleted file mode 100644 index 55c551a67e..0000000000 --- a/bsp/synopsys/embarc/device/designware/iic/dw_iic.h +++ /dev/null @@ -1,242 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-06-30 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \brief designware iic driver header file - * \ingroup DEVICE_DW_IIC - */ - -#ifndef _DW_IIC_H_ -#define _DW_IIC_H_ - -#include "device/device_hal/inc/dev_iic.h" - -#include "inc/arc/arc_exception.h" - - -/** - * If this header file is included, - * will indicate that this designware iic device - * is used - */ -#define DEVICE_USE_DESIGNWARE_IIC - -/** - * \defgroup DEVICE_DW_IIC_INFO DesignWare IIC Related Information - * \ingroup DEVICE_DW_IIC - * \brief Defines some macros of DesignWare IIC need. - * \details macros like, iic number - * @{ - */ -#define DW_IIC_MASTER_SUPPORTED (0x1) /*!< Support Designware IIC Master Mode */ -#define DW_IIC_SLAVE_SUPPORTED (0x2) /*!< Support Designware IIC Slave Mode */ -/*!< Support Designware IIC Both Master and Slave Mode */ -#define DW_IIC_BOTH_SUPPORTED (DW_IIC_MASTER_SUPPORTED|DW_IIC_SLAVE_SUPPORTED) -/** @} */ - -/** - * \defgroup DEVICE_DW_IIC_REGSTRUCT DesignWare IIC Register Structure - * \ingroup DEVICE_DW_IIC - * \brief contains definitions of DesignWare IIC register structure. - * \details detailed description of DesignWare IIC register information - * @{ - */ -/** - * \brief DesignWare IIC register structure - * \details Detailed struct description of DesignWare IIC - * block register information, implementation of dev_iic_info::iic_regs - */ -typedef volatile struct dw_iic_reg { - uint32_t IC_CON; /*!< (0x00) : IIC control */ - uint32_t IC_TAR; /*!< (0x04) : IIC target address */ - uint32_t IC_SAR; /*!< (0x08) : IIC slave address */ - uint32_t IC_HS_MADDR; /*!< (0x0c) : IIC HS Master Mode Code address */ - uint32_t IC_DATA_CMD; /*!< (0x10) : IIC Rx/Tx Data Buffer and Command */ - uint32_t IC_SS_SCL_HCNT; /*!< (0x14) : Standard Speed IIC clock SCL High Count */ - uint32_t IC_SS_SCL_LCNT; /*!< (0x18) : Standard Speed IIC clock SCL Low Count */ - uint32_t IC_FS_SCL_HCNT; /*!< (0x1c) : Fast Speed IIC clock SCL Low Count */ - uint32_t IC_FS_SCL_LCNT; /*!< (0x20) : Fast Speed IIC clock SCL Low Count */ - uint32_t IC_HS_SCL_HCNT; /*!< (0x24) : High Speed IIC clock SCL Low Count */ - uint32_t IC_HS_SCL_LCNT; /*!< (0x28) : High Speed IIC clock SCL Low Count */ - uint32_t IC_INTR_STAT; /*!< (0x2c) : IIC Interrupt Status */ - uint32_t IC_INTR_MASK; /*!< (0x30) : IIC Interrupt Mask */ - uint32_t IC_RAW_INTR_STAT; /*!< (0x34) : IIC Raw Interrupt Status */ - uint32_t IC_RX_TL; /*!< (0x38) : IIC Receive FIFO Threshold */ - uint32_t IC_TX_TL; /*!< (0x3c) : IIC Transmit FIFO Threshold */ - uint32_t IC_CLR_INTR; /*!< (0x40) : Clear combined and Individual Interrupts */ - uint32_t IC_CLR_RX_UNDER; /*!< (0x44) : Clear RX_UNDER Interrupt */ - uint32_t IC_CLR_RX_OVER; /*!< (0x48) : Clear RX_OVER Interrupt */ - uint32_t IC_CLR_TX_OVER; /*!< (0x4c) : Clear TX_OVER Interrupt */ - uint32_t IC_CLR_RD_REQ; /*!< (0x50) : Clear RQ_REQ Interrupt */ - uint32_t IC_CLR_TX_ABRT; /*!< (0x54) : Clear TX_ABRT Interrupt */ - uint32_t IC_CLR_RX_DONE; /*!< (0x58) : Clear RX_DONE Interrupt */ - uint32_t IC_CLR_ACTIVITY; /*!< (0x5c) : Clear ACTIVITY Interrupt */ - uint32_t IC_CLR_STOP_DET; /*!< (0x60) : Clear STOP_DET Interrupt */ - uint32_t IC_CLR_START_DET; /*!< (0x64) : Clear START_DET Interrupt */ - uint32_t IC_CLR_GEN_CALL; /*!< (0x68) : Clear GEN_CALL Interrupt */ - uint32_t IC_ENABLE; /*!< (0x6c) : IIC Enable */ - uint32_t IC_STATUS; /*!< (0x70) : IIC Status */ - uint32_t IC_TXFLR; /*!< (0x74) : Transmit FIFO Level Register */ - uint32_t IC_RXFLR; /*!< (0x78) : Receive FIFO Level Register */ - uint32_t IC_SDA_HOLD; /*!< (0x7c) : SDA Hold Time Length Reg */ - uint32_t IC_TX_ABRT_SOURCE; /*!< (0x80) : IIC Transmit Abort Status Reg */ - uint32_t IC_SLV_DATA_NACK_ONLY; /*!< (0x84) : Generate SLV_DATA_NACK Register */ - uint32_t IC_DMA_CR; /*!< (0x88) : DMA Control Register */ - uint32_t IC_DMA_TDLR; /*!< (0x8c) : DMA Transmit Data Level */ - uint32_t IC_DMA_RDLR; /*!< (0x90) : DMA Receive Data Level */ - uint32_t IC_SDA_SETUP; /*!< (0x94) : SDA Setup Register */ - uint32_t IC_ACK_GENERAL_CALL; /*!< (0x98) : ACK General Call Register */ - uint32_t IC_ENABLE_STATUS; /*!< (0x9c) : Enable Status Register */ - uint32_t IC_FS_SPKLEN; /*!< (0xa0) : ISS and FS spike suppression limit */ - uint32_t IC_HS_SPKLEN; /*!< (0xa4) : HS spike suppression limit */ - uint32_t RESERVED[19]; /*!< (0xa8) : Reserved */ - uint32_t IC_COMP_PARAM_1; /*!< (0xf4) : Component Parameter Register */ - uint32_t IC_COMP_VERSION; /*!< (0xf8) : Component Version ID Reg */ - uint32_t IC_COMP_TYPE; /*!< (0xfc) : Component Type Reg */ -} DW_IIC_REG, *DW_IIC_REG_PTR; -/** @} */ - -/** Spike Suppression Limit Configurations */ -typedef struct dw_iic_spklen { - uint32_t fs_spklen; /*!< value for IC_FS_SPKLEN, Tsp for fast mode is 50ns */ - uint32_t hs_spklen; /*!< value for IC_HS_SPKLEN, Tsp for high-speed mode is 10ns */ -} DW_IIC_SPKLEN, *DW_IIC_SPKLEN_PTR; - -/** IIC Clock SCL High and Low Count Configurations for Different Speed */ -typedef struct dw_iic_scl_cnt { - uint32_t ss_scl_hcnt; /*!< value for IC_SS_SCL_HCNT */ - uint32_t ss_scl_lcnt; /*!< value for IC_SS_SCL_LCNT */ - uint32_t fs_scl_hcnt; /*!< value for IC_FS_SCL_HCNT */ - uint32_t fs_scl_lcnt; /*!< value for IC_FS_SCL_LCNT */ - uint32_t hs_scl_hcnt; /*!< value for IC_HS_SCL_HCNT */ - uint32_t hs_scl_lcnt; /*!< value for IC_HS_SCL_LCNT */ -} DW_IIC_SCL_CNT, *DW_IIC_SCL_CNT_PTR; - -#define DW_IIC_GINT_DISABLED (0) /*!< designware interrupt disabled for control iic irq/fiq */ -#define DW_IIC_GINT_ENABLE (1<<0) /*!< designware interrupt enabled for control iic irq/fiq */ -#define DW_IIC_TXINT_ENABLE (1<<1) /*!< designware interrupt enabled for control transmit process */ -#define DW_IIC_RXINT_ENABLE (1<<2) /*!< designware interrupt enabled for control transmit process */ - -typedef struct dw_iic_buffer { - DEV_BUFFER *buf; - uint32_t ofs; - uint32_t len; -} DW_IIC_BUFFER, *DW_IIC_BUFFER_PTR; - -/** - * \brief DesignWare IIC control structure definition - * \details implement of dev_iic_info::iic_ctrl - */ -typedef struct dw_iic_ctrl { - DW_IIC_REG *dw_iic_regs; /*!< iic device registers */ - /* Variables which should be set during object implementation */ - uint32_t support_modes; /*!< supported iic modes */ - uint32_t tx_fifo_len; /*!< transmit fifo length */ - uint32_t rx_fifo_len; /*!< receive fifo length */ - uint32_t iic_master_code; /*!< value for IC_HS_MADDR */ - uint32_t retry_cnt; /*!< retry count for TX or RX */ - uint32_t intno; /*!< iic interrupt vector number */ - INT_HANDLER dw_iic_int_handler; /*!< iic interrupt handler */ - DW_IIC_SPKLEN iic_spklen; /*!< iic spike suppression length settings */ - DW_IIC_SCL_CNT iic_scl_cnt; /*!< iic scl count settings */ - /* Variables which always change during iic operation */ - uint32_t int_status; /*!< iic interrupt status */ - uint32_t iic_tx_over; /*!< iic tx overflow count */ - uint32_t iic_rx_over; /*!< iic rx overflow count */ - DW_IIC_BUFFER dw_iic_rxbuf; /*!< iic read buffer for receive data */ -} DW_IIC_CTRL, *DW_IIC_CTRL_PTR; - -/*!< One possible value for \ref dw_iic_ctrl::retry_cnt */ -#define DW_IIC_MAX_RETRY_COUNT (100000) - -#if DW_IIC_USE_IC_CLK_MHZ == 100 /*!< 100MHz */ -/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ -static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1}; - -/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ -#if DW_IIC_USE_HS_BUS_LOADING_100PF -static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0x6, 0x10}; -#else -static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0xc, 0x20}; -#endif - -#elif DW_IIC_USE_IC_CLK_MHZ == 50 /* 50MHz */ -/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ -static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1}; - -/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ -#if DW_IIC_USE_HS_BUS_LOADING_100PF -static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x00c8, 0x00eb, 0x001e, 0x0041, 0x6, 0x8}; -#else -static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x00c8, 0x00eb, 0x001e, 0x0041, 0x6, 0x10}; -#endif - -#else /* Default 100MHz */ -/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ -static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1}; - -/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */ -#if DW_IIC_USE_HS_BUS_LOADING_100PF -static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0x6, 0x10}; -#else -static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0xc, 0x20}; -#endif - -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup DEVICE_DW_IIC_FUNCDLR DesignWare IIC Function Declaration - * \ingroup DEVICE_DW_IIC - * \brief Contains declarations of designware iic functions. - * \details This are only used in iic object implementation source file - * @{ - */ -extern int32_t dw_iic_open (DEV_IIC *iic_obj, uint32_t mode, uint32_t param); -extern int32_t dw_iic_close (DEV_IIC *iic_obj); -extern int32_t dw_iic_control (DEV_IIC *iic_obj, uint32_t ctrl_cmd, void *param); -extern int32_t dw_iic_write (DEV_IIC *iic_obj, const void *data, uint32_t len); -extern int32_t dw_iic_read (DEV_IIC *iic_obj, void *data, uint32_t len); -extern void dw_iic_isr(DEV_IIC *iic_obj, void *ptr); - -#ifdef __cplusplus -} -#endif - -/** @} */ - -#endif /* _DW_IIC_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h b/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h deleted file mode 100644 index f7ec0d27a2..0000000000 --- a/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal.h +++ /dev/null @@ -1,186 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-06-30 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup DEVICE_DW_IIC - * \brief DesignWare IIC driver hardware description related header file - * \details detailed hardware related definitions of DesignWare IIC driver - */ - -#ifndef _DEVICE_DW_IIC_HAL_H_ -#define _DEVICE_DW_IIC_HAL_H_ - -#include "device/designware/iic/dw_iic_hal_cfg.h" - -/** Enable Designware IIC */ -#define DW_IIC_ENABLE (1) -/** Disable Designware IIC */ -#define DW_IIC_DISABLE (0) - -/** Stop Condition issue after this byte */ -#define IC_DATA_CMD_STOP (1 << 9) -/** Restart Condition issue after this byte */ -#define IC_DATA_CMD_RESTART (1 << 10) -/** No Restart or stop condition after this byte */ -#define IC_DATA_CMD_NONE (0) - -/** Perform a write request */ -#define IC_DATA_CMD_WRITE_REQ (0) -/** Perform a read request */ -#define IC_DATA_CMD_READ_REQ (1 << 8) - -/** Fields of IC_CON register */ -/* DW_APB I2C IP Config Dependencies. */ -#if DW_IIC_ALLOW_RESTART -#define IC_CON_RESTART_EN (1 << 5) -#else -#define IC_CON_RESTART_EN (0x00) -#endif - -/* Master Addressing Mode Config */ -#if DW_IIC_MST_10_BIT_ADDR_SUPPORT -#define MST_10_BIT_ADDR_MODE (1 << 4) -#define IC_10BITADDR_MASTER (1 << 12) -#else -#define MST_10_BIT_ADDR_MODE (0x00) -#define IC_10BITADDR_MASTER (0x00) -#endif - -/* Slave Addressing Mode Config */ -#if DW_IIC_SLV_10_BIT_ADDR_SUPPORT -#define SLV_10_BIT_ADDR_MODE (1 << 3) -#else -#define SLV_10_BIT_ADDR_MODE (0x00) -#endif - -#if DW_IIC_SPECIAL_START_BYTE -#define IC_TAR_SPECIAL (1 << 11) -#define IC_TAR_GC_OR_START (1 << 10) -#else -#define IC_TAR_SPECIAL (0x00) -#define IC_TAR_GC_OR_START (0x00) -#endif - -/** 7bit IIC address mask for target address register */ -#define IC_TAR_7BIT_ADDR_MASK (0x7F) -/** 7bit IIC address mask for slave address register */ -#define IC_SAR_7BIT_ADDR_MASK (0x7F) -/** 10bit IIC address mask for target address register */ -#define IC_TAR_10BIT_ADDR_MASK (0x3FF) -/** 10bit IIC address mask for slave address register */ -#define IC_SAR_10BIT_ADDR_MASK (0x3FF) - -/** Speed modes of IC_CON */ -#define IC_CON_SPEED_MASK (0x6) -#define IC_CON_SPEED_STANDARD (0x2) -#define IC_CON_SPEED_FAST (0x4) -#define IC_CON_SPEED_HIGH (0x6) -/** Working mode of IC_CON */ -#define IC_CON_MST_SLV_MODE_MASK (0x41) -#define IC_CON_ENA_MASTER_MODE (0x41) -#define IC_CON_ENA_SLAVE_MODE (0) - -/* IIC interrupt control */ -#define IC_INT_DISABLE_ALL (0x0) -#define IC_INT_ENABLE_ALL (0x7FF) -/* Interrupt Register Fields */ -#define IC_INTR_STAT_GEN_CALL (1 << 11) -#define IC_INTR_STAT_START_DET (1 << 10) -#define IC_INTR_STAT_STOP_DET (1 << 9) -#define IC_INTR_STAT_ACTIVITY (1 << 8) -#define IC_INTR_STAT_RX_DONE (1 << 7) -#define IC_INTR_STAT_TX_ABRT (1 << 6) -#define IC_INTR_STAT_RD_REQ (1 << 5) -#define IC_INTR_STAT_TX_EMPTY (1 << 4) -#define IC_INTR_STAT_TX_OVER (1 << 3) -#define IC_INTR_STAT_RX_FULL (1 << 2) -#define IC_INTR_STAT_RX_OVER (1 << 1) -#define IC_INTR_STAT_RX_UNDER (1 << 0) - -/* Interrupt enable mask as master */ -#define IC_INT_MST_TX_ENABLE (IC_INTR_STAT_TX_EMPTY|IC_INTR_STAT_TX_OVER|IC_INTR_STAT_TX_ABRT) -#define IC_INT_MST_RX_ENABLE (IC_INTR_STAT_TX_EMPTY|IC_INTR_STAT_RX_FULL|IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER|IC_INTR_STAT_TX_ABRT) - -/* Interrupt enable mask as master */ -#define IC_INT_SLV_COMMON_ENABLE (IC_INTR_STAT_START_DET|IC_INTR_STAT_STOP_DET) -#define IC_INT_SLV_TX_ENABLE (IC_INTR_STAT_RD_REQ|IC_INTR_STAT_TX_ABRT) -#define IC_INT_SLV_RX_ENABLE (IC_INTR_STAT_RX_FULL|IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER) - -/* IC_ENABLE_STATUS Bits */ -#define IC_ENABLE_STATUS_IC_EN (1 << 0) -#define IC_ENABLE_STATUS_SLV_DIS (1 << 1) -#define IC_ENABLE_STATUS_SLV_RX_LOST (1 << 2) - -/* IIC TX & RX threshold settings */ -#define IIC_TX_THRESHOLD (0) -#define IIC_RX_THRESHOLD (0) - -/* DW_APB IIC (DW_IC_STATUS) Status Register Fields. */ -#define IC_STATUS_ACTIVITY (0x01) -#define IC_STATUS_TFNF (0x02) /* (1 << 1) */ -#define IC_STATUS_TFE (0x04) /* (1 << 2) */ -#define IC_STATUS_RFNE (0x08) /* (1 << 3) */ -#define IC_STATUS_RFF (0x10) /* (1 << 4) */ -#define IC_STATUS_MASTER_ACT (0x20) /* (1 << 5) */ -#define IC_STATUS_SLAVE_ACT (0x40) /* (1 << 6) */ - -/* IC_TX_ABRT_SOURCE Register Bit Fields */ -#define IC_TX_ABRT_7B_ADDR_NOACK (1 << 0) -#define IC_TX_ABRT_10ADDR1_NOACK (1 << 1) -#define IC_TX_ABRT_10ADDR2_NOACK (1 << 2) -#define IC_TX_ABRT_TXDATA_NOACK (1 << 3) -#define IC_TX_ABRT_GCALL_NOACK (1 << 4) -#define IC_TX_ABRT_GCALL_READ (1 << 5) -#define IC_TX_ABRT_HS_ACKDET (1 << 6) -#define IC_TX_ABRT_SBYTE_ACKDET (1 << 7) -#define IC_TX_ABRT_HS_NORSTRT (1 << 8) -#define IC_TX_ABRT_SBYTE_NORSTRT (1 << 9) -#define IC_TX_ABRT_10B_RD_NORSTRT (1 << 10) -#define IC_TX_ABRT_MASTER_DIS (1 << 11) -#define IC_TX_ABRT_ARB_LOST (1 << 12) -#define IC_TX_ABRT_SLVFLUSH_TXFIFO (1 << 13) -#define IC_TX_ABRT_SLV_ARBLOST (1 << 14) -#define IC_TX_ABRT_SLVRD_INTX (1 << 15) - -/* Combined bits for iic abort source as master */ -#define IIC_MST_ABRT_ADDR_NOACK (IC_TX_ABRT_7B_ADDR_NOACK|IC_TX_ABRT_10ADDR1_NOACK|IC_TX_ABRT_10ADDR1_NOACK) -#define IIC_MST_ABRT_LOST_BUS (IC_TX_ABRT_ARB_LOST) -#define IIC_MST_ABRT_DATA_NOACK (IC_TX_ABRT_TXDATA_NOACK) - -/* Combined bits for iic abort source as slave */ -#define IIC_SLV_ABRT_LOST_BUS (IC_TX_ABRT_ARB_LOST|IC_TX_ABRT_SLV_ARBLOST) - -/** @} */ - -#endif /* _DEVICE_DW_IIC_HAL_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h b/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h deleted file mode 100644 index 1073162176..0000000000 --- a/bsp/synopsys/embarc/device/designware/iic/dw_iic_hal_cfg.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-07-01 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup DEVICE_DW_IIC - * \brief DesignWare IIC driver hardware description - * related header file configuration file - * \details configuration file to enable or disable some function of iic - */ - -#ifndef _DEVICE_DW_IIC_HAL_CFG_H_ -#define _DEVICE_DW_IIC_HAL_CFG_H_ - -#ifndef DW_IIC_ALLOW_RESTART -#define DW_IIC_ALLOW_RESTART (1) /*!< allow restart configuration */ -#endif - -#ifdef DW_IIC_SPECIAL_START_BYTE -#define DW_IIC_SPECIAL_START_BYTE (0) /*!< SPECIAL bit enable in IC_TAR */ -#endif - -#ifndef DW_IIC_MST_10_BIT_ADDR_SUPPORT -#define DW_IIC_MST_10_BIT_ADDR_SUPPORT (1) /*!< enable 10-bit address mode */ -#endif - -#ifdef DW_IIC_SLV_10_BIT_ADDR_SUPPORT -#define DW_IIC_SLV_10_BIT_ADDR_SUPPORT (1) /*!< slave 10-bit addressing mode */ -#endif - -#ifndef DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT -#define DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT (0) /*!< Dynamic target address update support */ -#endif - -#ifndef DW_IIC_DISABLE_MAX_T_POLL_CNT -#define DW_IIC_DISABLE_MAX_T_POLL_CNT (1250) /*!< Timeout count, approximate to be 25us in 50MHz CPU @ Standard mode */ -#endif - -#ifndef DW_IIC_CALC_FIFO_LEN_ENABLE -#define DW_IIC_CALC_FIFO_LEN_ENABLE (1) /*!< Default enable calculate fifo length */ -#endif - -#ifndef DW_IIC_USE_IC_CLK_MHZ -#define DW_IIC_USE_IC_CLK_MHZ (50) /*!< Default use 50MHz IC_CLK */ -#endif - -#ifndef DW_IIC_USE_HS_BUS_LOADING_100PF -#define DW_IIC_USE_HS_BUS_LOADING_100PF (1) /*!< Use bus loading 100pf */ -#endif - -#endif /* _DEVICE_DW_IIC_HAL_CFG_H_ */ - diff --git a/bsp/synopsys/embarc/device/designware/spi/dw_spi.c b/bsp/synopsys/embarc/device/designware/spi/dw_spi.c deleted file mode 100644 index bea413b411..0000000000 --- a/bsp/synopsys/embarc/device/designware/spi/dw_spi.c +++ /dev/null @@ -1,1337 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-06-25 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \defgroup DEVICE_DW_SPI Designware SPI Driver - * \ingroup DEVICE_DW - * \brief Designware SPI Driver Implementation - */ - -/** - * \file - * \brief DesignWare SPI driver implementation based on device hal layer definition (\ref dev_spi.h) - * \ingroup DEVICE_DW_SPI - */ -#include - -#include "inc/embARC_toolchain.h" -#include "inc/embARC_error.h" - -#include "inc/arc/arc_exception.h" - -#include "device/designware/spi/dw_spi_hal.h" -#include "device/designware/spi/dw_spi.h" - -/** - * \defgroup DEVICE_DW_SPI_DEFINES DesignWare SPI Driver Macros - * \ingroup DEVICE_DW_SPI - * \brief DesignWare SPI driver macros used in spi driver - * @{ - */ -/** check expressions used in DesignWare SPI driver implementation */ -#define DW_SPI_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit) - -/** convert DesignWare frequence to divisor */ -#define DW_SPI_FREQ2DV(perifreq, spifreq) ((perifreq) / (spifreq)) - -#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK -/** valid check of spi info object */ -#define VALID_CHK_SPI_INFO_OBJECT(spiinfo_obj_ptr) { \ - DW_SPI_CHECK_EXP((spiinfo_obj_ptr)!=NULL, E_OBJ); \ - DW_SPI_CHECK_EXP(((spiinfo_obj_ptr)->spi_ctrl)!=NULL, E_OBJ); \ - } -#endif - -/** - * \defgroup DEVICE_DW_SPI_DEF_CBR DesignWare SPI Interrupt Callback Routine Select Marcos - * \ingroup DEVICE_DW_SPI_DEFINES - * \brief DesignWare SPI interrupt callback routines select macros definitions - * @{ - */ -#define DW_SPI_RDY_SND (1U) /*!< ready to send callback */ -#define DW_SPI_RDY_RCV (2U) /*!< ready to receive callback */ -#define DW_SPI_RDY_XFER (3U) /*!< ready to transfer callback */ -/** @} */ - -/** @} */ - -/** - * \defgroup DEVICE_DW_SPI_STATIC DesignWare SPI Driver Static Functions - * \ingroup DEVICE_DW_SPI - * \brief Static or inline functions, variables for DesignWare SPI handle spi operations, - * only used in this file. - * @{ - */ - -/** Disable designware spi device */ -Inline void dw_spi_disable(DW_SPI_REG *spi_reg_ptr) -{ -/** disable spi operations, then program spi control regs is possible */ - spi_reg_ptr->SSIENR = DW_SPI_SSI_DISABLE; -} -/** Enable designware spi device */ -Inline void dw_spi_enable(DW_SPI_REG *spi_reg_ptr) -{ - spi_reg_ptr->SSIENR = DW_SPI_SSI_ENABLE; -} - -/** Clear all designware spi interrupt */ -Inline void dw_spi_clear_interrupt_all(DW_SPI_REG *spi_reg_ptr) -{ - (void)spi_reg_ptr->ICR; -} - -/** test whether spi is busy, busy return 1, else 0 */ -Inline int32_t dw_spi_busy(DW_SPI_REG *spi_reg_ptr) -{ - return ((spi_reg_ptr->SR & DW_SPI_SR_BUSY) != 0); -} -/** test whether spi is ready to send, 1 ready, 0 not ready */ -Inline int32_t dw_spi_putready(DW_SPI_REG *spi_reg_ptr) -{ - return ((spi_reg_ptr->SR & DW_SPI_SR_TFNF) != 0); -} -/** test whether spi is read to receive, 1 ready, 0 not ready */ -Inline int32_t dw_spi_getready(DW_SPI_REG *spi_reg_ptr) -{ - return ((spi_reg_ptr->SR & DW_SPI_SR_RFNE) != 0); -} -/** write data to spi send fifo */ -Inline void dw_spi_putdata(DW_SPI_REG *spi_reg_ptr, int32_t data) -{ - spi_reg_ptr->DATAREG = (uint32_t)data; -} -/** read data from spi receive fifo, return data received */ -Inline int32_t dw_spi_getdata(DW_SPI_REG *spi_reg_ptr) -{ - return (int32_t)spi_reg_ptr->DATAREG; -} -/** - * \brief send data by spi when available, - * mostly used in interrupt method, non-blocked function - * \param[in] spi_reg_ptr spi register structure pointer - * \param[in] data data to be sent - * \retval E_OK send successfully - * \retval E_OBJ not ready to send data - */ -Inline int32_t dw_spi_snd_dat(DW_SPI_REG *spi_reg_ptr, int32_t data) -{ - if (dw_spi_putready(spi_reg_ptr)) { - dw_spi_putdata(spi_reg_ptr, data); - return E_OK; - } - return E_OBJ; -} -/** - * \brief receive one char from spi, - * mostly used in interrupt routine, non-blocked function - * \param[in] spi_reg_ptr spi register structure pointer - * \return data received by the spi - */ -Inline int32_t dw_spi_rcv_dat(DW_SPI_REG *spi_reg_ptr) -{ - return dw_spi_getdata(spi_reg_ptr); -} -/** - * \brief send char by spi in poll method, blocked function - * \param[in] spi_reg_ptr spi register structure pointer - * \param[in] data data to be sent - */ -Inline void dw_spi_psnd_dat(DW_SPI_REG *spi_reg_ptr, int32_t data) -{ - /** wait until spi is ready to send */ - while (!dw_spi_putready(spi_reg_ptr)); /* blocked */ - /** send char */ - dw_spi_putdata(spi_reg_ptr, data); -} -/** - * \brief receive one char from spi in poll method, blocked function - * \param[in] spi_reg_ptr spi register structure pointer - * \return data received by the spi - */ -Inline int32_t dw_spi_prcv_dat(DW_SPI_REG *spi_reg_ptr) -{ - /** wait until spi is ready to receive */ - while (!dw_spi_getready(spi_reg_ptr)); /* blocked */ - /** receive data */ - return dw_spi_getdata(spi_reg_ptr); -} - -/** Reset designware FIFO by disable spi device, then enable device */ -Inline void dw_spi_reset_fifo(DW_SPI_REG *spi_reg_ptr) -{ - dw_spi_disable(spi_reg_ptr); - dw_spi_enable(spi_reg_ptr); -} - -/** Enable designware spi bit interrupt with mask */ -Inline void dw_spi_unmask_interrupt(DW_SPI_REG *spi_reg_ptr, uint32_t mask) -{ - spi_reg_ptr->IMR |= mask; -} - -/** Disable designware spi bit interrupt with mask */ -Inline void dw_spi_mask_interrupt(DW_SPI_REG *spi_reg_ptr, uint32_t mask) -{ - spi_reg_ptr->IMR &= ~mask; -} - -/** Set designware spi device frequency */ -Inline void dw_spi_set_freq(DW_SPI_CTRL *spi_ctrl_ptr, uint32_t freq) -{ - uint32_t sck_divisor; - DW_SPI_REG *spi_reg_ptr = spi_ctrl_ptr->dw_spi_regs; - - dw_spi_disable(spi_reg_ptr); - - sck_divisor = DW_SPI_FREQ2DV(spi_ctrl_ptr->dw_apb_bus_freq, freq); - spi_reg_ptr->BAUDR = sck_divisor; - dw_spi_enable(spi_reg_ptr); -} - -/** Set designware spi device data frame size */ -static int32_t dw_spi_set_dfs(DW_SPI_REG *spi_reg_ptr, uint32_t dfs) -{ - uint32_t ctrl0_reg; - if ((dfs <= 3) || (dfs > 16)) return -1; - - dw_spi_disable(spi_reg_ptr); - ctrl0_reg = spi_reg_ptr->CTRLR0; - ctrl0_reg &= ~(DW_SPI_CTRLR0_DFS_MASK); - spi_reg_ptr->CTRLR0 = ctrl0_reg | (dfs-1); - dw_spi_enable(spi_reg_ptr); - - return 0; -} - -/** Choose proper designware spi clock mode setting value */ -Inline uint32_t dw_spi_select_clockmode(uint32_t clk_mode) -{ - return (clk_mode << DW_SPI_CTRLR0_SC_OFS); -} - -/** Set designware spi clock mode */ -Inline int32_t dw_spi_set_clockmode(DW_SPI_REG *spi_reg_ptr, uint32_t clk_mode) -{ - if (clk_mode > SPI_CPOL_1_CPHA_1) { - return -1; - } - dw_spi_disable(spi_reg_ptr); - spi_reg_ptr->CTRLR0 &= ~(DW_SPI_CTRLR0_SC_MASK); - spi_reg_ptr->CTRLR0 |= dw_spi_select_clockmode(clk_mode); - dw_spi_enable(spi_reg_ptr); - return 0; -} - -/** Select a spi slave with slv_line */ -Inline int32_t dw_spi_select_slave(DW_SPI_REG *spi_reg_ptr, uint32_t slv_line) -{ - /* check if spi busy */ - if (dw_spi_busy(spi_reg_ptr)) return -1; - - spi_reg_ptr->SER = 1<SER = 0; - return 0; -} - -Inline void dw_spi_flush_tx(DW_SPI_REG *spi_reg_ptr) -{ - dw_spi_reset_fifo(spi_reg_ptr); -} - -Inline void dw_spi_flush_rx(DW_SPI_REG *spi_reg_ptr) -{ - dw_spi_reset_fifo(spi_reg_ptr); -} - -/** Get TX FIFO Length. - * calculate spi fifo length using fifo threshold method - * If you attempt to set bits [7:0] of this register to - * a value greater than or equal to the depth of the FIFO, - * this field is not written and retains its current value. - */ -static uint32_t dw_spi_get_txfifo_len(DW_SPI_REG *spi_reg_ptr) -{ - uint32_t fifo_thr_lev_tmp, left, right, i; - - fifo_thr_lev_tmp = spi_reg_ptr->TXFTLR; - - if (fifo_thr_lev_tmp != 0) { - left = fifo_thr_lev_tmp; - } else { - left = DW_SPI_MIN_FIFO_LENGTH; - } - right = DW_SPI_MAX_FIFO_LENGTH + 1; - - for (i = left; i <= right; i++) { - spi_reg_ptr->TXFTLR = i; - if (spi_reg_ptr->TXFTLR != i) { - break; - } - } - spi_reg_ptr->TXFTLR = fifo_thr_lev_tmp; /* restore old fifo threshold */ - - return (i); -} - -/** Get RX FIFO Length */ -static uint32_t dw_spi_get_rxfifo_len(DW_SPI_REG *spi_reg_ptr) -{ - uint32_t fifo_thr_lev_tmp, left, right, i; - - fifo_thr_lev_tmp = spi_reg_ptr->RXFTLR; - - if (fifo_thr_lev_tmp != 0) { - left = fifo_thr_lev_tmp; - } else { - left = DW_SPI_MIN_FIFO_LENGTH; - } - right = DW_SPI_MAX_FIFO_LENGTH + 1; - - for (i = left; i <= right; i++) { - spi_reg_ptr->RXFTLR = i; - if (spi_reg_ptr->RXFTLR != i) { - break; - } - } - spi_reg_ptr->RXFTLR = fifo_thr_lev_tmp; /* restore old fifo threshold */ - - return (i); -} - -/** Init Designware SPI Hardware */ -static void dw_spi_hw_init(DW_SPI_CTRL *spi_ctrl_ptr, uint32_t clk_mode, uint32_t dfs) -{ - uint32_t ctrl0_reg = 0; - DW_SPI_REG *spi_reg_ptr = spi_ctrl_ptr->dw_spi_regs; - - dw_spi_disable(spi_reg_ptr); - - /* Clear interrupts */ - ctrl0_reg = spi_reg_ptr->ICR; - /* Mask all interrupts */ - spi_reg_ptr->IMR = 0; - - ctrl0_reg = DW_SPI_CTRLR0_FRF_MOTOROLA | DW_SPI_TMOD_TRANSMIT_RECEIVE \ - | dw_spi_select_clockmode(clk_mode) | (dfs - 1) | DW_SPI_CTRLR0_SLV_OE_ENABLE; - spi_reg_ptr->CTRLR0 = ctrl0_reg; - spi_reg_ptr->CTRLR1 = 0; - - /* deselect slaves */ - spi_reg_ptr->SER = 0; - - /* Set threshold values for both tx and rx */ - spi_reg_ptr->TXFTLR = 0; - spi_reg_ptr->RXFTLR = 0; - - dw_spi_enable(spi_reg_ptr); -} - -/** enable designware spi */ -static void dw_spi_enable_device(DEV_SPI_INFO *spi_info_ptr) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - - if ((spi_info_ptr->status & DEV_ENABLED) == 0) { - dw_spi_enable(spi_reg_ptr); - spi_info_ptr->status |= DEV_ENABLED; - } -} - -/** disable designware spi */ -static void dw_spi_disable_device(DEV_SPI_INFO *spi_info_ptr) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - - dw_spi_disable(spi_reg_ptr); - spi_info_ptr->status &= ~DEV_ENABLED; -} - - -/** - * \brief disable designware spi send or receive interrupt - * \param[in] DEV_SPI_INFO *spi_info_ptr - * \param[in] cbrtn control code of callback routine of send or receive - */ -static int32_t dw_spi_dis_cbr(DEV_SPI_INFO *spi_info_ptr, uint32_t cbrtn) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - int32_t ercd = E_OK; - - if ((spi_info_ptr->status & DW_SPI_IN_XFER) != 0) { /* only in transfer need do check */ - switch (cbrtn) { - case DW_SPI_RDY_SND: - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_TX, E_CTX); - spi_info_ptr->status &= ~(DW_SPI_IN_TX); - break; - case DW_SPI_RDY_RCV: - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_RX, E_CTX); - spi_info_ptr->status &= ~(DW_SPI_IN_RX); - break; - case DW_SPI_RDY_XFER: - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_XFER, E_CTX); - spi_info_ptr->status &= ~(DW_SPI_IN_XFER); - break; - default: - break; - } - } - - dw_spi_mask_interrupt(spi_ctrl_ptr->dw_spi_regs, DW_SPI_IMR_XFER); - - if (spi_ctrl_ptr->int_status & DW_SPI_GINT_ENABLE) { - int_disable(spi_ctrl_ptr->intno); - spi_ctrl_ptr->int_status &= ~DW_SPI_GINT_ENABLE; - } - -error_exit: - return ercd; -} - -/** - * \brief enable DesignWare SPI send or receive interrupt - * \param[in] DEV_SPI_INFO *spi_info_ptr - * \param[in] cbrtn control code of callback routine of send or receive - */ -static int32_t dw_spi_ena_cbr(DEV_SPI_INFO *spi_info_ptr, uint32_t cbrtn) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - int32_t ercd = E_OK; - - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == 0, E_CTX); - switch (cbrtn) { - case DW_SPI_RDY_SND: - spi_info_ptr->status |= DW_SPI_IN_TX; - break; - case DW_SPI_RDY_RCV: - spi_info_ptr->status |= DW_SPI_IN_RX; - break; - case DW_SPI_RDY_XFER: - spi_info_ptr->status |= DW_SPI_IN_XFER; - break; - default: - break; - } - dw_spi_unmask_interrupt(spi_ctrl_ptr->dw_spi_regs, DW_SPI_IMR_XFER); - - if ((spi_ctrl_ptr->int_status & DW_SPI_GINT_ENABLE) == 0) { - spi_ctrl_ptr->int_status |= DW_SPI_GINT_ENABLE; - int_enable(spi_ctrl_ptr->intno); - } - -error_exit: - return ercd; -} - -/** - * \brief enable designware spi interrupt - * \param spi_info_ptr spi information structure pointer - */ -static void dw_spi_enable_interrupt(DEV_SPI_INFO *spi_info_ptr) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - - int_handler_install(spi_ctrl_ptr->intno, spi_ctrl_ptr->dw_spi_int_handler); - spi_ctrl_ptr->int_status |= DW_SPI_GINT_ENABLE; - int_enable(spi_ctrl_ptr->intno); /** enable spi interrupt */ -} -/** - * \brief disable designware spi interrupt - * \param spi_info_ptr spi information structure pointer - */ -static void dw_spi_disable_interrupt(DEV_SPI_INFO *spi_info_ptr) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - - /** disable spi send&receive interrupt after disable spi interrupt */ - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); - /* disable spi interrupt */ - dw_spi_mask_interrupt(spi_ctrl_ptr->dw_spi_regs, DW_SPI_IMR_XFER); - spi_info_ptr->status &= ~DW_SPI_IN_XFER; - int_disable(spi_ctrl_ptr->intno); - spi_ctrl_ptr->int_status &= ~(DW_SPI_GINT_ENABLE); -} - -static void dw_spi_reset_device(DEV_SPI_INFO *spi_info_ptr) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - - dw_spi_disable_device(spi_info_ptr); - dw_spi_disable_interrupt(spi_info_ptr); - dw_spi_clear_interrupt_all(spi_reg_ptr); - dw_spi_enable_device(spi_info_ptr); -} - -/** abort current interrupt transmit transfer */ -static int32_t dw_spi_abort_tx(DEV_SPI *spi_obj) -{ - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - int32_t ercd = E_OK; - - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) != 0, E_OK); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_TX, E_CTX); - - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); - spi_info_ptr->status |= DEV_IN_TX_ABRT; - if (spi_info_ptr->spi_cbs.tx_cb != NULL) { - spi_info_ptr->spi_cbs.tx_cb(spi_obj); - } - spi_info_ptr->status &= ~(DEV_IN_TX_ABRT); - -error_exit: - return ercd; -} - -/** abort current interrupt receive transfer */ -static int32_t dw_spi_abort_rx(DEV_SPI *spi_obj) -{ - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - int32_t ercd = E_OK; - - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) != 0, E_OK); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_RX, E_CTX); - - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); - spi_info_ptr->status |= DEV_IN_RX_ABRT; - if (spi_info_ptr->spi_cbs.rx_cb != NULL) { - spi_info_ptr->spi_cbs.rx_cb(spi_obj); - } - spi_info_ptr->status &= ~(DEV_IN_RX_ABRT); - -error_exit: - return ercd; -} - -/** abort current interrupt transfer */ -static int32_t dw_spi_abort_xfer(DEV_SPI *spi_obj) -{ - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - int32_t ercd = E_OK; - - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) != 0, E_OK); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_XFER, E_CTX); - - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); - spi_info_ptr->status |= DEV_IN_XFER_ABRT; - if (spi_info_ptr->spi_cbs.xfer_cb != NULL) { - spi_info_ptr->spi_cbs.xfer_cb(spi_obj); - } - spi_info_ptr->status &= ~(DEV_IN_XFER_ABRT); - -error_exit: - return ercd; -} - -/** Get available transmit fifo count */ -static int32_t dw_spi_get_txavail(DW_SPI_CTRL *spi_ctrl_ptr) -{ - int32_t tx_avail = 0; - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - -#if DW_SPI_CALC_FIFO_LEN_ENABLE - if (spi_ctrl_ptr->tx_fifo_len <= 1) { - if (dw_spi_putready(spi_reg_ptr) == 1) { - tx_avail = 1; - } else { - tx_avail = 0; - } - } else -#endif - { - tx_avail = spi_ctrl_ptr->tx_fifo_len - spi_reg_ptr->TXFLR; - } - return tx_avail; -} - -/** Get available receive fifo count */ -static int32_t dw_spi_get_rxavail(DW_SPI_CTRL *spi_ctrl_ptr) -{ - int32_t rx_avail = 0; - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - -#if DW_SPI_CALC_FIFO_LEN_ENABLE - if (spi_ctrl_ptr->rx_fifo_len <= 1) { - if (dw_spi_getready(spi_reg_ptr) == 1) { - rx_avail = 1; - } else { - rx_avail = 0; - } - } else -#endif - { - rx_avail = spi_reg_ptr->RXFLR; - } - return rx_avail; -} - -static uint32_t dw_spi_tx_max(DW_SPI_CTRL *spi_ctrl_ptr) -{ - uint32_t tx_left, tx_room; - DW_SPI_TRANSFER *xfer = &(spi_ctrl_ptr->dw_xfer); - - tx_left = (xfer->xfer_len - xfer->tx_idx) / xfer->nbytes; - tx_room = dw_spi_get_txavail(spi_ctrl_ptr); - - return (tx_left < tx_room) ? tx_left : tx_room; -} - -static uint32_t dw_spi_rx_max(DW_SPI_CTRL *spi_ctrl_ptr) -{ - uint32_t rx_left, rx_room; - DW_SPI_TRANSFER *xfer = &(spi_ctrl_ptr->dw_xfer); - - rx_left = (xfer->xfer_len - xfer->rx_idx) / xfer->nbytes; - rx_room = dw_spi_get_rxavail(spi_ctrl_ptr); - - return (rx_left < rx_room) ? rx_left : rx_room; -} - -Inline int32_t dw_spi_rx_end(DW_SPI_CTRL *spi_ctrl_ptr) -{ - DW_SPI_TRANSFER *xfer = &(spi_ctrl_ptr->dw_xfer); - - return (xfer->rx_idx >= xfer->xfer_len); -} - -Inline int32_t dw_spi_tx_end(DW_SPI_CTRL *spi_ctrl_ptr) -{ - DW_SPI_TRANSFER *xfer = &(spi_ctrl_ptr->dw_xfer); - - return (xfer->tx_idx >= xfer->xfer_len); -} - -/** 1 for end, 0 for not end */ -Inline int32_t dw_spi_xfer_end(DW_SPI_CTRL *spi_ctrl_ptr) -{ - return (dw_spi_tx_end(spi_ctrl_ptr) && dw_spi_rx_end(spi_ctrl_ptr)); -} - -static int32_t dw_spi_writer(DEV_SPI_INFO *spi_info_ptr) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); - DW_SPI_TRANSFER *dw_xfer = &(spi_ctrl_ptr->dw_xfer); - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - uint32_t tx_max = dw_spi_tx_max(spi_ctrl_ptr); - int32_t tx_w; - uint32_t tx_cnt = tx_max; - - if (dw_xfer->tx_xfer == NULL) { - return 0; - } - while (tx_max) { - if (dw_xfer->tx_xfer->tx_idx >= dw_xfer->tx_xfer->tot_len) { - dw_xfer->tx_xfer = dw_xfer->tx_xfer->next; - if (dw_xfer->tx_xfer == NULL) { - break; - } - } - if ( (dw_xfer->tx_xfer->tx_idx >= dw_xfer->tx_xfer->tx_ofs) \ - && (dw_xfer->tx_xfer->tx_idx < dw_xfer->tx_xfer->tx_totlen)) { - if (dw_xfer->nbytes == 1) { - tx_w = (int32_t)(*(int8_t *)(dw_xfer->tx_xfer->tx_buf)); - } else { - tx_w = (int32_t)(*(int16_t *)(dw_xfer->tx_xfer->tx_buf)); - } - dw_xfer->tx_xfer->tx_buf += dw_xfer->nbytes; - } else { - tx_w = spi_info_ptr->dummy; - } - dw_spi_putdata(spi_reg_ptr, tx_w); - dw_xfer->tx_xfer->tx_idx += dw_xfer->nbytes; - dw_xfer->tx_idx += dw_xfer->nbytes; - tx_max --; - } - return ((tx_cnt-tx_max) * dw_xfer->nbytes); -} - -static int32_t dw_spi_reader(DEV_SPI_INFO *spi_info_ptr) -{ - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); - DW_SPI_TRANSFER *dw_xfer = &(spi_ctrl_ptr->dw_xfer); - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - uint32_t rx_max = dw_spi_rx_max(spi_ctrl_ptr); - int32_t rx_w; - uint32_t rx_cnt = rx_max; - - if (dw_xfer->rx_xfer == NULL) { - return 0; - } - while (rx_max) { - if (dw_xfer->rx_xfer->rx_idx >= dw_xfer->rx_xfer->tot_len) { - dw_xfer->rx_xfer = dw_xfer->rx_xfer->next; - if (dw_xfer->rx_xfer == NULL) { - break; - } - } - rx_w = dw_spi_getdata(spi_reg_ptr); - if ( (dw_xfer->rx_xfer->rx_idx >= dw_xfer->rx_xfer->rx_ofs) \ - && (dw_xfer->rx_xfer->rx_idx < dw_xfer->rx_xfer->rx_totlen) ) { - if (dw_xfer->nbytes == 1) { - *(int8_t *)(dw_xfer->rx_xfer->rx_buf) = rx_w; - } else { - *(int16_t *)(dw_xfer->rx_xfer->rx_buf) = rx_w; - } - dw_xfer->rx_xfer->rx_buf += dw_xfer->nbytes; - } - dw_xfer->rx_xfer->rx_idx += dw_xfer->nbytes; - dw_xfer->rx_idx += dw_xfer->nbytes; - rx_max --; - } - return ((rx_cnt-rx_max) * dw_xfer->nbytes); -} - -Inline uint32_t dw_spi_nbytes(uint32_t dfs) -{ - uint32_t nbytes = 1; - - if (dfs > 8) nbytes = 2; - return nbytes; -} - -static void dw_spi_init_transfer(DW_SPI_CTRL *spi_ctrl_ptr, DEV_SPI_TRANSFER *xfer, uint32_t dfs) -{ - DW_SPI_TRANSFER *dw_xfer= &(spi_ctrl_ptr->dw_xfer); - uint32_t tot_len = 0; - - dw_xfer->tx_xfer = xfer; - dw_xfer->rx_xfer = xfer; - dw_xfer->tx_idx = 0; - dw_xfer->rx_idx = 0; - dw_xfer->nbytes = dw_spi_nbytes(dfs); - - /** Calculate all transfer length */ - while (xfer) { - DEV_SPI_XFER_INIT(xfer); - tot_len += xfer->tot_len; - xfer = xfer->next; - } - dw_xfer->xfer_len = tot_len; -} - -/* Check buffer align status, 0 for aligned, -1 for not-aligned */ -static int32_t dw_spi_chk_xfer_aligned(DEV_SPI_TRANSFER *xfer, uint32_t dfs) -{ - uint32_t align_bytes = 1; - if (xfer == NULL) return -1; - - if (dfs > 8) { - align_bytes = 2; - } else { - return 0; - } - - while (xfer) { - /* check tx buffer align status */ - if (xfer->tx_len != 0) { - if (xfer->tx_len % align_bytes) return -1; - if (xfer->tx_ofs % align_bytes) return -1; - if (!CHECK_ALIGN_BYTES(xfer->tx_buf, align_bytes)) return -1; - } - /* check tx buffer align status */ - if (xfer->rx_len != 0) { - if (xfer->rx_len % align_bytes) return -1; - if (xfer->rx_ofs % align_bytes) return -1; - if (!CHECK_ALIGN_BYTES(xfer->rx_buf, align_bytes)) return -1; - } - xfer = xfer->next; - } - return 0; -} - -static uint32_t dw_spi_poll_transfer(DEV_SPI_INFO *spi_info_ptr) -{ - uint32_t len = 0; - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); - - spi_info_ptr->status |= DEV_IN_XFER; - while (!dw_spi_xfer_end(spi_ctrl_ptr)) { - len += dw_spi_writer(spi_info_ptr); - len += dw_spi_reader(spi_info_ptr); - } - spi_info_ptr->status &= ~DEV_IN_XFER; - - return len>>1; -} - -/** @} */ - -/** - * \brief open a designware spi device - * \param[in] spi_obj spi object pointer - * \param[in] mode spi working mode (master or slave) - * \param[in] param parameter, for master, param is the freq, for slave, param is dfs - * \retval E_OK Open successfully without any issues - * \retval E_OPNED If device was opened before with different parameters, - * then just increase the \ref dev_spi_info::opn_cnt "opn_cnt" and return \ref E_OPNED - * \retval E_OBJ Device object is not valid - * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first. - * \retval E_PAR Parameter is not valid - * \retval E_NOSPT Open settings are not supported - */ -int32_t dw_spi_open (DEV_SPI *spi_obj, uint32_t mode, uint32_t param) -{ - int32_t ercd = E_OK; - uint32_t param2check; - uint32_t clk_mode, dfs_val; - uint32_t support_modes; - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - - /* START ERROR CHECK */ - VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); - DW_SPI_CHECK_EXP((mode==DEV_MASTER_MODE)||(mode==DEV_SLAVE_MODE), E_PAR); - if (mode == DEV_SLAVE_MODE) { /* clock mode should be in the enum structure */ - DW_SPI_CHECK_EXP((param>=SPI_CPOL_0_CPHA_0) && (param<=SPI_CPOL_1_CPHA_1), E_PAR); - } else { /* frequence should > 0 */ - DW_SPI_CHECK_EXP(param>0, E_PAR); - } - /* END OF ERROR CHECK */ - - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); - - /* Check supported modes, master or slave */ - support_modes = spi_ctrl_ptr->support_modes; - DW_SPI_CHECK_EXP( (((support_modes)&DW_SPI_MASTER_SUPPORTED)&&(mode == DEV_MASTER_MODE)) || \ - (((support_modes)&DW_SPI_SLAVE_SUPPORTED)&&(mode == DEV_SLAVE_MODE)), E_NOSPT); - - /** Check opened before use case */ - if (spi_info_ptr->opn_cnt > 0) { - if (mode != spi_info_ptr->mode) { - /* current working mode is different from passing mode */ - return E_SYS; - } - if (mode == DEV_MASTER_MODE) { /* param is freq when as master */ - param2check = spi_info_ptr->freq; - } else { /* param is clk_mode when as slave */ - param2check = spi_info_ptr->clk_mode; - } - spi_info_ptr->opn_cnt ++; - if (param != param2check) { /* open with different speed mode */ - return E_OPNED; - } else { - return E_OK; - } - } - /* auto increase open count */ - spi_info_ptr->opn_cnt ++; - - /* Do FIFO Length get before init */ -#if DW_SPI_CALC_FIFO_LEN_ENABLE - spi_ctrl_ptr->tx_fifo_len = dw_spi_get_txfifo_len(spi_ctrl_ptr->dw_spi_regs); - spi_ctrl_ptr->rx_fifo_len = dw_spi_get_rxfifo_len(spi_ctrl_ptr->dw_spi_regs); -#endif - /* hardware init */ - spi_info_ptr->mode = mode; - clk_mode = SPI_CLK_MODE_DEFAULT; - dfs_val = SPI_DFS_DEFAULT; - if (mode == DEV_SLAVE_MODE) { - clk_mode = param; - } - spi_info_ptr->dfs = dfs_val; - spi_info_ptr->clk_mode = clk_mode; - dw_spi_hw_init(spi_ctrl_ptr, clk_mode, dfs_val); - if (mode == DEV_MASTER_MODE) { /* Deselect all slaves, and set frequence */ - dw_spi_deselect_slave(spi_ctrl_ptr->dw_spi_regs, 0); - dw_spi_set_freq(spi_ctrl_ptr, param); - spi_info_ptr->freq = param; - } - - spi_info_ptr->status = DEV_ENABLED; - spi_info_ptr->extra = NULL; - spi_info_ptr->slave = SPI_SLAVE_NOT_SELECTED; - spi_info_ptr->dummy = 0xff; - - spi_ctrl_ptr->int_status = 0; - dw_spi_init_transfer(spi_ctrl_ptr, NULL, dfs_val); - - /** install spi interrupt into system */ - dw_spi_disable_interrupt(spi_info_ptr); - int_handler_install(spi_ctrl_ptr->intno, spi_ctrl_ptr->dw_spi_int_handler); - memset(&(spi_info_ptr->xfer), 0, sizeof(DEV_SPI_TRANSFER)); - memset(&(spi_info_ptr->spi_cbs), 0, sizeof(DEV_SPI_CBS)); - -error_exit: - return ercd; -} - -/** - * \brief close a DesignWare SPI device - * \param[in] spi_obj spi object pointer - * \retval E_OK Close successfully without any issues(including scenario that device is already closed) - * \retval E_OPNED Device is still opened, the device \ref dev_spi_info::opn_cnt "opn_cnt" decreased by 1 - * \retval E_OBJ Device object is not valid - */ -int32_t dw_spi_close (DEV_SPI *spi_obj) -{ - int32_t ercd = E_OK; - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - - /* START ERROR CHECK */ - VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); - DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_OK); - /* END OF ERROR CHECK */ - - spi_info_ptr->opn_cnt --; - if (spi_info_ptr->opn_cnt == 0) { - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - - dw_spi_disable_interrupt(spi_info_ptr); - dw_spi_abort_tx(spi_obj); - dw_spi_abort_rx(spi_obj); - memset(&(spi_info_ptr->xfer), 0, sizeof(DEV_SPI_TRANSFER)); - memset(&(spi_info_ptr->spi_cbs), 0, sizeof(DEV_SPI_CBS)); - memset(&(spi_ctrl_ptr->dw_xfer), 0, sizeof(DW_SPI_TRANSFER)); - dw_spi_disable_device(spi_info_ptr); - spi_info_ptr->status = DEV_DISABLED; - spi_info_ptr->extra = NULL; - } else { - ercd = E_OPNED; - } - -error_exit: - return ercd; -} - -/** - * \brief control spi by ctrl command - * \param[in] spi_obj spi object pointer - * \param[in] ctrl_cmd control command code to do specific spi work - * \param[in,out] param parameters used to control spi or return something - * \retval E_OK Control device successfully - * \retval E_CLSED Device is not opened - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled - * \retval E_CTX Control device failed, due to different reasons like in transfer state - * \retval E_NOSPT Control command is not supported or not valid - */ -int32_t dw_spi_control (DEV_SPI *spi_obj, uint32_t ctrl_cmd, void *param) -{ - int32_t ercd = E_OK; - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - - /* START ERROR CHECK */ - VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); - DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_CLSED); - /* END OF ERROR CHECK */ - - uint32_t val32; /** to receive unsigned int value */ - DEV_BUFFER *devbuf; - - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL *)(spi_info_ptr->spi_ctrl); - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - DEV_SPI_TRANSFER *spi_xfer = &(spi_info_ptr->xfer); - - /* check whether current device is disabled */ - if ((spi_info_ptr->status & DEV_ENABLED) == 0) { - /** When device is disabled, - * only SPI_CMD_ENA_DEV, SPI_CMD_DIS_DEV, SPI_CMD_GET_STATUS, SPI_CMD_RESET - * are available, other commands will return E_SYS - */ - if ((ctrl_cmd != SPI_CMD_ENA_DEV) && \ - (ctrl_cmd != SPI_CMD_DIS_DEV) && \ - (ctrl_cmd != SPI_CMD_GET_STATUS) && \ - (ctrl_cmd != SPI_CMD_RESET) ) { - return E_SYS; - } - } - - switch (ctrl_cmd) { - /* Commmon commands for both master and slave mode */ - case SPI_CMD_GET_STATUS: - DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = spi_info_ptr->status; - break; - case SPI_CMD_SET_CLK_MODE: - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - val32 = (uint32_t)param; - DW_SPI_CHECK_EXP((val32>=SPI_CPOL_0_CPHA_0) && (val32<=SPI_CPOL_1_CPHA_1), E_PAR); - if (dw_spi_set_clockmode(spi_reg_ptr, val32) == 0) { - spi_info_ptr->clk_mode = val32; - } else { - ercd = E_SYS; - } - break; - case SPI_CMD_ENA_DEV: - dw_spi_enable_device(spi_info_ptr); - break; - case SPI_CMD_DIS_DEV: - dw_spi_disable_device(spi_info_ptr); - break; - case SPI_CMD_RESET: - dw_spi_reset_device(spi_info_ptr); - break; - case SPI_CMD_FLUSH_TX: - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - dw_spi_flush_tx(spi_reg_ptr); - break; - case SPI_CMD_FLUSH_RX: - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - dw_spi_flush_rx(spi_reg_ptr); - break; - case SPI_CMD_SET_DFS: - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - val32 = (uint32_t)param; - DW_SPI_CHECK_EXP(val32>0, E_PAR); - if (dw_spi_set_dfs(spi_reg_ptr, val32) == 0) { - spi_info_ptr->dfs = val32; - } else { - ercd = E_SYS; - } - break; - case SPI_CMD_SET_DUMMY_DATA: - val32 = (uint32_t)param; - spi_info_ptr->dummy = val32; - break; - case SPI_CMD_GET_RXAVAIL: /* Notice in bytes unit */ - DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = dw_spi_get_rxavail(spi_ctrl_ptr) * dw_spi_nbytes(spi_info_ptr->dfs); - break; - case SPI_CMD_GET_TXAVAIL: /* Notice in bytes unit */ - DW_SPI_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = dw_spi_get_txavail(spi_ctrl_ptr) * dw_spi_nbytes(spi_info_ptr->dfs); - break; - case SPI_CMD_SET_TXCB: - DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - spi_info_ptr->spi_cbs.tx_cb = param; - break; - case SPI_CMD_SET_RXCB: - DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - spi_info_ptr->spi_cbs.rx_cb = param; - break; - case SPI_CMD_SET_XFERCB: - DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - spi_info_ptr->spi_cbs.xfer_cb = param; - break; - case SPI_CMD_SET_ERRCB: - DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - spi_info_ptr->spi_cbs.err_cb = param; - break; - case SPI_CMD_ABORT_TX: - ercd = dw_spi_abort_tx(spi_obj); - break; - case SPI_CMD_ABORT_RX: - ercd = dw_spi_abort_rx(spi_obj); - break; - case SPI_CMD_ABORT_XFER: - ercd = dw_spi_abort_xfer(spi_obj); - break; - case SPI_CMD_SET_TXINT: - val32 = (uint32_t)param; - if (val32 == 0) { - ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); - } else { - ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_SND); - } - break; - case SPI_CMD_SET_RXINT: - val32 = (uint32_t)param; - if (val32 == 0) { - ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); - } else { - ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_RCV); - } - break; - case SPI_CMD_SET_TXINT_BUF: - DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - if (param != NULL) { - devbuf = (DEV_BUFFER *)param; - DEV_SPI_XFER_SET_TXBUF(spi_xfer, devbuf->buf, 0, devbuf->len); - DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, devbuf->len, 0); - DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); - DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); - dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); - } else { - DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, 0, 0); - DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, 0, 0); - DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); - dw_spi_init_transfer(spi_ctrl_ptr, NULL, spi_info_ptr->dfs); - } - break; - case SPI_CMD_SET_RXINT_BUF: - DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - if (param != NULL) { - devbuf = (DEV_BUFFER *)param; - DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, devbuf->len, 0); - DEV_SPI_XFER_SET_RXBUF(spi_xfer, devbuf->buf, 0, devbuf->len); - DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); - /* Check transfer align */ - DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); - dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); - } else { - DEV_SPI_XFER_SET_TXBUF(spi_xfer, NULL, 0, 0); - DEV_SPI_XFER_SET_RXBUF(spi_xfer, NULL, 0, 0); - DEV_SPI_XFER_SET_NEXT(spi_xfer, NULL); - dw_spi_init_transfer(spi_ctrl_ptr, NULL, spi_info_ptr->dfs); - } - break; - case SPI_CMD_TRANSFER_POLLING: - DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - if (param != NULL) { - /* Check transfer align */ - DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned((DEV_SPI_TRANSFER *)param, spi_info_ptr->dfs) == 0, E_PAR); - *spi_xfer = *((DEV_SPI_TRANSFER *)param); - dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); - /* Transfer data by poll */ - dw_spi_poll_transfer(spi_info_ptr); - } else { - ercd = E_PAR; - } - break; - case SPI_CMD_TRANSFER_INT: - DW_SPI_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - if (param != NULL) { - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - /* Check transfer align */ - DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned((DEV_SPI_TRANSFER *)param, spi_info_ptr->dfs) == 0, E_PAR); - *spi_xfer = *((DEV_SPI_TRANSFER *)param); - dw_spi_init_transfer(spi_ctrl_ptr, spi_xfer, spi_info_ptr->dfs); - /* Transfer data by interrupt */ - ercd = dw_spi_ena_cbr(spi_info_ptr, DW_SPI_RDY_XFER); - } else { - ercd = dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); - } - break; - - /* Master mode only commands */ - case SPI_CMD_MST_SET_FREQ: - DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - val32 = (uint32_t)param; - DW_SPI_CHECK_EXP(val32>0, E_PAR); - dw_spi_set_freq(spi_ctrl_ptr, val32); - spi_info_ptr->freq = val32; - break; - case SPI_CMD_MST_SEL_DEV: - DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - val32 = (uint32_t)param; - if (dw_spi_select_slave(spi_reg_ptr, val32) == 0) { - spi_info_ptr->slave = val32; - } else { - ercd = E_SYS; - } - break; - case SPI_CMD_MST_DSEL_DEV: - DW_SPI_CHECK_EXP(spi_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - val32 = (uint32_t)param; - if (dw_spi_deselect_slave(spi_reg_ptr, val32) == 0) { - spi_info_ptr->slave = SPI_SLAVE_NOT_SELECTED; - } else { - ercd = E_SYS; - } - break; - - /* Slave mode only commands */ - - - default: - ercd = E_NOSPT; - break; - } - -error_exit: - return ercd; -} - -/** - * \brief send data through DesignWare SPI - * \param[in] spi_obj spi object pointer - * \param[in] data pointer to data need to send by spi - * \param[in] len length of data to be sent - * \retval >0 Byte count that was successfully sent for poll method - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid - * \retval E_CTX Device is still in transfer state - * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled - */ -int32_t dw_spi_write (DEV_SPI *spi_obj, const void *data, uint32_t len) -{ - int32_t ercd = E_OK; - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - - /* START ERROR CHECK */ - VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); - DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_CLSED); - DW_SPI_CHECK_EXP(spi_info_ptr->status & DEV_ENABLED, E_SYS); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - DW_SPI_CHECK_EXP(data!=NULL, E_PAR); - DW_SPI_CHECK_EXP(len>0, E_PAR); - /* END OF ERROR CHECK */ - - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); - DEV_SPI_TRANSFER spi_xfer; - - /* Master and Slave transmit */ - DEV_SPI_XFER_SET_TXBUF(&spi_xfer, data, 0, len); - DEV_SPI_XFER_SET_RXBUF(&spi_xfer, NULL, len, 0); - DEV_SPI_XFER_SET_NEXT(&spi_xfer, NULL); - - /* Check transfer align */ - DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(&spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); - - dw_spi_init_transfer(spi_ctrl_ptr, &spi_xfer, spi_info_ptr->dfs); - - ercd = dw_spi_poll_transfer(spi_info_ptr); - -error_exit: - return ercd; -} - -/** - * \brief read data through DesignWare SPI - * \param[in] spi_info_ptr spi information structure pointer - * \param[out] data data that need to read (data must be char type) - * \param[in] len data count need to read - * \retval >=0 data have been read - * \retval E_PAR arguments passed was wrong - * \retval E_OBJ spi has something error, nothing can be done - * \retval E_CLSED spi was closed, not available for control - * \retval <0 other error code not defined here - */ -int32_t dw_spi_read (DEV_SPI *spi_obj, void *data, uint32_t len) -{ - int32_t ercd = E_OK; - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - - /* START ERROR CHECK */ - VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); - DW_SPI_CHECK_EXP(spi_info_ptr->opn_cnt > 0, E_CLSED); - DW_SPI_CHECK_EXP(spi_info_ptr->status & DEV_ENABLED, E_SYS); - DW_SPI_CHECK_EXP((spi_info_ptr->status & DEV_IN_XFER) == 0, E_CTX); - DW_SPI_CHECK_EXP(data!=NULL, E_PAR); - DW_SPI_CHECK_EXP(len>0, E_PAR); - /* END OF ERROR CHECK */ - - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); - DEV_SPI_TRANSFER spi_xfer; - - /* Master and Slave transmit */ - DEV_SPI_XFER_SET_TXBUF(&spi_xfer, NULL, len, 0); - DEV_SPI_XFER_SET_RXBUF(&spi_xfer, data, 0, len); - DEV_SPI_XFER_SET_NEXT(&spi_xfer, NULL); - - /* Check transfer align */ - DW_SPI_CHECK_EXP(dw_spi_chk_xfer_aligned(&spi_xfer, spi_info_ptr->dfs) == 0, E_PAR); - - dw_spi_init_transfer(spi_ctrl_ptr, &spi_xfer, spi_info_ptr->dfs); - - ercd = dw_spi_poll_transfer(spi_info_ptr); - -error_exit: - return ercd; -} - -/** - * \brief DesignWare SPI interrupt processing routine - * \param[in] spi_info_ptr DEV_SPI_INFO *spi_info_ptr - * \param[in] ptr extra information - */ -void dw_spi_isr(DEV_SPI *spi_obj, void *ptr) -{ - int32_t ercd = E_OK; - DEV_SPI_INFO *spi_info_ptr = &(spi_obj->spi_info); - - /* START ERROR CHECK */ - VALID_CHK_SPI_INFO_OBJECT(spi_info_ptr); - /* END OF ERROR CHECK */ - - DW_SPI_CTRL *spi_ctrl_ptr = (DW_SPI_CTRL_PTR)(spi_info_ptr->spi_ctrl); - DW_SPI_REG *spi_reg_ptr = (DW_SPI_REG *)(spi_ctrl_ptr->dw_spi_regs); - - uint32_t isr_status; - - isr_status = spi_reg_ptr->ISR; - - if (!isr_status) return; - if (spi_ctrl_ptr->dw_xfer.xfer_len == 0) { - dw_spi_disable_interrupt(spi_info_ptr); - } else { - if (isr_status & (DW_SPI_IMR_TXOIM|DW_SPI_IMR_RXOIM|DW_SPI_IMR_RXUIM)) { - dw_spi_clear_interrupt_all(spi_reg_ptr); - dw_spi_disable_interrupt(spi_info_ptr); - if (spi_info_ptr->spi_cbs.err_cb) { - spi_info_ptr->spi_cbs.err_cb(spi_obj); - } - memset(&(spi_ctrl_ptr->dw_xfer), 0, sizeof(DW_SPI_TRANSFER)); - } - dw_spi_reader(spi_info_ptr); - if (isr_status & DW_SPI_IMR_TXEIM) { - dw_spi_writer(spi_info_ptr); - } - if (dw_spi_xfer_end(spi_ctrl_ptr)) { - if ((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_TX) { - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_SND); - if (spi_info_ptr->spi_cbs.tx_cb) { - spi_info_ptr->spi_cbs.tx_cb(spi_obj); - } - } else if ((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_RX) { - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_RCV); - if (spi_info_ptr->spi_cbs.rx_cb) { - spi_info_ptr->spi_cbs.rx_cb(spi_obj); - } - } else if ((spi_info_ptr->status & DW_SPI_IN_XFER) == DW_SPI_IN_XFER) { - dw_spi_dis_cbr(spi_info_ptr, DW_SPI_RDY_XFER); - if (spi_info_ptr->spi_cbs.xfer_cb) { - spi_info_ptr->spi_cbs.xfer_cb(spi_obj); - } - } else { - dw_spi_disable_interrupt(spi_info_ptr); - } - memset(&(spi_ctrl_ptr->dw_xfer), 0, sizeof(DW_SPI_TRANSFER)); - } - } - -error_exit: - return; -} -/** @} */ /* DEVICE_DW_SPI_IMPLEMENT */ - -/** @} */ /* DEVICE_DW_SPI */ diff --git a/bsp/synopsys/embarc/device/designware/spi/dw_spi.h b/bsp/synopsys/embarc/device/designware/spi/dw_spi.h deleted file mode 100644 index ef2faa90e6..0000000000 --- a/bsp/synopsys/embarc/device/designware/spi/dw_spi.h +++ /dev/null @@ -1,190 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-06-25 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \brief DesignWare SPI driver header file - * \ingroup DEVICE_DW_SPI - */ - -#ifndef _DEVICE_DW_SPI_H_ -#define _DEVICE_DW_SPI_H_ - -#include "device/device_hal/inc/dev_spi.h" - -/** - * if this header file is included, - * will indicate that this designware spi device - * is used - */ -#define DEVICE_USE_DESIGNWARE_SPI - -#define DW_SPI_IN_FREE (0) /*!< Currently not in spi transfer */ -#define DW_SPI_IN_XFER (DEV_IN_TX|DEV_IN_RX|DEV_IN_XFER) /*!< Currently in spi transfer */ -#define DW_SPI_IN_TX (DEV_IN_TX|DEV_IN_XFER) /*!< Currently in spi tx */ -#define DW_SPI_IN_RX (DEV_IN_RX|DEV_IN_XFER) /*!< Currently in spi rx */ - -#define DW_SPI_GINT_DISABLED (0) /*!< designware interrupt disabled for control iic irq/fiq */ -#define DW_SPI_GINT_ENABLE (1<<0) /*!< designware interrupt enabled for control iic irq/fiq */ - -#define DW_SPI_MASTER_SUPPORTED (0x1) /*!< Support Designware SPI Master Mode */ -#define DW_SPI_SLAVE_SUPPORTED (0x2) /*!< Support Designware SPI Slave Mode */ -/*!< Support Designware SPI Both Master and Slave Mode */ -#define DW_SPI_BOTH_SUPPORTED (DW_SPI_MASTER_SUPPORTED|DW_SPI_SLAVE_SUPPORTED) - -/** - * \defgroup DEVICE_DW_SPI_REGSTRUCT DesignWare SPI Register Structure - * \ingroup DEVICE_DW_SPI - * \brief contains definitions of DesignWare SPI register structure. - * \details detailed description of DesignWare SPI register information - * @{ - */ -/** - * \brief DesignWare SPI register structure - * \details Detailed struct description of DesignWare SPI - * block register information, implementation of dev_spi_info::spi_regs - */ -typedef volatile struct dw_spi_reg -{ - /*!< Control Register */ - /*!< SPI Control Register 0 (0x0) */ - uint32_t CTRLR0; - /*!< SPI Control Register 1 (0x4) */ - uint32_t CTRLR1; - /*!< Enable Register */ - /*!< SPI Enable Register (0x8) */ - uint32_t SSIENR; - /*!< SPI Microwire Control Register (0xC) */ - uint32_t MWCR; - /*!< SPI Slave Enable Register (0x10) */ - uint32_t SER; - /*!< SPI Baud Rate Select Register (0x14) */ - uint32_t BAUDR; - /*!< TX and RX FIFO Control Register */ - /*!< SPI Transmit FIFO Threshold Level Register (0x18) */ - uint32_t TXFTLR; - /*!< SPI Receive FIFO Threshold Level Register (0x1C) */ - uint32_t RXFTLR; - /*!< SPI Transmit FIFO Level Register (0x20) */ - uint32_t TXFLR; - /*!< SPI Receive FIFO Level Register (0x24) */ - uint32_t RXFLR; - /*!< SPI Status Register (0x28) */ - uint32_t SR; - /*!< Interrupt Enable/Disable/Control Registers */ - /*!< SPI Interrupt Mask Register (0x2C) */ - uint32_t IMR; - /*!< SPI Interrupt Status Register (0x30) */ - uint32_t ISR; - /*!< SPI Raw Interrupt Status Register (0x34) */ - uint32_t RISR; - /*!< SPI Transmit FIFO Overflow Interrupt Clear Register (0x38) */ - uint32_t TXOICR; - /*!< SPI Receive FIFO Overflow Interrupt Clear Register (0x3C) */ - uint32_t RXOICR; - /*!< SPI Receive FIFO Underflow Interrupt Clear Register (0x40) */ - uint32_t RXUICR; - /*!< SPI Multi-Master Interrupt Clear Register (0x44) */ - uint32_t MSTICR; - /*!< SPI Interrupt Clear Register (0x48) */ - uint32_t ICR; - /*!< DMA Control Register (0x4C) */ - uint32_t DMACR; - /*!< DMA Transmit Data Level (0x50) */ - uint32_t DMATDLR; - /*!< DMA Receive Data Level (0x54) */ - uint32_t DMARDLR; - /*!< SPI Identification Register (0x58) */ - uint32_t IDR; - /*!< SPI CoreKit ID Register (Value after Reset : 0x3332322A) (0x5C) */ - uint32_t SSI_VER_ID; - /*!< Data Register */ - /*!< SPI DATA Register for both Read and Write (0x60) */ - uint32_t DATAREG; -} DW_SPI_REG, *DW_SPI_REG_PTR; -/** @} */ - -/** Designware SPI Message Transfer */ -typedef struct dw_spi_transfer { - uint32_t xfer_len; - uint32_t tx_idx; - uint32_t rx_idx; - uint32_t nbytes; - DEV_SPI_TRANSFER *tx_xfer; - DEV_SPI_TRANSFER *rx_xfer; -} DW_SPI_TRANSFER, *DW_SPI_TRANSFER_PTR; - -/** - * \brief DesignWare SPI control structure definition - * \details implement of dev_spi_info::dev_spi_info - */ -typedef struct dw_spi_ctrl { - DW_SPI_REG *dw_spi_regs; /*!< spi register */ - /* Variables which should be set during object implementation */ - uint32_t support_modes; /*!< supported spi modes */ - uint32_t intno; /*!< interrupt no */ - uint32_t dw_apb_bus_freq; /*!< spi ip apb bus frequency */ - uint32_t tx_fifo_len; /*!< transmit fifo length */ - uint32_t rx_fifo_len; /*!< receive fifo length */ - INT_HANDLER dw_spi_int_handler; /*!< spi interrupt handler */ - /* Variables which always change during iic operation */ - uint32_t int_status; /*!< iic interrupt status */ - DW_SPI_TRANSFER dw_xfer; /*!< designware spi transfer */ -} DW_SPI_CTRL, *DW_SPI_CTRL_PTR; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup DEVICE_DW_SPI_FUNCDLR DesignWare SPI Function Declaration - * \ingroup DEVICE_DW_SPI - * \brief contains declarations of designware spi functions. - * \details This are only used in \ref dw_spi_obj.c - * @{ - */ -extern int32_t dw_spi_open (DEV_SPI *spi_obj, uint32_t mode, uint32_t param); -extern int32_t dw_spi_close (DEV_SPI *spi_obj); -extern int32_t dw_spi_control (DEV_SPI *spi_obj, uint32_t ctrl_cmd, void *param); -extern int32_t dw_spi_write (DEV_SPI *spi_obj, const void *data, uint32_t len); -extern int32_t dw_spi_read (DEV_SPI *spi_obj, void *data, uint32_t len); -extern void dw_spi_isr(DEV_SPI *spi_obj, void *ptr); -/** @} */ - -#ifdef __cplusplus -} -#endif - -/** @} */ - -#endif /* _DEVICE_DW_SPI_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h b/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h deleted file mode 100644 index b1a233c699..0000000000 --- a/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal.h +++ /dev/null @@ -1,141 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-06-25 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup DEVICE_DW_SPI - * \brief DesignWare SPI driver hardware description related header file - * \details detailed hardware related definitions of DesignWare SPI driver - */ - -#ifndef _DEVICE_DW_SPI_HAL_H_ -#define _DEVICE_DW_SPI_HAL_H_ - -#include "device/designware/spi/dw_spi_hal_cfg.h" - -/* DW APB SPI bit definitions */ - -/** - * \name DesignWare SPI HAL CTRL0 Macros - * \brief DesignWare SPI hal ctrl0 macros, - * include dfs, scph, scppl, tmod, etc - * @{ - */ -#define DW_SPI_CTRLR0_DFS_MASK (0xf) - -#define DW_SPI_CTRLR0_SC_OFS (6) -#define DW_SPI_CTRLR0_SC_MASK (0xC0) -#define DW_SPI_CTRLR0_SCPH_HIGH (0x40) -#define DW_SPI_CTRLR0_SCPH_LOW (0) -#define DW_SPI_CTRLR0_SCPOL_HIGH (0x80) -#define DW_SPI_CTRLR0_SCPOL_LOW (0) - -#define DW_SPI_CTRLR0_TMOD_MASK (0x300) -#define DW_SPI_TMOD_TRANSMIT_RECEIVE (0) -#define DW_SPI_TMOD_TRANSMIT_ONLY (0x100) -#define DW_SPI_TMOD_RECEIVE_ONLY (0x200) -#define DW_SPI_TMOD_EEPROM_READ_ONLY (0x300) - -#define DW_SPI_CTRLR0_FRF_MOTOROLA (0x0) -#define DW_SPI_CTRLR0_FRF_TI (0x10) -#define DW_SPI_CTRLR0_FRF_MICROWIRE (0x20) - -#define DW_SPI_CTRLR0_SLV_OE_DISABLE (1<<10) -#define DW_SPI_CTRLR0_SLV_OE_ENABLE (0) - - -/** @} */ - -/** - * \name DesignWare SPI HAL ISR Flags - * \brief DesignWare SPI hal Interrupt Status Flags - * @{ - */ -#define DW_SPI_TX_OVERFLOW_ERROR (0x2) -#define DW_SPI_RX_UNDERFLOW_ERROR (0x4) -#define DW_SPI_RX_OVERFLOW_ERROR (0x8) - -#define DW_SPI_ISR_RX_FIFO_INT_MASK (0x10) -#define DW_SPI_ISR_TX_FIFO_INT_MASK (0x1) -#define DW_SPI_ISR_TX_OVERFLOW_INT_MASK (0x2) -#define DW_SPI_ISR_RX_UNDERFLOW_INT_MASK (0x4) -#define DW_SPI_ISR_RX_OVERFLOW_INT_MASK (0x8) -/** @} */ - -/** - * \name DesignWare SPI HAL SR Flags - * \brief DesignWare SPI hal Status Flags - * @{ - */ -#define DW_SPI_SR_DCOL (0x40) -#define DW_SPI_SR_TXE (0x20) -#define DW_SPI_SR_RFF (0x10) -#define DW_SPI_SR_RFNE (0x8) -#define DW_SPI_SR_TFE (0x4) -#define DW_SPI_SR_TFNF (0x2) -#define DW_SPI_SR_BUSY (0x1) -/** @} */ - -/** - * \name DesignWare SPI HAL SSI Enable Macros - * \brief DesignWare SPI hal ssi enable macros - * @{ - */ -/* Macros */ -#define DW_SPI_SSI_ENABLE (1) /*!< SSI Enable */ -#define DW_SPI_SSI_DISABLE (0) /*!< SSI Disable */ -/** @} */ - -/** - * \name DesignWare SPI HAL IMR Macros - * \brief DesignWare SPI hal interrupt mask macros - * @{ - */ -#define DW_SPI_IMR_MSTIM (0x20) /*!< Multi-Master Contention Interrupt Mask */ -#define DW_SPI_IMR_RXFIM (0x10) /*!< Receive FIFO Full Interrupt Mask */ -#define DW_SPI_IMR_RXOIM (0x08) /*!< Receive FIFO Overflow Interrupt Mask */ -#define DW_SPI_IMR_RXUIM (0x04) /*!< Receive FIFO Underflow Interrupt Mask */ -#define DW_SPI_IMR_TXOIM (0x02) /*!< Transmit FIFO Overflow Interrupt Mask */ -#define DW_SPI_IMR_TXEIM (0x01) /*!< Transmit FIFO Empty Interrupt Mask */ - -#define DW_SPI_IMR_XFER (DW_SPI_IMR_TXEIM|DW_SPI_IMR_RXFIM|DW_SPI_IMR_TXOIM|DW_SPI_IMR_RXOIM|DW_SPI_IMR_RXUIM) -/** @} */ - -#define DW_SPI_SSI_IDLE (1) -#define DW_SPI_SPI_TRANSMIT (1) -#define DW_SPI_SPI_RECEIVE (2) -#define DW_SPI_SSI_MASTER (1) -#define DW_SPI_SSI_SLAVE (0) - - -#endif /* _DEVICE_DW_SPI_HAL_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h b/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h deleted file mode 100644 index d6caf71466..0000000000 --- a/bsp/synopsys/embarc/device/designware/spi/dw_spi_hal_cfg.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2015-09-09 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup DEVICE_DW_SPI - * \brief DesignWare SPI driver hardware description - * related header file configuration file - * \details configuration file to enable or disable some function of spi - */ - -#ifndef _DEVICE_DW_SPI_HAL_CFG_H_ -#define _DEVICE_DW_SPI_HAL_CFG_H_ - -#ifndef DW_SPI_CALC_FIFO_LEN_ENABLE -#define DW_SPI_CALC_FIFO_LEN_ENABLE (1) /*!< Defaultly enable calculate fifo length */ -#endif - -#ifndef DW_SPI_MAX_FIFO_LENGTH -#define DW_SPI_MAX_FIFO_LENGTH (256) /*!< Max FIFO depth for designware SPI device */ -#endif - -#ifndef DW_SPI_MIN_FIFO_LENGTH -#define DW_SPI_MIN_FIFO_LENGTH (2) /*!< Min FIFO depth for designware SPI device */ -#endif - -#endif /* _DEVICE_DW_SPI_HAL_CFG_H_ */ - diff --git a/bsp/synopsys/embarc/device/designware/uart/dw_uart.c b/bsp/synopsys/embarc/device/designware/uart/dw_uart.c deleted file mode 100644 index 999ee751e0..0000000000 --- a/bsp/synopsys/embarc/device/designware/uart/dw_uart.c +++ /dev/null @@ -1,956 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-20 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \defgroup DEVICE_DW_UART Designware UART Driver - * \ingroup DEVICE_DW - * \brief Designware UART Driver Implementation - */ - -/** - * \file - * \ingroup DEVICE_DW_UART - * \brief DesignWare UART driver implementation based on device hal layer definition (\ref dev_uart.h) - */ -#include - -#include "inc/embARC_toolchain.h" -#include "inc/embARC_error.h" - -#include "inc/arc/arc_exception.h" - -#include "device/designware/uart/dw_uart_hal.h" -#include "device/designware/uart/dw_uart.h" - - -/** - * \name DesignWare UART Driver Macros - * \brief DesignWare UART driver macros used in uart driver - * @{ - */ -/** check expressions used in DesignWare UART driver implementation */ -#define DW_UART_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit) - -#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK -/** valid check of uart info object */ -#define VALID_CHK_UART_INFO_OBJECT(uartinfo_obj_ptr) { \ - DW_UART_CHECK_EXP((uartinfo_obj_ptr)!=NULL, E_OBJ); \ - DW_UART_CHECK_EXP(((uartinfo_obj_ptr)->uart_ctrl)!=NULL, E_OBJ); \ - } -#endif - -/** convert DesignWare baudrate to divisor */ -#define DW_UART_BAUD2DIV(perifreq, baud) ((perifreq) / ((baud)*16)) - -/** - * \name DesignWare UART Interrupt Callback Routine Select Marcos - * \brief DesignWare UART interrupt callback routines select macros definitions - * @{ - */ -#define DW_UART_RDY_SND (1U) /*!< ready to send callback */ -#define DW_UART_RDY_RCV (2U) /*!< ready to receive callback */ -/** @} */ - -/** @} */ - -/** - * \defgroup DEVICE_DW_UART_STATIC DesignWare UART Driver Static Functions - * \ingroup DEVICE_DW_UART - * \brief Static or inline functions, variables for DesignWare UART handle uart operations, - * only used in this file - * @{ - */ -const uint8_t dw_uart_databits[] = { \ - DW_UART_LCR_WORD_LEN5, DW_UART_LCR_WORD_LEN6, \ - DW_UART_LCR_WORD_LEN7, DW_UART_LCR_WORD_LEN8}; -const uint8_t dw_uart_parity[] = { - DW_UART_LCR_PARITY_NONE, DW_UART_LCR_PARITY_ODD, - DW_UART_LCR_PARITY_EVEN, DW_UART_LCR_PARITY_MASK, - DW_UART_LCR_PARITY_SPACE -}; -const uint8_t dw_uart_stopbits[] = { - DW_UART_LCR_1_STOP_BIT, DW_UART_LCR_1D5_STOP_BIT, - DW_UART_LCR_2_STOP_BIT -}; - -/** test whether uart is ready to send, 1 ready, 0 not ready */ -Inline int32_t dw_uart_putready(DW_UART_REG *uart_reg_ptr) -{ - return ((uart_reg_ptr->USR & DW_UART_USR_TFNF) != 0); -} -/** test whether uart is ready to receive, 1 ready, 0 not ready */ -Inline int32_t dw_uart_getready(DW_UART_REG *uart_reg_ptr) -{ - return ((uart_reg_ptr->USR & DW_UART_USR_RFNE) != 0); -} -/** write char to uart send fifo */ -Inline void dw_uart_putchar(DW_UART_REG *uart_reg_ptr, char chr) -{ - uart_reg_ptr->DATA = chr; -} -/** read data from uart receive fifo, return data received */ -Inline int32_t dw_uart_getchar(DW_UART_REG *uart_reg_ptr) -{ - return (int32_t)uart_reg_ptr->DATA; -} -/** - * \brief send char by uart when available, - * mostly used in interrupt method, non-blocked function - * \param[in] uart_reg_ptr uart register structure pointer - * \param[in] chr char to be sent - * \retval 0 send successfully - * \retval -1 not ready to send data - */ -Inline int32_t dw_uart_snd_chr(DW_UART_REG *uart_reg_ptr, char chr) -{ - if (dw_uart_putready(uart_reg_ptr)) { - dw_uart_putchar(uart_reg_ptr, chr); - return 0; - } - return -1; -} -/** - * \brief receive one char from uart, - * mostly used in interrupt routine, non-blocked function - * \param[in] uart_reg_ptr uart register structure pointer - * \return data received by the uart - */ -Inline int32_t dw_uart_rcv_chr(DW_UART_REG *uart_reg_ptr) -{ - return dw_uart_getchar(uart_reg_ptr); -} -/** - * \brief send char by uart in poll method, blocked function - * \param[in] uart_reg_ptr uart register structure pointer - * \param[in] chr char to be sent - */ -Inline void dw_uart_psnd_chr(DW_UART_REG *uart_reg_ptr, char chr) -{ - /** wait until uart is ready to send */ - while (!dw_uart_putready(uart_reg_ptr)); /* blocked */ - /** send char */ - dw_uart_putchar(uart_reg_ptr, chr); -} -/** - * \brief receive one char from uart in poll method, blocked function - * \param[in] uart_reg_ptr uart register structure pointer - * \return data received by the uart - */ -Inline int32_t dw_uart_prcv_chr(DW_UART_REG *uart_reg_ptr) -{ - /** wait until uart is ready to receive */ - while (!dw_uart_getready(uart_reg_ptr)); /* blocked */ - /** receive data */ - return dw_uart_getchar(uart_reg_ptr); -} - -/** Get TX FIFO Length */ -Inline uint32_t dw_uart_get_txfifo_len(DW_UART_REG *uart_reg_ptr) -{ - uint32_t txfifolen; - uint32_t uart_cpr; - - uart_cpr = uart_reg_ptr->CPR; - if (uart_cpr & DW_UART_CPR_FIFO_STAT) { - txfifolen = ((uart_cpr & DW_UART_CPR_FIFO_MODE) >> DW_UART_CPR_FIFO_MODE_OFS) << 4; - } else { - txfifolen = 0; - } - - return txfifolen; -} - -/** Get RX FIFO Length */ -Inline uint32_t dw_uart_get_rxfifo_len(DW_UART_REG *uart_reg_ptr) -{ - uint32_t rxfifolen; - uint32_t uart_cpr; - - uart_cpr = uart_reg_ptr->CPR; - if (uart_cpr & DW_UART_CPR_FIFO_STAT) { - rxfifolen = ((uart_cpr & DW_UART_CPR_FIFO_MODE) >> DW_UART_CPR_FIFO_MODE_OFS) << 4; - } else { - rxfifolen = 0; - } - - return rxfifolen; -} - -/** - * \brief set designware uart DPS value - * \param uart_reg_ptr uart register structure - * \param dps data bits/parity bit/stop bits parameter - * \retval 0 Set ok - * \retval !0 Set failed - */ -static int32_t dw_uart_set_dps(DW_UART_REG *uart_reg_ptr, UART_DPS_FORMAT *dps) -{ - uint32_t dps_value = 0; - - if (dps == NULL) return -1; - /* data bits check */ - if ((dps->databits < 5) || (dps->databits > 8)) return -1; - /* stop bits check */ - if (dps->stopbits > UART_STPBITS_TWO) return -1; - /* parity bit type check */ - if (dps->parity > UART_PARITY_SPACE) return -1; - - dps_value |= (uint32_t)dw_uart_databits[dps->databits-5]; - dps_value |= (uint32_t)dw_uart_stopbits[dps->stopbits]; - dps_value |= (uint32_t)dw_uart_parity[dps->parity]; - - /* clear dps bits */ - uart_reg_ptr->LCR &= (~DW_UART_LCR_DPS_MASK); - /* set dps bits */ - uart_reg_ptr->LCR |= dps_value; - - return 0; -} - -/** - * \brief set designware uart baudrate - * \param uart_reg_ptr uart register structure - * \param baud_divisor uart baudrate divisor - */ -static void dw_uart_set_baud(DW_UART_REG *uart_reg_ptr, uint32_t baud_divisor) -{ - /* enable uart baudrate update */ - uart_reg_ptr->LCR |= DW_UART_LCR_DLAB; - /** - * setting uart baudrate registers - */ - uart_reg_ptr->DATA = baud_divisor & 0xff; /*!< DLL */ - uart_reg_ptr->IER = (baud_divisor>>8) & 0xff; /*!< DLH */ - /** disable DLAB */ - uart_reg_ptr->LCR &= ~(DW_UART_LCR_DLAB); -} - -/** - * \brief Do uart software reset - * \param uart_reg_ptr uart register structure - */ -Inline void dw_uart_software_reset(DW_UART_REG *uart_reg_ptr) -{ - uart_reg_ptr->SRR = DW_UART_SRR_UR|DW_UART_SRR_RFR|DW_UART_SRR_XFR; - while(uart_reg_ptr->USR & DW_UART_USR_BUSY); /* wait until software reset completed */ -} - -/** - * \brief set designware uart baudrate - * \param uart_reg_ptr uart register structure - * \param hwfc uart hardware flow control type - * \note Need to set corresponding pin functions - */ -static void dw_uart_set_hwfc(DW_UART_REG *uart_reg_ptr, UART_HW_FLOW_CONTROL hwfc) -{ - if (hwfc == UART_FC_NONE) { - uart_reg_ptr->MCR &= ~(DW_UART_MCR_AFCE|DW_UART_MCR_RTS); - } - if ((hwfc == UART_FC_RTS) || (hwfc == UART_FC_BOTH)) { - uart_reg_ptr->MCR |= (DW_UART_MCR_AFCE|DW_UART_MCR_RTS); - } - if ((hwfc == UART_FC_CTS) || (hwfc == UART_FC_BOTH)) { - uart_reg_ptr->MCR |= (DW_UART_MCR_AFCE); - } -} - -Inline void dw_uart_set_break(DW_UART_REG *uart_reg_ptr) -{ - uart_reg_ptr->LCR |= DW_UART_LCR_BREAK; -} - -Inline void dw_uart_clr_break(DW_UART_REG *uart_reg_ptr) -{ - uart_reg_ptr->LCR &= ~DW_UART_LCR_BREAK; -} - -/** - * \brief init designware uart with selected baud - * \param[in] uart_reg_ptr uart register structure pointer - * \param[in] baud_divisor baudrate divisor - */ -static void dw_uart_init(DW_UART_REG *uart_reg_ptr, uint32_t baud_divisor, UART_DPS_FORMAT *dps, UART_HW_FLOW_CONTROL hwfc) -{ - dw_uart_software_reset(uart_reg_ptr); - - dw_uart_set_hwfc(uart_reg_ptr, hwfc); - dw_uart_set_dps(uart_reg_ptr, dps); - dw_uart_set_baud(uart_reg_ptr, baud_divisor); - - uart_reg_ptr->IIR = 0x1; /** enable uart fifo (FCR IIR is the same) */ - uart_reg_ptr->IER = 0x0; /** disable all uart interrupt */ -} - -/** - * \brief set designware uart baudrate - * \param uart_info_ptr uart information structure pointer - */ -static void dw_uart_flush_output(DEV_UART_INFO *uart_info_ptr) -{ - uint32_t i; - char *p_charbuf; - - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - if (uart_info_ptr->tx_buf.buf != NULL) { - p_charbuf = (char *)(uart_info_ptr->tx_buf.buf); - for (i = uart_info_ptr->tx_buf.ofs; i < uart_info_ptr->tx_buf.len; i ++) { - dw_uart_psnd_chr(uart_reg_ptr, p_charbuf[i]); - } - /* clear transmit buffer */ - uart_info_ptr->tx_buf.buf = NULL; - uart_info_ptr->tx_buf.len = 0; - uart_info_ptr->tx_buf.ofs = 0; - } - /* wait until transmit fifo is empty */ - while ((uart_reg_ptr->USR & DW_UART_USR_TFE) == 0); - while (uart_reg_ptr->USR & DW_UART_USR_BUSY); -} - -/** - * \brief disable designware uart send or receive interrupt - * \param[in] DEV_UART_INFO *uart_info_ptr - * \param[in] cbrtn control code of callback routine of send or receive - */ -static void dw_uart_dis_cbr(DEV_UART_INFO *uart_info_ptr, uint32_t cbrtn) -{ - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - switch (cbrtn) { - case DW_UART_RDY_SND: - uart_reg_ptr->IER &= ~DW_UART_IER_XMIT_EMPTY; - uart_ctrl_ptr->int_status &= ~DW_UART_TXINT_ENABLE; - break; - case DW_UART_RDY_RCV: - uart_reg_ptr->IER &= ~DW_UART_IER_DATA_AVAIL; - uart_ctrl_ptr->int_status &= ~DW_UART_RXINT_ENABLE; - break; - default: - break; - } - if (uart_ctrl_ptr->int_status & DW_UART_GINT_ENABLE) { - if ((uart_ctrl_ptr->int_status & (DW_UART_RXINT_ENABLE|DW_UART_TXINT_ENABLE)) == 0) { - int_disable(uart_ctrl_ptr->intno); - uart_ctrl_ptr->int_status &= ~DW_UART_GINT_ENABLE; - } - } -} - -/** - * \brief enable DesignWare UART send or receive interrupt - * \param[in] DEV_UART_INFO *uart_info_ptr - * \param[in] cbrtn control code of callback routine of send or receive - */ -static void dw_uart_ena_cbr(DEV_UART_INFO *uart_info_ptr, uint32_t cbrtn) -{ - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - switch (cbrtn) { - case DW_UART_RDY_SND: - uart_ctrl_ptr->int_status |= DW_UART_TXINT_ENABLE; - uart_reg_ptr->IER |= DW_UART_IER_XMIT_EMPTY; - break; - case DW_UART_RDY_RCV: - uart_ctrl_ptr->int_status |= DW_UART_RXINT_ENABLE; - uart_reg_ptr->IER |= DW_UART_IER_DATA_AVAIL; - break; - default: - break; - } - if ((uart_ctrl_ptr->int_status & DW_UART_GINT_ENABLE) == 0) { - if (uart_ctrl_ptr->int_status & (DW_UART_RXINT_ENABLE|DW_UART_TXINT_ENABLE)) { - uart_ctrl_ptr->int_status |= DW_UART_GINT_ENABLE; - int_enable(uart_ctrl_ptr->intno); - } - } -} - -/** - * \brief enable designware uart interrupt - * \param uart_info_ptr uart information structure pointer - */ -static void dw_uart_enable_interrupt(DEV_UART_INFO *uart_info_ptr) -{ - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - - int_handler_install(uart_ctrl_ptr->intno, uart_ctrl_ptr->dw_uart_int_handler); - uart_ctrl_ptr->int_status |= DW_UART_GINT_ENABLE; - int_enable(uart_ctrl_ptr->intno); /** enable uart interrupt */ -} -/** - * \brief disable designware uart interrupt - * \param uart_info_ptr uart information structure pointer - */ -static void dw_uart_disable_interrupt(DEV_UART_INFO *uart_info_ptr) -{ - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - - /** disable uart send&receive interrupt after disable uart interrupt */ - dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND); - dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV); - /* disable uart interrupt */ - int_disable(uart_ctrl_ptr->intno); - uart_ctrl_ptr->int_status &= ~(DW_UART_GINT_ENABLE|DW_UART_TXINT_ENABLE|DW_UART_RXINT_ENABLE); -} - -/** enable designware uart */ -static void dw_uart_enable_device(DEV_UART_INFO *uart_info_ptr) -{ - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - if ((uart_info_ptr->status & DEV_ENABLED) == 0) { - dw_uart_set_baud(uart_reg_ptr, uart_info_ptr->baudrate); - uart_info_ptr->status |= DEV_ENABLED; - } -} - -/** disable designware uart */ -static void dw_uart_disable_device(DEV_UART_INFO *uart_info_ptr) -{ - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - if ((uart_info_ptr->status & DEV_ENABLED) == DEV_ENABLED) { - dw_uart_set_baud(uart_reg_ptr, 0); - uart_info_ptr->status &= ~DEV_ENABLED; - } -} - -/** abort current interrupt transmit transfer */ -static void dw_uart_abort_tx(DEV_UART *uart_obj) -{ - DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - - if (uart_ctrl_ptr->int_status & DW_UART_TXINT_ENABLE) { - dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND); - uart_info_ptr->status |= DEV_IN_TX_ABRT; - if (uart_info_ptr->uart_cbs.tx_cb != NULL) { - uart_info_ptr->uart_cbs.tx_cb(uart_obj); - } - uart_info_ptr->status &= ~(DEV_IN_TX_ABRT); - } -} - -/** abort current interrupt receive transfer */ -static void dw_uart_abort_rx(DEV_UART *uart_obj) -{ - DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - - if (uart_ctrl_ptr->int_status & DW_UART_RXINT_ENABLE) { - dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV); - uart_info_ptr->status |= DEV_IN_RX_ABRT; - if (uart_info_ptr->uart_cbs.rx_cb != NULL) { - uart_info_ptr->uart_cbs.rx_cb(uart_obj); - } - uart_info_ptr->status &= ~(DEV_IN_RX_ABRT); - } -} - -/** Get available transmit fifo count */ -static int32_t dw_uart_get_txavail(DW_UART_CTRL *uart_ctrl_ptr) -{ - int32_t tx_avail = 0; - DW_UART_REG *uart_reg_ptr = (DW_UART_REG *)(uart_ctrl_ptr->dw_uart_regbase); - - if (uart_ctrl_ptr->tx_fifo_len <= 1) { - if (dw_uart_putready(uart_reg_ptr) == 1) { - tx_avail = 1; - } else { - tx_avail = 0; - } - } else { - tx_avail = uart_ctrl_ptr->tx_fifo_len - uart_reg_ptr->TFL; - } - return tx_avail; -} - -/** Get available receive fifo count */ -static int32_t dw_uart_get_rxavail(DW_UART_CTRL *uart_ctrl_ptr) -{ - int32_t rx_avail = 0; - DW_UART_REG *uart_reg_ptr = (DW_UART_REG *)(uart_ctrl_ptr->dw_uart_regbase); - - if (uart_ctrl_ptr->rx_fifo_len <= 1) { - if (dw_uart_getready(uart_reg_ptr) == 1) { - rx_avail = 1; - } else { - rx_avail = 0; - } - } else { - rx_avail = uart_reg_ptr->RFL; - } - return rx_avail; -} - - -/** @} end of group DEVICE_DW_UART_STATIC */ - -/** - * \brief open a designware uart device - * \param[in] uart_obj uart object structure pointer - * \param[in] baud baudrate to initialized - * \retval E_OK Open successfully without any issues - * \retval E_OPNED If device was opened before with different baudrate, then return E_OPNED - * \retval E_OBJ Device object is not valid - * \retval E_PAR Parameter is not valid - * \retval E_NOSPT Open settings are not supported - */ -int32_t dw_uart_open (DEV_UART *uart_obj, uint32_t baud) -{ - int32_t ercd = E_OK; - DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); - - /* START ERROR CHECK */ - VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); - DW_UART_CHECK_EXP(baud>0, E_PAR); - /* END OF ERROR CHECK */ - - uart_info_ptr->opn_cnt ++; - if (uart_info_ptr->opn_cnt > 1) { /* opened before */ - if (baud == uart_info_ptr->baudrate) { /* baudrate is the same */ - return E_OK; - } else { /* open with different baudrate */ - return E_OPNED; - } - } - - int32_t baud_divisor = 0; - - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - /* Get FIFO Length */ - uart_ctrl_ptr->tx_fifo_len = dw_uart_get_txfifo_len(uart_reg_ptr); - uart_ctrl_ptr->rx_fifo_len = dw_uart_get_rxfifo_len(uart_reg_ptr); - - /** init uart */ - uart_info_ptr->baudrate = baud; - baud_divisor = DW_UART_BAUD2DIV(uart_ctrl_ptr->dw_apb_bus_freq, baud); - uart_info_ptr->dps_format = dps_format_default; - uart_info_ptr->hwfc = hwfc_default; - dw_uart_init(uart_reg_ptr, baud_divisor, &(uart_info_ptr->dps_format), uart_info_ptr->hwfc); - - uart_info_ptr->status = DEV_ENABLED; - uart_info_ptr->extra = NULL; - - /** - * uart interrupt related init - */ - dw_uart_disable_interrupt(uart_info_ptr); - /** install uart interrupt into system */ - int_handler_install(uart_ctrl_ptr->intno, uart_ctrl_ptr->dw_uart_int_handler); - - memset(&(uart_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER)); - memset(&(uart_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER)); - memset(&(uart_info_ptr->uart_cbs), 0, sizeof(DEV_UART_CBS)); - -error_exit: - return ercd; -} - -/** - * \brief close a DesignWare UART device - * \param[in] uart_obj uart object structure pointer - * \retval E_OK Open successfully without any issues - * \retval E_OPNED Device is still opened, the device opn_cnt decreased by 1 - * \retval E_OBJ Device object is not valid - */ -int32_t dw_uart_close (DEV_UART *uart_obj) -{ - int32_t ercd = E_OK; - DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); - - /* START ERROR CHECK */ - VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); - DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_OK); - /* END OF ERROR CHECK */ - - uart_info_ptr->opn_cnt --; - if (uart_info_ptr->opn_cnt == 0) { - dw_uart_disable_interrupt(uart_info_ptr); - dw_uart_abort_tx(uart_obj); - dw_uart_abort_rx(uart_obj); - dw_uart_flush_output(uart_info_ptr); - memset(&(uart_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER)); - memset(&(uart_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER)); - memset(&(uart_info_ptr->uart_cbs), 0, sizeof(DEV_UART_CBS)); - dw_uart_disable_device(uart_info_ptr); - uart_info_ptr->status = 0; - uart_info_ptr->extra = NULL; - } else { - ercd = E_OPNED; - } - -error_exit: - return ercd; -} - -/** - * \brief control uart by ctrl command - * \param[in] uart_obj uart object structure pointer - * \param[in] ctrl_cmd control command code to do specific uart work - * \param[in,out] param parameters used to control uart or return something - * \retval E_OK Control device successfully - * \retval E_CLSED Device is not opened - * \retval E_DIS Device is disabled - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Control device failed, due to hardware issues - * \retval E_CTX Control device failed, due to different reasons like in transfer state - * \retval E_NOSPT Control command is not supported or not valid - */ -int32_t dw_uart_control (DEV_UART *uart_obj, uint32_t ctrl_cmd, void *param) -{ - int32_t ercd = E_OK; - DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); - - /* START ERROR CHECK */ - VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); - DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_CLSED); - /* END OF ERROR CHECK */ - - uint32_t val32; /** to receive unsigned int value */ - int32_t baud_divisor = 0; - DEV_BUFFER *devbuf; - UART_DPS_FORMAT *dps_ptr; - UART_HW_FLOW_CONTROL hwfc_local; - - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - /* check whether current device is disabled */ - if ((uart_info_ptr->status & DEV_ENABLED) == 0) { - /** When device is disabled, - * only UART_CMD_ENA_DEV, UART_CMD_DIS_DEV, UART_CMD_GET_STATUS - * are available, other commands will return E_SYS - */ - if ((ctrl_cmd != UART_CMD_ENA_DEV) && \ - (ctrl_cmd != UART_CMD_DIS_DEV) && \ - (ctrl_cmd != UART_CMD_GET_STATUS) ) { - return E_SYS; - } - } - - switch (ctrl_cmd) { - case UART_CMD_SET_BAUD: - val32 = (uint32_t)param; - DW_UART_CHECK_EXP(val32>0, E_PAR); - if (val32 != uart_info_ptr->baudrate) { - baud_divisor = DW_UART_BAUD2DIV(uart_ctrl_ptr->dw_apb_bus_freq, val32); - dw_uart_set_baud(uart_reg_ptr, baud_divisor); - uart_info_ptr->baudrate = val32; - } - break; - case UART_CMD_GET_STATUS: - DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = uart_info_ptr->status; - break; - case UART_CMD_ENA_DEV: - dw_uart_enable_device(uart_info_ptr); - break; - case UART_CMD_DIS_DEV: - dw_uart_disable_device(uart_info_ptr); - break; - case UART_CMD_FLUSH_OUTPUT: - dw_uart_flush_output(uart_info_ptr); - break; - case UART_CMD_GET_RXAVAIL: - DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = dw_uart_get_rxavail(uart_ctrl_ptr); - break; - case UART_CMD_GET_TXAVAIL: - DW_UART_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR); - *((int32_t *)param) = dw_uart_get_txavail(uart_ctrl_ptr); - break; - case UART_CMD_BREAK_SET: - dw_uart_set_break(uart_reg_ptr); - break; - case UART_CMD_BREAK_CLR: - dw_uart_clr_break(uart_reg_ptr); - break; - case UART_CMD_SET_DPS_FORMAT: - DW_UART_CHECK_EXP(param!=NULL, E_PAR); - dps_ptr = (UART_DPS_FORMAT *)param; - if (dw_uart_set_dps(uart_reg_ptr, dps_ptr) == 0) { - uart_info_ptr->dps_format = *dps_ptr; - } else { - ercd = E_PAR; - } - break; - case UART_CMD_SET_HWFC: - hwfc_local = (UART_HW_FLOW_CONTROL)param; - DW_UART_CHECK_EXP(((hwfc_local>=UART_FC_NONE) && (hwfc_local<=UART_FC_BOTH)), E_PAR); - dw_uart_set_hwfc(uart_reg_ptr, hwfc_local); - uart_info_ptr->hwfc = hwfc_local; - break; - case UART_CMD_SET_TXCB: - DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - uart_info_ptr->uart_cbs.tx_cb = param; - break; - case UART_CMD_SET_RXCB: - DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - uart_info_ptr->uart_cbs.rx_cb = param; - break; - case UART_CMD_SET_ERRCB: - DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - uart_info_ptr->uart_cbs.err_cb = param; - break; - case UART_CMD_ABORT_TX: - dw_uart_abort_tx(uart_obj); - break; - case UART_CMD_ABORT_RX: - dw_uart_abort_rx(uart_obj); - break; - case UART_CMD_SET_TXINT: - val32 = (uint32_t)param; - if (val32 == 0) { - dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND); - } else { - dw_uart_ena_cbr(uart_info_ptr, DW_UART_RDY_SND); - } - break; - case UART_CMD_SET_RXINT: - val32 = (uint32_t)param; - if (val32 == 0) { - dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV); - } else { - dw_uart_ena_cbr(uart_info_ptr, DW_UART_RDY_RCV); - } - break; - case UART_CMD_SET_TXINT_BUF: - DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - if (param != NULL) { - devbuf = (DEV_BUFFER *)param; - uart_info_ptr->tx_buf = *devbuf; - uart_info_ptr->tx_buf.ofs = 0; - } else { - uart_info_ptr->tx_buf.buf = NULL; - uart_info_ptr->tx_buf.len = 0; - uart_info_ptr->tx_buf.ofs = 0; - } - break; - case UART_CMD_SET_RXINT_BUF: - DW_UART_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR); - if (param != NULL) { - devbuf = (DEV_BUFFER *)param; - uart_info_ptr->rx_buf = *devbuf; - uart_info_ptr->rx_buf.ofs = 0; - } else { - uart_info_ptr->rx_buf.buf = NULL; - uart_info_ptr->rx_buf.len = 0; - uart_info_ptr->rx_buf.ofs = 0; - } - break; - default: - ercd = E_NOSPT; - break; - } - -error_exit: - return ercd; -} - -/** - * \brief send data through DesignWare UART - * \param[in] uart_obj uart object structure pointer - * \param[in] data data that need to send (data must be char type) - * \param[in] len data length need to send - * \retval >0 Byte count that was successfully sent for poll method - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Can't write data to hardware due to hardware issues - */ -int32_t dw_uart_write (DEV_UART *uart_obj, const void *data, uint32_t len) -{ - int32_t ercd = E_OK; - DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); - - /* START ERROR CHECK */ - VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); - DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_CLSED); - DW_UART_CHECK_EXP(uart_info_ptr->status & DEV_ENABLED, E_SYS); - DW_UART_CHECK_EXP(data!=NULL, E_PAR); - DW_UART_CHECK_EXP(len>0, E_PAR); - /* END OF ERROR CHECK */ - - int32_t i = 0; - const char *p_charbuf = (const char *)data; - - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - while (i < len) { - dw_uart_psnd_chr(uart_reg_ptr, p_charbuf[i++]); - } - ercd = i; - -error_exit: - return ercd; -} - -/** - * \brief read data through DesignWare UART - * \param[in] uart_obj uart object structure pointer - * \param[out] data data that need to read (data must be char type) - * \param[in] len data count need to read - * \retval >0 Byte count that was successfully sent for poll method - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled - */ -int32_t dw_uart_read (DEV_UART *uart_obj, void *data, uint32_t len) -{ - int32_t ercd = E_OK; - DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); - - /* START ERROR CHECK */ - VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); - DW_UART_CHECK_EXP(uart_info_ptr->opn_cnt > 0, E_CLSED); - DW_UART_CHECK_EXP(uart_info_ptr->status & DEV_ENABLED, E_SYS); - DW_UART_CHECK_EXP(data!=NULL, E_PAR); - DW_UART_CHECK_EXP(len>0, E_PAR); - /* END OF ERROR CHECK */ - - int32_t i = 0; - char *p_charbuf = (char *)data; - - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - while (i < len) { - p_charbuf[i++] = dw_uart_prcv_chr(uart_reg_ptr); - } - ercd = i; - -error_exit: - return ercd; -} - -/** - * \brief DesignWare UART interrupt processing routine - * \param[in] uart_obj uart object structure pointer - * \param[in] ptr extra information - */ -void dw_uart_isr (DEV_UART *uart_obj, void *ptr) -{ - int32_t ercd = E_OK; - DEV_UART_INFO *uart_info_ptr = &(uart_obj->uart_info); - - /* START ERROR CHECK */ - VALID_CHK_UART_INFO_OBJECT(uart_info_ptr); - /* END OF ERROR CHECK */ - - uint32_t uart_int_status; /** uart interrupt status */ - volatile uint32_t temp; /** read error status to clear interrupt */ - DEV_BUFFER *buf_ptr; - char *p_charbuf; - - DW_UART_CTRL *uart_ctrl_ptr = (DW_UART_CTRL_PTR)(uart_info_ptr->uart_ctrl); - DW_UART_REG *uart_reg_ptr = (DW_UART_REG_PTR)(uart_ctrl_ptr->dw_uart_regbase); - - /** get uart interrupt status */ - uart_int_status = (uart_reg_ptr->IIR) & DW_UART_IIR_INT_ID_MASK; - - switch (uart_int_status) { - case DW_UART_IIR_MDM_STATUS: - temp = (volatile uint32_t)(uart_reg_ptr->MSR); - break; - case DW_UART_IIR_LINE_STATUS: - if (uart_info_ptr->uart_cbs.err_cb) { - uart_info_ptr->uart_cbs.err_cb(uart_info_ptr); - } - temp = (volatile uint32_t)(uart_reg_ptr->LSR); - break; - case DW_UART_IIR_XMIT_EMPTY: - buf_ptr = &(uart_info_ptr->tx_buf); - p_charbuf = (char *)buf_ptr->buf; - if (p_charbuf != NULL) { - while (dw_uart_putready(uart_reg_ptr)) { - dw_uart_putchar(uart_reg_ptr, p_charbuf[buf_ptr->ofs]); - buf_ptr->ofs ++; - if (buf_ptr->ofs >= buf_ptr->len) { - dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_SND); - if (uart_info_ptr->uart_cbs.tx_cb) { - uart_info_ptr->uart_cbs.tx_cb(uart_obj); - } - /* clear the send buffer pointer */ - memset(buf_ptr, 0, sizeof(DEV_BUFFER)); - break; - } - } - } else { - if (uart_info_ptr->uart_cbs.tx_cb) { - uart_info_ptr->uart_cbs.tx_cb(uart_obj); - } - } - break; - case DW_UART_IIR_RX_TIMEOUT: - temp = dw_uart_getchar(uart_reg_ptr); - break; - case DW_UART_IIR_DATA_AVAIL: - buf_ptr = &(uart_info_ptr->rx_buf); - p_charbuf = (char *)buf_ptr->buf; - if (p_charbuf != NULL) { - while (dw_uart_getready(uart_reg_ptr)) { - p_charbuf[buf_ptr->ofs] = (char)dw_uart_getchar(uart_reg_ptr); - buf_ptr->ofs ++; - if (buf_ptr->ofs >= buf_ptr->len) { - dw_uart_dis_cbr(uart_info_ptr, DW_UART_RDY_RCV); - if (uart_info_ptr->uart_cbs.rx_cb) { - uart_info_ptr->uart_cbs.rx_cb(uart_obj); - } - /* clear the send buffer pointer */ - memset(buf_ptr, 0, sizeof(DEV_BUFFER)); - break; - } - } - } else { - if (uart_info_ptr->uart_cbs.rx_cb) { - uart_info_ptr->uart_cbs.rx_cb(uart_obj); - } - } - break; - default: - temp = (volatile uint32_t)(uart_reg_ptr->USR); - break; - } - -error_exit: - return; -} diff --git a/bsp/synopsys/embarc/device/designware/uart/dw_uart.h b/bsp/synopsys/embarc/device/designware/uart/dw_uart.h deleted file mode 100644 index 366c4fccc2..0000000000 --- a/bsp/synopsys/embarc/device/designware/uart/dw_uart.h +++ /dev/null @@ -1,141 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-20 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup DEVICE_DW_UART - * \brief DesignWare UART driver header file - * \details detailed definitions of designware uart driver - */ - -#ifndef _DW_UART_H_ -#define _DW_UART_H_ - -#include "device/device_hal/inc/dev_uart.h" - -#include "inc/arc/arc_exception.h" - -/** - * if this header file is included, - * will indicate that this designware uart device - * is used - */ -#define DEVICE_USE_DESIGNWARE_UART - -/** - * \name DesignWare UART Register Structure - * \brief contains definitions of DesignWare UART register structure. - * @{ - */ -/** - * \brief DesignWare UART register structure - * \details Detailed struct description of DesignWare UART - * block register information, implementation of dev_uart_info::uart_regs - */ -typedef volatile struct dw_uart_reg { - uint32_t DATA; /*!< data in/out and DLL */ - uint32_t IER; /*!< Interrupt enable register and DLH */ - uint32_t IIR; /*!< Interrupt Id register and FCR */ - uint32_t LCR; /*!< Line control Register */ - uint32_t MCR; /*!< Modem control register */ - uint32_t LSR; /*!< Line Status Register */ - uint32_t MSR; /*!< Modem status Register */ - uint32_t SCRATCHPAD; /*!< Uart scratch pad register */ - uint32_t LPDLL; /*!< Low Power Divisor Latch (Low) Reg */ - uint32_t LPDLH; /*!< Low Power Divisor Latch (High) Reg */ - uint32_t RES1[2]; /*!< Reserved */ - uint32_t SHR[16]; /*!< Shadow data register(SRBR and STHR) */ - uint32_t FAR; /*!< FIFO Access register */ - uint32_t TFR; /*!< Transmit FIFO Read */ - uint32_t RFW; /*!< Receive FIFO write */ - uint32_t USR; /*!< UART status register */ - uint32_t TFL; /*!< Transmit FIFO level */ - uint32_t RFL; /*!< Receive FIFO level */ - uint32_t SRR; /*!< Software reset register */ - uint32_t SRTS; /*!< Shadow request to send */ - uint32_t SBCR; /*!< Shadow break control */ - uint32_t SDMAM; /*!< Shadow DMA mode */ - uint32_t SFE; /*!< Shadow FIFO enable */ - uint32_t SRT; /*!< Shadow RCVR Trigger */ - uint32_t STET; /*!< Shadow TX empty register */ - uint32_t HTX; /*!< Halt TX */ - uint32_t DMASA; /*!< DMA Software ACK */ - uint32_t RES2[18]; /*!< Reserved */ - uint32_t CPR; /*!< Camponent parameter register */ - uint32_t UCV; /*!< UART Component Version */ - uint32_t CTR; /*!< Component typw register */ -} DW_UART_REG, *DW_UART_REG_PTR; -/** @} */ - -#define DW_UART_GINT_DISABLED (0) /*!< designware interrupt disabled for control uart irq/fiq */ -#define DW_UART_GINT_ENABLE (1<<0) /*!< designware interrupt enabled for control uart irq/fiq */ -#define DW_UART_TXINT_ENABLE (1<<1) /*!< designware interrupt enabled for control transmit process */ -#define DW_UART_RXINT_ENABLE (1<<2) /*!< designware interrupt enabled for control transmit process */ - -/** - * \brief DesignWare UART control structure definition - * \details implement of dev_uart_info::uart_ctrl - */ -typedef struct dw_uart_ctrl { - uint32_t dw_uart_regbase; /*!< uart ip register base */ - uint32_t dw_apb_bus_freq; /*!< uart ip apb bus frequency */ - uint32_t intno; /*!< uart interrupt vector number */ - INT_HANDLER dw_uart_int_handler; /*!< uart interrupt handler */ - uint32_t tx_fifo_len; /*!< transmit fifo length, set by user in object implementation */ - uint32_t rx_fifo_len; /*!< receive fifo length, set by user in object implementation */ - uint32_t int_status; /*!< interrupt status for designware uart */ -} DW_UART_CTRL, *DW_UART_CTRL_PTR; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name DesignWare UART Function Declaration - * \brief contains declarations of designware uart functions. - * \details This are only used in uart object implementation source file - * @{ - */ -extern int32_t dw_uart_open (DEV_UART *uart_obj, uint32_t baud); -extern int32_t dw_uart_close (DEV_UART *uart_obj); -extern int32_t dw_uart_control (DEV_UART *uart_obj, uint32_t ctrl_cmd, void *param); -extern int32_t dw_uart_write (DEV_UART *uart_obj, const void *data, uint32_t len); -extern int32_t dw_uart_read (DEV_UART *uart_obj, void *data, uint32_t len); -extern void dw_uart_isr(DEV_UART *uart_obj, void *ptr); -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* _DW_UART_H_ */ diff --git a/bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h b/bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h deleted file mode 100644 index 367894df99..0000000000 --- a/bsp/synopsys/embarc/device/designware/uart/dw_uart_hal.h +++ /dev/null @@ -1,253 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-20 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup DEVICE_DW_IIC - * \brief DesignWare UART driver hardware description related header file - * \details detailed hardware related definitions of DesignWare UART driver - */ - -#ifndef _DEVICE_DW_UART_HAL_H_ -#define _DEVICE_DW_UART_HAL_H_ - -/* DW APB UART bit definitions */ - -/** - * \name DesignWare UART HAL IER Marcos - * \brief DesignWare UART hal IER related macros - * @{ - */ -/* IER */ -#define DW_UART_IER_DATA_AVAIL (0x01) -#define DW_UART_IER_XMIT_EMPTY (0x02) -#define DW_UART_IER_LINE_STATUS (0x04) -#define DW_UART_IER_MDM_STATUS (0x08) -#define DW_UART_IER_PTIME (0x80) -/** @} */ - -/** - * \name DesignWare UART HAL IIR Marcos - * \brief DesignWare UART hal IIR related macros - * @{ - */ -/* IIR */ -/* IIR READ */ -#define DW_UART_IIR_IP (0x01) -#define DW_UART_IIR_MASK (0x0E) -#define DW_UART_IIR_READ_FIFO_ENABLE (0xC0) - -/* Possible interrupt IIR_MASK values */ -#define DW_UART_IIR_MDM_STATUS (0x00) -#define DW_UART_IIR_XMIT_EMPTY (0x02) -#define DW_UART_IIR_DATA_AVAIL (0x04) -#define DW_UART_IIR_LINE_STATUS (0x06) -#define DW_UART_IIR_RX_TIMEOUT (0x0C) -#define DW_UART_IIR_INT_ID_MASK (0x0f) - -/* IIR WRITE */ -#define DW_UART_IIR_FIFO_ENABLE (0x01) -#define DW_UART_IIR_RCVR_FIFO_RESET (0x02) -#define DW_UART_IIR_XMIT_FIFO_RESET (0x04) -#define DW_UART_IIR_DMA_MODE_SELECT (0x08) -#define DW_UART_IIR_RCV_TRIGGER_MASK (0xC0) - -/* Values for IIR receive trigger */ -#define DW_UART_IIR_TRIGGER_LEVEL_1_CHAR (0x00) -#define DW_UART_IIR_TRIGGER_LEVEL_1_4_FULL (0x40) -#define DW_UART_IIR_TRIGGER_LEVEL_1_2_FULL (0x80) -#define DW_UART_IIR_TRIGGER_LEVEL_2_LESS_FULL (0xC0) -/** @} */ - -/** - * \name DesignWare UART HAL LCR Marcos - * \brief DesignWare UART hal LCR related macros - * @{ - */ -/* LCR */ -#define DW_UART_LCR_WORD_LEN_MASK (0x03) -#define DW_UART_LCR_STOP_BIT_MASK (0x04) -#define DW_UART_LCR_PARITY_MASK (0x38) -#define DW_UART_LCR_DPS_MASK (0x3F) -#define DW_UART_LCR_STICK_PARITY (0x20) -#define DW_UART_LCR_BREAK (0x40) -#define DW_UART_LCR_DLAB (0x80) - -/* Word length values */ -#define DW_UART_LCR_WORD_LEN5 (0x00) -#define DW_UART_LCR_WORD_LEN6 (0x01) -#define DW_UART_LCR_WORD_LEN7 (0x02) -#define DW_UART_LCR_WORD_LEN8 (0x03) - -/* stop bit values */ -#define DW_UART_LCR_1_STOP_BIT (0x00) -#define DW_UART_LCR_1D5_STOP_BIT (0x04) -#define DW_UART_LCR_2_STOP_BIT (0x04) - -/* Parity bit values */ -#define DW_UART_LCR_PARITY_NONE (0x00) -#define DW_UART_LCR_PARITY_ODD (0x08) -#define DW_UART_LCR_PARITY_EVEN (0x18) -#define DW_UART_LCR_PARITY_MARK (0x28) -#define DW_UART_LCR_PARITY_SPACE (0x38) - -/** @} */ - -/** - * \name DesignWare UART HAL MCR Marcos - * \brief DesignWare UART hal MCR related macros - * @{ - */ -/* MCR */ -#define DW_UART_MCR_DTR (0x01) -#define DW_UART_MCR_RTS (0x02) -#define DW_UART_MCR_LOOPBACK (0x10) -#define DW_UART_MCR_AFCE (0x20) -#define DW_UART_MCR_SIRE (0x40) -/** @} */ - -/** - * \name DesignWare UART HAL LSR Marcos - * \brief DesignWare UART hal LSR related macros - * @{ - */ -/* LSR */ -#define DW_UART_LSR_DR (0x01) -#define DW_UART_LSR_OVERRUN (0x02) -#define DW_UART_LSR_PARITYERR (0x04) -#define DW_UART_LSR_FRAMEERR (0x08) -#define DW_UART_LSR_BREAKRCVD (0x10) -#define DW_UART_LSR_TXD_EMPTY (0x20) -#define DW_UART_LSR_TX_STATUS (0x40) -#define DW_UART_LSR_RX_FIFOERR (0x80) -/** @} */ - -/** - * \name DesignWare UART HAL MSR Marcos - * \brief DesignWare UART hal MSR related macros - * @{ - */ -/* MSR */ -#define DW_UART_MSR_DCTS (0x01) -#define DW_UART_MSR_DDSR (0x02) -#define DW_UART_MSR_TERI (0x04) -#define DW_UART_MSR_DDCD (0x08) -#define DW_UART_MSR_CTS (0x10) -#define DW_UART_MSR_DSR (0x20) -#define DW_UART_MSR_RIC (0x40) -#define DW_UART_MSR_DCD (0x80) -/** @} */ - -/** - * \name DesignWare UART HAL FCR Marcos - * \brief DesignWare UART hal FCR related macros - * @{ - */ -/* FCR */ -#define DW_UART_FCR_FEN (0x01) -#define DW_UART_FCR_RFR (0x02) -#define DW_UART_FCR_TFR (0x04) -#define DW_UART_FCR_DMS (0x08) -#define DW_UART_FCR_RTL (0xC0) -/** @} */ - -/** - * \name DesignWare UART HAL USR Marcos - * \brief DesignWare UART hal USR related macros - * @{ - */ -/* USR */ -#define DW_UART_USR_BUSY (0x01) -#define DW_UART_USR_TFNF (0x02) -#define DW_UART_USR_TFE (0x04) -#define DW_UART_USR_RFNE (0x08) -#define DW_UART_USR_RFF (0x10) -/** @} */ - -/** - * \name DesignWare UART HAL SFE Marcos - * \brief DesignWare UART hal SFE related macros - * @{ - */ -/* SFE */ -#define DW_UART_SFE_SHADOW_FIFO_ENABLE (0x01) -/** @} */ - -/** - * \name DesignWare UART HAL SRR Marcos - * \brief DesignWare UART hal SRR related macros - * @{ - */ -/* SRR */ -#define DW_UART_SRR_UR (0x01) -#define DW_UART_SRR_RFR (0x02) -#define DW_UART_SRR_XFR (0x04) -/** @} */ - -/** - * \name DesignWare UART HAL SRT Marcos - * \brief DesignWare UART hal SRT related macros - * @{ - */ -/* SRT */ -#define DW_UART_SRT_TRIGGER_LEVEL_1_CHAR (0x00) -#define DW_UART_SRT_TRIGGER_LEVEL_1_4_FULL (0x01) -#define DW_UART_SRT_TRIGGER_LEVEL_1_2_FULL (0x02) -#define DW_UART_SRT_TRIGGER_LEVEL_2_LESS_FULL (0x03) -/** @} */ - -/** - * \name DesignWare UART HAL STET Marcos - * \brief DesignWare UART hal STET related macros - * @{ - */ -/* STET*/ -#define DW_UART_STET_FIFO_EMPTY (0x00) -#define DW_UART_STET_2_CHARS_IN_FIFO (0x01) -#define DW_UART_STET_1_4_FULL (0x02) -#define DW_UART_STET_1_2_FULL (0x03) -/** @} */ - -/** - * \name DesignWare UART HAL CPR Marcos - * \brief DesignWare UART hal CPR related macros - * @{ - */ -/* CPR*/ -#define DW_UART_CPR_FIFO_STAT (1<<10) -#define DW_UART_CPR_FIFO_MODE_OFS (16) -#define DW_UART_CPR_FIFO_MODE_MASK (0xFF) -#define DW_UART_CPR_FIFO_MODE (0xFF0000) -/** @} */ - -#endif /* _DEVICE_DW_UART_HAL_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_common.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_common.h deleted file mode 100644 index 623d54a611..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_common.h +++ /dev/null @@ -1,173 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-16 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \defgroup DEVICE_HAL_COMMON Common Device Layer Definitions - * \ingroup DEVICE_HAL_DEF - * \brief common definitions for device layer (\ref dev_common.h) - * - * @{ - * - * \file - * \brief header file to define common definitions for device layer - * \details Here in this file provide definitions that need by other - * devices in device layer - */ - -#ifndef _DEVICE_HAL_COMMON_H_ -#define _DEVICE_HAL_COMMON_H_ - -#include - -/** - * \defgroup DEVICE_HAL_COMMON_DEVSTATE Common Device State - * \ingroup DEVICE_HAL_COMMON - * \brief definitions for device state - * \details here defines macros for device open/close, - * device working good/error, used in - * \ref DEVICE_HAL_UART, \ref DEVICE_HAL_SPI, - * \ref DEVICE_HAL_IIC, \ref DEVICE_HAL_GPIO - * @{ - */ -/* - * macros for device open and close state - */ -#define DEV_CLOSED (0) /*!< Indicate that device was closed */ -#define DEV_OPENED (1) /*!< Indicate that the device was opened */ - -/* - * macros for device good and error state - */ -#define DEV_GOOD (0) /*!< Indicate device is good */ -#define DEV_ERROR (1) /*!< Indicate device error */ -/** @} */ - -/** - * \defgroup DEVICE_HAL_COMMON_DEVMTHD Common Device Working Method - * \ingroup DEVICE_HAL_COMMON - * \brief definitions for device working method(interrupt or poll) - * \details here defines macros for working method, - * interrupt or poll method,used in - * \ref DEVICE_HAL_UART, \ref DEVICE_HAL_SPI, - * \ref DEVICE_HAL_IIC, \ref DEVICE_HAL_GPIO - * @{ - */ -/* - * macros for device working method - */ -#define DEV_POLL_METHOD (0) /*!< Indicate that the device running in poll method */ -#define DEV_INTERRUPT_METHOD (1) /*!< Indicate that the device running in interrupt method */ -/** @} */ - -/** - * \defgroup DEVICE_HAL_COMMON_DEVMODE Common Device Working Mode - * \ingroup DEVICE_HAL_COMMON - * \brief definitions for device working mode(master or slave) - * \details here defines macros for working mode, - * Master or Slave mode,used in - * \ref DEV_HAL_IIC, \ref DEV_HAL_SPI. - * @{ - */ -/* - * macros for device working mode - */ -#define DEV_MASTER_MODE (0) /*!< Indicate that the device working as master */ -#define DEV_SLAVE_MODE (1) /*!< Indicate that the device working as slave */ -/** @} */ - -/** - * \defgroup DEVICE_HAL_COMMON_DEVSTATUS Common Device Status - * \ingroup DEVICE_HAL_COMMON - * \brief definitions for device status, 1 bit for 1 function - * @{ - */ -#define DEV_DISABLED (0) /*!< Bit 0 for device enabled state, disabled */ -#define DEV_ENABLED (1<<0) /*!< Bit 0 for device enabled state, enabled */ -#define DEV_IN_TX (1<<1) /*!< Bit 1 for device in transmit state */ -#define DEV_IN_RX (1<<2) /*!< Bit 2 for device in receive state */ -#define DEV_IN_XFER (1<<3) /*!< Bit 3 for device in transfer state */ -#define DEV_IN_TX_ABRT (1<<4) /*!< Bit 4 for device in transmit abort state */ -#define DEV_IN_RX_ABRT (1<<5) /*!< Bit 5 for device in receive abort state */ -#define DEV_IN_XFER_ABRT (1<<6) /*!< Bit 6 for device in transfer abort state */ -/** @} */ - -/** - * \defgroup DEVICE_HAL_COMMON_DEFCMD Common Device Defining Command - * \ingroup DEVICE_HAL_COMMON - * \brief definitions for defining command code - * \details here defines macros to define command code, - * in system code, use \ref DEV_SET_SYSCMD to define command code. - * in user code, use \ref DEV_SET_USRCMD to define command code. - * So that there will be no conflicts in system and user defined command code. - * this used used in - * \ref DEVICE_HAL_UART, \ref DEVICE_HAL_SPI, - * \ref DEVICE_HAL_IIC, \ref DEVICE_HAL_GPIO, - * and in user code - * @{ - */ -/* - * macros for control command base - */ -#define DEV_SYS_CMDBSE (0x00000000) /*!< default system device control command base(defined by embARC) */ -#define DEV_USR_CMDBSE (0x80000000) /*!< default user device control command base(defined by user) in user implementing */ -#define DEV_SET_SYSCMD(cmd) (DEV_SYS_CMDBSE|(cmd)) /*!< set device system control command */ -#define DEV_SET_USRCMD(cmd) (DEV_USR_CMDBSE|(cmd)) /*!< set device user control command */ - -#define CONV2VOID(param) ((void *)(param)) /*!< convert param into void * type */ -/** @} */ - -/** - * Common Device Buffer Structure - */ -typedef struct dev_buffer { - void *buf; /*!< buffer pointer */ - uint32_t len; /*!< buffer length in bytes */ - uint32_t ofs; /*!< current offset in buffer */ -} DEV_BUFFER; - -/** Init device buffer */ -#define DEV_BUFFER_INIT(devbuf, buffer, size) { \ - (devbuf)->buf = (void *)(buffer); \ - (devbuf)->len = (uint32_t)(size); \ - (devbuf)->ofs = (uint32_t)(0); \ - } - -/** - * Device callback function typedef. - * This is usually used in device callback settings, - * and \ptr should be the device object pointer, - * such as DEV_IIC * */ -typedef void (*DEV_CALLBACK) (void *ptr); - -/** @} */ -#endif /* _DEVICE_HAL_COMMON_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h deleted file mode 100644 index 290fd313a2..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_gpio.h +++ /dev/null @@ -1,424 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-17 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \defgroup DEVICE_HAL_GPIO GPIO Device HAL Interface - * \ingroup DEVICE_HAL_DEF - * \brief definitions for gpio device hardware layer (\ref dev_gpio.h) - * \details provide interfaces for gpio driver to implement - * Here is a diagram for the gpio interface. - * - * \htmlonly - *
    - *
    - * GPIO Device HAL Interface Diagram - *

    GPIO Device HAL Interface Diagram

    - *
    - *
    - * \endhtmlonly - * - * @{ - * - * \file - * \brief gpio device hardware layer definitions - * \details Provide common definitions for gpio device, - * then the software developer can develop gpio driver - * following these definitions, and the applications - * can directly call this definition to realize functions - * - */ - -#ifndef _DEVICE_HAL_GPIO_H_ -#define _DEVICE_HAL_GPIO_H_ - -#include "device/device_hal/inc/dev_common.h" - -/** - * \defgroup DEVICE_HAL_GPIO_DEFDIR GPIO Port Direction Definition - * \ingroup DEVICE_HAL_GPIO - * \brief Define macros to indicate gpio directions - * @{ - */ -/* - * defines for gpio directions - */ -#define GPIO_DIR_INPUT (0) /*!< gpio works as input */ -#define GPIO_DIR_OUTPUT (1) /*!< gpio works as output */ -/** @} */ - -/** - * \defgroup DEVICE_HAL_GPIO_CTRLCMD GPIO Device Control Commands - * \ingroup DEVICE_HAL_GPIO - * \brief Definitions for gpio control command, used in \ref dev_gpio::gpio_control "GPIO IO Control" - * \details These commands defined here can be used in user code directly. - * - Parameters Usage - * - For passing parameters like integer, just use uint32_t/int32_t to directly pass values - * - For passing parameters for a structure, please use pointer to pass values - * - For getting some data, please use pointer to store the return data - * - Common Return Values - * - \ref E_OK, Control device successfully - * - \ref E_CLSED, Device is not opened - * - \ref E_OBJ, Device object is not valid or not exists - * - \ref E_PAR, Parameter is not valid for current control command - * - \ref E_SYS, Control device failed, due to hardware issues such as device is disabled - * - \ref E_NOSPT, Control command is not supported or not valid - * @{ - */ -/** - * Set the \ref dev_gpio_info::direction "direction" of masked bits of gpio port into \ref GPIO_DIR_INPUT "input" - * - Param type : uint32_t - * - Param usage : 1 in each bit will be masked. - * - Return value explanation : - */ -#define GPIO_CMD_SET_BIT_DIR_INPUT DEV_SET_SYSCMD(0) -/** - * Set the \ref dev_gpio_info::direction "direction" of masked bits of gpio port into \ref GPIO_DIR_OUTPUT "output" - * - Param type : uint32_t - * - Param usage : 1 in each bit will be masked. - * - Return value explanation : - */ -#define GPIO_CMD_SET_BIT_DIR_OUTPUT DEV_SET_SYSCMD(1) -/** - * Get \ref dev_gpio_info::direction "gpio port direction". - * - Param type : uint32_t - * - Param usage : 1 bit for 1 bit of gpio port, 0 for input, 1 for output - * - Return value explanation : - */ -#define GPIO_CMD_GET_BIT_DIR DEV_SET_SYSCMD(2) -/** - * Set gpio interrupt configuration for each bit. - * - Param type : \ref DEV_GPIO_INT_CFG * - * - Param usage : store gpio interrupt configuration for each bit. - * - Return value explanation : - */ -#define GPIO_CMD_SET_BIT_INT_CFG DEV_SET_SYSCMD(3) -/** - * Get gpio interrupt configuration for each bit. - * - Param type : \ref DEV_GPIO_INT_CFG * - * - Param usage : First set int_bit_mask in DEV_GPIO_INT_CFG structure to - * the mask of which bit of GPIO you want to get. And the interrupt configuration - * will be stored in the structure DEV_GPIO_INT_CFG, each bit stand for each bit of port. - * - Return value explanation : - */ -#define GPIO_CMD_GET_BIT_INT_CFG DEV_SET_SYSCMD(4) -/** - * Set gpio service routine for each bit. - * - Param type : \ref DEV_GPIO_BIT_ISR * - * - Param usage : store gpio handler information for each bit, int handler's param will be DEV_GPIO *. - * - Return value explanation : - */ -#define GPIO_CMD_SET_BIT_ISR DEV_SET_SYSCMD(5) -/** - * Get gpio service routine for each bit. - * - Param type : \ref DEV_GPIO_BIT_ISR * - * - Param usage : By passing int_bit_ofs in DEV_GPIO_BIT_ISR, - * it will return interrupt handler for this bit and store it in int_bit_handler. - * - Return value explanation : - */ -#define GPIO_CMD_GET_BIT_ISR DEV_SET_SYSCMD(6) -/** - * Enable gpio interrupt of the masked bits. - * - Param type : uint32_t - * - Param usage : 1 in each bit will be masked. - * - Return value explanation : - */ -#define GPIO_CMD_ENA_BIT_INT DEV_SET_SYSCMD(7) -/** - * Disable gpio interrupt of the masked bits. - * - Param type : uint32_t - * - Param usage : 1 in each bit will be masked. - * - Return value explanation : - */ -#define GPIO_CMD_DIS_BIT_INT DEV_SET_SYSCMD(8) -/** - * Get \ref dev_gpio_info::method "gpio interrupt enable status". - * - Param type : uint32_t * - * - Param usage : 1 bit for 1 bit of gpio port, 0 for poll, 1 for interrupt - * - Return value explanation : - */ -#define GPIO_CMD_GET_BIT_MTHD DEV_SET_SYSCMD(9) -/* @} */ - -/** - * \defgroup DEVICE_HAL_GPIO_INT_CFG_SET GPIO Device Int Configuration Settings - * \ingroup DEVICE_HAL_GPIO - * \brief definition of gpio interrupt type - * @{ - */ - -/* GPIO Mask Defintions */ -/** Mask none bits of the max 32bits */ -#define GPIO_BITS_MASK_NONE (0) -/** Mask all bits of the max 32bits */ -#define GPIO_BITS_MASK_ALL (0XFFFFFFFF) - -/* GPIO Interrupt Type Related Definitions */ - -/** Level sensitive interrupt type for 1 bit */ -#define GPIO_INT_LEVEL_TRIG (0) -/** Edge sensitive interrupt type for 1 bit */ -#define GPIO_INT_EDGE_TRIG (1) -/** Level sensitive interrupt type for all 32 bits */ -#define GPIO_INT_LEVEL_TRIG_ALL (0) -/** Edge sensitive interrupt type for all 32 bits */ -#define GPIO_INT_EDGE_TRIG_ALL (0XFFFFFFFF) - -/* For bit settings */ -/** Set bit interrupt type of gpio into level sensitive */ -#define GPIO_INT_BIT_LEVEL_TRIG(bit_ofs) (GPIO_INT_LEVEL_TRIG<<(bit_ofs)) -/** Set bit interrupt type of gpio into edge sensitive */ -#define GPIO_INT_BIT_EDGE_TRIG(bit_ofs) (GPIO_INT_EDGE_TRIG<<(bit_ofs)) -/* For bits settings */ -/** Set interrupt type of masked bits of gpio into level sensitive */ -#define GPIO_INT_BITS_LEVEL_TRIG(bit_mask) (GPIO_INT_LEVEL_TRIG_ALL&(bit_mask)) -/** Set bit interrupt type of gpio into edge sensitive */ -#define GPIO_INT_BITS_EDGE_TRIG(bit_mask) (GPIO_INT_EDGE_TRIG_ALL&(bit_mask)) - -/* GPIO Interrupt Polarity Related Definitions */ - -/** GPIO Interrupt polarity type enum */ -typedef enum gpio_int_polarity { - /* Polarity for 1 bit */ - GPIO_INT_ACTIVE_LOW = 0, /*!< Active low for level-sensitive interrupt for 1 bit */ - GPIO_INT_FALLING_EDGE = 0, /*!< Falling-edge for edge-sensitive interrupt for 1 bit */ - GPIO_INT_ACTIVE_HIGH = 1, /*!< Active high for level-sensitive interrupt for 1 bit */ - GPIO_INI_RISING_EDGE = 1, /*!< Rising-edge for edge-sensitive interrupt for 1 bit */ - /* Polartiy for all 32 bits */ - GPIO_INT_ACTIVE_LOW_ALL = 0, /*!< Active low for level-sensitive interrupt for all bits */ - GPIO_INT_FALLING_EDGE_ALL = 0, /*!< Falling-edge for edge-sensitive interrupt for all bits */ - GPIO_INT_ACTIVE_HIGH_ALL = 0XFFFFFFFF, /*!< Active high for level-sensitive interrupt for all bits */ - GPIO_INI_RISING_EDGE_ALL = 0XFFFFFFFF /*!< Rising-edge for edge-sensitive interrupt for all bits */ -} GPIO_INT_POLARITY; - -/* For bit settings */ -/** Set bit polarity of gpio into active low */ -#define GPIO_INT_BIT_POL_ACT_LOW(bit_ofs) (GPIO_INT_ACTIVE_LOW<<(bit_ofs)) -/** Set bit polarity of gpio into active high */ -#define GPIO_INT_BIT_POL_ACT_HIGH(bit_ofs) (GPIO_INT_ACTIVE_HIGH<<(bit_ofs)) -/** Set bit polarity of gpio into falling edge */ -#define GPIO_INT_BIT_POL_FALL_EDGE(bit_ofs) (GPIO_INT_FALLING_EDGE<<(bit_ofs)) -/** Set bit polarity of gpio into rising edge */ -#define GPIO_INT_BIT_POL_RISE_EDGE(bit_ofs) (GPIO_INI_RISING_EDGE<<(bit_ofs)) - -/* For bits settings */ -/** Set polarity of masked bits of gpio into active low */ -#define GPIO_INT_BITS_POL_ACT_LOW(bit_mask) (GPIO_INT_ACTIVE_LOW_ALL&(bit_mask)) -/** Set polarity of masked bits of gpio into active high */ -#define GPIO_INT_BITS_POL_ACT_HIGH(bit_mask) (GPIO_INT_ACTIVE_HIGH_ALL&(bit_mask)) -/** Set polarity of masked bits of gpio into falling edge */ -#define GPIO_INT_BITS_POL_FALL_EDGE(bit_mask) (GPIO_INT_FALLING_EDGE_ALL&(bit_mask)) -/** Set polarity of masked bits of gpio into rising edge */ -#define GPIO_INT_BITS_POL_RISE_EDGE(bit_mask) (GPIO_INI_RISING_EDGE_ALL&(bit_mask)) - -/* GPIO Interrupt Debounce Related Definitions */ - -/* For bit settings */ -/** Disable debounce circuitry for 1 bit */ -#define GPIO_INT_NO_DEBOUNCE (0) -/** Enable debounce circuitry for 1 bit */ -#define GPIO_INT_DEBOUNCE (1) - -/* For bits settings */ -/** Disable debounce circuitry for all bits */ -#define GPIO_INT_NO_DEBOUNCE_ALL (0) -/** Enable debounce circuitry for all bits */ -#define GPIO_INT_DEBOUNCE_ALL (0XFFFFFFFF) - -/* For bit settings */ -/** Set bit interrupt debounce of gpio into enabled */ -#define GPIO_INT_BIT_ENA_DEBOUNCE(bit_ofs) (GPIO_INT_DEBOUNCE<<(bit_ofs)) -/** Set bit interrupt debounce of gpio into disabled */ -#define GPIO_INT_BIT_DIS_DEBOUNCE(bit_ofs) (GPIO_INT_NO_DEBOUNCE<<(bit_ofs)) -/* For bits settings */ -/** Set bit interrupt debounce of gpio into enabled */ -#define GPIO_INT_BITS_ENA_DEBOUNCE(bit_mask) (GPIO_INT_DEBOUNCE_ALL&(bit_mask)) -/** Set bit interrupt debounce of gpio into disabled */ -#define GPIO_INT_BITS_DIS_DEBOUNCE(bit_mask) (GPIO_INT_NO_DEBOUNCE_ALL&(bit_mask)) - -/** GPIO interrupt configuration */ -typedef struct dev_gpio_int_cfg { - uint32_t int_bit_mask; /*!< interrupt bit mask for gpio */ - uint32_t int_bit_type; /*!< \ref GPIO_INT_LEVEL_TRIG "level sensitive" or \ref GPIO_INT_EDGE_TRIG "edge sensitive" for each gpio bit */ - uint32_t int_bit_polarity; /*!< active high or low, refer to \ref GPIO_INT_POLARITY for each gpio bit */ - uint32_t int_bit_debounce; /*!< \ref GPIO_INT_DEBOUNCE "enable" or \ref GPIO_INT_NO_DEBOUNCE "disable" debounce logic for each gpio bit */ -} DEV_GPIO_INT_CFG, * DEV_GPIO_INT_CFG_PTR; - -/** Default interrupt configuration for all gpio bits */ -static const DEV_GPIO_INT_CFG gpio_int_cfg_default = \ - {GPIO_BITS_MASK_ALL, GPIO_INT_LEVEL_TRIG_ALL, \ - GPIO_INT_ACTIVE_LOW_ALL, GPIO_INT_NO_DEBOUNCE_ALL}; - -/** GPIO interrupt handler or Interrupt Service Routine(ISR) */ -typedef void (*DEV_GPIO_HANDLER) (void *ptr); - -/** interrupt handler for each port bit */ -typedef struct dev_gpio_bit_isr { - uint32_t int_bit_ofs; /*!< int bit offset */ - DEV_GPIO_HANDLER int_bit_handler; /*!< interrupt handler */ -} DEV_GPIO_BIT_ISR, * DEV_GPIO_BIT_ISR_PTR; -/* @} */ - -/** - * \defgroup DEVICE_HAL_GPIO_DEVSTRUCT GPIO Device Interface Definition - * \ingroup DEVICE_HAL_GPIO - * \brief contains definitions of gpio device structure. - * \details This structure will be used in user implemented code, which was called - * \ref DEVICE_IMPL "Device Driver Implement Layer" for gpio to use in implementation code. - * Application developer should use the GPIO API provided here to access to GPIO devices. - * BSP developer should follow the API definition to implement GPIO device drivers. - * @{ - */ -/** - * \brief gpio information struct definition - * \details informations about gpio open count, working status - * gpio registers and control block, gpio io direction and interrupt/poll for each bit of gpio - * \note Only available for gpio with max 32bits - */ -typedef struct dev_gpio_info { - void *gpio_ctrl; /*!< gpio control related pointer, implemented by bsp developer, and this should be set during gpio object implementation */ - uint32_t opn_cnt; /*!< gpio open count, open it will increase 1, close it will decrease 1, 0 for close, >0 for open */ - uint32_t direction; /*!< each bit direction of this GPIO, default all \ref GPIO_DIR_INPUT "input" for first open */ - uint32_t method; /*!< int/poll method for each bit of GPIO, 0 for poll, 1 for interrupt, default all \ref DEV_POLL_METHOD "poll" for first open */ - void * extra; /*!< a extra pointer to get hook to applications which should not used by bsp developer, - this should be NULL for first open and you can \ref DEV_GPIO_INFO_SET_EXTRA_OBJECT "set" - or \ref DEV_GPIO_INFO_GET_EXTRA_OBJECT "get" the extra information pointer */ -} DEV_GPIO_INFO, * DEV_GPIO_INFO_PTR; -/** Set extra information pointer of gpio info */ -#define DEV_GPIO_INFO_SET_EXTRA_OBJECT(gpio_info_ptr, extra_info) (gpio_info_ptr)->extra = (void *)(extra_info) -/** Get extra information pointer of gpio info */ -#define DEV_GPIO_INFO_GET_EXTRA_OBJECT(gpio_info_ptr) ((gpio_info_ptr)->extra) - -/** Method of all gpio bits set to poll */ -#define DEV_GPIO_BITS_MTHD_POLL (0) -/** Method of all gpio bits set to interrupt */ -#define DEV_GPIO_BITS_MTHD_INTERRUPT (0xFFFFFFFF) -/** Default method of all gpio bits should be poll for first open */ -#define DEV_GPIO_BITS_MTHD_DEFAULT (DEV_GPIO_BITS_MTHD_POLL) - -/** - * \brief gpio device interface definition - * \details define gpio device interface, like gpio information structure, - * fuctions to open/close/control gpio, write or read data via gpio - * \note all this details are implemented by user in user porting code - */ -typedef struct dev_gpio { - DEV_GPIO_INFO gpio_info; /*!< gpio device information */ - int32_t (*gpio_open) (uint32_t dir); /*!< open gpio device with pre-defined gpio direction */ - int32_t (*gpio_close) (void); /*!< close gpio device */ - int32_t (*gpio_control) (uint32_t ctrl_cmd, void *param); /*!< control gpio device */ - int32_t (*gpio_write) (uint32_t val, uint32_t mask); /*!< write gpio device with val, only write the masked bits */ - int32_t (*gpio_read) (uint32_t *val, uint32_t mask); /*!< read gpio device val, only read the masked bits */ -} DEV_GPIO, * DEV_GPIO_PTR; - -/** - * \fn int32_t (* dev_gpio::gpio_open) (uint32_t dir) - * \details Open a gpio device with pre-defined io direction. - * \param[in] dir gpio direction for each bit - * \retval E_OK Open successfully without any issues - * \retval E_OPNED If device was opened before with different parameters, - * then just increase the \ref dev_gpio_info::opn_cnt "opn_cnt" and return \ref E_OPNED - * \retval E_OBJ Device object is not valid - * \retval E_PAR Parameter is not valid - * \retval E_NOSPT Open settings are not supported - */ - -/** - * \fn int32_t (* dev_gpio::gpio_close) (void) - * \details Close an gpio device, just decrease the \ref dev_gpio_info::opn_cnt "opn_cnt", - * if \ref dev_gpio_info::opn_cnt "opn_cnt" equals 0, then close the device - * \retval E_OK Close successfully without any issues(including scenario that device is already closed) - * \retval E_OPNED Device is still opened, the device \ref dev_gpio_info::opn_cnt "opn_cnt" decreased by 1 - * \retval E_OBJ Device object is not valid - */ - -/** - * \fn int32_t (* dev_gpio::gpio_control) (uint32_t ctrl_cmd, void *param) - * \details Control an gpio device by \ref ctrl_cmd, with passed \ref param. - * you can control gpio device using predefined gpio control commands defined using \ref DEV_SET_SYSCMD - * (which must be implemented by bsp developer), such as \ref GPIO_CMD_SET_BIT_DIR_INPUT - * "change masked gpio direction to input", and \ref DEVICE_HAL_GPIO_CTRLCMD "more". - * And you can also control gpio device using your own specified commands defined using \ref DEV_SET_USRCMD, - * but these specified commands should be defined in your own gpio device driver implementation. - * \param[in] ctrl_cmd \ref DEVICE_HAL_GPIO_CTRLCMD "control command", to change or get some thing related to gpio - * \param[in,out] param parameters that maybe argument of the command, or return values of the command - * \retval E_OK Control device successfully - * \retval E_CLSED Device is not opened - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Control device failed, due to hardware issues - * \retval E_CTX Control device failed, due to different reasons like in transfer state - * \retval E_NOSPT Control command is not supported or not valid, such as interrupt is not supported - */ - -/** - * \fn int32_t (* dev_gpio::gpio_write) (uint32_t val, uint32_t mask) - * \details Write gpio with \ref val, and only change the masked bits of gpio. - * \param[in] val the data that need to write to gpio - * \param[in] mask gpio bit mask - * \retval E_OK Write gpio with specified value successfully - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid - */ - -/** - * \fn int32_t (* dev_gpio::gpio_read) (uint32_t *val, uint32_t mask) - * \details Read the masked gpio value - * \param[out] val pointer to data need to read from gpio - * \param[in] mask gpio bit mask - * \retval E_OK Read gpio data successfully - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid - */ - -/** @} */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief get an \ref dev_gpio "gpio device" by gpio device id. - * For how to use gpio device hal refer to \ref dev_gpio "Functions in gpio device structure" - * \param[in] gpio_id id of gpio, defined by user - * \retval !NULL pointer to an \ref dev_gpio "gpio device structure" - * \retval NULL failed to find the gpio device by \ref gpio_id - * \note need to implemented by user in user code - */ -extern DEV_GPIO_PTR gpio_get_dev(int32_t gpio_id); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* _DEVICE_HAL_GPIO_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h deleted file mode 100644 index 14106671ff..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_iic.h +++ /dev/null @@ -1,526 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-06-16 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \defgroup DEVICE_HAL_IIC IIC Device HAL Interface - * \ingroup DEVICE_HAL_DEF - * \brief definitions for iic device hardware layer (\ref dev_iic.h) - * \details provide interfaces for iic driver to implement - * Here is a diagram for the iic interface. - * - * \htmlonly - *
    - *
    - * IIC Device HAL Interface Diagram - *

    IIC Device HAL Interface Diagram

    - *
    - *
    - * \endhtmlonly - * - * @{ - * - * \file - * \brief iic device hardware layer definitions - * \details provide common definitions for iic device, - * then software developer can develop iic driver - * following this definitions, and the applications - * can directly call this definition to realize functions - */ - -#ifndef _DEVICE_HAL_IIC_H_ -#define _DEVICE_HAL_IIC_H_ - -#include "device/device_hal/inc/dev_common.h" - -/** - * \defgroup DEVICE_HAL_IIC_CFG IIC Related Configurations - * \ingroup DEVICE_HAL_IIC - * \brief Macros for IIC device related configurations. - * @{ - */ -/** IIC Bus possible speed modes */ -typedef enum iic_speed_mode { - IIC_SPEED_STANDARD = 0, /*!< Bidirectional, Standard-mode (Sm), with a bit rate up to 100 kbit/s */ - IIC_SPEED_FAST = 1, /*!< Bidirectional, Fast-mode (Fm), with a bit rate up to 400 kbit/s */ - IIC_SPEED_FASTPLUS = 2, /*!< Bidirectional, Fast-mode Plus (Fm+), with a bit rate up to 1 Mbit/s */ - IIC_SPEED_HIGH = 3, /*!< Bidirectional, High-speed mode (Hs-mode), with a bit rate up to 3.4 Mbit/s */ - IIC_SPEED_ULTRA = 4 /*!< Unidirectional(Write only), Ultra Fast-mode (UFm), with a bit rate up to 5 Mbit/s */ -} IIC_SPEED_MODE; - -/** IIC next Condition */ -typedef enum iic_next_condtion { - IIC_MODE_STOP = 0, /*!< Send a STOP condition after write/read operation */ - IIC_MODE_RESTART = 1 /*!< Send a RESTART condition after write/read operation */ -} IIC_NEXT_CONDTION; - -/** IIC Error State */ -typedef enum iic_error_state { - IIC_ERR_NONE = 0, /*!< Currently in iic device free state */ - IIC_ERR_LOST_BUS = 1, /*!< Master or slave lost bus during operation */ - IIC_ERR_ADDR_NOACK = 2, /*!< Slave address is sent but not addressed by any slave devices */ - IIC_ERR_DATA_NOACK = 3, /*!< Data in transfer is not acked when it should be acked */ - IIC_ERR_TIMEOUT = 4, /*!< Transfer timeout, no more data is received or sent */ - IIC_ERR_MSTSTOP = 5, /*!< Slave received a STOP condition from master device */ - IIC_ERR_UNDEF = 6 /*!< Undefined error cases */ -} IIC_ERROR_STATE; - -/** IIC Working State */ -typedef enum iic_working_state { - IIC_FREE = 0, /*!< Currently in iic device free state */ - IIC_IN_TX = 1, /*!< Currently in iic master transmit state */ - IIC_IN_RX = 2 /*!< Currently in iic master receive state */ -} IIC_WORKING_STATE; - -/** IIC Addressing Mode */ -typedef enum iic_address_mode { - IIC_7BIT_ADDRESS = 0, /*!< Use 7bit address mode */ - IIC_10BIT_ADDRESS = 1 /*!< Use 10bit address mode */ -} IIC_ADDRESS_MODE; - -/** IIC Slave State */ -typedef enum iic_slave_state { - IIC_SLAVE_STATE_FREE = 0, /*!< None state, in free */ - IIC_SLAVE_STATE_START = (1<<1), /*!< Start or Restart condition, clear it when read */ - IIC_SLAVE_STATE_STOP = (1<<2), /*!< Stop condition, clear it when read */ - IIC_SLAVE_STATE_RD_REQ = (1<<3), /*!< Read request from master, this will trigger the slave transmit callback */ - IIC_SLAVE_STATE_RD_DONE = (1<<4), /*!< Read request done from master, clear it when read */ - IIC_SLAVE_STATE_WR_REQ = (1<<5), /*!< Write request from master, this will trigger the slave receive callback */ - IIC_SLAVE_STATE_GC_REQ = (1<<6), /*!< General call request from master */ - IIC_SLAVE_STATE_ERROR = (1<<7) /*!< Error, clear it when read */ -} IIC_SLAVE_STATE; - -/** 7bit IIC address mask */ -#define IIC_7BIT_ADDRESS_MASK (0x7F) -/** 10bit IIC address mask */ -#define IIC_10BIT_ADDRESS_MASK (0x3FF) -/** @} */ - -/** - * \defgroup DEVICE_HAL_IIC_CTRLCMD IIC Device Control Commands - * \ingroup DEVICE_HAL_IIC - * \brief Definitions for iic control command, used in \ref dev_iic::iic_control "IIC IO Control" - * \details These commands defined here can be used in user code directly. - * - Parameters Usage - * - For passing parameters like integer, just use uint32_t/int32_t to directly pass values - * - For passing parameters for a structure, please use pointer to pass values - * - For getting some data, please use pointer to store the return data - * - Common Return Values - * - \ref E_OK, Control device successfully - * - \ref E_CLSED, Device is not opened - * - \ref E_OBJ, Device object is not valid or not exists - * - \ref E_PAR, Parameter is not valid for current control command - * - \ref E_SYS, Control device failed, due to hardware issues such as device is disabled - * - \ref E_CTX, Control device failed, due to different reasons like in transfer state - * - \ref E_NOSPT, Control command is not supported or not valid - * @{ - */ - -/** Define IIC control commands for common usage */ -#define DEV_SET_IIC_SYSCMD(cmd) DEV_SET_SYSCMD((cmd)) -/** Define IIC control commands for master usage */ -#define DEV_SET_IIC_MST_SYSCMD(cmd) DEV_SET_SYSCMD(0x00004000|(cmd)) -/** Define IIC control commands for slave usage */ -#define DEV_SET_IIC_SLV_SYSCMD(cmd) DEV_SET_SYSCMD(0x00008000|(cmd)) - -/* ++++ Common commands for IIC Device ++++ */ -/** - * Get \ref dev_iic_info::status "current device status" - * - Param type : uint32_t * - * - Param usage : store result of current status - * - Return value explanation : - */ -#define IIC_CMD_GET_STATUS DEV_SET_IIC_SYSCMD(0) -/** - * Set \ref dev_iic_info::addr_mode "iic addressing mode". - * - Param type : uint32_t - * - Param usage : iic addressing mode, possible values can be found \ref IIC_ADDRESS_MODE "here" - * - Return value explanation : - */ -#define IIC_CMD_SET_ADDR_MODE DEV_SET_IIC_SYSCMD(1) -/** - * Set \ref dev_iic_cbs::tx_cb "iic transmit success callback" function - * when all required bytes are transmitted for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : transmit success callback function for iic - * - Return value explanation : - */ -#define IIC_CMD_SET_TXCB DEV_SET_IIC_SYSCMD(2) -/** - * Set \ref dev_iic_cbs::rx_cb "iic receive success callback" function - * when all required bytes are received for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : receive success callback function for iic - * - Return value explanation : - */ -#define IIC_CMD_SET_RXCB DEV_SET_IIC_SYSCMD(3) -/** - * Set \ref dev_iic_cbs::err_cb "iic transfer error callback" function - * when something error happened for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : transfer error callback function for iic - * - Return value explanation : - */ -#define IIC_CMD_SET_ERRCB DEV_SET_IIC_SYSCMD(4) -/** - * Set buffer for interrupt transmit, and it will set \ref dev_iic_info::tx_buf "tx_buf". - * - IIC master mode use case \n - * For master mode, if you set tx buffer to NULL, when tx interrupt is enabled and entered into tx interrupt, - * it will automatically disable the tx interrupt, so when you want to transfer something, you need to set the - * tx buffer to Non-NULL and enable tx interrupt, when the tx buffer is sent, it will disable the tx interrupt - * and call tx callback function if available. - * - IIC slave mode use case \n - * For slave mode, the tx buffer is not used, only tx callback function is used, and if tx callback is not set, - * then it will automatically disable the tx interrupt, if tx callback is set, it will call the tx callback function - * and you need to write or read in the tx callback function, to avoid meaningless waiting, you can use control command - * \ref IIC_CMD_GET_TXAVAIL to get how many bytes space existing in transmit fifo, and use iic_write to send the available - * bytes. - * - Param type : DEV_BUFFER * or NULL - * - Param usage : buffer structure pointer, if param is NULL, then it will set tx_buf to NULL - * - Return value explanation : - */ -#define IIC_CMD_SET_TXINT_BUF DEV_SET_IIC_SYSCMD(5) -/** - * Set buffer for interrupt receive, and it will set \ref dev_iic_info::rx_buf "rx_buf" - * - IIC master mode use case \n - * Similar to \ref IIC_CMD_SET_TXINT_BUF - * - IIC slave mode use case \n - * Similiar to \ref IIC_CMD_SET_TXINT_BUF - * - Param type : DEV_BUFFER * or NULL - * - Param usage : buffer structure pointer, if param is NULL, then it will set rx_buf to NULL - * - Return value explanation : - */ -#define IIC_CMD_SET_RXINT_BUF DEV_SET_IIC_SYSCMD(6) -/** - * Enable or disable transmit interrupt, - * for master mode, only one of tx and rx interrupt can be enabled, - * if tx interrupt is enabled, then rx interrupt can't be changed. - * - Param type : uint32_t - * - Param usage : enable(none-zero) or disable(zero) flag - * - Return value explanation : - */ -#define IIC_CMD_SET_TXINT DEV_SET_IIC_SYSCMD(7) -/** - * Enable or disable receive interrupt, - * for master mode, only one of tx and rx interrupt can be enabled, - * if rx interrupt is enabled, then tx interrupt can't be changed. - * - Param type : uint32_t - * - Param usage : enable(none-zero) or disable(zero) flag - * - Return value explanation : - */ -#define IIC_CMD_SET_RXINT DEV_SET_IIC_SYSCMD(8) -/** - * Abort current interrupt transmit operation if tx interrupt enabled, - * it will disable transmit interrupt, and set \ref DEV_IN_TX_ABRT - * in \ref dev_iic_info::status "status" variable, - * and call the transmit callback function, when tx callback is finished, - * it will clear \ref DEV_IN_TX_ABRT and return - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define IIC_CMD_ABORT_TX DEV_SET_IIC_SYSCMD(9) -/** - * Abort current interrupt receive operation if rx interrupt enabled, - * it will disable receive interrupt, and set \ref DEV_IN_TX_ABRT - * in \ref dev_iic_info::status "status" variable, - * and call the receive callback function, when rx callback is finished, - * it will clear \ref DEV_IN_TX_ABRT and return - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define IIC_CMD_ABORT_RX DEV_SET_IIC_SYSCMD(10) -/** - * Do a software reset for IIC device, it will stop current transfer, - * and clear error state and bring device to normal state, set next condition to STOP - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define IIC_CMD_RESET DEV_SET_IIC_SYSCMD(11) -/** - * Flush iic device transmit buffer or fifo - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define IIC_CMD_FLUSH_TX DEV_SET_IIC_SYSCMD(12) -/** - * Flush iic device receive buffer or fifo - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define IIC_CMD_FLUSH_RX DEV_SET_IIC_SYSCMD(13) -/** - * Enable iic device - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define IIC_CMD_ENA_DEV DEV_SET_IIC_SYSCMD(14) -/** - * Disable iic device, when device is disabled, - * only \ref IIC_CMD_ENA_DEV, \ref IIC_CMD_DIS_DEV, - * \ref IIC_CMD_GET_STATUS and \ref IIC_CMD_RESET - * commands can be executed, other commands will return \ref E_SYS - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define IIC_CMD_DIS_DEV DEV_SET_IIC_SYSCMD(15) -/** - * Get how many bytes space in iic are available to transmit, - * this can be used in interrupt callback functions, - * cooperate with \ref dev_iic::iic_write "iic_write" API to realize non-blocked write - * - Param type : int32_t * - * - Param usage : store the write available bytes, > 0 for available bytes, 0 for not available - * - Return value explaination : - */ -#define IIC_CMD_GET_TXAVAIL DEV_SET_IIC_SYSCMD(16) -/** - * Get how many bytes in iic are available to receive, - * this can be used in interrupt callback functions, - * cooperate with \ref dev_iic::iic_read "iic_read" API to realize non-blocked read - * - Param type : int32_t * - * - Param usage : store the read available bytes, > 0 for available bytes, 0 for not available - * - Return value explanation : - */ -#define IIC_CMD_GET_RXAVAIL DEV_SET_IIC_SYSCMD(17) - -/* ++++ Master only commands for IIC Device ++++ */ -/** - * Set \ref dev_iic_info::speed_mode "iic speed mode". - * - Param type : uint32_t - * - Param usage : iic speed mode, possible values can be found \ref IIC_SPEED_MODE "here", - * and if passing mode is not supported, it will choose a lower supported speed mode - * - Return value explanation : - */ -#define IIC_CMD_MST_SET_SPEED_MODE DEV_SET_IIC_MST_SYSCMD(0) -/** - * Set next condition for following transmit or receive operation. - * For example, you can change next condition before iic_read or iic_write, - * then in iic_read/iic_write operation, it will send a STOP/RESTART condition - * after the last byte of this operation. For interrupt, this is similar. - * - Param type : uint32_t - * - Param usage : next condition can be \ref IIC_NEXT_CONDTION - * - Return value explanation : - */ -#define IIC_CMD_MST_SET_NEXT_COND DEV_SET_IIC_MST_SYSCMD(1) -/** - * Set target slave device address for selecting slave device - * - Param type : uint32_t - * - Param usage : target slave address value - * - Return value explanation : - */ -#define IIC_CMD_MST_SET_TAR_ADDR DEV_SET_IIC_MST_SYSCMD(2) - - -/* ++++ Slave only commands for IIC Device ++++ */ -/** - * Set slave address when working as slave iic device - * - Param type : uint32_t - * - Param usage : slave address value - * - Return value explanation : - */ -#define IIC_CMD_SLV_SET_SLV_ADDR DEV_SET_IIC_SLV_SYSCMD(0) -/** - * Get \ref iic_slave_state "slave state" when working as slave iic device - * - Param type : uint32_t * - * - Param usage : slave state - * - Return value explanation : - */ -#define IIC_CMD_SLV_GET_SLV_STATE DEV_SET_IIC_SLV_SYSCMD(1) - -/** @} */ - -/** - * \defgroup DEVICE_HAL_IIC_CALLBACK IIC Interrupt callback functions - * \ingroup DEVICE_HAL_IIC - * \brief callback function structure for IIC device - * @{ - */ -typedef struct dev_iic_cbs { - DEV_CALLBACK tx_cb; /*!< iic data transmit success required bytes callback */ - DEV_CALLBACK rx_cb; /*!< iic data receive success required bytes callback */ - DEV_CALLBACK err_cb; /*!< iic error callback */ -} DEV_IIC_CBS, *DEV_IIC_CBS_PTR; -/** @} */ - -/** - * \defgroup DEVICE_HAL_IIC_DEVSTRUCT IIC Device Structure - * \ingroup DEVICE_HAL_IIC - * \brief contains definitions of iic device structure. - * \details this structure will be used in user implemented code, which was called - * Device Driver Implement Layer for iic to realize in user code. - * @{ - */ -/** - * \brief iic information struct definition - * \details informations about iic open state, working state, - * baurate, iic registers, working method, interrupt number - */ -typedef struct dev_iic_info { - void *iic_ctrl; /*!< iic control related pointer, implemented by bsp developer, and this should be set during iic object implementation */ - uint32_t opn_cnt; /*!< iic open count, open it will increase 1, close it will decrease 1, 0 for close, >0 for open */ - uint32_t status; /*!< current working status, refer to \ref DEVICE_HAL_COMMON_DEVSTATUS, this should be \ref DEV_ENABLED for first open */ - uint32_t mode; /*!< current working mode, which can be \ref DEV_MASTER_MODE "master mode" or \ref DEV_SLAVE_MODE "slave mode" */ - uint32_t speed_mode; /*!< current working \ref IIC_SPEED_MODE "iic speed mode" */ - uint32_t cur_state; /*!< \ref IIC_WORKING_STATE "current working state for iic device", this should be \ref IIC_FREE for first open */ - uint32_t err_state; /*!< \ref IIC_ERROR_STATE "current error state for iic device", this should be \ref IIC_ERR_NONE for first open */ - uint32_t addr_mode; /*!< \ref IIC_ADDRESS_MODE "current addressing mode", this should be \ref IIC_7BIT_ADDRESS for first open */ - uint32_t slv_addr; /*!< slave address when working as slave iic device, this should be 0 for first open */ - uint32_t tar_addr; /*!< target slave device address when addressing that slave device, this should be 0 for first open */ - uint32_t next_cond; /*!< \ref IIC_NEXT_CONDTION "next condition for master transmit or receive", \ - possible values are STOP or RESTART, it should be STOP for first open */ - DEV_BUFFER tx_buf; /*!< transmit buffer via interrupt, this should be all zero for first open */ - DEV_BUFFER rx_buf; /*!< receive buffer via interrupt, this should be all zero for first open */ - DEV_IIC_CBS iic_cbs; /*!< iic callbacks, for both master and slave mode, this should be all NULL for first open */ - void *extra; /*!< a extra pointer to get hook to applications which should not used by bsp developer, - this should be NULL for first open and you can \ref DEV_IIC_INFO_SET_EXTRA_OBJECT "set" - or \ref DEV_IIC_INFO_GET_EXTRA_OBJECT "get" the extra information pointer */ -} DEV_IIC_INFO, * DEV_IIC_INFO_PTR; - -/** Set extra information pointer of iic info */ -#define DEV_IIC_INFO_SET_EXTRA_OBJECT(iic_info_ptr, extra_info) (iic_info_ptr)->extra = (void *)(extra_info) -/** Get extra information pointer of iic info */ -#define DEV_IIC_INFO_GET_EXTRA_OBJECT(iic_info_ptr) ((iic_info_ptr)->extra) - -/** - * \brief iic device interface definition - * \details define iic device interface, like iic information structure, - * fuctions to get iic info, open/close/control iic, send/receive data by iic - * \note all this details are implemented by user in user porting code - */ -typedef struct dev_iic { - DEV_IIC_INFO iic_info; /*!< iic device information */ - int32_t (*iic_open) (uint32_t mode, uint32_t param); /*!< open iic device in master/slave mode, \ - when in master mode, param stands for speed mode, \ - when in slave mode, param stands for slave address */ - int32_t (*iic_close) (void); /*!< close iic device */ - int32_t (*iic_control) (uint32_t ctrl_cmd, void *param);/*!< control iic device */ - int32_t (*iic_write) (const void *data, uint32_t len); /*!< send data by iic device (blocking method) */ - int32_t (*iic_read) (void *data, uint32_t len); /*!< read data from iic device (blocking method) */ -} DEV_IIC, * DEV_IIC_PTR; - -/** - * \fn int32_t (* dev_iic::iic_open) (uint32_t mode, uint32_t param) - * \details open an iic device with selected mode (master or slave) with defined \ref param - * \param[in] mode working mode (\ref DEV_MASTER_MODE "master" or \ref DEV_SLAVE_MODE "slave") - * \param[in] param When mode is \ref DEV_MASTER_MODE, param stands for \ref dev_iic_info::speed_mode "speed mode", - * when mode is \ref DEV_SLAVE_MODE, param stands for \ref dev_iic_info::slv_addr "slave device 7bit address" - * \retval E_OK Open successfully without any issues - * \retval E_OPNED If device was opened before with different parameters, - * then just increase the \ref dev_iic_info::opn_cnt "opn_cnt" and return \ref E_OPNED - * \retval E_OBJ Device object is not valid - * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first. - * \retval E_PAR Parameter is not valid - * \retval E_NOSPT Open settings are not supported - */ - -/** - * \fn int32_t (* dev_iic::iic_close) (void) - * \details close an iic device, just decrease the \ref dev_iic_info::opn_cnt "opn_cnt", - * if \ref dev_iic_info::opn_cnt "opn_cnt" equals 0, then close the device - * \retval E_OK Close successfully without any issues(including scenario that device is already closed) - * \retval E_OPNED Device is still opened, the device \ref dev_iic_info::opn_cnt "opn_cnt" decreased by 1 - * \retval E_OBJ Device object is not valid - */ - -/** - * \fn int32_t (* dev_iic::iic_control) (uint32_t ctrl_cmd, void *param) - * \details control an iic device by \ref ctrl_cmd, with passed \ref param. - * you can control iic device using predefined iic control commands defined using \ref DEV_SET_SYSCMD - * (which must be implemented by bsp developer), such as \ref IIC_CMD_SET_SPEED "set iic speed mode", - * \ref IIC_CMD_FLUSH_TX "flush tx" and \ref DEVICE_HAL_IIC_CTRLCMD "more". - * And you can also control iic device using your own specified commands defined using \ref DEV_SET_USRCMD, - * but these specified commands should be defined in your own iic device driver implementation. - * \param[in] ctrl_cmd \ref DEVICE_HAL_IIC_CTRLCMD "control command", to change or get some thing related to iic - * \param[in,out] param parameters that maybe argument of the command, - * or return values of the command, must not be NULL - * \retval E_OK Control device successfully - * \retval E_CLSED Device is not opened - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled - * \retval E_CTX Control device failed, due to different reasons like in transfer state - * \retval E_NOSPT Control command is not supported or not valid - */ - -/** - * \fn int32_t (* dev_iic::iic_write) (const void *data, uint32_t len) - * \details send \ref data through iic with defined \ref len to slave device which slave address is \ref slv_addr. - * \param[in] data pointer to data need to send by iic - * \param[in] len length of data to be sent - * \retval >0 Byte count that was successfully sent for poll method, - * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state". - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid - * \retval E_CTX Device is still in transfer state - * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled - */ - -/** - * \fn int32_t (* dev_iic::iic_read) (void *data, uint32_t len) - * \details receive \ref data of defined \ref len through iic from slave device which slave address is \ref slv_addr. - * \param[out] data pointer to data need to received by iic - * \param[in] len length of data to be received - * \retval >0 Byte count that was successfully received for poll method, - * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state". - * \retval E_OBJ Device object is not valid or not exists - * \retval E_CTX Device is still in transfer state - * \retval E_PAR Parameter is not valid - * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled - */ -/** @} */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief get an \ref dev_iic "iic device" by iic device id. - * For how to use iic device hal refer to \ref DEVICE_HAL_IIC_DEVSTRUCT "Functions in iic device structure" - * \param[in] iic_id id of iic, defined by user - * \retval !NULL pointer to an \ref dev_iic "iic device structure" - * \retval NULL failed to find the iic device by \ref iic_id - * \note need to implemented by user in user code - */ -extern DEV_IIC_PTR iic_get_dev(int32_t iic_id); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* _DEVICE_HAL_IIC_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h deleted file mode 100644 index 4469654e54..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_spi.h +++ /dev/null @@ -1,577 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-06-16 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \defgroup DEVICE_HAL_SPI SPI Device HAL Interface - * \ingroup DEVICE_HAL_DEF - * \brief definitions for spi device hardware layer (\ref dev_spi.h) - * \details provide interfaces for spi driver to implement - * Here is a diagram for the spi interface. - * - * \htmlonly - *
    - *
    - * SPI Device HAL Interface Diagram - *

    SPI Device HAL Interface Diagram

    - *
    - *
    - * \endhtmlonly - * - * @{ - * - * \file - * \brief spi device hardware layer definitions - * \details provide common definitions for spi device, - * then software developer can develop spi driver - * following this definitions, and the applications - * can directly call this definition to realize functions - */ - -#ifndef _DEVICE_HAL_SPI_H_ -#define _DEVICE_HAL_SPI_H_ - -#include "device/device_hal/inc/dev_common.h" - - -/** - * \defgroup DEVICE_HAL_SPI_CTRLCMD SPI Device Control Commands - * \ingroup DEVICE_HAL_SPI - * \brief Definitions for spi control command, used in \ref dev_spi::spi_control "SPI IO Control" - * \details These commands defined here can be used in user code directly. - * - Parameters Usage - * - For passing parameters like integer, just use uint32_t/int32_t to directly pass values - * - For passing parameters for a structure, please use pointer to pass values - * - For getting some data, please use pointer to store the return data - * - Common Return Values - * - \ref E_OK, Control device successfully - * - \ref E_CLSED, Device is not opened - * - \ref E_OBJ, Device object is not valid or not exists - * - \ref E_PAR, Parameter is not valid for current control command - * - \ref E_SYS, Control device failed, due to hardware issues such as device is disabled - * - \ref E_CTX, Control device failed, due to different reasons like in transfer state - * - \ref E_NOSPT, Control command is not supported or not valid - * - Usage Comment - * - For SPI poll or interrupt read/write/transfer operations, only 1 operation can be triggered. - * If there is a operation is running, any other operation will return \ref E_CTX - * - If SPI is in transfer, then the following operations may return \ref E_CTX. Like - * \ref SPI_CMD_SET_CLK_MODE, \ref SPI_CMD_SET_TXINT_BUF, \ref SPI_CMD_SET_RXINT_BUF, - * \ref SPI_CMD_SET_TXINT, \ref SPI_CMD_SET_RXINT, \ref SPI_CMD_ABORT_TX, \ref SPI_CMD_ABORT_RX, - * \ref SPI_CMD_FLUSH_TX, \ref SPI_CMD_FLUSH_RX, \ref SPI_CMD_SET_DFS, \ref SPI_CMD_TRANSFER_POLLING, - * \ref SPI_CMD_TRANSFER_INT, \ref SPI_CMD_ABORT_XFER, \ref SPI_CMD_MST_SEL_DEV, \ref SPI_CMD_MST_DSEL_DEV, - * \ref SPI_CMD_MST_SET_FREQ and \ref dev_spi::spi_write "SPI Poll Write" or \ref dev_spi::spi_read "SPI Poll Read". - * @{ - */ - -/** Define SPI control commands for common usage */ -#define DEV_SET_SPI_SYSCMD(cmd) DEV_SET_SYSCMD((cmd)) -/** Define SPI control commands for master usage */ -#define DEV_SET_SPI_MST_SYSCMD(cmd) DEV_SET_SYSCMD(0x00001000|(cmd)) -/** Define SPI control commands for slave usage */ -#define DEV_SET_SPI_SLV_SYSCMD(cmd) DEV_SET_SYSCMD(0x00002000|(cmd)) - - -/* ++++ Common commands for SPI Device ++++ */ -/** - * Get \ref dev_spi_info::status "current device status" - * - Param type : uint32_t * - * - Param usage : store result of current status - * - Return value explanation : - */ -#define SPI_CMD_GET_STATUS DEV_SET_SPI_SYSCMD(0) -/** - * set the \ref dev_spi_info::clk_mode "clock mode" of spi transfer - * - Param type : uint32_t - * - Param usage : spi clock mode to choose clock phase and clock polarity - * - Return value explanation : - */ -#define SPI_CMD_SET_CLK_MODE DEV_SET_SPI_SYSCMD(1) -/** - * set spi \ref dev_spi_info::dfs "data frame size" - * - Param type : uint32_t - * - Param usage : should > 0 - * - Return value explanation : If dfs is not supported, then return \ref E_SYS - */ -#define SPI_CMD_SET_DFS DEV_SET_SPI_SYSCMD(2) -/** - * set the \ref dev_spi_info::dummy "dummy data" during spi transfer - * - Param type : uint32_t - * - Param usage : dummy data to transfer - * - Return value explanation : - */ -#define SPI_CMD_SET_DUMMY_DATA DEV_SET_SPI_SYSCMD(3) -/** - * Set \ref dev_spi_cbs::tx_cb "spi transmit success callback" function - * when all required bytes are transmitted for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : transmit success callback function for spi - * - Return value explanation : - */ -#define SPI_CMD_SET_TXCB DEV_SET_SPI_SYSCMD(4) -/** - * Set \ref dev_spi_cbs::rx_cb "spi receive success callback" function - * when all required bytes are received for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : receive success callback function for spi - * - Return value explanation : - */ -#define SPI_CMD_SET_RXCB DEV_SET_SPI_SYSCMD(5) -/** - * Set \ref dev_spi_cbs::xfer_cb "spi transfer success callback" function - * when all required transfer are done for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : transfer success callback function for spi - * - Return value explanation : - */ -#define SPI_CMD_SET_XFERCB DEV_SET_SPI_SYSCMD(6) -/** - * Set \ref dev_spi_cbs::err_cb "spi transfer error callback" function - * when something error happened for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : transfer error callback function for spi - * - Return value explanation : - */ -#define SPI_CMD_SET_ERRCB DEV_SET_SPI_SYSCMD(7) -/** - * Set buffer in interrupt transmit, and it will set \ref dev_spi_info::xfer "spi tranfer". - * - SPI master and slave mode use case \n - * For both master and slave mode, if you set tx buffer to NULL, when tx interrupt is enabled and entered into tx interrupt, - * it will automatically disable the tx interrupt, so when you want to transfer something, you need to set the - * tx buffer to Non-NULL and enable tx interrupt, when the tx buffer is sent, it will disable the tx interrupt - * and call tx callback function if available. - * - Param type : DEV_BUFFER * or NULL - * - Param usage : buffer structure pointer, if param is NULL, then it will set xfer to empty - * - Return value explanation : - */ -#define SPI_CMD_SET_TXINT_BUF DEV_SET_SPI_SYSCMD(8) -/** - * Set buffer in interrupt receive, and it will set \ref dev_spi_info::xfer "spi tranfer". - * - SPI master mode use case \n - * Similar to \ref SPI_CMD_SET_TXINT_BUF - * - SPI slave mode use case \n - * Similiar to \ref SPI_CMD_SET_TXINT_BUF - * - Param type : DEV_BUFFER * or NULL - * - Param usage : buffer structure pointer, if param is NULL, then it will set xfer to empty - * - Return value explanation : - */ -#define SPI_CMD_SET_RXINT_BUF DEV_SET_SPI_SYSCMD(9) -/** - * Enable or disable transmit interrupt, - * for master mode, only one of tx and rx interrupt can be enabled, - * if tx interrupt is enabled, then rx interrupt can't be enabled. - * - Param type : uint32_t - * - Param usage : enable(none-zero) or disable(zero) flag - * - Return value explanation : - */ -#define SPI_CMD_SET_TXINT DEV_SET_SPI_SYSCMD(10) -/** - * Enable or disable receive interrupt, - * for master mode, only one of tx and rx interrupt can be enabled, - * if rx interrupt is enabled, then tx interrupt can't be enabled. - * - Param type : uint32_t - * - Param usage : enable(none-zero) or disable(zero) flag - * - Return value explanation : - */ -#define SPI_CMD_SET_RXINT DEV_SET_SPI_SYSCMD(11) -/** - * start the transfer by polling - * - Param type : \ref DEV_SPI_TRANSFER * - * - Param usage : - * - Return value explanation : - */ -#define SPI_CMD_TRANSFER_POLLING DEV_SET_SPI_SYSCMD(12) -/** - * start the transfer by interrupt - * - Param type : \ref DEV_SPI_TRANSFER * or NULL - * - Param usage : If NULL, it will disable transfer interrupt, if not NULL, it will enable transfer interrupt - * - Return value explanation : - */ -#define SPI_CMD_TRANSFER_INT DEV_SET_SPI_SYSCMD(13) -/** - * Abort current interrupt transmit operation if tx interrupt enabled, - * it will disable transmit interrupt, and set \ref DEV_IN_TX_ABRT - * in \ref dev_spi_info::status "status" variable, - * and call the transmit callback function, when tx callback is finished, - * it will clear \ref DEV_IN_TX_ABRT and return - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define SPI_CMD_ABORT_TX DEV_SET_SPI_SYSCMD(14) -/** - * Abort current interrupt receive operation if rx interrupt enabled, - * it will disable receive interrupt, and set \ref DEV_IN_TX_ABRT - * in \ref dev_spi_info::status "status" variable, - * and call the receive callback function, when rx callback is finished, - * it will clear \ref DEV_IN_TX_ABRT and return - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define SPI_CMD_ABORT_RX DEV_SET_SPI_SYSCMD(15) -/** - * Abort current interrupt transfer operation if transfer is issued, - * it will disable transfer interrupt, and set \ref DEV_IN_XFER_ABRT - * in \ref dev_spi_info::status "status" variable, - * and call the transfer callback function, when xfer callback is finished, - * it will clear \ref DEV_IN_XFER_ABRT and return - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define SPI_CMD_ABORT_XFER DEV_SET_SPI_SYSCMD(16) -/** - * Do a software reset for SPI device, it will stop current transfer, - * and clear error state and bring device to normal state, set next condition to STOP - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define SPI_CMD_RESET DEV_SET_SPI_SYSCMD(17) -/** - * Flush spi tx fifo, this will clear the data in tx fifo - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define SPI_CMD_FLUSH_TX DEV_SET_SPI_SYSCMD(18) -/** - * Flush spi rx fifo, this will clear the data in rx fifo - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define SPI_CMD_FLUSH_RX DEV_SET_SPI_SYSCMD(19) -/** - * Enable spi device - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define SPI_CMD_ENA_DEV DEV_SET_SPI_SYSCMD(20) -/** - * Disable spi device, when device is disabled, - * only \ref SPI_CMD_ENA_DEV, \ref SPI_CMD_DIS_DEV, - * \ref SPI_CMD_GET_STATUS and \ref SPI_CMD_RESET - * commands can be executed, other commands will return \ref E_SYS - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define SPI_CMD_DIS_DEV DEV_SET_SPI_SYSCMD(21) -/** - * Get how many bytes space in spi are available to transmit, - * this can be used in interrupt callback functions, - * cooperate with \ref dev_spi::spi_write "spi_write" API to realize non-blocked write - * - Param type : int32_t * - * - Param usage : store the write available bytes, > 0 for available bytes, 0 for not available - * - Return value explanation : - */ -#define SPI_CMD_GET_TXAVAIL DEV_SET_SPI_SYSCMD(22) -/** - * Get how many bytes in spi are available to receive, - * this can be used in interrupt callback functions, - * cooperate with \ref dev_spi::spi_read "spi_read" API to realize non-blocked read - * - Param type : int32_t * - * - Param usage : store the read available bytes, > 0 for available bytes, 0 for not available - * - Return value explanation : - */ -#define SPI_CMD_GET_RXAVAIL DEV_SET_SPI_SYSCMD(23) - - -/* ++++ Master only commands for SPI Device ++++ */ -/** - * select spi slave device - * - Param type : uint32_t - * - Param usage : the number of spi slave device to select - * - Return value explanation : return \ref E_SYS when selection can't be done, return \ref E_CTX during transfer - */ -#define SPI_CMD_MST_SEL_DEV DEV_SET_SPI_MST_SYSCMD(0) -/** - * de-select spi slave device - * - Param type : uint32_t - * - Param usage : the number of spi slave device to de-select - * - Return value explanation : return \ref E_SYS when selection can't be done, return \ref E_CTX during transfer - */ -#define SPI_CMD_MST_DSEL_DEV DEV_SET_SPI_MST_SYSCMD(1) - /** - * Set \ref dev_spi_info::freq "spi frequency". - * - Param type : uint32_t - * - Param usage : spi freq - * - Return value explanation : no return - */ -#define SPI_CMD_MST_SET_FREQ DEV_SET_SPI_MST_SYSCMD(2) - - -/* ++++ Slave only commands for SPI Device ++++ */ - -/* \todo add spi slave related CMDs */ - -/** @} */ - -/** - * \defgroup DEVICE_HAL_SPI_CALLBACK SPI Interrupt callback functions - * \ingroup DEVICE_HAL_SPI - * \brief callback function structure for SPI device - * @{ - */ -typedef struct dev_spi_cbs { - DEV_CALLBACK tx_cb; /*!< spi data transmit success required bytes callback */ - DEV_CALLBACK rx_cb; /*!< spi data receive success required bytes callback */ - DEV_CALLBACK err_cb; /*!< spi error callback */ - DEV_CALLBACK xfer_cb; /*!< transfer callback */ -} DEV_SPI_CBS, *DEV_SPI_CBS_PTR; -/** @} */ - -/** SPI Clock Mode */ -typedef enum spi_clk_mode { - SPI_CPOL_0_CPHA_0 = 0, /*!< Inactive state of serial clock is low, serial clock toggles in middle of first data bit */ - SPI_CPOL_0_CPHA_1 = 1, /*!< Inactive state of serial clock is low, serial clock toggles at start of first data bit */ - SPI_CPOL_1_CPHA_0 = 2, /*!< Inactive state of serial clock is high, serial clock toggles in middle of first data bit */ - SPI_CPOL_1_CPHA_1 = 3, /*!< Inactive state of serial clock is high, serial clock toggles at start of first data bit */ - - SPI_CLK_MODE_0 = SPI_CPOL_0_CPHA_0, /*!< Equal to \ref SPI_CPOL_0_CPHA_0 */ - SPI_CLK_MODE_1 = SPI_CPOL_0_CPHA_1, /*!< Equal to \ref SPI_CPOL_0_CPHA_1 */ - SPI_CLK_MODE_2 = SPI_CPOL_1_CPHA_0, /*!< Equal to \ref SPI_CPOL_1_CPHA_0 */ - SPI_CLK_MODE_3 = SPI_CPOL_1_CPHA_1 /*!< Equal to \ref SPI_CPOL_1_CPHA_1 */ -} SPI_CLK_MODE; - -#define SPI_CLK_MODE_DEFAULT SPI_CPOL_0_CPHA_0 /*!< Default SPI device clock mode */ - -/** - * \defgroup DEVICE_HAL_SPI_DEVSTRUCT SPI Device Structure - * \ingroup DEVICE_HAL_SPI - * \brief contains definitions of spi device structure. - * \details this structure will be used in user implemented code, which was called - * Device Driver Implement Layer for spi to realize in user code. - * @{ - */ -typedef struct dev_spi_transfer DEV_SPI_TRANSFER, *DEV_SPI_TRANSFER_PTR; -/** - * \brief spi read and write data structure used by \ref SPI_CMD_TRANSFER - * spi write then read data - * - */ -struct dev_spi_transfer { - DEV_SPI_TRANSFER *next; - /* Calc by software */ - /** tot_len = (tx_totlen>rx_totlen)?tx_totlen:rx_totlen */ - uint32_t tot_len; - /* Set by user */ - uint8_t *tx_buf; - uint32_t tx_ofs; - uint32_t tx_len; - uint8_t *rx_buf; - uint32_t rx_ofs; - uint32_t rx_len; - /* Should auto set to proper value during set buffer value */ - uint32_t tx_idx; - uint32_t tx_totlen; /** tx_totlen = tx_len + tx_ofs */ - uint32_t rx_idx; - uint32_t rx_totlen; /** rx_totlen = rx_len + rx_ofs */ -}; - -/** Set tx buffer of device spi transfer */ -#define DEV_SPI_XFER_SET_TXBUF(xfer, buf, ofs, len) { \ - (xfer)->tx_buf = (uint8_t *)(buf); \ - (xfer)->tx_len = (uint32_t)(len); \ - (xfer)->tx_ofs = (uint32_t)(ofs); \ - (xfer)->tx_idx = 0; \ - (xfer)->tx_totlen = ( (uint32_t)(len) \ - + (uint32_t)(ofs) ) ; \ - } - -/** Set rx buffer of device spi transfer */ -#define DEV_SPI_XFER_SET_RXBUF(xfer, buf, ofs, len) { \ - (xfer)->rx_buf = (uint8_t *)(buf); \ - (xfer)->rx_len = (uint32_t)(len); \ - (xfer)->rx_ofs = (uint32_t)(ofs); \ - (xfer)->rx_idx = 0; \ - (xfer)->rx_totlen = ( (uint32_t)(len) \ - + (uint32_t)(ofs) ) ; \ - } - -/** Calculate total length of current transfer without next transfer */ -#define DEV_SPI_XFER_CALC_TOTLEN(xfer) (xfer)->tot_len = \ - ((xfer)->tx_totlen > (xfer)->rx_totlen) ? (xfer)->tx_totlen : (xfer)->rx_totlen ; - -/** Set next SPI transfer */ -#define DEV_SPI_XFER_SET_NEXT(xfer, next_xfer) (xfer)->next = (next_xfer); - -/** Init spi transfer */ -#define DEV_SPI_XFER_INIT(xfer) { \ - (xfer)->tx_idx = 0; \ - (xfer)->rx_idx = 0; \ - (xfer)->tx_totlen = ((xfer)->tx_len \ - + (xfer)->tx_ofs) ; \ - (xfer)->rx_totlen = ((xfer)->rx_len \ - + (xfer)->rx_ofs) ; \ - DEV_SPI_XFER_CALC_TOTLEN(xfer); \ - } -/** - * \brief spi information struct definition - * \details informations about spi open state, working state, - * frequency, spi registers, working method, interrupt number - */ -typedef struct dev_spi_info { - void *spi_ctrl; /*!< spi control related */ - uint32_t status; /*!< current working status, refer to \ref DEVICE_HAL_COMMON_DEVSTATUS, this should be \ref DEV_ENABLED for first open */ - uint32_t freq; /*!< spi working baudrate */ - uint8_t mode; /*!< spi working mode (master/slave) */ - uint8_t clk_mode; /*!< spi clock phase and polarity, this should be \ref SPI_CLK_MODE_DEFAULT for first open */ - uint8_t opn_cnt; /*!< spi open count, open it will increase 1, close it will decrease 1, 0 for close, >0 for open */ - uint8_t slave; /*!< current selected slave device no, start from 0, this should be \ref SPI_SLAVE_NOT_SELECTED for first open */ - uint8_t dfs; /*!< data frame size, this should be \ref SPI_DFS_DEFAULT for first open */ - - DEV_SPI_TRANSFER xfer; /*!< spi transfer, this should be set to all zero for first open */ - DEV_SPI_CBS spi_cbs; /*!< spi callbacks, for both master and slave mode, this should be all NULL for first open */ - void *extra; /*!< a extra pointer to get hook to applications which should not used by bsp developer, - this should be NULL for first open and you can \ref DEV_SPI_INFO_SET_EXTRA_OBJECT "set" - or \ref DEV_SPI_INFO_GET_EXTRA_OBJECT "get" the extra information pointer */ - uint32_t dummy; /*!< dummy write data when send and receive, this should be \ref SPI_DUMMY_DEFAULT for first open */ -} DEV_SPI_INFO, * DEV_SPI_INFO_PTR; - -/** Set extra information pointer of spi info */ -#define DEV_SPI_INFO_SET_EXTRA_OBJECT(spi_info_ptr, extra_info) (spi_info_ptr)->extra = (void *)(extra_info) -/** Get extra information pointer of spi info */ -#define DEV_SPI_INFO_GET_EXTRA_OBJECT(spi_info_ptr) ((spi_info_ptr)->extra) - -#define SPI_DFS_DEFAULT 8 /*!< Default spi data frame size */ -#define SPI_SLAVE_NOT_SELECTED (0xFF) /*!< Slave is not selected */ -#define SPI_DUMMY_DEFAULT (0xFF) /*!< default dummy value for first open */ - -/** - * \brief spi device interface definition - * \details define spi device interface, like spi information structure, - * fuctions to get spi info, open/close/control spi, send/receive data by spi - * \note all this details are implemented by user in user porting code - */ -typedef struct dev_spi { - DEV_SPI_INFO spi_info; /*!< spi device information */ - int32_t (*spi_open) (uint32_t mode, uint32_t param); /*!< open spi device in master/slave mode, \ - when in master mode, param stands for frequency, \ - when in slave mode, param stands for clock mode */ - int32_t (*spi_close) (void); /*!< close spi device */ - int32_t (*spi_control) (uint32_t ctrl_cmd, void *param); /*!< control spi device */ - int32_t (*spi_write) (const void *data, uint32_t len); /*!< send data to spi device (blocking method) */ - int32_t (*spi_read) (void *data, uint32_t len); /*!< read data from spi device (blocking method) */ -} DEV_SPI, * DEV_SPI_PTR; - -/** - * \fn int32_t (* dev_spi::spi_open) (uint32_t mode, uint32_t param) - * \details open an spi device with selected mode (master or slave) with defined \ref param - * \param[in] mode working mode (\ref DEV_MASTER_MODE "master" or \ref DEV_SLAVE_MODE "slave") - * \param[in] param When mode is \ref DEV_MASTER_MODE, param stands for \ref dev_spi_info::freq "frequency", - * when mode is \ref DEV_SLAVE_MODE, param stands for \ref dev_spi_info::clk_mode "slave clock mode" - * \retval E_OK Open successfully without any issues - * \retval E_OPNED If device was opened before with different parameters, - * then just increase the \ref dev_spi_info::opn_cnt "opn_cnt" and return \ref E_OPNED - * \retval E_OBJ Device object is not valid - * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first. - * \retval E_PAR Parameter is not valid - * \retval E_NOSPT Open settings are not supported - */ - -/** - * \fn int32_t (* dev_spi::spi_close) (void) - * \details close an spi device, just decrease the \ref dev_spi_info::opn_cnt "opn_cnt", - * if \ref dev_spi_info::opn_cnt "opn_cnt" equals 0, then close the device - * \retval E_OK Close successfully without any issues(including scenario that device is already closed) - * \retval E_OPNED Device is still opened, the device \ref dev_spi_info::opn_cnt "opn_cnt" decreased by 1 - * \retval E_OBJ Device object is not valid - */ - -/** - * \fn int32_t (* dev_spi::spi_control) (uint32_t ctrl_cmd, void *param) - * \details control an spi device by \ref ctrl_cmd, with passed \ref param. - * you can control spi device using predefined spi control commands defined using \ref DEV_SET_SYSCMD - * (which must be implemented by bsp developer), such as \ref SPI_CMD_MST_SET_FREQ "set spi master frequency", - * \ref SPI_CMD_FLUSH_TX "flush tx" and \ref DEVICE_HAL_SPI_CTRLCMD "more". - * And you can also control spi device using your own specified commands defined using \ref DEV_SET_USRCMD, - * but these specified commands should be defined in your own spi device driver implementation. - * \param[in] ctrl_cmd \ref DEVICE_HAL_SPI_CTRLCMD "control command", to change or get some thing related to spi - * \param[in,out] param parameters that maybe argument of the command, - * or return values of the command, must not be NULL - * \retval E_OK Control device successfully - * \retval E_CLSED Device is not opened - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled - * \retval E_CTX Control device failed, due to different reasons like in transfer state - * \retval E_NOSPT Control command is not supported or not valid - */ - -/** - * \fn int32_t (* dev_spi::spi_write) (const void *data, uint32_t len) - * \details send \ref data through spi with defined \ref len to slave device . - * \param[in] data pointer to data need to send by spi - * \param[in] len length of data to be sent - * \retval >0 Byte count that was successfully sent for poll method - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid - * \retval E_CTX Device is still in transfer state - * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled - */ - -/** - * \fn int32_t (* dev_spi::spi_read) (void *data, uint32_t len) - * \details receive \ref data of defined \ref len through spi from slave device . - * \param[out] data pointer to data need to received by spi - * \param[in] len length of data to be received - * \retval >0 Byte count that was successfully received for poll method - * \retval E_OBJ Device object is not valid or not exists - * \retval E_CTX Device is still in transfer state - * \retval E_PAR Parameter is not valid - * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled - */ -/** @} */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief get an \ref dev_spi "spi device" by spi device id. - * For how to use spi device hal refer to \ref dev_spi "Functions in spi device structure" - * \param[in] spi_id id of spi, defined by user - * \retval !NULL pointer to an \ref dev_spi "spi device structure" - * \retval NULL failed to find the spi device by \ref spi_id - * \note need to implemented by user in user code - */ -extern DEV_SPI_PTR spi_get_dev(int32_t spi_id); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* _DEVICE_HAL_SPI_H_ */ diff --git a/bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h b/bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h deleted file mode 100644 index c8e17d6421..0000000000 --- a/bsp/synopsys/embarc/device/device_hal/inc/dev_uart.h +++ /dev/null @@ -1,475 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-16 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \defgroup DEVICE_HAL_UART UART Device HAL Interface - * \ingroup DEVICE_HAL_DEF - * \brief Definitions for uart device hardware layer (\ref dev_uart.h) - * \details Provide unified APIs for uart driver to implement. - * Here is a diagram for the uart interface. - * - * \htmlonly - *
    - *
    - * UART Device HAL Interface Diagram - *

    UART Device HAL Interface Diagram

    - *
    - *
    - * \endhtmlonly - * - * ### Reference Links - * * [Serial Port](https://en.wikipedia.org/wiki/Serial_port) - * - * @{6 - * - * \file - * \brief uart device hardware layer definitions - * \details Provide common definitions for uart device, - * then software developer can develop uart driver - * following this definitions, and the applications - * can directly call this definition to realize functions - * - */ - -#ifndef _DEVICE_HAL_UART_H_ -#define _DEVICE_HAL_UART_H_ - -#include "device/device_hal/inc/dev_common.h" - -/** - * \defgroup DEVICE_HAL_UART_BAUD UART Device Baudrate Definitions - * \ingroup DEVICE_HAL_UART - * \brief Macros for uart baudrate. - * \details Definitions for baudrate from 4800 to 115200bps. - * @{ - */ -/* - * defines for uart baudrates - */ -#define UART_BAUDRATE_110 (110) /*!< uart baudrate 110bps */ -#define UART_BAUDRATE_300 (300) /*!< uart baudrate 300bps */ -#define UART_BAUDRATE_600 (600) /*!< uart baudrate 600bps */ -#define UART_BAUDRATE_1200 (1200) /*!< uart baudrate 1200bps */ -#define UART_BAUDRATE_2400 (2400) /*!< uart baudrate 2400bps */ -#define UART_BAUDRATE_4800 (4800) /*!< uart baudrate 4800bps */ -#define UART_BAUDRATE_9600 (9600) /*!< uart baudrate 9600bps */ -#define UART_BAUDRATE_14400 (14400) /*!< uart baudrate 14400bps */ -#define UART_BAUDRATE_19200 (19200) /*!< uart baudrate 19200bps */ -#define UART_BAUDRATE_38400 (38400) /*!< uart baudrate 38400bps */ -#define UART_BAUDRATE_57600 (57600) /*!< uart baudrate 57600bps */ -#define UART_BAUDRATE_115200 (115200) /*!< uart baudrate 115200bps */ -#define UART_BAUDRATE_230400 (230400) /*!< uart baudrate 230400bps */ -#define UART_BAUDRATE_460800 (460800) /*!< uart baudrate 460800bps */ -#define UART_BAUDRATE_921600 (921600) /*!< uart baudrate 921600bps */ -/** @} */ - -/** - * \defgroup DEVICE_HAL_UART_FORMAT UART Device Format Definitions - * \ingroup DEVICE_HAL_UART - * \brief Macros for uart format. - * \details Definitions for uart format like databits, parity, stopbits. - * @{ - */ -/** - * UART Device Parity Types Enum - */ -typedef enum { - UART_PARITY_NONE = 0, /*!< no parity bit */ - UART_PARITY_ODD = 1, /*!< odd parity bit */ - UART_PARITY_EVEN = 2, /*!< even parity bit */ - UART_PARITY_MARK = 3, /*!< mark parity bit, always logical 1 */ - UART_PARITY_SPACE = 4 /*!< space parity bit, always logical 0 */ -} UART_PARITY; - -/** - * UART Device Stop Bits Enum - */ -typedef enum { - UART_STPBITS_ONE = 0, /*!< 1 stop bit */ - UART_STPBITS_ONEHALF = 1, /*!< 1.5 stop bits */ - UART_STPBITS_TWO = 2 /*!< 2 stop bits */ -} UART_STOPBITS; - -/** - * UART DPS Format: databits/parity/stopbits - */ -typedef struct uart_dps_format { - uint32_t databits; /*!< data bits */ - UART_PARITY parity; /*!< parity bit type */ - UART_STOPBITS stopbits; /*!< stop bits */ -} UART_DPS_FORMAT; - -#define UART_DATABITS_DEFAULT 8 /*!< default data bits */ - -/** Default UART DPS format */ -static const UART_DPS_FORMAT dps_format_default = {UART_DATABITS_DEFAULT, UART_PARITY_NONE, UART_STPBITS_ONE}; -/** @} */ - -/** - * UART Device Hardware Flow Control Types Enum - */ -typedef enum { - UART_FC_NONE = 0, /*!< Non hardware flow control */ - UART_FC_RTS = 1, /*!< Request To Send */ - UART_FC_CTS = 2, /*!< Clear To Send */ - UART_FC_BOTH = 3 /*!< Both hardware flow control methods */ -} UART_HW_FLOW_CONTROL; -/** Default hardware flow control method */ -static const UART_HW_FLOW_CONTROL hwfc_default = UART_FC_NONE; - -/** - * \defgroup DEVICE_HAL_UART_CTRLCMD UART Device Control Commands - * \ingroup DEVICE_HAL_UART - * \brief Definitions for uart control command, used in \ref dev_uart::uart_control "UART IO Control" - * \details These commands defined here can be used in user code directly. - * - Parameters Usage - * - For passing parameters like integer, just use uint32_t/int32_t to directly pass values - * - For passing parameters for a structure, please use pointer to pass values - * - For getting some data, please use pointer to store the return data - * - Common Return Values - * - \ref E_OK, Control device successfully - * - \ref E_CLSED, Device is not opened - * - \ref E_OBJ, Device object is not valid or not exists - * - \ref E_PAR, Parameter is not valid for current control command - * - \ref E_SYS, Control device failed, due to hardware issues such as device is disabled - * - \ref E_CTX, Control device failed, due to different reasons like in transfer state - * - \ref E_NOSPT, Control command is not supported or not valid - * @{ - */ -/** - * Set \ref dev_uart_info::baudrate "uart baudrate". - * - Param type : uint32_t - * - Param usage : uart baudrate, must above zero. Here is a list of \ref DEVICE_HAL_UART_BAUD "possible baudrates" - * - Return value explanation : - */ -#define UART_CMD_SET_BAUD DEV_SET_SYSCMD(0) -/** - * Get \ref dev_uart_info::status "current device status" - * - Param type : uint32_t * - * - Param usage : store result of current status - * - Return value explanation : - */ -#define UART_CMD_GET_STATUS DEV_SET_SYSCMD(1) -/** - * Enable uart device - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define UART_CMD_ENA_DEV DEV_SET_SYSCMD(2) -/** - * Disable uart device, when device is disabled, - * only \ref UART_CMD_ENA_DEV, \ref UART_CMD_DIS_DEV and - * \ref UART_CMD_GET_STATUS commands can be executed, - * other commands will return \ref E_SYS - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define UART_CMD_DIS_DEV DEV_SET_SYSCMD(3) -/** - * Flush uart device output - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define UART_CMD_FLUSH_OUTPUT DEV_SET_SYSCMD(4) -/** - * Get how many bytes space in uart are available to transmit, - * this can be used in interrupt callback functions, - * cooperate with \ref dev_uart::uart_write "uart_write" API to realize non-blocked write - * - Param type : int32_t * - * - Param usage : store the write available bytes, > 0 for available bytes, 0 for not available - * - Return value explanation : - */ -#define UART_CMD_GET_TXAVAIL DEV_SET_SYSCMD(5) -/** - * Get how many bytes in uart are available to receive, - * this can be used in interrupt callback functions, - * cooperate with \ref dev_uart::uart_read "uart_read" API to realize non-blocked read - * - Param type : int32_t * - * - Param usage : store the read available bytes, > 0 for available bytes, 0 for not available - * - Return value explanation : - */ -#define UART_CMD_GET_RXAVAIL DEV_SET_SYSCMD(6) -/** - * Cause a break condition to be transmitted to the receiving device - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define UART_CMD_BREAK_SET DEV_SET_SYSCMD(7) -/** - * Clear break condition and return to normal - * - Param type : NULL - * - Param usage : param is not required - * - Return value explanation : - */ -#define UART_CMD_BREAK_CLR DEV_SET_SYSCMD(8) -/** - * Change uart \ref dev_uart_info::dps_format "D/P/S(Data/Parity/Stop) format" - * - Param type : \ref UART_DPS_FORMAT * - * - Param usage : uart dps format including databits, parity and stopbits - * - Return value explanation : - */ -#define UART_CMD_SET_DPS_FORMAT DEV_SET_SYSCMD(9) -/** - * Set uart device \ref dev_uart_info::hwfc "hardware flow control" - * - Param type : \ref UART_HW_FLOW_CONTROL - * - Param usage : uart dps format including databits, parity and stopbits - * - Return value explanation : - */ -#define UART_CMD_SET_HWFC DEV_SET_SYSCMD(10) -/** - * Set \ref dev_uart_cbs::tx_cb "uart transmit success callback" function - * when all required bytes are transmitted for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : transmit success callback function for uart - * - Return value explanation : - */ -#define UART_CMD_SET_TXCB DEV_SET_SYSCMD(11) -/** - * Set \ref dev_uart_cbs::rx_cb "uart receive success callback" function - * when all required bytes are received for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : receive success callback function for uart - * - Return value explanation : - */ -#define UART_CMD_SET_RXCB DEV_SET_SYSCMD(12) -/** - * Set \ref dev_uart_cbs::err_cb "uart transfer error callback" function - * when something error happened for interrupt method - * - Param type : \ref DEV_CALLBACK * or NULL - * - Param usage : transfer error callback function for uart - * - Return value explanation : - */ -#define UART_CMD_SET_ERRCB DEV_SET_SYSCMD(13) -/** - * Set transmit buffer via interrupt, and it will set \ref dev_uart_info::tx_buf "tx_buf" - * - Param type : DEV_BUFFER * or NULL - * - Param usage : buffer structure pointer, if param is NULL, then it will set tx_buf to NULL - * - Return value explanation : - */ -#define UART_CMD_SET_TXINT_BUF DEV_SET_SYSCMD(14) -/** - * Set receive buffer via interrupt, and it will set \ref dev_uart_info::rx_buf "rx_buf" - * - Param type : DEV_BUFFER * or NULL - * - Param usage : buffer structure pointer, if param is NULL, then it will set rx_buf to NULL - * - Return value explanation : - */ -#define UART_CMD_SET_RXINT_BUF DEV_SET_SYSCMD(15) -/** - * Enable or disable transmit interrupt - * - Param type : uint32_t - * - Param usage : enable(none-zero) or disable(zero) flag - * - Return value explanation : - */ -#define UART_CMD_SET_TXINT DEV_SET_SYSCMD(16) -/** - * Enable or disable receive interrupt - * - Param type : uint32_t - * - Param usage : enable(none-zero) or disable(zero) flag - * - Return value explanation : - */ -#define UART_CMD_SET_RXINT DEV_SET_SYSCMD(17) -/** - * Abort current interrupt transmit operation if tx interrupt enabled, - * it will disable transmit interrupt, and set \ref DEV_IN_TX_ABRT - * in \ref dev_uart_info::status "status" variable, - * and call the transmit callback function, when tx callback is finished, - * it will clear \ref DEV_IN_TX_ABRT and return - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define UART_CMD_ABORT_TX DEV_SET_SYSCMD(18) -/** - * Abort current interrupt receive operation if rx interrupt enabled, - * it will disable receive interrupt, and set \ref DEV_IN_TX_ABRT - * in \ref dev_uart_info::status "status" variable, - * and call the receive callback function, when rx callback is finished, - * it will clear \ref DEV_IN_TX_ABRT and return - * - Param type : NULL - * - Param usage : - * - Return value explanation : - */ -#define UART_CMD_ABORT_RX DEV_SET_SYSCMD(19) - -/** @} */ - -/** - * \defgroup DEVICE_HAL_UART_CALLBACK UART Interrupt callback functions - * \ingroup DEVICE_HAL_UART - * \brief callback function structure for UART device - * @{ - */ -typedef struct dev_uart_cbs { - DEV_CALLBACK tx_cb; /*!< uart data transmit success required bytes callback */ - DEV_CALLBACK rx_cb; /*!< uart data receive success required bytes callback */ - DEV_CALLBACK err_cb; /*!< uart error callback */ -} DEV_UART_CBS, *DEV_UART_CBS_PTR; -/** @} */ - -/** - * \defgroup DEVICE_HAL_UART_DEVSTRUCT UART Device Interface Definition - * \ingroup DEVICE_HAL_UART - * \brief Contains definitions of uart device interface structure. - * \details This structure will be used in user implemented code, which was called - * \ref DEVICE_IMPL "Device Driver Implement Layer" for uart to use in implementation code. - * Application developer should use the UART API provided here to access to UART devices. - * BSP developer should follow the API definition to implement UART device drivers. - * @{ - */ -/** - * \brief UART information struct definition - * \details informations about uart open count, working status, - * baudrate, uart registers and ctrl structure, uart dps format - */ -typedef struct dev_uart_info { - void *uart_ctrl; /*!< uart control related pointer, implemented by bsp developer, and this should be set during uart object implementation */ - uint32_t opn_cnt; /*!< uart open count, open it will increase 1, close it will decrease 1, 0 for close, >0 for open */ - uint32_t status; /*!< current working status, refer to \ref DEVICE_HAL_COMMON_DEVSTATUS, this should be \ref DEV_ENABLED for first open */ - uint32_t baudrate; /*!< uart baud rate, this should be the value of baud passing by uart_open if first successfully opened */ - UART_DPS_FORMAT dps_format; /*!< D/P/S format settings for uart device, here is \ref dps_format_default "default settings for first open" */ - UART_HW_FLOW_CONTROL hwfc; /*!< UART hardware flow control, here is \ref hwfc_default "default hardware flow control settings for first open" */ - DEV_BUFFER tx_buf; /*!< transmit buffer via interrupt, this should be all zero for first open */ - DEV_BUFFER rx_buf; /*!< receive buffer via interrupt, this should be all zero for first open */ - DEV_UART_CBS uart_cbs; /*!< uart callbacks, callback arguments should be \ref DEV_UART * or NULL, this should be all NULL for first open */ - void *extra; /*!< a extra pointer to get hook to applications which should not used by bsp developer, - this should be NULL for first open and you can \ref DEV_UART_INFO_SET_EXTRA_OBJECT "set" - or \ref DEV_UART_INFO_GET_EXTRA_OBJECT "get" the extra information pointer */ -} DEV_UART_INFO, * DEV_UART_INFO_PTR; - -/** Set extra information pointer of uart info */ -#define DEV_UART_INFO_SET_EXTRA_OBJECT(uart_info_ptr, extra_info) (uart_info_ptr)->extra = (void *)(extra_info) -/** Get extra information pointer of uart info */ -#define DEV_UART_INFO_GET_EXTRA_OBJECT(uart_info_ptr) ((uart_info_ptr)->extra) - -/** - * \brief UART device interface definition - * \details Define uart device interface, like uart information structure, - * provide functions to open/close/control uart, send/receive data by uart - * \note All this details are implemented by user in user porting code - */ -typedef struct dev_uart { - DEV_UART_INFO uart_info; /*!< UART device information */ - int32_t (*uart_open) (uint32_t baud); /*!< Open uart device */ - int32_t (*uart_close) (void); /*!< Close uart device */ - int32_t (*uart_control) (uint32_t ctrl_cmd, void *param); /*!< Control uart device */ - int32_t (*uart_write) (const void *data, uint32_t len); /*!< Send data by uart device(blocked) */ - int32_t (*uart_read) (void *data, uint32_t len); /*!< Read data from uart device(blocked) */ -} DEV_UART, * DEV_UART_PTR; - -/** - * \fn int32_t (* dev_uart::uart_open) (uint32_t baud) - * \details open an uart device with defined baudrate - * \param[in] baud \ref DEVICE_HAL_UART_BAUD "initial baudrate of uart", must > 0 - * \retval E_OK Open successfully without any issues - * \retval E_OPNED If device was opened before with different parameters, - * then just increase the \ref dev_uart_info::opn_cnt "opn_cnt" and return \ref E_OPNED - * \retval E_OBJ Device object is not valid - * \retval E_PAR Parameter is not valid - * \retval E_NOSPT Open settings are not supported - */ - -/** - * \fn int32_t (* dev_uart::uart_close) (void) - * \details close an uart device, just decrease the \ref dev_uart_info::opn_cnt "opn_cnt", - * if \ref dev_uart_info::opn_cnt "opn_cnt" equals 0, then close the device - * \retval E_OK Close successfully without any issues(including scenario that device is already closed) - * \retval E_OPNED Device is still opened, the device \ref dev_uart_info::opn_cnt "opn_cnt" decreased by 1 - * \retval E_OBJ Device object is not valid - */ - -/** - * \fn int32_t (* dev_uart::uart_control) (uint32_t ctrl_cmd, void *param) - * \details control an uart device by \ref ctrl_cmd, with passed \ref param. - * you can control uart device using predefined uart control commands defined using \ref DEV_SET_SYSCMD - * (which must be implemented by bsp developer), such as \ref UART_CMD_SET_BAUD "change baudrate", - * \ref UART_CMD_FLUSH_OUTPUT "flush output" and \ref DEVICE_HAL_UART_CTRLCMD "more". - * And you can also control uart device using your own specified commands defined using \ref DEV_SET_USRCMD, - * but these specified commands should be defined in your own uart device driver implementation. - * \param[in] ctrl_cmd \ref DEVICE_HAL_UART_CTRLCMD "control command", to change or get some thing related to uart - * \param[in,out] param parameters that maybe argument of the command, or return values of the command - * \retval E_OK Control device successfully - * \retval E_CLSED Device is not opened - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid for current control command - * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled - * \retval E_CTX Control device failed, due to different reasons like in transfer state - * \retval E_NOSPT Control command is not supported or not valid - */ - -/** - * \fn int32_t (* dev_uart::uart_write) (const void *data, uint32_t len) - * \details send \ref data through uart with defined \ref len(blocked). - * \param[in] data pointer to data need to send by uart, must not be NULL - * \param[in] len length of data to be sent, must > 0 - * \retval >0 Byte count that was successfully sent for poll method - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid - * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled - */ - -/** - * \fn int32_t (* dev_uart::uart_read) (void *data, uint32_t len) - * \details receive \ref data of defined \ref len through uart(blocked). - * \param[out] data pointer to data need to received by uart, must not be NULL - * \param[in] len length of data to be received, must > 0 - * \retval >0 Byte count that was successfully received for poll method - * \retval E_OBJ Device object is not valid or not exists - * \retval E_PAR Parameter is not valid - * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled - */ -/** @} */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief get an \ref dev_uart "uart device" by uart device id. - * For how to use uart device hal refer to \ref DEVICE_HAL_UART_DEVSTRUCT "Functions in uart device structure" - * \param[in] uart_id id of uart, defined by user - * \retval !NULL pointer to an \ref dev_uart "uart device structure" - * \retval NULL failed to find the uart device by \ref uart_id - * \note need to implemented by user in user code - */ -extern DEV_UART_PTR uart_get_dev(int32_t uart_id); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* _DEVICE_HAL_UART_H_ */ diff --git a/bsp/synopsys/embarc/inc/arc/arc.h b/bsp/synopsys/embarc/inc/arc/arc.h deleted file mode 100644 index 91c0a3850e..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc.h +++ /dev/null @@ -1,436 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-20 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_CORE_COMM - * \brief header file including common core definitions - */ - - /** - * \addtogroup ARC_HAL_CORE_COMM - * @{ - */ - - -#ifndef _ARC_HAL_CORE_H_ -#define _ARC_HAL_CORE_H_ - -#include "inc/arc/arc_feature_config.h" - -/** - * \name exception number definitions - * @{ - */ - -/* ARC exception number */ -#define EXC_NO_RESET (0) /*!< reset vector, the entry of power up and reset */ -#define EXC_NO_MEM_ERR (1) /*!< external memory bus error */ -#define EXC_NO_INS_ERR (2) /*!< illegal instruction or illegal instruction sequence */ -#define EXC_NO_MAC_CHK (3) /*!< machine check error */ -#define EXC_NO_TLB_MISS_I (4) /*!< instruction TLB missing exception, useless without MMU */ -#define EXC_NO_TLB_MISS_D (5) /*!< data TLB missing exception, useless without MMU */ -#define EXC_NO_PRO_VIO (6) /*!< protection violation */ -#define EXC_NO_PRI_VIO (7) /*!< privilege violation */ -#define EXC_NO_SWI (8) /*!< software interrupt */ -#define EXC_NO_TRAP (9) /*!< trap */ -#define EXC_NO_EXT (10) /*!< extension exception */ -#define EXC_NO_DIV_ZER0 (11) /*!< divide by zero */ -#define EXC_NO_DC_ERR (12) /*!< data cache consistency error */ -#define EXC_NO_MAL_ALIGN (13) /*!< misaligned data access */ -#define EXC_NO_RESERVE0 (14) /*!< reserved */ -#define EXC_NO_RESERVE1 (15) /*!< reserved */ - -/* extension interrupts */ -#define EXC_NO_16 (16) /*!< interrupt vector 16 */ -#define EXC_NO_17 (17) /*!< interrupt vector 17 */ -#define EXC_NO_18 (18) /*!< interrupt vector 18 */ -#define EXC_NO_19 (19) /*!< interrupt vector 19 */ -#define EXC_NO_20 (20) /*!< interrupt vector 20 */ -#define EXC_NO_21 (21) /*!< interrupt vector 21 */ -#define EXC_NO_22 (22) /*!< interrupt vector 22 */ -#define EXC_NO_23 (23) /*!< interrupt vector 23 */ -#define EXC_NO_24 (24) /*!< interrupt vector 24 */ -#define EXC_NO_25 (25) /*!< interrupt vector 25 */ -#define EXC_NO_26 (26) /*!< interrupt vector 26 */ -#define EXC_NO_27 (27) /*!< interrupt vector 27 */ -#define EXC_NO_28 (28) /*!< interrupt vector 28 */ -#define EXC_NO_29 (29) /*!< interrupt vector 29 */ -#define EXC_NO_30 (30) /*!< interrupt vector 30 */ -#define EXC_NO_31 (31) /*!< interrupt vector 31 */ -/* ... ARC supports 255 interrupt vectors at most */ -#define EXC_NO_255 (255) /*!< interrupt vector 255 */ - -/** @} */ - -/** - * \name exception vector offset - * @{ - */ -#define EXC_NO_TO_OFFSET(no) (no << 2) - -/* ARC exception vector offset */ -#define EXC_VECTOR_RESET (0x00) /*!< EXC_NO_RESET offset */ -#define EXC_VECTOR_MEM_ERR (0x04) /*!< EXC_NO_MEM_ERR offset */ -#define EXC_VECTOR_INS_ERR (0x08) /*!< EXC_NO_INS_ERR offset */ -#define EXC_VECTOR_MAC_CHK (0x0c) /*!< EXC_NO_MAC_CHK offset */ -#define EXC_VECTOR_TLB_MISS_I (0x10) /*!< EXC_NO_TLB_MISS_I offset */ -#define EXC_VECTOR_TLB_MISS_D (0x14) /*!< EXC_NO_TLB_MISS_D offset */ -#define EXC_VECTOR_PRO_VIO (0x18) /*!< EXC_NO_PRO_VIO offset */ -#define EXC_VECTOR_PRI_VIO (0x1c) /*!< EXC_NO_PRI_VIO offset */ -#define EXC_VECTOR_SWI (0x20) /*!< EXC_NO_SWI offset */ -#define EXC_VECTOR_TRAP (0x24) /*!< EXC_NO_TRAP offset */ -#define EXC_VECTOR_EXT (0x28) /*!< EXC_NO_EXT offset */ -#define EXC_VECTOR_DIV_ZER0 (0x2c) /*!< EXC_NO_DIV_ZER0 offset */ -#define EXC_VECTOR_DC_ERR (0x30) /*!< EXC_NO_DC_ERR offset */ -#define EXC_VECTOR_MAL_ALIGN (0x34) /*!< EXC_NO_MAL_ALIGN offset */ -#define EXC_VECTOR_RESERVE0 (0x38) /*!< EXC_NO_RESERVE0 offset */ -#define EXC_VECTOR_RESERVE1 (0x3c) /*!< EXC_NO_RESERVE1 offset */ -/** @} */ - -/** - * \name build configuration register - * @{ - */ -#define AUX_BCR_VER (0x60) /*!< build configuration register version */ -#define AUX_BCR_BTA (0x63) /*!< build configuration for BTA LINK */ -#define AUX_BCR_VECBASE (0x68) /*!< build configuration for interrupt vector base */ -#define AUX_BCR_MPU (0x6d) /*!< build configuration for memory protection unit */ -#define AUX_BCR_RF (0x6e) /*!< build configuration for core registers */ -#define AUX_BCR_D_CACHE (0x72) /*!< build configuration for data cache */ -#define AUX_BCR_DCCM (0x74) /*!< build configuration for DCCM */ -#define AUX_BCR_TIMERS (0x75) /*!< build configuration for processor timers */ -#define AUX_BCR_AP (0x76) /*!< build configuration for actionpoints */ -#define AUX_BCR_I_CACHE (0x77) /*!< build configuration for instruction cache */ -#define AUX_BCR_ICCM (0x78) /*!< build configuration for ICCM */ -#define AUX_BCR_DSP (0x7a) /*!< build configuration for DSP */ -#define AUX_BCR_MUL (0x7b) /*!< build configuration for multiply */ -#define AUX_BCR_SWAP (0x7c) /*!< build configuration for swap */ -#define AUX_BCR_NORM (0x7d) /*!< build configuration for normalize */ -#define AUX_BCR_MIXMAX (0x7e) /*!< build configuration for MIN/MAX */ -#define AUX_BCR_BARREL (0x7f) /*!< build configuration for barrel shift */ -#define AUX_BCR_ISA (0xc1) /*!< build configuration for ISA configuration */ -#define AUX_BCR_STACK (0xc5) /*!< build configuration for stack region */ -#define AUX_BCR_ERP (0xc7) /*!< build configuration for error protection */ -#define AUX_BCR_FPU (0xc8) /*!< build configuration for floating-point unit */ -#define AUX_BCR_CPORT (0xc9) /*!< build configuration for code protection */ -#define AUX_BCR_BS (0xcb) /*!< build configuration for bitstream */ -#define AUX_BCR_AGU (0xcc) /*!< build configuration for address generate unit */ -#define AUX_BCR_DMAC (0xcd) /*!< build configuration for DMA */ -#define AUX_BCR_CONNECT_SYSTEM (0xd0) /*!< build configuration for arc connect */ -#define AUX_BCR_CONNECT_SEMA (0xd1) /*!< build configuration for inter-core semaphore */ -#define AUX_BCR_CONNECT_MESSAGE (0xd2) /*!< build configuration for inter-code message */ -#define AUX_BCR_CONNECT_PMU (0xd3) /*!< build configuration for power management unit */ -#define AUX_BCR_CONNECT_GFRC (0xd6) /*!< build configuration for global free running counter */ -#define AUX_BCR_CAL_STORE (0xd9) /*!< build configuration for calibration parameter storage */ -#define AUX_BCR_CONNECT_ICI (0xe0) /*!< build configuration for inter-core interrupt unit */ -#define AUX_BCR_CONNECT_ICD (0xe1) /*!< build configuration for inter-core debug unit */ -#define AUX_BCR_CONNECT_PDM (0xe3) /*!< build configuration for power domain management unit*/ -#define AUX_BCR_RTT (0xf2) /*!< build configuration for real-time trace */ -#define AUX_BCR_IRQ (0xf3) /*!< build configuration for interrupt */ -#define AUX_BCR_PCT (0xf5) /*!< build configuration for performance counters */ -#define AUX_BCR_CC (0xf6) /*!< build configuration for performance counters */ -#define AUX_BCR_PDM_DVFS (0xf7) /*!< build configuration for PDM and DVFS */ - -#define AUX_BCR_SEC_BUILD (0xdb) - -/* from 0xF5 and 0xF6 */ - -#define AUX_BCR_IFQUEUE (0xfe) /*!< build configuration for instruction fetch queue */ -#define AUX_BCR_SMART (0xff) /*!< build configuration for SmaRT debug feature */ -/** @} */ - - -#define AUX_SEC_STAT (0x9) -#define AUX_SEC_STAT_BIT_SSC (0) -#define AUX_SEC_STAT_BIT_NSRT (1) -#define AUX_SEC_STAT_BIT_NSRU (2) -#define AUX_SEC_STAT_BIT_IRM (3) -#define AUX_SEC_STAT_BIT_SUE (4) -#define AUX_SEC_STAT_BIT_NIC (5) - -/** - * \name status register STATUS32 - * @{ - */ -#define AUX_STATUS32 (0xa) -#define AUX_STATUS32_P0 (0xb) - -/* STATUS32 bit-field definition */ -#define AUX_STATUS_BIT_AE (5) /*!< processor is in an exception */ -#define AUX_STATUS_BIT_DE (6) /*!< delayed branch is pending */ -#define AUX_STATUS_BIT_U (7) /*!< user mode */ -#define AUX_STATUS_BIT_L (12) /*!< zero-overhead loop enable */ -#define AUX_STATUS_BIT_IE (31) /*!< interrupt enable */ - -/* masks correspond to STATUS32 bit-field */ -#define AUX_STATUS_MASK_AE (1< Pre Incr - * Eff Addr for load = [reg2 + x] - * - * LD.ab reg1, [reg2, x] => Post Incr - * Eff Addr for load = [reg2] - */ -#if defined(__GNU__) -.macro PUSH reg - st.a \reg, [sp, -4] -.endm - -.macro PUSHAX aux - lr r10, [\aux] - PUSH r10 -.endm - -.macro POP reg - ld.ab \reg, [sp, 4] -.endm - -.macro POPAX aux - POP r10 - sr r10, [\aux] -.endm -#else -.macro PUSH, reg - st.a reg, [sp, -4] -.endm - -.macro PUSHAX, aux - lr r10, [aux] - PUSH r10 -.endm - -.macro POP, reg - ld.ab reg, [sp, 4] -.endm - -.macro POPAX, aux - POP r10 - sr r10, [aux] -.endm -#endif - -/*-------------------------------------------------------------- - * Helpers to save/restore callee-saved regs: - * used by several macros below - *-------------------------------------------------------------*/ -.macro SAVE_CALLEE_REGS - PUSH r13 - PUSH r14 - PUSH r15 -#ifndef ARC_FEATURE_RF16 - PUSH r16 - PUSH r17 - PUSH r18 - PUSH r19 - PUSH r20 - PUSH r21 - PUSH r22 - PUSH r23 - PUSH r24 - PUSH r25 -#endif -.endm - -.macro RESTORE_CALLEE_REGS -#ifndef ARC_FEATURE_RF16 - POP r25 - POP r24 - POP r23 - POP r22 - POP r21 - POP r20 - POP r19 - POP r18 - POP r17 - POP r16 -#endif - POP r15 - POP r14 - POP r13 -.endm - -.macro CLEAR_CALLEE_REGS -#ifndef ARC_FEATURE_RF16 - mov r25, 0 - mov r24, 0 - mov r23, 0 - mov r22, 0 - mov r21, 0 - mov r20, 0 - mov r19, 0 - mov r18, 0 - mov r17, 0 - mov r16, 0 -#endif - mov r15, 0 - mov r14, 0 - mov r13, 0 -.endm - -.macro CLEAR_SCRATCH_REGS - mov r1, 0 - mov r2, 0 - mov r3, 0 - mov r4, 0 - mov r5, 0 - mov r6, 0 - mov r7, 0 - mov r8, 0 - mov r9, 0 - mov r10, 0 - mov r11, 0 - mov r12, 0 - - mov fp, 0 - mov r29, 0 - mov r30, 0 -.endm - - -.macro SAVE_LP_REGS - PUSH r60 - PUSHAX AUX_LP_START - PUSHAX AUX_LP_END -.endm - -.macro RESTORE_LP_REGS - POPAX AUX_LP_END - POPAX AUX_LP_START - POP r10 -/* must not use the LP_COUNT register(r60) as the destination of multi-cycle instruction */ - mov r60, r10 - -.endm - -.macro SAVE_R0_TO_R12 - PUSH r0 - PUSH r1 - PUSH r2 - PUSH r3 -#ifndef ARC_FEATURE_RF16 - PUSH r4 - PUSH r5 - PUSH r6 - PUSH r7 - PUSH r8 - PUSH r9 -#endif - PUSH r10 - PUSH r11 - PUSH r12 -.endm - -.macro RESTORE_R0_TO_R12 - POP r12 - POP r11 - POP r10 -#ifndef ARC_FEATURE_RF16 - POP r9 - POP r8 - POP r7 - POP r6 - POP r5 - POP r4 -#endif - POP r3 - POP r2 - POP r1 - POP r0 -.endm - -.macro SAVE_CODE_DENSITY - PUSHAX AUX_JLI_BASE - PUSHAX AUX_LDI_BASE - PUSHAX AUX_EI_BASE -.endm - -.macro RESTORE_CODE_DENSITY - POPAX AUX_EI_BASE - POPAX AUX_LDI_BASE - POPAX AUX_JLI_BASE -.endm - -/* todo: check the contents of NON_SCRATCH_REGS in debug */ -.macro SAVE_NONSCRATCH_REGS -/* r0-r12 are saved by caller function */ - PUSH gp - PUSH fp - PUSH blink - SAVE_CALLEE_REGS -.endm - -.macro RESTORE_NONSCRATCH_REGS - RESTORE_CALLEE_REGS - POP blink - POP fp - POP gp -.endm - - -.macro SAVE_FIQ_EXC_REGS -#ifndef ARC_FEATURE_RGF_BANKED_REGS - SAVE_R0_TO_R12 - - PUSH gp - PUSH fp - PUSH r30 /* general purpose */ - PUSH blink - -#else -#if ARC_FEATURE_RGF_BANKED_REGS != 4 && ARC_FEATURE_RGF_BANKED_REGS != 8 && \ - ARC_FEATURE_RGF_BANKED_REGS != 16 && ARC_FEATURE_RGF_BANKED_REGS != 32 -#error "unsupported ARC_FEATURE_RGF_BANKED_REGS" -#endif - -#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 || \ - ARC_FEATURE_RGF_BANKED_REGS == 16 - PUSH r4 - PUSH r5 - PUSH r6 - PUSH r7 - PUSH r8 - PUSH r9 -#endif - -#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 - PUSH r10 - PUSH r11 -#endif - -#if ARC_FEATURE_RGF_BANKED_REGS == 4 - PUSH r12 -#endif - -#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 - PUSH gp - PUSH fp - PUSH r30 /* general purpose */ - PUSH blink -#endif - -#endif /* #ifndef ARC_FEATURE_RGF_BANKED_REGS */ - -#ifdef ARC_FEATURE_CODE_DENSITY - SAVE_CODE_DENSITY -#endif - SAVE_LP_REGS -.endm - -.macro RESTORE_FIQ_EXC_REGS - RESTORE_LP_REGS -#ifdef ARC_FEATURE_CODE_DENSITY - RESTORE_CODE_DENSITY -#endif - -#ifndef ARC_FEATURE_RGF_BANKED_REGS - POP blink - POP r30 - POP fp - POP gp - - RESTORE_R0_TO_R12 -#else - -#if ARC_FEATURE_RGF_BANKED_REGS != 4 && ARC_FEATURE_RGF_BANKED_REGS != 8 && \ - ARC_FEATURE_RGF_BANKED_REGS != 16 && ARC_FEATURE_RGF_BANKED_REGS != 32 -#error "unsupported ARC_FEATURE_RGF_BANKED_REGS" -#endif - -#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 - POP blink - POP r30 - POP fp - POP gp -#endif - -#if ARC_FEATURE_RGF_BANKED_REGS == 4 - POP r12 -#endif - -#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 - POP r11 - POP r10 -#endif - -#if ARC_FEATURE_RGF_BANKED_REGS == 4 || ARC_FEATURE_BANKED_REGS == 8 || \ - ARC_FEATURE_RGF_BANKED_REGS == 16 - POP r9 - POP r8 - POP r7 - POP r6 - POP r5 - POP r4 -#endif - -#endif /* #ifndef ARC_FEATURE_RGF_BANKED_REGS */ -.endm - -/* normal interrupt prologue, pc, status and r0-r11 are saved by hardware */ -.macro INTERRUPT_PROLOGUE - PUSH r12 - PUSH gp - PUSH fp - PUSH ilink - PUSH r30 - - sub sp, sp, 4 /* skip bta */ -.endm - - -/* normal interrupt epilogue, pc, status and r0-r11 are restored by hardware */ -.macro INTERRUPT_EPILOGUE - add sp, sp, 4 /* skip bta */ - - POP r30 - POP ilink - POP fp - POP gp - POP r12 -.endm - -#if SECURESHIELD_VERSION == 2 -/* exception prologue, create the same frame of interrupt manually */ -.macro EXCEPTION_PROLOGUE - st.as r10, [sp, -6] /* save r10 first, free up a register*/ - - PUSHAX AUX_ERSTATUS - sub sp, sp, 4 /* slot for SEC_STAT */ - PUSHAX AUX_ERRET - - PUSH blink - - PUSH r11 - sub sp, sp, 4 /* r10 is pushed before */ -#ifndef ARC_FEATURE_RF16 - PUSH r9 - PUSH r8 - PUSH r7 - PUSH r6 - PUSH r5 - PUSH r4 -#endif - PUSH r3 - PUSH r2 - PUSH r1 - PUSH r0 - -#ifdef ARC_FEATURE_CODE_DENSITY - SAVE_CODE_DENSITY -#endif - SAVE_LP_REGS - - PUSH r12 - PUSH gp - PUSH fp - PUSH ilink - PUSH r30 - - PUSHAX AUX_ERBTA -.endm - -/* exception epilogue, restore the same frame of interrupt manually */ -.macro EXCEPTION_EPILOGUE - POPAX AUX_ERBTA - - POP r30 - POP ilink - POP fp - POP gp - POP r12 - - RESTORE_LP_REGS - -#ifdef ARC_FEATURE_CODE_DENSITY - RESTORE_CODE_DENSITY -#endif - POP r0 - POP r1 - POP r2 - POP r3 -#ifndef ARC_FEATURE_RF16 - POP r4 - POP r5 - POP r6 - POP r7 - POP r8 - POP r9 -#endif - add sp, sp, 4 /* r10 will be popped finally */ - POP r11 - - POP blink - - - POPAX AUX_ERRET - add sp, sp, 4 /* slot for SEC_STAT */ - POPAX AUX_ERSTATUS - - ld.as r10, [sp, -6] /* restore r10 */ -.endm -#else /* normal version */ -/* exception prologue, create the same frame of interrupt manually */ -.macro EXCEPTION_PROLOGUE -#ifdef ARC_FEATURE_CODE_DENSITY - st.as r10, [sp, -11] /* save r10 first, free up a register*/ -#else - st.as r10, [sp, -8] -#endif - PUSHAX AUX_ERSTATUS - PUSHAX AUX_ERRET - -#ifdef ARC_FEATURE_CODE_DENSITY - SAVE_CODE_DENSITY -#endif - SAVE_LP_REGS - - PUSH blink - - PUSH r11 - sub sp, sp, 4 /* r10 is pushed before */ -#ifndef ARC_FEATURE_RF16 - PUSH r9 - PUSH r8 - PUSH r7 - PUSH r6 - PUSH r5 - PUSH r4 -#endif - PUSH r3 - PUSH r2 - PUSH r1 - PUSH r0 - - PUSH r12 - PUSH gp - PUSH fp - PUSH ilink - PUSH r30 - - PUSHAX AUX_ERBTA -.endm - -/* exception epilogue, restore the same frame of interrupt manually */ -.macro EXCEPTION_EPILOGUE - POPAX AUX_ERBTA - - POP r30 - POP ilink - POP fp - POP gp - POP r12 - - POP r0 - POP r1 - POP r2 - POP r3 -#ifndef ARC_FEATURE_RF16 - POP r4 - POP r5 - POP r6 - POP r7 - POP r8 - POP r9 -#endif - add sp, sp, 4 /* r10 will be popped finally */ - POP r11 - - POP blink - - RESTORE_LP_REGS - -#ifdef ARC_FEATURE_CODE_DENSITY - RESTORE_CODE_DENSITY -#endif - - POPAX AUX_ERRET - POPAX AUX_ERSTATUS - -#ifdef ARC_FEATURE_CODE_DENSITY - ld.as r10, [sp, -11] /* restore r10 */ -#else - ld.as r10, [sp, -8] -#endif -.endm - -#endif /* SECURESHIELD_VERSION == 2 */ - -#endif /* _ARC_HAL_ASM_COMMON_H */ -/** @endcond */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_builtin.h b/bsp/synopsys/embarc/inc/arc/arc_builtin.h deleted file mode 100644 index d9b76124ff..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_builtin.h +++ /dev/null @@ -1,301 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-12 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_BUILTIN - * \brief header file of builtin and helper functions - * - * The Metaware toolchain and the GNU toolchain are supported. The details please go to see the file. - */ - -/** - * \addtogroup ARC_HAL_BUILTIN - * @{ - */ - -#ifndef _ARC_HAL_BUILTIN_H_ -#define _ARC_HAL_BUILTIN_H_ - -#include "inc/embARC_toolchain.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined (__MW__) /* Metaware toolchain */ - -#define _arc_nop _nop /*!< no operation, generate a nop instruction produces a single NOP instruction in the compiled code */ - -#define _arc_brk _brk /*!< generate a brk instruction */ - -#define _arc_clri _clri /*!< generate a clri instruction */ - -#define _arc_seti(c) _seti(c) /*!< generate a seti instruction */ - -#define _arc_core_write(regno, val) _core_write(val, regno) /*!< write core register */ - -#define _arc_core_read(regno) _core_read(regno) /*!< read core register */ - -#define _arc_lr_reg(aux) _lr(aux) /*!< read auxiliary register */ - -#define _arc_sr_reg(aux, val) _sr(val, aux) /*!< write auxiliary register */ - -#define _arc_sleep(a) _sleep(a) /*!< generate a sleep instruction */ - -#define _arc_flag(a) _flag(a) /*!< generate a flag instruction */ - -#define _arc_kflag(a) - -#define _arc_sync _sync /*!< generate a sync instruction */ - -/* - * !< _arc_usually (expr) evaluates expression expr and - * informs the compiler that the value is usually true. - */ -#define _arc_usually(a) _Usually((a)) - -/* - * !< _arc_rarely (expr) evaluates expression expr and - * informs the compiler that the value is rarely true. - */ -#define _arc_rarely(a) _Rarely((a)) - -#if 0 -/** - * \brief Reverses the byte order of the 16-bit operand, - * reversing the endianness of the value. - * Not for ARC HS family - */ -#define _arc_swap16(a) _swap16(a) -/** - * \brief Reverses the byte order of the 32-bit operand, - * reversing the endianness of the value. - * Not for ARC HS family - */ -#define _arc_swap32(a) _swap32(a) -#else -Inline uint32_t _arc_swap32(uint32_t val) { - register uint32_t v; - __asm__ volatile ("swape %0, %1" :"=r"(v): "r"(val)); - return v; -} - -Inline uint16_t _arc_swap16(uint32_t val) { - register uint32_t temp; - register uint32_t v; - __asm__ volatile ("swape %0, %1" :"=r"(temp): "r"(val)); - __asm__ volatile ("lsr16 %0, %1" :"=r"(v): "r"(temp)); - return (unsigned short)v; -} -#endif - -/** - * \brief Each call to _swi() generates one - * software interrupt instruction (SWI) for processors - * to support the SWI instruction. - */ -#define _arc_swi _swi - -/* \todo add more builtin functions of metaware tool */ - -#elif defined (__GNU__) /* GNU toolchain */ - -#define _arc_nop __builtin_arc_nop -#define _arc_brk __builtin_arc_brk -#define _arc_seti(c) __builtin_arc_seti(c) -#define _arc_core_write(regno, val) __builtin_arc_core_write(regno,val) -#define _arc_core_read(regno) __builtin_arc_core_read(regno) -#define _arc_flag(a) __builtin_arc_flag(a) -#define _arc_kflag(a) __builtin_arc_kflag(a) -#define _arc_lr_reg(aux) __builtin_arc_lr(aux) -/* don't uncomment this now */ -//#define _arc_sr_reg(aux, val) __builtin_arc_sr(aux, val) -#define _arc_sleep(a) __builtin_arc_sleep(a) -//#define _arc_sync __builtin_arc_sync - -/** - * \brief _arc_usually (expr) evaluates expression expr and - * informs the compiler that the value is usually true. - */ -#define _arc_usually(a) __builtin_expect((int)(a), 1) - -/** - * \brief _arc_rarely (expr) evaluates expression expr and - * informs the compiler that the value is rarely true. - */ -#define _arc_rarely(a) __builtin_expect((int)(a), 0) - -/** - * \brief Each call to _swi() generates one - * software interrupt instruction (SWI) for processors - * to support the SWI instruction. - */ -#define _arc_swi __builtin_arc_swi - -Inline uint32_t _arc_clri(void) { - register uint32_t v; - __asm__ volatile ("clri %0" :"=r"(v)); - return v; - -} -/* \todo add more builtin functions of gnu tool */ - -Inline uint32_t _arc_swap32(uint32_t val) { - register uint32_t v; - __asm__ volatile ("swape %0, %1" :"=r"(v): "r"(val)); - return v; -} - -Inline uint16_t _arc_swap16(uint32_t val) { - register uint32_t temp; - register uint32_t v; - __asm__ volatile ("swape %0, %1" :"=r"(temp): "r"(val)); - __asm__ volatile ("lsr16 %0, %1" :"=r"(v): "r"(temp)); - return (unsigned short)v; -} - -Inline void _arc_sync(void) { - __asm__ volatile ("sync"); -} - -/** - * \note Following is a workaround for arc gcc - * built-in function __builtin_arc_sr. - * But it is wrong in GCC arc-4.8-R3-rc3 and shouldn't be used. - */ - -/* - * The auxiliary register address is specified as a long immediate operand by caller. - * e.g. - * write_aux_reg(0x69, some_val); - * This generates the tightest code. - */ -#define write_aux_reg(reg_imm, val) \ -({ \ - Asm( \ - " sr %0, [%1] \n" \ - : \ - : "ir"(val), "r"(reg_imm)); \ -}) - -#define _arc_sr_reg(aux, val) write_aux_reg(aux, val) - -#endif - -/* \todo add more helper functions here, such as memory operation */ - -#define _arc_aux_read(aux) _arc_lr_reg(aux) -#define _arc_aux_write(aux, val) _arc_sr_reg(aux, val) - -/** - * \name cache related helper function - * @{ - */ - -/** - * \brief read memory and bypass the cache - * \param[in] ptr memory address - * \return value in the memory - */ -Inline uint32_t _arc_read_uncached_32(void *ptr) -{ - uint32_t __ret; - Asm("ld.di %0, [%1]":"=r"(__ret):"r"(ptr)); - return __ret; -} - -/** - * \brief write memory and bypass the cache - * \param[in] ptr memory address - * \param[in] data vaule to be written - */ -Inline void _arc_write_uncached_32(void *ptr, uint32_t data) -{ - Asm("st.di %0, [%1]":: "r"(data), "r"(ptr)); -} - -/** - * \brief read memory with cache - * \param[in] ptr memory address - * \returns value in the memory - */ -Inline uint32_t _arc_read_cached_32(void *ptr) -{ - uint32_t __ret; - Asm("ld %0, [%1]":"=r"(__ret):"r"(ptr)); - return __ret; -} - -/** - * \brief read memory with cache - * \param[in] ptr memory address - * \param[in] data vaule to be written - * \return description - */ -Inline void _arc_write_cached_32(void *ptr, uint32_t data) -{ - Asm("st %0, [%1]":: "r"(data), "r"(ptr)); -} - -/** - * \brief go to main function with proper arguments - * \param argc argument count - * \param argv argument content array - * \retval return value of main function - */ -Inline int32_t _arc_goto_main(int argc, char **argv) { - int __ret; - __asm__ volatile( - "mov %%r0, %1\n" - "mov %%r1, %2\n" - "push_s %%blink\n" - "jl main\n" - "pop_s %%blink\n" - "mov %0, %%r0" - :"=r"(__ret): "r"(argc), "r"(argv)); - return (int)__ret; -} - -#ifdef __cplusplus -} -#endif - -#if defined(LIB_SECURESHIELD) && defined(LIB_SECURESHIELD_OVERRIDES) && (SECURESHIELD_VERSION == 1) -#define OVERRIDE_ARC_HAL_BUILTIN_H -#include "secureshield_overrides.h" -#endif - -/** @} */ -#endif /* _ARC_HAL_BUILTIN_H_ */ -/** @} */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_cache.h b/bsp/synopsys/embarc/inc/arc/arc_cache.h deleted file mode 100644 index dfbc7df9a5..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_cache.h +++ /dev/null @@ -1,321 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-15 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_MISC_CACHE - * \brief header file of cache module - */ - -#ifndef _ARC_HAL_CACHE_H_ -#define _ARC_HAL_CACHE_H_ - -#include "inc/embARC_toolchain.h" -#include "inc/arc/arc.h" -#include "inc/arc/arc_builtin.h" -#include "inc/arc/arc_exception.h" - -/** - * \name instruction cache control register related definition - * \todo this definitions will be reviewed. - * @{ - */ -#define IC_CTRL_IC_ENABLE 0x0 /*!< enable instruction cache */ -#define IC_CTRL_IC_DISABLE 0x1 /*!< disable instruction cache */ -#define IC_CTRL_DIRECT_ACCESS 0x0 /*!< direct access mode */ -#define IC_CTRL_INDIRECT_ACCESS 0x20 /*!< indirect access mode */ -#define IC_CTRL_OP_SUCCEEDED 0x8 /*!< instruction cache operation succeeded */ -/** @} */ - -/** - * \name data cache control register related definition - * \todo this definition will be reviewed. - * @{ - */ -#define IC_CTRL_I -#define DC_CTRL_DC_ENABLE 0x0 /*!< enable data cache */ -#define DC_CTRL_DC_DISABLE 0x1 /*!< disable data cache */ -#define DC_CTRL_INVALID_ONLY 0x0 /*!< invalid data cache only */ -#define DC_CTRL_INVALID_FLUSH 0x40 /*!< invalid and flush data cache */ -#define DC_CTRL_ENABLE_FLUSH_LOCKED 0x80 /*!< the locked data cache can be flushed */ -#define DC_CTRL_DISABLE_FLUSH_LOCKED 0x0 /*!< the locked data cache cannot be flushed */ -#define DC_CTRL_FLUSH_STATUS 0x100 /*!< flush status */ -#define DC_CTRL_DIRECT_ACCESS 0x0 /*!< direct access mode */ -#define DC_CTRL_INDIRECT_ACCESS 0x20 /*!< indirect access mode */ -#define DC_CTRL_OP_SUCCEEDED 0x4 /*!< data cache operation succeeded */ -/** @} */ - -/** - * \name instruction cache related inline function - * @{ - */ - -/** - * \brief check whether instruction cache is available, - * 0 for not available, >0 for available - */ -Inline uint8_t icache_available(void) -{ - return (_arc_aux_read(AUX_BCR_I_CACHE) & 0xF); -} - -/** - * \brief enable instruction cache - * \param[in] icache_en_mask operation mask - */ -Inline void icache_enable(uint32_t icache_en_mask) -{ - if (!icache_available()) return; - _arc_aux_write(AUX_IC_CTRL, icache_en_mask); -} - -/** - * \brief disable instruction cache - */ -Inline void icache_disable(void) -{ - if (!icache_available()) return; - _arc_aux_write(AUX_IC_CTRL, IC_CTRL_IC_DISABLE); -} - -/** - * \brief invalidate the entire instruction cache - */ -Inline void icache_invalidate(void) -{ - if (!icache_available()) return; - /* invalidate the entire icache */ - _arc_aux_write(AUX_IC_IVIC, 0); - Asm("nop_s"); - Asm("nop_s"); - Asm("nop_s"); -} - -/** - * \brief invalidate specific cache line - * \param[in] address memory address - */ -Inline void icache_invalidate_line(uint32_t address) -{ - if (!icache_available()) return; - _arc_aux_write(AUX_IC_IVIL, address); - /* the 3 nops are required by ARCv2 ISA */ - Asm("nop_s"); - Asm("nop_s"); - Asm("nop_s"); -} - -/** - * \brief lock specific cache line - * \param[in] address memory address - * \return 0, succeeded, -1, failed - */ -Inline int32_t icache_lock_line(uint32_t address) -{ - if (!icache_available()) return -1; - _arc_aux_write(AUX_IC_LIL, address); - if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) { - return 0; - } else { - return -1; - } -} - -/** - * \brief set icache access mode - * \param[in] mode, access mode, 1: indirect access 0:direct access - */ -Inline void icache_access_mode(uint32_t mode) -{ - if (!icache_available()) return; - if (mode) { - _arc_aux_write(AUX_IC_CTRL, _arc_aux_read(AUX_IC_CTRL) | IC_CTRL_INDIRECT_ACCESS); - } else { - _arc_aux_write(AUX_IC_CTRL, _arc_aux_read(AUX_IC_CTRL) & (~IC_CTRL_INDIRECT_ACCESS)); - } -} - - -/** @} */ - -/** - * \name data cache related inline functions - * @{ - */ - -/** - * \brief check whether data cache is available, - * 0 for not available, >0 for available - */ -Inline uint8_t dcache_available(void) -{ - return (_arc_aux_read(AUX_BCR_D_CACHE) & 0xF); -} - -/** - * \brief invalidate the entire data cache - */ -Inline void dcache_invalidate(void) -{ - if (!dcache_available()) return; - uint32_t status; - - status = cpu_lock_save(); - _arc_aux_write(AUX_DC_IVDC, 1); - /* wait for flush completion */ - while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); - cpu_unlock_restore(status); -} - -/** - * \brief invalidate the specific cache line - * \param[in] address memory address - */ -Inline void dcache_invalidate_line(uint32_t address) -{ - if (!dcache_available()) return; - _arc_aux_write(AUX_DC_IVDL, address); - Asm("nop_s"); - Asm("nop_s"); - Asm("nop_s"); -} - -/** - * \brief enable data cache - * \param[in] dcache_en_mask operation mask - */ -Inline void dcache_enable(uint32_t dcache_en_mask) -{ - if (!dcache_available()) return; - _arc_aux_write(AUX_DC_CTRL, dcache_en_mask); -} - -/** - * \brief disable data cache - */ -Inline void dcache_disable(void) -{ - if (!dcache_available()) return; - _arc_aux_write(AUX_DC_CTRL, DC_CTRL_DC_DISABLE); -} - -/** - * \brief flush data cache - */ -Inline void dcache_flush(void) -{ - if (!dcache_available()) return; - uint32_t status; - - status = cpu_lock_save(); - _arc_aux_write(AUX_DC_FLSH, 1); - /* wait for flush completion */ - while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); - cpu_unlock_restore(status); -} - -/** - * \brief flush the specific data cache line - * \param[in] address memory address - */ -Inline void dcache_flush_line(uint32_t address) -{ - if (!dcache_available()) return; - - uint32_t status; - - status = cpu_lock_save(); - _arc_aux_write(AUX_DC_FLDL, address); - while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS); - cpu_unlock_restore(status); -} - -/** - * \brief lock the specific data cache line - * \param[in] address memory address - * \return 0, succeeded, -1, failed - */ -Inline int dcache_lock_line(uint32_t address) -{ - if (!dcache_available()) return -1; - _arc_aux_write(AUX_DC_LDL, address); - if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) { - return 0; - } else { - return -1; - } -} - -/** - * \brief set dcache access mode - * \param[in] mode, access mode, 1: indirect access 0:direct access - */ -Inline void dcache_access_mode(uint32_t mode) -{ - if (!dcache_available()) return; - if (mode) { - _arc_aux_write(AUX_DC_CTRL, _arc_aux_read(AUX_DC_CTRL) | DC_CTRL_INDIRECT_ACCESS); - } else { - _arc_aux_write(AUX_DC_CTRL, _arc_aux_read(AUX_DC_CTRL) & (~DC_CTRL_INDIRECT_ACCESS)); - } -} - -/** @} */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \name declarations of cache related functions - * @{ - */ -extern int32_t icache_invalidate_mlines(uint32_t start_addr, uint32_t size); -extern int32_t icache_lock_mlines(uint32_t start_addr, uint32_t size); -extern int32_t icache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data); -extern int32_t icache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data); -extern int32_t icache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data); -extern int32_t dcache_invalidate_mlines(uint32_t start_addr, uint32_t size); -extern int32_t dcache_flush_mlines(uint32_t start_addr, uint32_t size); -extern int32_t dcache_lock_mlines(uint32_t start_addr, uint32_t size); -extern int32_t dcache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data); -extern int32_t dcache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data); -extern int32_t dcache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data); -extern void arc_cache_init(void); - -#ifdef __cplusplus -} -#endif - -/** @} */ -#endif /* _ARC_HAL_CACHE_H_ */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_em.h b/bsp/synopsys/embarc/inc/arc/arc_em.h deleted file mode 100644 index cfb9636449..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_em.h +++ /dev/null @@ -1,133 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-06-12 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_CORE_EM - * \brief header file of EM series - */ - -/** - * \addtogroup ARC_HAL_CORE_EM - * @{ - */ - -#ifndef _ARC_HAL_EM_H_ -#define _ARC_HAL_EM_H_ - -#include "inc/arc/arc.h" - -#define AUX_ACC0_LO (0x580) -#define AUX_ACC0_GLO (0x581) -#define AUX_ACC0_HI (0x582) -#define AUX_ACC0_GHI (0x583) -#define AUX_DSP_BFLY0 (0x598) -#define AUX_DSP_FFT_CTRL (0x59e) -#define AUX_DSP_CTRL (0x59f) - -#define AUX_AGU_AUX_AP0 (0x5c0) -#define AUX_AGU_AUX_AP1 (0x5c1) -#define AUX_AGU_AUX_AP2 (0x5c2) -#define AUX_AGU_AUX_AP3 (0x5c3) -#define AUX_AGU_AUX_AP4 (0x5c4) -#define AUX_AGU_AUX_AP5 (0x5c5) -#define AUX_AGU_AUX_AP6 (0x5c6) -#define AUX_AGU_AUX_AP7 (0x5c7) -#define AUX_AGU_AUX_AP8 (0x5c8) -#define AUX_AGU_AUX_AP9 (0x5c9) -#define AUX_AGU_AUX_AP10 (0x5ca) -#define AUX_AGU_AUX_AP11 (0x5cb) -#define AUX_AGU_AUX_AP12 (0x5cc) -#define AUX_AGU_AUX_AP13 (0x5cd) -#define AUX_AGU_AUX_AP14 (0x5ce) -#define AUX_AGU_AUX_AP15 (0x5cf) - -#define AUX_AGU_AXU_OS0 (0x5d0) -#define AUX_AGU_AXU_OS1 (0x5d1) -#define AUX_AGU_AXU_OS2 (0x5d2) -#define AUX_AGU_AXU_OS3 (0x5d3) -#define AUX_AGU_AXU_OS4 (0x5d4) -#define AUX_AGU_AXU_OS5 (0x5d5) -#define AUX_AGU_AXU_OS6 (0x5d6) -#define AUX_AGU_AXU_OS7 (0x5d7) -#define AUX_AGU_AXU_OS8 (0x5d8) -#define AUX_AGU_AXU_OS9 (0x5d9) -#define AUX_AGU_AXU_OS10 (0x5da) -#define AUX_AGU_AXU_OS11 (0x5db) -#define AUX_AGU_AXU_OS12 (0x5dc) -#define AUX_AGU_AXU_OS13 (0x5dd) -#define AUX_AGU_AXU_OS14 (0x5de) -#define AUX_AGU_AXU_OS15 (0x5df) - -#define AUX_AGU_AUX_MOD0 (0x5e0) -#define AUX_AGU_AUX_MOD1 (0x5e1) -#define AUX_AGU_AUX_MOD2 (0x5e2) -#define AUX_AGU_AUX_MOD3 (0x5e3) -#define AUX_AGU_AUX_MOD4 (0x5e4) -#define AUX_AGU_AUX_MOD5 (0x5e5) -#define AUX_AGU_AUX_MOD6 (0x5e6) -#define AUX_AGU_AUX_MOD7 (0x5e7) -#define AUX_AGU_AUX_MOD8 (0x5e8) -#define AUX_AGU_AUX_MOD9 (0x5e9) -#define AUX_AGU_AUX_MOD10 (0x5ea) -#define AUX_AGU_AUX_MOD11 (0x5eb) -#define AUX_AGU_AUX_MOD12 (0x5ec) -#define AUX_AGU_AUX_MOD13 (0x5ed) -#define AUX_AGU_AUX_MOD14 (0x5ee) -#define AUX_AGU_AUX_MOD15 (0x5ef) -#define AUX_AGU_AUX_MOD16 (0x5f0) -#define AUX_AGU_AUX_MOD17 (0x5f1) -#define AUX_AGU_AUX_MOD18 (0x5f2) -#define AUX_AGU_AUX_MOD19 (0x5f3) -#define AUX_AGU_AUX_MOD20 (0x5f4) -#define AUX_AGU_AUX_MOD21 (0x5f5) -#define AUX_AGU_AUX_MOD22 (0x5f6) -#define AUX_AGU_AUX_MOD23 (0x5f7) - -#define AUX_XCCM_BASE (0x5f8) -#define AUX_YCCM_BASE (0x5f9) - - -/** \todo add em series specific definitions here */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _ARC_HAL_EM_H_ */ - -/** @} */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_exception.h b/bsp/synopsys/embarc/inc/arc/arc_exception.h deleted file mode 100644 index e485b159c3..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_exception.h +++ /dev/null @@ -1,461 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-15 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT - * \brief header file of exception and interrupt management module - */ - -#ifndef _ARC_HAL_EXCEPTION_H_ -#define _ARC_HAL_EXCEPTION_H_ - -#include "inc/embARC_toolchain.h" -#include "inc/arc/arc.h" -#include "inc/arc/arc_builtin.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup ARC_HAL_EXCEPTION_CPU - * @{ - * \todo need a conf.h from application or board to define the - * features of processor, such as number of exception, code - * density and FIQ. - */ -#ifndef NUM_EXC_CPU -#define NUM_EXC_CPU 16 /*!< number of CPU exceptions */ -#endif - -#ifndef NUM_EXC_INT -#define NUM_EXC_INT 9 /*!< number of interrupt exceptions, defined by users*/ -#endif - -#define NUM_EXC_ALL (NUM_EXC_CPU + NUM_EXC_INT) /*!< total number of exceptions */ - - - -#ifdef ARC_FEATURE_SEC_PRESENT -typedef struct int_exc_frame { - uint32_t erbta; - - uint32_t r30; /* r30 is useless, skipped? */ - uint32_t ilink; /* r29 is useless, skipped?*/ - /* r28 is sp, saved other place */ - uint32_t fp; /* r27 */ - uint32_t gp; /* r26 */ - - uint32_t r12; - - uint32_t lp_end, lp_start, lp_count; - -#ifdef ARC_FEATURE_CODE_DENSITY - uint32_t ei, ldi, jli; -#endif - - uint32_t r0, r1, r2, r3; -#ifndef ARC_FEATURE_RF16 - uint32_t r4, r5, r6, r7, r8, r9; -#endif - uint32_t r10, r11; - - uint32_t blink; /* r31 */ - uint32_t ret; - uint32_t sec_stat; - uint32_t status32; -} EMBARC_PACKED INT_EXC_FRAME; -#else -typedef struct int_exc_frame { - uint32_t erbta; - - uint32_t r30; /* r30 is useless, skipped? */ - uint32_t ilink; /* r29 is useless, skipped?*/ - /* r28 is sp, saved other place */ - uint32_t fp; /* r27 */ - uint32_t gp; /* r26 */ - - uint32_t r12; - - uint32_t r0, r1, r2, r3; -#ifndef ARC_FEATURE_RF16 - uint32_t r4, r5, r6, r7, r8, r9; -#endif - uint32_t r10, r11; - - uint32_t blink; /* r31 */ - - uint32_t lp_end, lp_start, lp_count; - -#ifdef ARC_FEATURE_CODE_DENSITY - uint32_t ei, ldi, jli; -#endif - - uint32_t ret; - uint32_t status32; -} EMBARC_PACKED INT_EXC_FRAME; -#endif - -typedef struct callee_frame { -#ifndef ARC_FEATURE_RF16 - uint32_t r25; - uint32_t r24; - uint32_t r23; - uint32_t r22; - uint32_t r21; - uint32_t r20; - uint32_t r19; - uint32_t r18; - uint32_t r17; - uint32_t r16; -#endif - uint32_t r15; - uint32_t r14; - uint32_t r13; -} EMBARC_PACKED CALLEE_FRAME; - -typedef struct processor_frame { - CALLEE_FRAME callee_regs; - INT_EXC_FRAME exc_frame; -} EMBARC_PACKED PROCESSOR_FRAME; - -#define ARC_PROCESSOR_FRAME_SIZE (sizeof(PROCESSOR_FRAME) / sizeof(uint32_t)) -#define ARC_EXC_FRAME_SIZE (sizeof(INT_EXC_FRAME) / sizeof(uint32_t)) -#define ARC_CALLEE_FRAME_SIZE (sizeof(CALLEE_FRAME) / sizeof(uint32_t)) - - -extern uint32_t exc_nest_count; - -/** - * \brief write the exception vector base - * - * \param[in] vec_base the target vector base - */ -Inline void arc_vector_base_write(const void * vec_base) -{ - _arc_aux_write(AUX_INT_VECT_BASE, (uint32_t)vec_base); -} - -/** - * \brief read current exception vector base - * - * \returns exception vector base (uint32_t) - */ -Inline uint32_t arc_vector_base_read(void) -{ - return _arc_aux_read(AUX_INT_VECT_BASE); -} - -/** - * \brief sense whether in exc/interrupt processing - * - * \retval 0 not in exc/interrupt processing - * \retval 1 in exc/interrupt processing - */ -Inline uint32_t exc_sense(void) -{ - return (exc_nest_count > 0U); -} - -/** @}*/ - -/** - * \addtogroup ARC_HAL_EXCEPTION_INTERRUPT - * @{ - */ -#ifndef INT_PRI_MIN -#define INT_PRI_MIN (-2) /*!< the minimum interrupt priority */ -#endif - -#define INT_PRI_MAX (-1) /*!< the maximum interrupt priority */ -/** - * \brief disable the specific interrupt - * - * \param[in] intno interrupt number - */ -Inline void arc_int_disable(const uint32_t intno) -{ - _arc_aux_write(AUX_IRQ_SELECT, intno); - _arc_aux_write(AUX_IRQ_ENABLE, 0); -} - -/** - * \brief enable the specific int - * - * \param[in] intno interrupt number - */ -Inline void arc_int_enable(const uint32_t intno) -{ - _arc_aux_write(AUX_IRQ_SELECT, intno); - _arc_aux_write(AUX_IRQ_ENABLE, 1); -} - -/** - * \brief check whether the specific int is enabled - * - * \param[in] intno interrupt number - * \return 0 disabled, 1 enabled - */ -Inline uint32_t arc_int_enabled(const uint32_t intno) -{ - _arc_aux_write(AUX_IRQ_SELECT, intno); - return _arc_aux_read(AUX_IRQ_ENABLE); -} - -/** - * \brief get the interrupt priority mask - * - * \returns interrupt priority mask, negative num - */ -Inline uint32_t arc_int_ipm_get(void) -{ - return ((_arc_aux_read(AUX_STATUS32) >> 1) & 0x0f); -} - -/** - * \brief set the interrupt priority mask - * - * \param[in] intpri interrupt priority - */ -Inline void arc_int_ipm_set(uint32_t intpri) -{ - volatile uint32_t status; - status = _arc_aux_read(AUX_STATUS32) & ~0x1e; - - status = status | ((intpri << 1) & 0x1e); - /* sr cannot write AUX_STATUS32 */ - Asm("kflag %0"::"ir"(status)); -} - -/** - * \brief get current interrupt priority mask - * - * \param[in] intno interrupt number - */ -Inline uint32_t arc_int_pri_get(const uint32_t intno) -{ - _arc_aux_write(AUX_IRQ_SELECT, intno); - return _arc_aux_read(AUX_IRQ_PRIORITY); -} - -/** - * \brief set interrupt priority - * - * \param[in] intno interrupt number - * \param[in] intpri interrupt priority - */ -Inline void arc_int_pri_set(const uint32_t intno, uint32_t intpri) -{ - _arc_aux_write(AUX_IRQ_SELECT, intno); - _arc_aux_write(AUX_IRQ_PRIORITY, intpri | (_arc_aux_read(AUX_IRQ_PRIORITY) & 0xfffffff0)); -} - -/** - * \brief set interrupt secure or not secure - * - * \param[in] intno interrupt number - * \param[in] secure, 0 for normal, >0 for secure - */ -Inline void arc_int_secure_set(const uint32_t intno, uint32_t secure) -{ - - _arc_aux_write(AUX_IRQ_SELECT, intno); - - if (secure) { - _arc_aux_write(AUX_IRQ_PRIORITY, _arc_aux_read(AUX_IRQ_PRIORITY) | - (1 << AUX_IRQ_PRIORITY_BIT_S)); - } else { - _arc_aux_write(AUX_IRQ_PRIORITY, _arc_aux_read(AUX_IRQ_PRIORITY) & 0xf); - } - -} - -/** - * \brief probe the pending status of interrupt - * - * \param[in] intno interrupt number - * - * \returns 1 pending, 0 no pending - */ -Inline uint32_t arc_int_probe(const uint32_t intno) -{ - _arc_aux_write(AUX_IRQ_SELECT, intno); - return _arc_aux_read(AUX_IRQ_PENDING); -} - -/** - * \brief trigger the interrupt in software - * - * \param[in] intno interrupt number - */ -Inline void arc_int_sw_trigger(const uint32_t intno) -{ - _arc_aux_write(AUX_IRQ_HINT, intno); -} - -/** - * \brief config the interrupt level triggered or pulse triggered - * - * \param[in] intno interrupt number - * \param[in] level, 0-level trigger, 1-pluse triggered - */ -Inline void arc_int_level_config(const uint32_t intno, const uint32_t level) -{ - _arc_aux_write(AUX_IRQ_SELECT, intno); - _arc_aux_write(AUX_IRQ_TRIGGER, level); -} - -/** - * \brief lock cpu, disable interrupts - */ -Inline void arc_lock(void) -{ - Asm("clri"); - Asm("":::"memory"); -} - -/** - * \brief unlock cpu, enable interrupts to happen - */ -Inline void arc_unlock(void) -{ - Asm("":::"memory"); - Asm("seti"); -} - -/** - * \brief lock cpu and staus - * - * \returns cpu status - */ -Inline uint32_t arc_lock_save(void) -{ - return _arc_clri(); -} - -/** - * \brief unlock cpu with the specific status - * - * \param[in] status cpu status saved by cpu_lock_save - */ -Inline void arc_unlock_restore(const uint32_t status) -{ - _arc_seti(status); -} -/** @}*/ - -/** - * \addtogroup ARC_HAL_EXCEPTION_CPU - * @{ - */ -/** - * \typedef EXC_ENTRY - * \brief the data type for exception entry - */ -typedef void (*EXC_ENTRY) (void); -/** - * \typedef EXC_HANDLER - * \brief the data type for exception handler - */ -typedef void (*EXC_HANDLER) (void *exc_frame); -/** @}*/ - - -/** - * \ingroup ARC_HAL_EXCEPTION_INTERRUPT - * \typedef INT_HANDLER - * \brief the data type for interrupt handler - */ -typedef void (*INT_HANDLER) (void *ptr); - -extern EXC_ENTRY exc_entry_table[NUM_EXC_ALL]; -extern EXC_HANDLER exc_int_handler_table[NUM_EXC_ALL]; - -/** \ingroup ARC_HAL_EXCEPTION_CPU - * @{ - */ -/** - * \fn _arc_reset - * \brief the reset entry - */ -extern void _arc_reset(void); -/** - * \fn exc_entry_cpu - * \brief the default CPU exception entry - */ -extern void exc_entry_cpu(void); - -/** - * \fn exc_entry_firq - * \brief the fast interrupt exception entry - */ -extern void exc_entry_firq(void); -/** - * \fn exc_entry_int - * \brief the interrupt exception entry - */ -extern void exc_entry_int(void); -/** @}*/ - -/* excetpion related apis */ -extern void exc_int_init(void); -extern int32_t exc_entry_install(const uint32_t excno, EXC_ENTRY entry); -extern EXC_ENTRY exc_entry_get(const uint32_t excno); -extern int32_t exc_handler_install(const uint32_t excno, EXC_HANDLER handler); -extern EXC_HANDLER exc_handler_get(const uint32_t excno); - -/* interrupt related apis */ -extern int32_t int_disable(const uint32_t intno); -extern int32_t int_enable(const uint32_t intno); -extern int32_t int_enabled(const uint32_t intno); -extern int32_t int_ipm_get(void); -extern int32_t int_ipm_set(int32_t intpri); -extern int32_t int_pri_get(const uint32_t intno); -extern int32_t int_pri_set(const uint32_t intno, int32_t intpri); -extern int32_t int_probe(const uint32_t intno); -extern int32_t int_sw_trigger(const uint32_t intno); -extern int32_t int_level_config(const uint32_t intno, const uint32_t level); -extern void cpu_lock(void); -extern void cpu_unlock(void); -extern uint32_t cpu_lock_save(void); -extern void cpu_unlock_restore(const uint32_t status); -extern int32_t int_handler_install(const uint32_t intno, INT_HANDLER handler); -extern INT_HANDLER int_handler_get(const uint32_t intno); -extern int32_t int_secure_set(const uint32_t intno, uint32_t secure); - -#ifdef __cplusplus -} -#endif - -#endif /* _ARC_HAL_EXCEPTION_H_*/ diff --git a/bsp/synopsys/embarc/inc/arc/arc_feature_config.h b/bsp/synopsys/embarc/inc/arc/arc_feature_config.h deleted file mode 100644 index 87b1913df5..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_feature_config.h +++ /dev/null @@ -1,397 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2016-09-08 - * \author Huaqi Fang(Huaqi.Fang@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_MISC - * \brief header file for arc feature configuration - */ - -/** - * \addtogroup ARC_HAL_MISC - * @{ - */ - -#ifndef _ARC_FEATURE_CONFIG_H_ -#define _ARC_FEATURE_CONFIG_H_ - -// Enable core_config.h in EMSK OSP -//#ifdef EMBARC_TCF_GENERATED -#include "arc_core_config.h" -//#endif - -/** ARC baseline instruction set version number */ -#if !defined(_ARCVER) -#if defined(core_config_cir_identity_arcver) -#define _ARCVER core_config_cir_identity_arcver -#else -#define _ARCVER 0x42 -#endif -#endif - -/** ARC CPU Clock Frequency in Hz unit */ -#if !defined(ARC_FEATURE_CPU_CLOCK_FREQ) -#if defined(core_config_clock_speed) -#define ARC_FEATURE_CPU_CLOCK_FREQ (core_config_clock_speed*1000000) -#endif -#endif - -/** ARC PC size */ -#if !defined(ARC_FEATURE_PC_SIZE) -#if defined(core_config_pc_size) -#define ARC_FEATURE_PC_SIZE core_config_pc_size -#else -#define ARC_FEATURE_PC_SIZE 32 -#endif -#endif - -/** ARC LPC size */ -#if !defined(ARC_FEATURE_LPC_SIZE) -#if defined(core_config_lpc_size) -#define ARC_FEATURE_LPC_SIZE core_config_lpc_size -#else -#define ARC_FEATURE_LPC_SIZE 32 -#endif -#endif - -/** ARC Addr size */ -#if !defined(ARC_FEATURE_ADDR_SIZE) -#if defined(core_config_addr_size) -#define ARC_FEATURE_ADDR_SIZE core_config_addr_size -#else -#define ARC_FEATURE_ADDR_SIZE 32 -#endif -#endif - -/** ARC Endian/Byte Order */ -#define ARC_FEATURE_LITTLE_ENDIAN 1234 -#define ARC_FEATURE_BIG_ENDIAN 4321 - -#if !defined(ARC_FEATURE_BYTE_ORDER) -#if defined(core_config_bcr_isa_config_b) -#if core_config_bcr_isa_config_b == 0 -#define ARC_FEATURE_BYTE_ORDER ARC_FEATURE_LITTLE_ENDIAN -#else -#define ARC_FEATURE_BYTE_ORDER ARC_FEATURE_BIG_ENDIAN -#endif -#else -#define ARC_FEATURE_BYTE_ORDER ARC_FEATURE_LITTLE_ENDIAN -#endif -#endif - -/** Reduced register option, if enabled, ARC_FEATURE_RF16 will be defined */ -#if !defined(ARC_FEATURE_RF16) -#if defined(core_config_bcr_rf_build_e) && core_config_bcr_rf_build_e == 1 -#define ARC_FEATURE_RF16 -#endif -#endif - -/** Unaligned access option, if enabled, ARC_FEATURE_UNALIGNED will be defined */ -#if !defined(ARC_FEATURE_UNALIGNED) -#if defined(core_config_unaligned) && core_config_unaligned == 1 -#define ARC_FEATURE_UNALIGNED -#endif -#endif - - -/** Code density option, if enabled, ARC_FEATURE_CODE_DENSITY will be defined */ -#if !defined(ARC_FEATURE_CODE_DENSITY) -#if defined(core_config_code_density) && core_config_code_density == 1 -#define ARC_FEATURE_CODE_DENSITY -#endif -#endif - -/** The number of register file banks */ -#if !defined(ARC_FEATURE_RGF_NUM_BANKS) -#if defined(core_config_rgf_num_banks) -#define ARC_FEATURE_RGF_NUM_BANKS core_config_rgf_num_banks -#else -#define ARC_FEATURE_RGF_NUM_BANKS 1 -#endif -#endif - -/** The number of registers replicated per register bank */ -#if !defined(ARC_FEATURE_RGF_BANKED_REGS) -#if defined(core_config_rgf_banked_regs) -#define ARC_FEATURE_RGF_BANKED_REGS core_config_rgf_banked_regs -#endif -#endif - -/** Interrupt unit presence */ -#if !defined(ARC_FEATURE_INTERRUPTS_PRESENT) -#if defined(core_config_interrupts_present) -#define ARC_FEATURE_INTERRUPTS_PRESENT core_config_interrupts_present -#endif -#endif - -/** FIRQ_OPTION configuration option, 1 for enabled, 0 for disabled */ -#if !defined(ARC_FEATURE_FIRQ) -#if defined(core_config_bcr_irq_build_f) -#define ARC_FEATURE_FIRQ core_config_bcr_irq_build_f -#else -#define ARC_FEATURE_FIRQ 0 -#endif -#endif - -/** The number of interrupts */ -#if !defined(NUM_EXC_INT) -#if defined(core_config_interrupts_number) -#define NUM_EXC_INT core_config_interrupts_number -#endif -#endif - -/** The number of external interrupts */ -#if !defined(NUM_EXC_EXT_INT) -#if defined(core_config_interrupts_externals) -#define NUM_EXC_EXT_INT core_config_interrupts_externals -#endif -#endif - -/** The interrupt priority levels */ -#if !defined(INT_PRI_MIN) -#if defined(core_config_interrupts_priorities) -#define INT_PRI_MIN (-core_config_interrupts_priorities) -#endif -#endif - -// ARC TIMER_BUILD -/** Timer0 present or not */ -#if !defined(ARC_FEATURE_TIMER0_PRESENT) -#if defined(core_config_timer0) -#define ARC_FEATURE_TIMER0_PRESENT core_config_timer0 -#define ARC_FEATURE_TIMER0_LEVEL (core_config_timer0_level-core_config_interrupts_priorities) -#define ARC_FEATURE_TIMER0_VECTOR core_config_timer0_vector -#endif -#endif - -/** Timer1 present or not */ -#if !defined(ARC_FEATURE_TIMER1_PRESENT) -#if defined(core_config_timer1) -#define ARC_FEATURE_TIMER1_PRESENT core_config_timer1 -#define ARC_FEATURE_TIMER1_LEVEL (core_config_timer1_level-core_config_interrupts_priorities) -#define ARC_FEATURE_TIMER1_VECTOR core_config_timer1_vector -#endif -#endif - -/** Secure Timer0 present or not */ -#if !defined(ARC_FEATURE_SEC_TIMER0_PRESENT) -#if defined(core_config_sec_timer0) -#define ARC_FEATURE_SEC_TIMER0_PRESENT core_config_sec_timer0 -#define ARC_FEATURE_SEC_TIMER0_LEVEL (core_config_sec_timer0_level-core_config_interrupts_priorities) -#define ARC_FEATURE_SEC_TIMER0_VECTOR 20 -#endif -#endif - -/** Secure Timer1 present or not */ -#if !defined(ARC_FEATURE_SEC_TIMER1_PRESENT) -#if defined(core_config_sec_timer1) -#define ARC_FEATURE_SEC_TIMER1_PRESENT core_config_sec_timer1 -#define ARC_FEATURE_SEC_TIMER1_LEVEL (core_config_sec_timer1_level-core_config_interrupts_priorities) -#define ARC_FEATURE_SEC_TIMER1_VECTOR 21 -#endif -#endif - - -/** 64bit RTC present or not */ -#if !defined(ARC_FEATURE_RTC_PRESENT) -#if defined(core_config_rtc) -#define ARC_FEATURE_RTC_PRESENT core_config_rtc -#endif -#endif - -// Memory related definitions -/** ICCM Presence, base address and size */ -#if !defined(ARC_FEATURE_ICCM_PRESENT) -#if defined(core_config_iccm_present) && core_config_iccm_present == 1 -#define ARC_FEATURE_ICCM_PRESENT 1 -#define ARC_FEATURE_ICCM_BASE core_config_iccm_base -#define ARC_FEATURE_ICCM_SIZE core_config_iccm_size -#endif -#endif - -/** ICCM0 Presence, base address and size */ -#if !defined(ARC_FEATURE_ICCM0_PRESENT) -#if defined(core_config_iccm0_present) && core_config_iccm0_present == 1 -#define ARC_FEATURE_ICCM0_PRESENT 1 -#define ARC_FEATURE_ICCM0_BASE core_config_iccm0_base -#define ARC_FEATURE_ICCM0_SIZE core_config_iccm0_size -#endif -#endif - -/** ICCM1 Presence, base address and size */ -#if !defined(ARC_FEATURE_ICCM1_PRESENT) -#if defined(core_config_iccm1_present) && core_config_iccm1_present == 1 -#define ARC_FEATURE_ICCM1_PRESENT 1 -#define ARC_FEATURE_ICCM1_BASE core_config_iccm1_base -#define ARC_FEATURE_ICCM1_SIZE core_config_iccm1_size -#endif -#endif - -/** DCCM Presence, base address and size */ -#if !defined(ARC_FEATURE_DCCM_PRESENT) -#if defined(core_config_dccm_present) && core_config_dccm_present == 1 -#define ARC_FEATURE_DCCM_PRESENT 1 -#define ARC_FEATURE_DCCM_BASE core_config_dccm_base -#define ARC_FEATURE_DCCM_SIZE core_config_dccm_size -#ifdef core_config_dccm_interleave -#define ARC_FEATURE_DCCM_INTERLEAVE core_config_dccm_interleave -#endif -#endif -#endif - -/** Peripheral memory region(DMP) base address, if dmp configured, this macro will be defined as base address */ -#if !defined(ARC_FEATURE_DMP_PERIPHERAL) -#if defined(core_config_cir_dmp_peripheral) -#define ARC_FEATURE_DMP_PERIPHERAL core_config_cir_dmp_peripheral -#endif -#endif - -/** MPU options */ -#if !defined(ARC_FEATURE_MPU_PRESENT) -#if defined(core_config_mpu_present) && core_config_mpu_present == 1 -#define ARC_FEATURE_MPU_PRESENT 1 -#define ARC_FEATURE_MPU_VERSION core_config_bcr_mpu_build_version -#define ARC_FEATURE_MPU_REGIONS core_config_mpu_regions -#ifdef core_config_bcr_mpu_build_i -#define ARC_FEATURE_MPU_BUILD_I core_config_bcr_mpu_build_i -#endif -#ifdef core_config_bcr_mpu_build_s -#define ARC_FEATURE_MPU_BUILD_S core_config_bcr_mpu_build_s -#endif -#endif -#endif - -/** Secure BCR SEC_BUILD BCR */ -#if !defined(ARC_FEATURE_SEC_PRESENT) -#if defined(core_config_bcr_sec_build) -#define ARC_FEATURE_SEC_PRESENT 1 -#define ARC_FEATURE_SEC_VERSION core_config_bcr_sec_build_version -#define ARC_FEATURE_SEC_BUILD_DSM core_config_bcr_sec_build_dsm -#define ARC_FEATURE_SEC_BUILD_NSM core_config_bcr_sec_build_nsm -#define ARC_FEATURE_SEC_BUILD_I1SM core_config_bcr_sec_build_i1sm -#define ARC_FEATURE_SEC_BUILD_I0SM core_config_bcr_sec_build_i0sm -#define ARC_FEATURE_SEC_BUILD_S core_config_bcr_sec_build_s -#define ARC_FEATURE_SEC_BUILD_EI core_config_bcr_sec_build_ei -#define ARC_FEATURE_SEC_BUILD_ED core_config_bcr_sec_build_ed -#endif -#endif - -#if !defined(ARC_FEATURE_SEC_MODES) -#if defined(core_config_sec_modes) -#define ARC_FEATURE_SEC_MODES core_config_sec_modes -#endif -#endif - -/** Data Cache options */ -#if !defined(ARC_FEATURE_DCACHE_PRESENT) -#if defined(core_config_dcache_present) && core_config_dcache_present == 1 -#define ARC_FEATURE_DCACHE_PRESENT 1 -#define ARC_FEATURE_DCACHE_BUILD core_config_bcr_d_cache_build -#define ARC_FEATURE_DCACHE_BUILD_VERSION core_config_bcr_d_cache_build_version -#define ARC_FEATURE_DCACHE_BUILD_ASSOC core_config_bcr_d_cache_build_assoc -#define ARC_FEATURE_DCACHE_BUILD_CAPACITY core_config_bcr_d_cache_build_capacity -#define ARC_FEATURE_DCACHE_BUILD_BSIZE core_config_bcr_d_cache_build_bsize -#define ARC_FEATURE_DCACHE_BUILD_FL core_config_bcr_d_cache_build_fl -#define ARC_FEATURE_DCACHE_BUILD_U core_config_bcr_d_cache_build_u -#define ARC_FEATURE_DCACHE_SIZE core_config_dcache_size -#define ARC_FEATURE_DCACHE_LINE_SIZE core_config_dcache_line_size -#define ARC_FEATURE_DCACHE_WAYS core_config_dcache_ways -#define ARC_FEATURE_DCACHE_FEATURE core_config_dcache_feature -#endif -#endif - -/** Instruction Cache options */ -#if !defined(ARC_FEATURE_ICACHE_PRESENT) -#if defined(core_config_icache_present) && core_config_icache_present == 1 -#define ARC_FEATURE_ICACHE_PRESENT 1 -#define ARC_FEATURE_ICACHE_BUILD core_config_bcr_i_cache_build -#define ARC_FEATURE_ICACHE_BUILD_VERSION core_config_bcr_i_cache_build_version -#define ARC_FEATURE_ICACHE_BUILD_ASSOC core_config_bcr_i_cache_build_assoc -#define ARC_FEATURE_ICACHE_BUILD_CAPACITY core_config_bcr_i_cache_build_capacity -#define ARC_FEATURE_ICACHE_BUILD_BSIZE core_config_bcr_i_cache_build_bsize -#define ARC_FEATURE_ICACHE_BUILD_FL core_config_bcr_i_cache_build_fl -#define ARC_FEATURE_ICACHE_BUILD_D core_config_bcr_i_cache_build_d -#define ARC_FEATURE_ICACHE_SIZE core_config_icache_size -#define ARC_FEATURE_ICACHE_LINE_SIZE core_config_icache_line_size -#define ARC_FEATURE_ICACHE_WAYS core_config_icache_ways -#define ARC_FEATURE_ICACHE_FEATURE core_config_icache_feature -#endif -#endif - -/** ARC uDMA options */ -#if !defined(ARC_FEATURE_DMAC) -#if defined(core_config_dmac) -#define ARC_FEATURE_DMAC core_config_dmac -#define CORE_DMAC_CHANNELS core_config_dmac_channels -#define CORE_DMAC_REGISTERS core_config_dmac_registers -#if core_config_bcr_dmac_build_int_cfg == 2 && core_config_bcr_dmac_build_int_cfg == 4 -#define DMA_MULTI_IRQ 1 -#else -#define DMA_MULTI_IRQ 0 -#endif -#define ARC_FEATURE_DMAC_PRESENT core_config_dmac -#define ARC_FEATURE_DMAC_VERSION core_config_bcr_dmac_build_version -#define ARC_FEATURE_DMAC_CHANNELS core_config_dmac_channels -#define ARC_FEATURE_DMAC_REGISTERS core_config_dmac_registers -#define ARC_FEATURE_DMAC_INT_CFG core_config_bcr_dmac_build_int_cfg -#define ARC_FEATURE_DMAC_FIFO_DEPTH core_config_dmac_fifo_depth - -#ifdef ARC_FEATURE_SEC_TIMER0_PRESENT -#define DMA_IRQ_NUM_START 22 -#define ARC_FEATURE_DMAC_VECTOR_START 22 -#else -#define DMA_IRQ_NUM_START 20 -#define ARC_FEATURE_DMAC_VECTOR_START 20 -#endif - -#endif -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef ARC_FEATURE_UNALIGNED -#define STATUS32_RESET_VALUE (1<<19) -#else -#define STATUS32_RESET_VALUE (0) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _ARC_FEATURE_CONFIG_H_ */ - -/** @} */ diff --git a/bsp/synopsys/embarc/inc/arc/arc_timer.h b/bsp/synopsys/embarc/inc/arc/arc_timer.h deleted file mode 100644 index b5237f31a9..0000000000 --- a/bsp/synopsys/embarc/inc/arc/arc_timer.h +++ /dev/null @@ -1,99 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-07-15 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup ARC_HAL_MISC_TIMER - * \brief header file of ARC internal timer - */ - -/** - * \addtogroup ARC_HAL_MISC_TIMER - * @{ - */ - -#ifndef _ARC_HAL_TIMER_H_ -#define _ARC_HAL_TIMER_H_ -#include "inc/arc/arc.h" -#include "inc/embARC_toolchain.h" - -/** - * \name arc internal timers names - * @{ - */ -#define TIMER_0 0 /*!< macro name for arc internal timer 0 */ -#define TIMER_1 1 /*!< macro name for arc internal timer 1 */ -#define TIMER_RTC 2 /*!< macro name for arc internal RTC */ - -/** @} */ - -/** - * \name bit definition of RTC CTRL reg - * @{ - */ - -#define TIMER_RTC_ENABLE 0x01 /*!< enable RTC */ -#define TIMER_RTC_CLEAR 0x02 /* clears the AUX_RTC_LOW and AUX_RTC_HIGH */ -#define TIMER_RTC_STATUS_A0 0x40000000 /*!< track bit of atomicity of reads of RTC */ -#define TIMER_RTC_STATUS_A1 0x80000000 /*!< track bit of atomicity of reads of RTC */ - -/** @} */ - -/** - * \name bit definition of timer CTRL reg - * @{ - */ -#define TIMER_CTRL_IE (1 << 0) /*!< Interrupt when count reaches limit */ -#define TIMER_CTRL_NH (1 << 1) /*!< Count only when CPU NOT halted */ -#define TIMER_CTRL_W (1 << 2) /*!< watchdog enable */ -#define TIMER_CTRL_IP (1 << 3) /*!< interrupt pending */ - -/** @} */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int32_t arc_timer_present(const uint32_t no); -extern int32_t arc_timer_start(const uint32_t no, const uint32_t mode, const uint32_t val); -extern int32_t arc_timer_stop(const uint32_t no); -extern int32_t arc_timer_current(const uint32_t no, void* val); -extern int32_t arc_timer_int_clear(const uint32_t no); -extern void arc_timer_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _ARC_HAL_TIMER_H_ */ -/** }@*/ diff --git a/bsp/synopsys/embarc/inc/embARC_debug.h b/bsp/synopsys/embarc/inc/embARC_debug.h deleted file mode 100644 index 092374622d..0000000000 --- a/bsp/synopsys/embarc/inc/embARC_debug.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2017, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2017.03 - * \date 2014-12-26 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup EMBARC_DEBUG - * \brief necessary definitions of debug - */ - -#ifndef _EMBARC_DEBUG_H_ -#define _EMBARC_DEBUG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef EMBARC_PRINTF - #include "common/xprintf.h" - #define EMBARC_PRINTF xprintf -#endif - -/* - * if you want to use DBG or dbg_printf, - * please define DEBUG or DBG_LESS or DBG_MORE before include embARC_debug.h - * DEBUG: enable debug print - * DBG_LESS: enable less debug msg - * DBG_MORE: enable more debug msg - **/ - -#if defined(DEBUG) -#if defined(DEBUG_HOSTLINK) -#include -#define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__) -#else -#define DBG(fmt, ...) EMBARC_PRINTF(fmt, ##__VA_ARGS__) -#endif -#else -#define DBG(fmt, ...) -#endif - -#define DBG_LESS_INFO 0x01 /* less debug messages */ -#define DBG_MORE_INFO 0x02 /* more debug messages */ - - -#if defined (DBG_LESS) -#define DBG_TYPE (DBG_LESS_INFO) -#elif defined (DBG_MORE) -#define DBG_TYPE ((DBG_LESS_INFO) | (DBG_MORE_INFO)) -#else -#define DBG_TYPE 0 -#endif - -#if DBG_TYPE > 0 -#define dbg_printf(type, fmt, ...) \ - if (((type) & DBG_TYPE)) { EMBARC_PRINTF(fmt, ##__VA_ARGS__); } -#else -#define dbg_printf(type, fmt, ...) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* DEBUG_H_ */ diff --git a/bsp/synopsys/embarc/inc/embARC_error.h b/bsp/synopsys/embarc/inc/embARC_error.h deleted file mode 100644 index 9bd9c318aa..0000000000 --- a/bsp/synopsys/embarc/inc/embARC_error.h +++ /dev/null @@ -1,156 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-12-25 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup EMBARC_ERROR - * \brief header file to define common definitions error management - */ - -/** - * \addtogroup EMBARC_ERROR - * @{ - */ - -#ifndef _EMBARC_ERROR_H_ -#define _EMBARC_ERROR_H_ - -#include -#include "inc/arc/arc_builtin.h" - -#ifdef __cplusplus -extern "C" { -#endif -/** - * \name Main Error Code Definitions - * @{ - */ -#define E_OK (0) /*!< ok */ -#define E_SYS (-5) /*!< system error */ -#define E_NOSPT (-9) /*!< unsupported features */ -#define E_RSFN (-10) /*!< reserved function code */ -#define E_RSATR (-11) /*!< reserved attribute */ -#define E_PAR (-17) /*!< parameter error */ -#define E_ID (-18) /*!< invalid ID number */ -#define E_CTX (-25) /*!< context error */ -#define E_MACV (-26) /*!< memory access violation */ -#define E_OACV (-27) /*!< object access violation */ -#define E_ILUSE (-28) /*!< illegal service call use */ -#define E_NOMEM (-33) /*!< insufficient memory */ -#define E_NOID (-34) /*!< no ID number available */ -#define E_NORES (-35) /*!< no resource available */ -#define E_OBJ (-41) /*!< object state error */ -#define E_NOEXS (-42) /*!< non-existent object */ -#define E_QOVR (-43) /*!< queue overflow */ -#define E_RLWAI (-49) /*!< forced release from waiting */ -#define E_TMOUT (-50) /*!< polling failure or timeout */ -#define E_DLT (-51) /*!< waiting object deleted */ -#define E_CLS (-52) /*!< waiting object state changed */ -#define E_WBLK (-57) /*!< non-blocking accepted */ -#define E_BOVR (-58) /*!< buffer overflow */ -#define E_OPNED (-6) /*!< device is opened */ -#define E_CLSED (-7) /*!< device is closed */ -/** @} end of name */ - -/** - * \name Generate And Decompose Error Code - * @{ - */ -#ifndef ERCD -/** generate error code using main error code and sub error code */ -#define ERCD(mercd, sercd) \ - ((uint32_t)((((uint32_t) sercd) << 8) | (((uint32_t) mercd) & 0xffU))) -#endif /* ERCD */ - -#ifndef MERCD -#ifdef INT8_MAX -/** get main error code from error code */ -#define MERCD(ercd) ((uint32_t)((int8_t)(ercd))) -#else /* INT8_MAX */ -/** get main error code from error code */ -#define MERCD(ercd) ((uint32_t)(((uint32_t) ercd) | ~0xffU)) -#endif /* INT8_MAX */ -#endif /* MERCD */ - -#ifndef SERCD -/** get sub error code from error code */ -#define SERCD(ercd) ((uint32_t)((ercd) >> 8)) -#endif /* SERCD */ -/** @} end of name */ - -/** - * \name Check Error - * @{ - */ -/** - * \brief check an expression to see if it is right, and when error - * set the ercd, and goto exit_label - * \param EXPR the expression that need to be checked (==0 failed) - * \param ERCD MUST pass a variable to here to get the error code - * \param ERROR_CODE error code that pass to ERCD - * \param EXIT_LABEL a label to go when error happens - */ -#define CHECK_EXP(EXPR, ERCD, ERROR_CODE, EXIT_LABEL) { \ - if (_arc_rarely(!(EXPR))) { \ - ERCD = (ERROR_CODE); \ - goto EXIT_LABEL; \ - } \ - } -/** - * \brief check an expression to see if it is right, and when error - * directly goto exit_label - * \param EXPR the expression that need to be checked (==0 failed) - * \param EXIT_LABEL a label to go when error happens - * \retval - */ -#define CHECK_EXP_NOERCD(EXPR, EXIT_LABEL) { \ - if (_arc_rarely(!(EXPR))) { \ - goto EXIT_LABEL; \ - } \ - } -/** check cnt bytes align, 1 for aligned, 0 for not-aligned */ -#define CHECK_ALIGN_BYTES(pointer, cnt) ((((uint32_t)(pointer)) & (cnt-1)) == 0) -/** check 2 bytes align, 1 for aligned, 0 for not-aligned */ -#define CHECK_ALIGN_2BYTES(pointer) ((((uint32_t)(pointer)) & 0x1) == 0) -/** check 4 bytes align, 1 for aligned, 0 for not-aligned */ -#define CHECK_ALIGN_4BYTES(pointer) ((((uint32_t)(pointer)) & 0x3) == 0) -/** check 8 bytes align, 1 for aligned, 0 for not-aligned */ -#define CHECK_ALIGN_8BYTES(pointer) ((((uint32_t)(pointer)) & 0x7) == 0) -/** @} end of name */ - -#ifdef __cplusplus -} -#endif - -#endif /* _EMBARC_ERROR_H_ */ -/** @} end of group EMBARC_ERROR */ diff --git a/bsp/synopsys/embarc/inc/embARC_toolchain.h b/bsp/synopsys/embarc/inc/embARC_toolchain.h deleted file mode 100644 index 37aef66064..0000000000 --- a/bsp/synopsys/embarc/inc/embARC_toolchain.h +++ /dev/null @@ -1,121 +0,0 @@ -/* ------------------------------------------ - * Copyright (c) 2016, Synopsys, Inc. All rights reserved. - - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - - * 1) Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - - * 2) Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - - * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * \version 2016.05 - * \date 2014-12-25 - * \author Wayne Ren(Wei.Ren@synopsys.com) ---------------------------------------------- */ - -/** - * \file - * \ingroup TOOLCHAIN - * \brief toolchain dependent definitions - */ - -#include /* C99 standard lib */ -#include /* C99 standard lib */ -#include /* C99 standard lib */ -#include /* C99 standard lib */ - -#include "embARC_BSP_config.h" - -/** - * \addtogroup TOOLCHAIN - * @{ - */ - -#ifndef _EMBARC_TOOLCHAIN_H_ -#define _EMBARC_TOOLCHAIN_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * macro definitions of compiler extend function - */ -#ifndef __cplusplus /* C++ supports inline */ -#if __STDC_VERSION__ < 199901L /* C99 supports inline */ -#ifndef inline -#define inline __inline__ /* inline function */ -#endif -#endif /* __STDC_VERSION__ < 199901L */ -#endif /* __cplusplus */ - -#ifndef Inline -#define Inline static __inline__ /* inline function */ -#endif - -#ifndef __cplusplus /* C++ supports asm */ -#ifndef asm -#define asm __asm__ /* inline asm */ -#endif -#endif /* __cplusplus */ - -#ifndef Asm -#define Asm __asm__ volatile /* inline asm (no optimization) */ -#endif - -/* compiler attributes */ -#define EMBARC_FORCEINLINE __attribute__((always_inline)) -#define EMBARC_NOINLINE __attribute__((noinline)) -#define EMBARC_PACKED __attribute__((packed)) -#define EMBARC_WEAK __attribute__((weak)) -#define EMBARC_ALIAS(f) __attribute__((weak, alias (#f))) -#define EMBARC_LINKTO(f) __attribute__((alias (#f))) -#define EMBARC_NORETURN __attribute__((noreturn)) -#define EMBARC_NAKED __attribute__((naked)) /* function without return */ -#define EMBARC_ALIGNED(x) __attribute__((aligned(x))) - - -/* array count macro */ -#define EMBARC_ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0])) - -/* convert macro argument to string */ -/* note: this needs one level of indirection, accomplished with the helper macro - * __EMBARC_TO_STRING */ -#define __EMBARC_TO_STRING(x) #x -#define EMBARC_TO_STRING(x) __EMBARC_TO_STRING(x) - -#if defined(__GNU__) -/* GNU tool specific definitions */ - -#elif defined(__MW__) -/* Metaware tool specific definitions */ -/* Metaware toolchain related definitions */ - -#else -#error "unsupported toolchain" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _EMBARC_TOOLCHAIN_H_ */ -/** }@ */ diff --git a/bsp/synopsys/emsk_em9d/README.md b/bsp/synopsys/emsk_em9d/README.md deleted file mode 100644 index d5cc11fe88..0000000000 --- a/bsp/synopsys/emsk_em9d/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# Synopsys DesignWare ARC EM Starter Kit - -## Overview - -The DesignWare™ ARC™ EM Starter Kit(EMSK, emsk) is a low-cost, versatile -solution enabling rapid software development and software debugging, and -profiling for the ARC EM Family of processors. The EM Family includes the EM4, -EM6, EM5D, EM7D, EM9D, and EM11D cores. - -![EM Starter Kit](figures/emsk_board.jpg) - -The EMSK consists of a hardware platform and a software package, including -pre-installed FPGA images of different configurations of the ARC EM Processor -with peripherals. - -The development board is based on a Xilinx Spartan-6 LX45 FPGA. It supports -hardware extensions using six 2x6 connectors supporting a total of 48 user I/O -pins (plus power and ground pins) that can be used to connect components such -as sensors, actuators, memories, displays, buttons, switches, and -communication devices. A Digilent Pmod™ compatible extension board containing -a four-channel 12-bit A/D converter with an IIC interface and an AC power -adapter are included in the package. - -## Board Resources - -| Hardware | Description | -| -- | -- | -| SOC | EMSK | -| Core | EM9D | -| Arch | 32-bit ARC EM | -| Frequency | 20/25 Mhz | -| RAM | 128 MB DDR RAM + 256 KB Instruction CCM + 256 KB Data CCM | -|Flash | 16 MB SPI Flash for FPGA configuration with 128 KB reserved for application | - -## Usage - -### FPGA Configuration - -Current, only em9d configuration is supported and tested for RT-Thread. However, -it's can be easily applied to other configurations because all emsk configurations almost share the same memory map and periphreals. - -Please refer [EMSK configuration](https://embarc.org/embarc_osp/doc/build/html/board/emsk.html) for details. - -### Toolchain - -The ARC GNU Toolchain offers all of the benefits of open source tools, including complete source code and a large install base. The ARC GNU IDE Installer consists of Eclipse IDE with [ARC GNU plugin for Eclipse](https://github.com/foss-for-synopsys-dwc-arc-processors/arc_gnu_eclipse/releases), [ARC GNU prebuilt toolchain](https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases) and [OpenOCD for ARC](https://github.com/foss-for-synopsys-dwc-arc-processors/openocd>) - -Here, the ARC GNU toolchain is installed to `c:\arc\gnu`. If not, please change the path configuration in rtconfig.py. - -### Compile - -please run the following cmds to compile - - cd /bsp/synopsys/emsk_em9d - scons - -## Debug - -You need to install [Zadig](http://zadig.akeo.ie) to replace the default FTDI driver with WinUSB driver. See [How to Use OpenOCD on Windows](https://github.com/foss-for-synopsys-dwc-arc-processors/arc_gnu_eclipse/wiki/How-to-Use-OpenOCD-on-Windows>) for more information. - -After compile, please use the following cmds to debug - - scons --gdb - - -## Supported Drivers - -| Driver | Supported | Comment | -| ------ | ---- | :------: | -| UART1 | yes | USB-UART for shell & log | -| UART0 | yes | PMOD A UART for UART modules, e.g. esp8266 | - -## Maintainer -- [vonhust](https://github.com/vonhust) - -## Notes - diff --git a/bsp/synopsys/emsk_em9d/SConstruct b/bsp/synopsys/emsk_em9d/SConstruct deleted file mode 100644 index d8e88ebeea..0000000000 --- a/bsp/synopsys/emsk_em9d/SConstruct +++ /dev/null @@ -1,53 +0,0 @@ -import os -import sys -import rtconfig - -if os.getenv('RTT_ROOT'): - RTT_ROOT = os.getenv('RTT_ROOT') -else: - RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') - -sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] - -try: - from building import * -except: - print('Cannot found RT-Thread root directory, please check RTT_ROOT') - print(RTT_ROOT) - exit(-1) - -TARGET = 'rtthread_snps_emsk_em9d.' + rtconfig.TARGET_EXT - -# use scons --gdb to debug emsk -AddOption('--gdb', - dest = 'gdb', - action = 'store_true', - default = False, - help = 'use gdb to debug the elf') - -if GetOption('gdb'): - if os.path.isfile(rtconfig.TARGET): - os.system(rtconfig.DBG + rtconfig.DBG_HW_FLAGS + rtconfig.TARGET) - else: - print rtconfig.TARGET + 'not exist, please build first!!' - exit(0) - -DefaultEnvironment(tools=[]) -env = Environment(tools = ['mingw'], - AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, - CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, - AR = rtconfig.AR, ARFLAGS = '-rc', - LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) -env.PrependENVPath('PATH', rtconfig.EXEC_PATH) - -Export('RTT_ROOT') -Export('rtconfig') - -# prepare building environment -objs = PrepareBuilding(env, RTT_ROOT) - -# if the linker script changed, relink the target -Depends(TARGET, rtconfig.LINK_SCRIPT) - -# make a building -DoBuilding(TARGET, objs) diff --git a/bsp/synopsys/emsk_em9d/drivers/arc_core_config.h b/bsp/synopsys/emsk_em9d/drivers/arc_core_config.h deleted file mode 100644 index 8340e94091..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/arc_core_config.h +++ /dev/null @@ -1,229 +0,0 @@ -/* This file is automatically generated from tcf file. DO NOT EDIT */ -#ifndef __core_config_h - #define __core_config_h 1 - #define core_config_cir_identity 0x00000042 - #define core_config_cir_identity_chipid 0 - #define core_config_cir_identity_arcnum 0 - #define core_config_cir_identity_arcver 66 - #define core_config_cir_identity_family 4 - #define core_config_cir_identity_corever 2 - #define core_config_cir_aux_dccm 0x80000000 - #define core_config_bcr_bcr_ver 0x00000002 - #define core_config_bcr_bcr_ver_version 2 - #define core_config_bcr_vecbase_ac_build 0x00000010 - #define core_config_bcr_rf_build 0x0000c902 - #define core_config_bcr_rf_build_version 2 - #define core_config_bcr_rf_build_p 1 - #define core_config_bcr_rf_build_e 0 - #define core_config_bcr_rf_build_r 0 - #define core_config_bcr_rf_build_b 1 - #define core_config_bcr_rf_build_d 3 - #define core_config_bcr_dccm_build 0x00010904 - #define core_config_bcr_dccm_build_cycles 0 - #define core_config_bcr_dccm_build_interleave 1 - #define core_config_bcr_dccm_build_size1 0 - #define core_config_bcr_dccm_build_size0 9 - #define core_config_bcr_dccm_build_version 4 - #define core_config_bcr_timer_build 0x00010304 - #define core_config_bcr_timer_build_sp1 0 - #define core_config_bcr_timer_build_sp0 0 - #define core_config_bcr_timer_build_p1 0 - #define core_config_bcr_timer_build_p0 1 - #define core_config_bcr_timer_build_st1 0 - #define core_config_bcr_timer_build_st0 0 - #define core_config_bcr_timer_build_rtc 0 - #define core_config_bcr_timer_build_rtsc_ver 1 - #define core_config_bcr_timer_build_rtsc 0 - #define core_config_bcr_timer_build_t0 1 - #define core_config_bcr_timer_build_t1 1 - #define core_config_bcr_timer_build_version 4 - #define core_config_bcr_ap_build 0x00000405 - #define core_config_bcr_ap_build_version 5 - #define core_config_bcr_ap_build_type 4 - #define core_config_bcr_iccm_build 0x00000a04 - #define core_config_bcr_iccm_build_iccm1_size1 0 - #define core_config_bcr_iccm_build_iccm0_size1 0 - #define core_config_bcr_iccm_build_iccm1_size0 0 - #define core_config_bcr_iccm_build_iccm0_size0 10 - #define core_config_bcr_iccm_build_version 4 - #define core_config_bcr_xy_build 0x00001620 - #define core_config_bcr_xy_build_memsize 1 - #define core_config_bcr_xy_build_interleaved 1 - #define core_config_bcr_xy_build_config 2 - #define core_config_bcr_xy_build_version 32 - #define core_config_bcr_dsp_build 0x00003521 - #define core_config_bcr_dsp_build_wide 0 - #define core_config_bcr_dsp_build_itu_pa 1 - #define core_config_bcr_dsp_build_acc_shift 2 - #define core_config_bcr_dsp_build_comp 1 - #define core_config_bcr_dsp_build_divsqrt 1 - #define core_config_bcr_dsp_build_version 33 - #define core_config_bcr_multiply_build 0x00022a06 - #define core_config_bcr_multiply_build_version16x16 2 - #define core_config_bcr_multiply_build_dsp 2 - #define core_config_bcr_multiply_build_cyc 2 - #define core_config_bcr_multiply_build_type 2 - #define core_config_bcr_multiply_build_version32x32 6 - #define core_config_bcr_swap_build 0x00000003 - #define core_config_bcr_swap_build_version 3 - #define core_config_bcr_norm_build 0x00000003 - #define core_config_bcr_norm_build_version 3 - #define core_config_bcr_minmax_build 0x00000002 - #define core_config_bcr_minmax_build_version 2 - #define core_config_bcr_barrel_build 0x00000303 - #define core_config_bcr_barrel_build_version 3 - #define core_config_bcr_barrel_build_shift_option 3 - #define core_config_bcr_isa_config 0x12447402 - #define core_config_bcr_isa_config_d 1 - #define core_config_bcr_isa_config_c 2 - #define core_config_bcr_isa_config_l 0 - #define core_config_bcr_isa_config_n 1 - #define core_config_bcr_isa_config_a 0 - #define core_config_bcr_isa_config_b 0 - #define core_config_bcr_isa_config_addr_size 4 - #define core_config_bcr_isa_config_lpc_size 7 - #define core_config_bcr_isa_config_pc_size 4 - #define core_config_bcr_isa_config_version 2 - #define core_config_bcr_stack_region_build 0x00000002 - #define core_config_bcr_fpu_build 0x00000f02 - #define core_config_bcr_fpu_build_da 0 - #define core_config_bcr_fpu_build_dd 0 - #define core_config_bcr_fpu_build_dc 0 - #define core_config_bcr_fpu_build_df 0 - #define core_config_bcr_fpu_build_dp 0 - #define core_config_bcr_fpu_build_fd 0 - #define core_config_bcr_fpu_build_fm 0 - #define core_config_bcr_fpu_build_sd 1 - #define core_config_bcr_fpu_build_sc 1 - #define core_config_bcr_fpu_build_sf 1 - #define core_config_bcr_fpu_build_sp 1 - #define core_config_bcr_fpu_build_version 2 - #define core_config_bcr_bs_build 0x00000001 - #define core_config_bcr_bs_build_version 1 - #define core_config_bcr_agu_build 0x01988c01 - #define core_config_bcr_agu_build_accordian 1 - #define core_config_bcr_agu_build_wb_size 4 - #define core_config_bcr_agu_build_num_modifier 24 - #define core_config_bcr_agu_build_num_offset 8 - #define core_config_bcr_agu_build_num_addr 12 - #define core_config_bcr_agu_build_version 1 - #define core_config_bcr_dmac_build 0x000a0101 - #define core_config_bcr_dmac_build_int_cfg 1 - #define core_config_bcr_dmac_build_fifo 1 - #define core_config_bcr_dmac_build_chan_mem 0 - #define core_config_bcr_dmac_build_channels 1 - #define core_config_bcr_dmac_build_version 1 - #define core_config_bcr_core_config 0x00000101 - #define core_config_bcr_core_config_turbo_boost 1 - #define core_config_bcr_core_config_version 1 - #define core_config_bcr_irq_build 0x13101401 - #define core_config_bcr_irq_build_raz 0 - #define core_config_bcr_irq_build_f 1 - #define core_config_bcr_irq_build_p 3 - #define core_config_bcr_irq_build_exts 16 - #define core_config_bcr_irq_build_irqs 20 - #define core_config_bcr_irq_build_version 1 - #define core_config_bcr_pct_build 0x08080102 - #define core_config_bcr_pct_build_version 2 - #define core_config_bcr_pct_build_s 1 - #define core_config_bcr_pct_build_i 0 - #define core_config_bcr_pct_build_c 8 - #define core_config_bcr_cc_build 0x006f0004 - #define core_config_bcr_cc_build_version 4 - #define core_config_bcr_cc_build_cc 111 - #define core_config_bcr_ifqueue_build 0x00000002 - #define core_config_bcr_ifqueue_build_bd 0 - #define core_config_bcr_ifqueue_build_version 2 - #define core_config_bcr_smart_build 0x00002003 - #define core_config_bcr_smart_build_version 3 - #define core_config_bcr_smart_build_stack_size 8 - #define core_config_cir_aux_iccm 0x00000000 - #define core_config_cir_dmp_peripheral 0xf0000000 - #define core_config_cir_xccm_base 0xc0000000 - #define core_config_cir_yccm_base 0xe0000000 - #define core_config_family 4 - #define core_config_core_version 2 - #define core_config_family_name "arcv2em" - #define core_config_rgf_num_banks 2 - #define core_config_rgf_banked_regs 32 - #define core_config_rgf_num_wr_ports 2 - #define core_config_endian "little" - #define core_config_endian_little 1 - #define core_config_endian_big 0 - #define core_config_lpc_size 32 - #define core_config_pc_size 32 - #define core_config_addr_size 32 - #define core_config_unaligned 1 - #define core_config_code_density 1 - #define core_config_div_rem "radix2" - #define core_config_div_rem_radix2 1 - #define core_config_turbo_boost 1 - #define core_config_swap 1 - #define core_config_bitscan 1 - #define core_config_mpy_option "mpyd" - #define core_config_mpy_option_num 8 - #define core_config_shift_assist 1 - #define core_config_barrel_shifter 1 - #define core_config_dsp 1 - #define core_config_dsp2 1 - #define core_config_dsp_complex 1 - #define core_config_dsp_divsqrt "radix2" - #define core_config_dsp_divsqrt_radix2 1 - #define core_config_dsp_itu 1 - #define core_config_dsp_accshift "full" - #define core_config_dsp_accshift_full 1 - #define core_config_agu_large 1 - #define core_config_agu_wb_depth 4 - #define core_config_agu_accord 1 - #define core_config_xy 1 - #define core_config_xy_config "dccm_x_y" - #define core_config_xy_config_dccm_x_y 1 - #define core_config_xy_size 8192 - #define core_config_xy_size_KM "8K" - #define core_config_xy_interleave 1 - #define core_config_xy_x_base 0xc0000000 - #define core_config_xy_y_base 0xe0000000 - #define core_config_bitstream 1 - #define core_config_fpus_div 1 - #define core_config_fpu_mac 1 - #define core_config_fpus_mpy_slow 1 - #define core_config_fpus_div_slow 1 - #define core_config_timer0 1 - #define core_config_timer0_level 1 - #define core_config_timer0_vector 16 - #define core_config_timer1 1 - #define core_config_timer1_level 0 - #define core_config_timer1_vector 17 - #define core_config_action_points 2 - #define core_config_stack_check 1 - #define core_config_smart_stack_entries 8 - #define core_config_ifq_present 1 - #define core_config_ifq_entries 1 - #define core_config_interrupts_present 1 - #define core_config_interrupts_number 20 - #define core_config_interrupts_priorities 4 - #define core_config_interrupts_externals 16 - #define core_config_interrupts 20 - #define core_config_interrupt_priorities 4 - #define core_config_ext_interrupts 16 - #define core_config_interrupts_firq 1 - #define core_config_interrupts_base 0x0 - #define core_config_dccm_present 1 - #define core_config_dccm_size 0x20000 - #define core_config_dccm_base 0x80000000 - #define core_config_dccm_interleave 1 - #define core_config_iccm_present 1 - #define core_config_iccm0_present 1 - #define core_config_iccm_size 0x40000 - #define core_config_iccm0_size 0x40000 - #define core_config_iccm_base 0x00000000 - #define core_config_iccm0_base 0x00000000 - #define core_config_pct_counters 8 - #define core_config_dmac 1 - #define core_config_dmac_channels 2 - #define core_config_dmac_registers 0 - #define core_config_dmac_fifo_depth 2 - #define core_config_dmac_int_config "single_internal" - #define core_config_clock_speed 20 -#endif /* __core_config_h */ - diff --git a/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c b/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c deleted file mode 100644 index 8701a0e9c7..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "inc/arc/arc.h" -#include "inc/arc/arc_builtin.h" - -#include "dw_gpio_obj.h" - -#include "emsk_hardware.h" -/* - * Uncomment this to enable default - * gpio bit handler output message - * by uart - */ - -#ifdef ARC_FEATURE_DMP_PERIPHERAL -#define PERIPHERAL_BASE ARC_FEATURE_DMP_PERIPHERAL -#else -#define PERIPHERAL_BASE _arc_aux_read(AUX_DMP_PERIPHERAL) -#endif - -#if (USE_DW_GPIO_PORT_A) -static DEV_GPIO port_a; -static DW_GPIO_PORT dw_gpio_port_a; -static DEV_GPIO_HANDLER dw_gpio_bit_handler_a[EMSK_GPIO_A_INT_MAX_COUNT]; -static DW_GPIO_BIT_ISR dw_gpio_bit_isr_a = { - EMSK_GPIO_A_INT_MAX_COUNT, dw_gpio_bit_handler_a -}; - -static int32_t porta_open(uint32_t dir) -{ - return dw_gpio_open(&port_a, dir); -} - -static int32_t porta_close(void) -{ - return dw_gpio_close(&port_a); -} - -static int32_t porta_control(uint32_t ctrl_cmd, void *param) -{ - return dw_gpio_control(&port_a, ctrl_cmd, param); -} - -static int32_t porta_write(uint32_t val, uint32_t mask) -{ - return dw_gpio_write(&port_a, val, mask); -} - -static int32_t porta_read(uint32_t *val, uint32_t mask) -{ - return dw_gpio_read(&port_a, val, mask); -} - -static void porta_isr(void *ptr) -{ - dw_gpio_isr_handler(&port_a, ptr); -} - -static void porta_install(void) -{ - uint32_t i; - DEV_GPIO_PTR port_ptr = &port_a; - DEV_GPIO_INFO_PTR info_ptr = &(port_a.gpio_info); - DW_GPIO_PORT_PTR dw_port_ptr = &(dw_gpio_port_a); - - info_ptr->gpio_ctrl = (void *)dw_port_ptr; - info_ptr->opn_cnt = 0; - info_ptr->method = 0; - info_ptr->direction = 0; - info_ptr->extra = 0; - - dw_port_ptr->no = DW_GPIO_PORT_A; - dw_port_ptr->regs = (DW_GPIO_REG_PTR)(PERIPHERAL_BASE|REL_REGBASE_GPIO0); - dw_port_ptr->valid_bit_mask = EMSK_GPIO_A_VALID_MASK; - dw_port_ptr->intno = INTNO_GPIO; - dw_port_ptr->int_handler = porta_isr; - - for (i=0; igpio_bit_isr = &dw_gpio_bit_isr_a; - - port_ptr->gpio_open = porta_open; - port_ptr->gpio_close = porta_close; - port_ptr->gpio_control = porta_control; - port_ptr->gpio_write = porta_write; - port_ptr->gpio_read = porta_read; -} -#endif - -#if (USE_DW_GPIO_PORT_B) -static DEV_GPIO port_b; -static DW_GPIO_PORT dw_gpio_port_b; - -static int32_t portb_open(uint32_t dir) -{ - return dw_gpio_open(&port_b, dir); -} - -static int32_t portb_close(void) -{ - return dw_gpio_close(&port_b); -} - -static int32_t portb_control(uint32_t ctrl_cmd, void *param) -{ - return dw_gpio_control(&port_b, ctrl_cmd, param); -} - -static int32_t portb_write(uint32_t val, uint32_t mask) -{ - return dw_gpio_write(&port_b, val, mask); -} - -static int32_t portb_read(uint32_t *val, uint32_t mask) -{ - return dw_gpio_read(&port_b, val, mask); -} - -static void portb_isr(void *ptr) -{ - dw_gpio_isr_handler(&port_b, ptr); -} - -static void portb_install(void) -{ - DEV_GPIO_PTR port_ptr = &port_b; - DEV_GPIO_INFO_PTR info_ptr = &(port_b.gpio_info); - DW_GPIO_PORT_PTR dw_port_ptr = &(dw_gpio_port_b); - - info_ptr->gpio_ctrl = (void *)dw_port_ptr; - info_ptr->opn_cnt = 0; - info_ptr->method = 0; - info_ptr->direction = 0; - info_ptr->extra = 0; - - dw_port_ptr->no = DW_GPIO_PORT_B; - dw_port_ptr->regs = (DW_GPIO_REG_PTR)(PERIPHERAL_BASE|REL_REGBASE_GPIO0); - dw_port_ptr->valid_bit_mask = EMSK_GPIO_B_VALID_MASK; - - dw_port_ptr->intno = INTNO_GPIO; - dw_port_ptr->int_handler = portb_isr; - dw_port_ptr->gpio_bit_isr = NULL; - - port_ptr->gpio_open = portb_open; - port_ptr->gpio_close = portb_close; - port_ptr->gpio_control = portb_control; - port_ptr->gpio_write = portb_write; - port_ptr->gpio_read = portb_read; -} -#endif - - -#if (USE_DW_GPIO_PORT_C) -static DEV_GPIO port_c; -static DW_GPIO_PORT dw_gpio_port_c; - -static int32_t portc_open(uint32_t dir) -{ - return dw_gpio_open(&port_c, dir); -} - -static int32_t portc_close(void) -{ - return dw_gpio_close(&port_c); -} - -static int32_t portc_control(uint32_t ctrl_cmd, void *param) -{ - return dw_gpio_control(&port_c, ctrl_cmd, param); -} - -static int32_t portc_write(uint32_t val, uint32_t mask) -{ - return dw_gpio_write(&port_c, val, mask); -} - -static int32_t portc_read(uint32_t *val, uint32_t mask) -{ - return dw_gpio_read(&port_c, val, mask); -} - -static void portc_isr(void *ptr) -{ - dw_gpio_isr_handler(&port_c, ptr); -} - -static void portc_install(void) -{ - DEV_GPIO_PTR port_ptr = &port_c; - DEV_GPIO_INFO_PTR info_ptr = &(port_c.gpio_info); - DW_GPIO_PORT_PTR dw_port_ptr = &(dw_gpio_port_c); - - info_ptr->gpio_ctrl = (void *)dw_port_ptr; - info_ptr->opn_cnt = 0; - info_ptr->method = 0; - info_ptr->direction = 0; - info_ptr->extra = 0; - - dw_port_ptr->no = DW_GPIO_PORT_C; - dw_port_ptr->regs = (DW_GPIO_REG_PTR)(PERIPHERAL_BASE|REL_REGBASE_GPIO0); - dw_port_ptr->valid_bit_mask = EMSK_GPIO_C_VALID_MASK; - - dw_port_ptr->intno = INTNO_GPIO; - dw_port_ptr->int_handler = portc_isr; - dw_port_ptr->gpio_bit_isr = NULL; - - port_ptr->gpio_open = portc_open; - port_ptr->gpio_close = portc_close; - port_ptr->gpio_control = portc_control; - port_ptr->gpio_write = portc_write; - port_ptr->gpio_read = portc_read; -} -#endif - -#if (USE_DW_GPIO_PORT_D) -static DEV_GPIO port_d; -static DW_GPIO_PORT dw_gpio_port_d; - -static int32_t portd_open(uint32_t dir) -{ - return dw_gpio_open(&port_d, dir); -} - -static int32_t portd_close(void) -{ - return dw_gpio_close(&port_d); -} - -static int32_t portd_control(uint32_t ctrl_cmd, void *param) -{ - return dw_gpio_control(&port_d, ctrl_cmd, param); -} - -static int32_t portd_write(uint32_t val, uint32_t mask) -{ - return dw_gpio_write(&port_d, val, mask); -} - -static int32_t portd_read(uint32_t *val, uint32_t mask) -{ - return dw_gpio_read(&port_d, val, mask); -} - -static void portd_isr(void *ptr) -{ - dw_gpio_isr_handler(&port_d, ptr); -} - -static void portd_install(void) -{ - DEV_GPIO_PTR port_ptr = &port_d; - DEV_GPIO_INFO_PTR info_ptr = &(port_d.gpio_info); - DW_GPIO_PORT_PTR dw_port_ptr = &(dw_gpio_port_d); - - info_ptr->gpio_ctrl = (void *)dw_port_ptr; - info_ptr->opn_cnt = 0; - info_ptr->method = 0; - info_ptr->direction = 0; - info_ptr->extra = 0; - - dw_port_ptr->no = DW_GPIO_PORT_D; - dw_port_ptr->regs = (DW_GPIO_REG_PTR)(PERIPHERAL_BASE|REL_REGBASE_GPIO0); - dw_port_ptr->valid_bit_mask = EMSK_GPIO_D_VALID_MASK; - - dw_port_ptr->intno = INTNO_GPIO; - dw_port_ptr->int_handler = portd_isr; - dw_port_ptr->gpio_bit_isr = NULL; - - port_ptr->gpio_open = portd_open; - port_ptr->gpio_close = portd_close; - port_ptr->gpio_control = portd_control; - port_ptr->gpio_write = portd_write; - port_ptr->gpio_read = portd_read; -} -#endif - -DEV_GPIO_PTR gpio_get_dev(int32_t gpio_id) -{ - static uint32_t install_flag = 0; - - /* intall device objects */ - if (install_flag == 0) { - install_flag = 1; - dw_gpio_all_install(); - } - - switch (gpio_id) { -#if (USE_DW_GPIO_PORT_A) - case DW_GPIO_PORT_A: return &port_a; -#endif -#if (USE_DW_GPIO_PORT_B) - case DW_GPIO_PORT_B: return &port_b; -#endif -#if (USE_DW_GPIO_PORT_C) - case DW_GPIO_PORT_C: return &port_c; -#endif -#if (USE_DW_GPIO_PORT_D) - case DW_GPIO_PORT_D: return &port_d; -#endif - default: - break; - } - return NULL; -} - -void dw_gpio_all_install(void) -{ -#if (USE_DW_GPIO_PORT_A) - porta_install(); -#endif -#if (USE_DW_GPIO_PORT_B) - portb_install(); -#endif -#if (USE_DW_GPIO_PORT_C) - portc_install(); -#endif -#if (USE_DW_GPIO_PORT_D) - portd_install(); -#endif -} diff --git a/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h b/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h deleted file mode 100644 index d39a09159d..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/dw_gpio_obj.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef _DW_GPIO_OBJ_H_ -#define _DW_GPIO_OBJ_H_ - -#include "device/designware/gpio/dw_gpio.h" - -/** - * \name Designware GPIO Port Bank Control Macros - * @{ - */ -#define USE_DW_GPIO_PORT_A 1 -#define USE_DW_GPIO_PORT_B 1 -#define USE_DW_GPIO_PORT_C 1 -#define USE_DW_GPIO_PORT_D 1 -/** @} end of name */ - -/** - * \name Designware GPIO Port Interrupt Available Number Macros - * @{ - */ -#define EMSK_GPIO_A_INT_MAX_COUNT 32 -#define EMSK_GPIO_B_INT_MAX_COUNT 0 -#define EMSK_GPIO_C_INT_MAX_COUNT 0 -#define EMSK_GPIO_D_INT_MAX_COUNT 0 -/** @} end of name */ - -/** - * \name Designware GPIO Port Available Bits Macros - * @{ - */ -#define EMSK_GPIO_A_VALID_MASK DW_GPIO_MASK_ALL -#define EMSK_GPIO_B_VALID_MASK DW_GPIO_MASK_ALL -#define EMSK_GPIO_C_VALID_MASK DW_GPIO_MASK_ALL -#define EMSK_GPIO_D_VALID_MASK DW_GPIO_MASK_ALL -/** @} end of name */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern void dw_gpio_all_install(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _DW_GPIO_OBJ_H_*/ diff --git a/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c b/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c deleted file mode 100644 index 9e3ebd3db9..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "inc/arc/arc.h" -#include "inc/arc/arc_builtin.h" -#include "inc/embARC_toolchain.h" -#include "inc/embARC_error.h" - -#include "inc/arc/arc_exception.h" -#include "device/designware/uart/dw_uart.h" -#include "dw_uart_obj.h" - -#include "emsk_hardware.h" - -#define DW_UART_FIFO_LEN 32 - -/** - * \name EMSK DesignWare UART 0 Object Instantiation - * @{ - */ -#if (USE_DW_UART_0) -static void dw_uart_0_isr(void *ptr); -#define DW_UART_0_RELBASE (REL_REGBASE_UART0) /*!< designware uart 0 relative baseaddr */ -#define DW_UART_0_INTNO (INTNO_UART0) /*!< designware uart 0 interrupt number */ - -DEV_UART dw_uart_0; /*!< designware uart object */ -DW_UART_CTRL dw_uart_0_ctrl = { /*!< designware uart 0 ctrl */ - 0, CLK_BUS_APB, DW_UART_0_INTNO, (INT_HANDLER)dw_uart_0_isr, - DW_UART_FIFO_LEN, DW_UART_FIFO_LEN, 0 -}; - -/** designware uart 0 open */ -static int32_t dw_uart_0_open (uint32_t baud) -{ - return dw_uart_open(&dw_uart_0, baud); -} -/** designware uart 0 close */ -static int32_t dw_uart_0_close (void) -{ - return dw_uart_close(&dw_uart_0); -} -/** designware uart 0 control */ -static int32_t dw_uart_0_control (uint32_t ctrl_cmd, void *param) -{ - return dw_uart_control(&dw_uart_0, ctrl_cmd, param); -} -/** designware uart 0 write */ -static int32_t dw_uart_0_write (const void *data, uint32_t len) -{ - return dw_uart_write(&dw_uart_0, data, len); -} -/** designware uart 0 close */ -static int32_t dw_uart_0_read (void *data, uint32_t len) -{ - return dw_uart_read(&dw_uart_0, data, len); -} -/** designware uart 0 interrupt rountine */ -static void dw_uart_0_isr(void *ptr) -{ - dw_uart_isr(&dw_uart_0, ptr); -} -/** install designware uart 0 to system */ -static void dw_uart_0_install(void) -{ - uint32_t uart_abs_base = 0; - DEV_UART *dw_uart_ptr = &dw_uart_0; - DEV_UART_INFO *dw_uart_info_ptr = &(dw_uart_0.uart_info); - DW_UART_CTRL *dw_uart_ctrl_ptr = &dw_uart_0_ctrl; - - /** - * get absolute designware base address - */ - uart_abs_base = (uint32_t)PERIPHERAL_BASE + DW_UART_0_RELBASE; - dw_uart_ctrl_ptr->dw_uart_regbase = uart_abs_base; - - /** uart info init */ - dw_uart_info_ptr->uart_ctrl = (void *)dw_uart_ctrl_ptr; - dw_uart_info_ptr->opn_cnt = 0; - dw_uart_info_ptr->status = 0; - dw_uart_info_ptr->baudrate = UART_BAUDRATE_115200; /* default 115200bps */ - - /** uart dev init */ - dw_uart_ptr->uart_open = dw_uart_0_open; - dw_uart_ptr->uart_close = dw_uart_0_close; - dw_uart_ptr->uart_control = dw_uart_0_control; - dw_uart_ptr->uart_write = dw_uart_0_write; - dw_uart_ptr->uart_read = dw_uart_0_read; - -} -#endif /* USE_DW_UART_0 */ -/** @} end of name */ - -/** - * \name EMSK DesignWare UART 1 Object Instantiation - * @{ - */ -#if (USE_DW_UART_1) -static void dw_uart_1_isr(void *ptr); -#define DW_UART_1_RELBASE (REL_REGBASE_UART1) /*!< designware uart 1 relative baseaddr */ -#define DW_UART_1_INTNO (INTNO_UART1) /*!< designware uart 1 interrupt number */ - -DEV_UART dw_uart_1; /*!< designware uart 1 object */ -DW_UART_CTRL dw_uart_1_ctrl = { /*!< designware uart 1 ctrl */ - 0, CLK_BUS_APB, DW_UART_1_INTNO, (INT_HANDLER)dw_uart_1_isr, - DW_UART_FIFO_LEN, DW_UART_FIFO_LEN, 0 -}; - -/** designware uart 1 open */ -static int32_t dw_uart_1_open (uint32_t baud) -{ - return dw_uart_open(&dw_uart_1, baud); -} -/** designware uart 1 close */ -static int32_t dw_uart_1_close (void) -{ - return dw_uart_close(&dw_uart_1); -} -/** designware uart 1 control */ -static int32_t dw_uart_1_control (uint32_t ctrl_cmd, void *param) -{ - return dw_uart_control(&dw_uart_1, ctrl_cmd, param); -} -/** designware uart 1 write */ -static int32_t dw_uart_1_write (const void *data, uint32_t len) -{ - return dw_uart_write(&dw_uart_1, data, len); -} -/** designware uart 1 close */ -static int32_t dw_uart_1_read (void *data, uint32_t len) -{ - return dw_uart_read(&dw_uart_1, data, len); -} -/** designware uart 1 interrupt routine */ -static void dw_uart_1_isr(void *ptr) -{ - dw_uart_isr(&dw_uart_1, ptr); -} -/** install designware uart 1 to system */ -static void dw_uart_1_install(void) -{ - uint32_t uart_abs_base = 0; - DEV_UART *dw_uart_ptr = &dw_uart_1; - DEV_UART_INFO *dw_uart_info_ptr = &(dw_uart_1.uart_info); - DW_UART_CTRL *dw_uart_ctrl_ptr = &dw_uart_1_ctrl; - - /** - * get absolute designware base address - */ - uart_abs_base = (uint32_t)PERIPHERAL_BASE + DW_UART_1_RELBASE; - dw_uart_ctrl_ptr->dw_uart_regbase = uart_abs_base; - - /** uart info init */ - dw_uart_info_ptr->uart_ctrl = (void *)dw_uart_ctrl_ptr; - dw_uart_info_ptr->opn_cnt = 0; - dw_uart_info_ptr->status = 0; - dw_uart_info_ptr->baudrate = UART_BAUDRATE_115200; /* default 115200bps */ - - /** uart dev init */ - dw_uart_ptr->uart_open = dw_uart_1_open; - dw_uart_ptr->uart_close = dw_uart_1_close; - dw_uart_ptr->uart_control = dw_uart_1_control; - dw_uart_ptr->uart_write = dw_uart_1_write; - dw_uart_ptr->uart_read = dw_uart_1_read; -} -#endif /* USE_DW_UART_1 */ -/** @} end of name */ - -/** get one designware device structure */ -DEV_UART_PTR uart_get_dev(int32_t uart_id) -{ - static uint32_t install_flag = 0; - - /* intall device objects */ - if (install_flag == 0) { - install_flag = 1; - dw_uart_all_install(); - } - - switch (uart_id) { -#if (USE_DW_UART_0) - case DW_UART_0_ID: - return &dw_uart_0; - break; -#endif -#if (USE_DW_UART_1) - case DW_UART_1_ID: - return &dw_uart_1; - break; -#endif - default: - break; - } - return NULL; -} - -/** - * \brief install all uart objects - * \note \b MUST be called during system init - */ -void dw_uart_all_install(void) -{ -#if (USE_DW_UART_0) - dw_uart_0_install(); -#endif -#if (USE_DW_UART_1) - dw_uart_1_install(); -#endif -} diff --git a/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h b/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h deleted file mode 100644 index 7a63880fab..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/dw_uart_obj.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef _DW_UART_OBJ_H_ -#define _DW_UART_OBJ_H_ - -#include "device/device_hal/inc/dev_uart.h" - -/** - * \name DesignWare UART Object Number - * @{ - */ -#define DW_UART_NUM (2) /*!< DesignWare UART valid number */ -/** @} end of name */ - -/** - * \name Designware UART Object ID Macros - * @{ - */ -#define DW_UART_0_ID 0 /*!< uart 0 id macro */ -#define DW_UART_1_ID 1 /*!< uart 1 id macro */ -/** @} end of name */ - -/** - * \name Designware UART Object Control Macros - * @{ - */ -#define USE_DW_UART_0 1 /*!< enable use designware uart 0 */ -#define USE_DW_UART_1 1 /*!< enable use designware uart 1 */ -/** @} end of name */ - -/** - * \name Designware UART Ringbuffer Size Control Macros - * @{ - */ -#define MAX_SNDBUF_SIZE 256 /*!< max size of uart send buffer */ -#define MAX_RCVBUF_SIZE 10 /*!< max size of uart recv buffer */ -/** @} end of name */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern void dw_uart_all_install(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _DW_UART_OBJ_H_ */ diff --git a/bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h b/bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h deleted file mode 100644 index 706aac94c4..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/embARC_BSP_config.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef _EMBARC_BSP_CONFIG_H_ -#define _EMBARC_BSP_CONFIG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define BOARD_EMSK -/**************************************************************************** - * BSP Definitions - ****************************************************************************/ -/** - * Toolchain Definition for MetaWare or GNU - */ -//#define __MW__ -#define __GNU__ - -/** - * Must be set. - * If changed, modify .lcf file for - * .stack ALIGN(4) SIZE(524288): {} - * .heap? ALIGN(4) SIZE(524288): {} - */ -#define _STACKSIZE (4 * 1024) -#define _HEAPSZ (32 * 1024) - - - -#ifdef __cplusplus -} -#endif - -#endif /* _EMBARC_CONFIG_BSP_H_ */ diff --git a/bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h b/bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h deleted file mode 100644 index d60e314389..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/emsk_hardware.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef _EMSK_HARDWARE_H_ -#define _EMSK_HARDWARE_H_ - -#include "inc/arc/arc_feature_config.h" - -/** CPU Clock Frequency definition */ -#if defined(BOARD_CPU_FREQ) - /*!< Get cpu clock frequency definition from build system */ - #define CLK_CPU (BOARD_CPU_FREQ) -#elif defined(ARC_FEATURE_CPU_CLOCK_FREQ) - /*!< Get cpu clock frequency definition from tcf file */ - #define CLK_CPU (ARC_FEATURE_CPU_CLOCK_FREQ) -#else - /*!< Default cpu clock frequency */ - #define CLK_CPU (20000000) -#endif - -/** Peripheral Bus Reference Clock definition */ -#ifdef BOARD_DEV_FREQ - /*!< Get peripheral bus reference clock defintion from build system */ - #define CLK_BUS_APB (BOARD_DEV_FREQ) -#else - /*!< Default peripheral bus reference clock defintion */ - #define CLK_BUS_APB (50000000U) -#endif - -#ifdef ARC_FEATURE_DMP_PERIPHERAL -#define PERIPHERAL_BASE ARC_FEATURE_DMP_PERIPHERAL -#else -#define PERIPHERAL_BASE _arc_aux_read(AUX_DMP_PERIPHERAL) -#endif - -/* Device Register Base Address */ -#define REL_REGBASE_PINMUX (0x00000000U) /*!< PINMUX */ -#define REL_REGBASE_SPI_MST_CS_CTRL (0x00000014U) /*!< SPI Master Select Ctrl */ -#define REL_REGBASE_GPIO0 (0x00002000U) /*!< GPIO 0 Onboard */ -#define REL_REGBASE_TIMERS (0x00003000U) /*!< DW TIMER */ -#define REL_REGBASE_I2C0 (0x00004000U) /*!< I2C 0 */ -#define REL_REGBASE_I2C1 (0x00005000U) /*!< I2C 1 */ -#define REL_REGBASE_SPI0 (0x00006000U) /*!< SPI Master */ -#define REL_REGBASE_SPI1 (0x00007000U) /*!< SPI Slave */ -#define REL_REGBASE_UART0 (0x00008000U) /*!< UART0 is connected to PMOD */ -#define REL_REGBASE_UART1 (0x00009000U) /*!< UART1 is USB-UART use UART1 as default */ -#define REL_REGBASE_UART2 (0x0000A000U) /*!< UART2 */ -#define REL_REGBASE_WDT (0x0000B000U) /*!< WDT */ -// #define REL_REGBASE_I2S_MASTER_IN (0x0000C000U) /*!< I2S Master In */ -// #define REL_REGBASE_I2S_MASTER_OUT (0x0000D000U) /*!< I2S Master Out */ -// #define REL_REGBASE_GMAC (0x0000E000U) /*!< GMAC */ - -/* Interrupt Connection */ -#define INTNO_TIMER0 16 /*!< ARC Timer0 */ -#define INTNO_TIMER1 17 /*!< ARC Timer1 */ -#define INTNO_SECURE_TIMER0 20 /*!< Core Secure Timer 0 */ -#define INTNO_DMA_START 22 /*!< Core DMA Controller */ -#define INTNO_DMA_COMPLETE 22 /*!< Core DMA Controller Complete */ -#define INTNO_DMA_ERROR 23 /*!< Core DMA Controller Error */ -#define INTNO_GPIO 24 /*!< GPIO controller */ -#define INTNO_I2C0 25 /*!< I2C_0 controller */ -#define INTNO_I2C1 26 /*!< I2C_1 controller */ -#define INTNO_SPI_MASTER 27 /*!< SPI Master controller */ -#define INTNO_SPI_SLAVE 28 /*!< SPI Slave controller */ -#define INTNO_UART0 29 /*!< UART0 */ -#define INTNO_UART1 30 /*!< UART1 */ -#define INTNO_UART2 31 /*!< UART2 */ -#define INTNO_DW_WDT 32 /*!< WDT */ -#define INTNO_DW_TMR0 33 /*!< DW Timer 0 */ -#define INTNO_DW_TMR1 34 /*!< DW Timer 1 */ -// #define INTNO_I2S_Master_In 33 /*!< I2S Master In */ -// #define INTNO_I2S_Master_Out 34 /*!< I2S Master Out */ -// #define INTNO_GMAC 35 /*!< GMAC */ - -/* SPI Mater Signals Usage */ -#define EMSK_SPI_LINE_0 0 /*!< CS0 -- Pmod 6 pin1 */ -#define EMSK_SPI_LINE_1 1 /*!< CS1 -- Pmod 5 pin1 or Pmod 6 pin 7 */ -#define EMSK_SPI_LINE_2 2 /*!< CS2 -- Pmod 6 pin8 */ -#define EMSK_SPI_LINE_SDCARD 3 /*!< CS3 -- On-board SD card */ -#define EMSK_SPI_LINE_SPISLAVE 4 /*!< CS4 -- Internal SPI slave */ -#define EMSK_SPI_LINE_SFLASH 5 /*!< CS5 -- On-board SPI Flash memory */ - -#endif /* _EMSK_HARDWARE_H_ */ diff --git a/bsp/synopsys/emsk_em9d/drivers/mux.c b/bsp/synopsys/emsk_em9d/drivers/mux.c deleted file mode 100644 index a56cb15212..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/mux.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "mux_hal.h" -#include "mux.h" - -static MUX_REG *mux_ctrl_regs = (MUX_REG *)0; - -/** initialize i2c controller and set slave device address */ -void mux_init(MUX_REG *mux_regs) -{ - // Initialize Mux controller registers by default values - mux_regs[PMOD_MUX_CTRL] = PMOD_MUX_CTRL_DEFAULT; - mux_regs[SPI_MAP_CTRL] = SPI_MAP_CTRL_DEFAULT; - mux_regs[UART_MAP_CTRL] = UART_MAP_CTRL_DEFAULT; - mux_ctrl_regs = mux_regs; -} - -/** Get mux ctrl register pointer, only valid after mux_init */ -MUX_REG *get_mux_regs(void) -{ - return mux_ctrl_regs; -} - -/** set PMOD muxer scheme */ -void set_pmod_mux(MUX_REG *mux_regs, uint32_t val) -{ - mux_regs[PMOD_MUX_CTRL] = val; -} - -/** get PMOD muxer scheme */ -uint32_t get_pmod_mux(MUX_REG *mux_regs) -{ - return (uint32_t) mux_regs[PMOD_MUX_CTRL]; -} - -/** set PMOD muxer scheme */ -void change_pmod_mux(MUX_REG *mux_regs, uint32_t val, uint32_t change_bits) -{ - mux_regs[PMOD_MUX_CTRL] = ((mux_regs[PMOD_MUX_CTRL] & ~change_bits) | val); -} - -/** set SPI connection scheme */ -void set_spi_map(MUX_REG *mux_regs, uint32_t val) -{ - mux_regs[SPI_MAP_CTRL] = val; -} - -/** get SPI connection scheme */ -uint32_t get_spi_map(MUX_REG *mux_regs) -{ - return (uint32_t) mux_regs[SPI_MAP_CTRL]; -} - -/** set UART connection scheme */ -void set_uart_map(MUX_REG *mux_regs, uint32_t val) -{ - mux_regs[UART_MAP_CTRL] = val; -} - -/** get UART connection scheme */ -uint32_t get_uart_map(MUX_REG *mux_regs) -{ - return (uint32_t) mux_regs[UART_MAP_CTRL]; -} diff --git a/bsp/synopsys/emsk_em9d/drivers/mux.h b/bsp/synopsys/emsk_em9d/drivers/mux.h deleted file mode 100644 index 47f796bebe..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/mux.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef _MUX_H_ -#define _MUX_H_ - -#include "inc/embARC_toolchain.h" - -#define BIT0 (0) -#define BIT1 (1) -#define BIT2 (2) -#define BIT3 (3) -#define PM1_OFFSET (0) -#define PM2_OFFSET (4) -#define PM3_OFFSET (8) -#define PM4_OFFSET (12) -#define PM5_OFFSET (16) -#define PM6_OFFSET (20) -#define PM7_OFFSET (24) - -#define PM1_MASK (0xf << PM1_OFFSET) -#define PM2_MASK (0xf << PM2_OFFSET) -#define PM3_MASK (0xf << PM3_OFFSET) -#define PM4_MASK (0xf << PM4_OFFSET) -#define PM5_MASK (0xf << PM5_OFFSET) -#define PM6_MASK (0xf << PM6_OFFSET) -#define PM7_MASK (0xf << PM7_OFFSET) - - -#define SPI_MAP_NORMAL (0) -#define SPI_MAP_LOOPBACK (1) - -#define UART_MAP_TYPE4 (0xE4) -#define UART_MAP_TYPE3 (0x6C) - -/** - * \name Default pin muxer settings - * @{ - */ -#define PMOD_MUX_CTRL_DEFAULT (0) /*!< all pins are configured as GPIO inputs */ -#define SPI_MAP_CTRL_DEFAULT (SPI_MAP_NORMAL) /*!< normal SPI mode */ -#define UART_MAP_CTRL_DEFAULT (UART_MAP_TYPE4) /*!< TYPE4 PMOD compatible */ -/** @} end of name */ - -/** - * \name PMOD 1 Multiplexor - * @{ - */ -#define PM1_UR_GPIO_C ((0 << BIT0) << PM1_OFFSET) /*!< Pmod1[4:1] are connected to DW GPIO Port C[11:8] */ -#define PM1_UR_UART_0 ((1 << BIT0) << PM1_OFFSET) /*!< Pmod1[4:1] are connected to DW UART0 signals */ - -#define PM1_LR_GPIO_A ((0 << BIT2) << PM1_OFFSET) /*!< Pmod1[10:7] are connected to DW GPIO Port A[11:8] */ -#define PM1_LR_SPI_S ((1 << BIT2) << PM1_OFFSET) /*!< Pmod1[10:7] are connected to DW SPI Slave signals */ -/** @} end of name */ - - -/** - * \name PMOD 2 Multiplexor - * @{ - */ -#define PM2_GPIO_AC ((0 << BIT0) << PM2_OFFSET) /*!< Pmod2[4:1] are connected to DW GPIO Port C[15:12], - Pmod2[10:7] are connected to DW GPIO Port A[15:12] */ - -#define PM2_I2C_HRI ((1 << BIT0) << PM2_OFFSET) /*!< connect I2C to Pmod2[4:1] and halt/run interface to Pmod2[10:7] */ -/** @} end of name */ - - -/** - * \name PMOD 3 Multiplexor - * @{ - */ -#define PM3_GPIO_AC ((0 << BIT0) << PM3_OFFSET) /*!< Pmod3[4:1] are connected to DW GPIO Port C[19:16], - Pmod3[10:7] are connected to DW GPIO Port A[19:16] */ - -#define PM3_I2C_GPIO_D ((1 << BIT0) << PM3_OFFSET) /*!< Pmod3[4:3] are connected to DW I2C signals, - Pmod3[2:1] are connected to DW GPIO Port D[1:0], - Pmod3[10:7] are connected to DW GPIO Port D[3:2] */ -/** @} end of name */ - - -/** - * \name PMOD 4 Multiplexor - * @{ - */ -#define PM4_GPIO_AC ((0 << BIT0) << PM4_OFFSET) /*!< Pmod4[4:1] are connected to DW GPIO Port C[23:20], - Pmod4[10:7] are connected to DW GPIO Port A[23:20] */ - -#define PM4_I2C_GPIO_D ((1 << BIT0) << PM4_OFFSET) /*!< Pmod4[4:3] are connected to DW I2C signals, - Pmod4[2:1] are connected to DW GPIO Port D[5:4], - Pmod4[10:7] are connected to DW GPIO Port D[7:6] */ -/** @} end of name */ - -/** - * \name PMOD 5 Multiplexor - * @{ - */ -#define PM5_UR_GPIO_C ((0 << BIT0) << PM5_OFFSET) /*!< Pmod5[4:1] are connected to DW GPIO Port C[27:24] */ -#define PM5_UR_SPI_M1 ((1 << BIT0) << PM5_OFFSET) /*!< Pmod5[4:1] are connected to DW SPI Master signals using CS1_N */ - -#define PM5_LR_GPIO_A ((0 << BIT2) << PM5_OFFSET) /*!< Pmod5[10:7] are connected to DW GPIO Port A[27:24] */ -#define PM5_LR_SPI_M2 ((1 << BIT2) << PM5_OFFSET) /*!< Pmod5[10:7] are connected to DW SPI Master signals using CS2_N */ -/** @} end of name */ - - -/** - * \name PMOD 6 Multiplexor - * @{ - */ -#define PM6_UR_GPIO_C ((0 << BIT0) << PM6_OFFSET) /*!< Pmod6[4:1] are connected to DW GPIO Port C[31:28] */ -#define PM6_UR_SPI_M0 ((1 << BIT0) << PM6_OFFSET) /*!< Pmod6[4:1] are connected to DW SPI Master signals using CS0_N */ - -#define PM6_LR_GPIO_A ((0 << BIT2) << PM6_OFFSET) /*!< Pmod6[10:7] are connected to DW GPIO Port A[31:28] */ - -#define PM6_LR_CSS_STAT ((1 << BIT2) << PM6_OFFSET) /*!< Pmod6[8:7] are connected to the DW SPI Master chip select signals CS1_N and CS2_N, - Pmod6[6:5] are connected to the ARC EM halt and sleep status signals */ -/** @} end of name */ - -/** - * \name PMOD 7 Multiplexor - * @{ - */ -#define PM7_GPIO_D ((0 << BIT0) << PM7_OFFSET) /*!< Pmod7[4:1] are connected to DW GPIO Port D[11:8] */ -#define PM7_STAT ((1 << BIT0) << PM7_OFFSET) /*!< Pmod7[4:1] are connected to the ARC EM sleep status signals */ -/** @} end of name */ -typedef volatile uint32_t MUX_REG; - -#ifdef __cplusplus -extern "C" { -#endif - -extern void mux_init(MUX_REG *mux_regs); -extern MUX_REG *get_mux_regs(void); -extern void set_pmod_mux(MUX_REG *mux_regs, uint32_t val); -extern uint32_t get_pmod_mux(MUX_REG *mux_regs); -extern void change_pmod_mux(MUX_REG *mux_regs, uint32_t val, uint32_t change_bits); -extern void set_spi_map(MUX_REG *mux_regs, uint32_t val); -extern uint32_t get_spi_map(MUX_REG *mux_regs); -extern void set_uart_map(MUX_REG *mux_regs, uint32_t val); -extern uint32_t get_uart_map(MUX_REG *mux_regs); - -#ifdef __cplusplus -} -#endif - -#endif /* _MUX_H_ */ diff --git a/bsp/synopsys/emsk_em9d/drivers/mux_hal.h b/bsp/synopsys/emsk_em9d/drivers/mux_hal.h deleted file mode 100644 index 9a5c8c14b9..0000000000 --- a/bsp/synopsys/emsk_em9d/drivers/mux_hal.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2018, Synopsys, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef _MUX_HAL_H_ -#define _MUX_HAL_H_ - -/** - * \name Mux Control Register Index - * @{ - */ -#define PMOD_MUX_CTRL 0 /*!< 32-bits, offset 0x0, - This register controls mapping of the peripheral device signals on Pmod connectors */ - -#define I2C_MAP_CTRL 1 /*!< 32-bits, offset 0x4 */ - -#define SPI_MAP_CTRL 2 /*!< 32-bits, offset 0x8, - SPI_MAP_CTRL[0] selects the mode of operation of the SPI Slave: - - Normal operation, SPI_MAP_CTRL[0]=0: SPI Slave is connected to Pmod1 at connector J1. - - Loop-back mode, SPI_MAP_CTRL[0]=1: SPI Slave is connected to the SPI Master inside the FPGA using CS4. - */ - -#define UART_MAP_CTRL 3 /*!< 32-bits, offset 0x8, - This register controls the mapping of the UART signals on the Pmod1 connector. */ -/** @} end of name */ - - -#endif /* _MUX_HAL_H_ */ diff --git a/bsp/synopsys/emsk_em9d/emsk_em9d.ld b/bsp/synopsys/emsk_em9d/emsk_em9d.ld deleted file mode 100644 index 849ecf6329..0000000000 --- a/bsp/synopsys/emsk_em9d/emsk_em9d.ld +++ /dev/null @@ -1,114 +0,0 @@ -MEMORY -{ - ICCM : ORIGIN = 0x00000000, LENGTH = 0x40000 - DCCM : ORIGIN = 0x80000000, LENGTH = 0x20000 - EXT_RAM : ORIGIN = 0x10000000, LENGTH = 0x8000000 -} -ENTRY(_start) -SECTIONS -{ - .init : - { - _f_init = .; - KEEP (*(.init_vector)) - KEEP (*(.init_bootstrap)) - _e_init = .; - } > EXT_RAM - .vector : ALIGN(1024) - { - _f_vector = .; - *(.vector) - _e_vector = .; - } > EXT_RAM - .text : ALIGN(4) - { - _f_text = .; - *(.text .text.* .gnu.linkonce.t.*) - _e_text = .; - } > EXT_RAM - .rodata : ALIGN(4) - { - _f_rodata = .; - - /* section information for finsh shell */ - . = ALIGN(4); - __fsymtab_start = .; - KEEP(*(FSymTab)) - __fsymtab_end = .; - . = ALIGN(4); - __vsymtab_start = .; - KEEP(*(VSymTab)) - __vsymtab_end = .; - - . = ALIGN(4); - __rt_init_start = .; - KEEP(*(SORT(.rti_fn*))) - __rt_init_end = .; - . = ALIGN(4); - - - __CTOR_LIST__ = .; - LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) - KEEP(*(SORT_BY_NAME(".ctors*"))) - LONG(0) - __CTOR_END__ = .; - . = ALIGN(4); - __init_array_start = .; - KEEP(*(SORT_BY_NAME(".init_array*"))) - __init_array_end = .; - . = ALIGN(4); - __DTOR_LIST__ = .; - LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) - KEEP(*(SORT_BY_NAME(".dtors*"))) - LONG(0) - __DTOR_END__ = .; - *(.rodata .rodata.* .gnu.linkonce.r.*) - _e_rodata = .; - } > EXT_RAM - .data : ALIGN(4) - { - _f_data = .; - *(.data .data.* .gnu.linkonce.d.*) - _f_sdata = .; - __SDATA_BEGIN__ = .; - *(.sdata .sdata.* .gnu.linkonce.s.*) - _e_sdata = .; - _e_data = .; - } > EXT_RAM - .bss (NOLOAD) : ALIGN(8) - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - _f_bss = .; - _f_sbss = .; - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - _e_sbss = .; - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - _e_bss = .; - } > EXT_RAM - .stack (NOLOAD) : - { - . = ALIGN(4); - _f_stack = .; - . = . + 4096; - _e_stack = .; - } > EXT_RAM - .heap (NOLOAD) : - { - . = ALIGN(4); - __start_heap = . ; - _f_heap = .; - . = . + 0x8000; - _e_heap = .; - __end_heap = . ; - } > EXT_RAM - _load_addr_text = LOADADDR(.text); - _load_addr_rodata = LOADADDR(.rodata); - _load_addr_data = LOADADDR(.data); -} diff --git a/bsp/synopsys/emsk_em9d/figures/emsk_board.jpg b/bsp/synopsys/emsk_em9d/figures/emsk_board.jpg deleted file mode 100644 index c96c3d6b6efe2c637ff55cb78767089c310740be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 483486 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⪼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

    7!PP_GdKS0+Yc80kL<+}UPL^{ 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

    HwCV3{VbWFNs>)O-wVC) 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 uy=_`Os9 zHMbA=)mv^MVg;JHIok^_Vs&_fRYoC4p`PHlkIG`8|BtGo=HUcP>20y#Ilr=Pu7IqT!cLf zIirU0jHmUzl_|57s^0Bs@)Tvrr1^ z)yY5FKS#O~^twdXlbzt#H>>^ZHG?Fe1GM`K*JZ@*VUw0KobyaH9>d9bP%Po$HTWLVN(UuOYiPm?)6$?tv}fK zzg(v_436QrQ5etV>A|V3$X~fRquBKn#7d~}Wyu`zk zu!fcD1;aFqx>X(d+Tv};ezDyHTWvsqK%6gv_YFt1q7c(c)JsjDskq4ma?}wG*&GQD ztr4?0?a=AXmon&4C$-Ed4mz}0{u7vpr~3B9$KRQO$>kPXq_yFdq=btTLZTZ))WiNmqVitJAzB2t1|-P>QY7%g-fUH5{nFd|BIwb5}#MpkV9tgD})4E?@Y`u5Wh!JD;Oe(Auv7 z_XCqqC671O*NfaB7vu>|uv`o*GloF6>_9 z!snn9`!Bl;kgKv1Ow}e-%?pF z>SO6(qCRlJ-_5UjMu0dz%DY2xqda><|XQTH0lu~aY14JBzll9 zE}<(y%Ib559Uf=pFd|EOZd@a<%9>vo;4 zSxQK`3UadoE3@AWA`41)nSJK@|-cT zWk}

    J;s;pIOMjBOPjf-lfX>Jy|$I0mTWw=K+7^_!| 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 z�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%0A*}hH+qoXr4CoG)$8HXC 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 S2FY{)0000R8Sa1B_^0N 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